This is tifflink.c in view mode; [Download] [Up]
/* * tifflink.c - A utility to take all .tiff files in a directory (and sub- * directories) and replace duplicate .tiff files with hard links. * * Version 1.0, Michael.Glenn@Dartmouth.edu, March 3 1993. */ #include <stdio.h> #include <sys/types.h> #include <sys/dir.h> #include <sys/stat.h> #define PRIME 101 struct node { char *file; int inode, size; struct node *next; }; struct node *table[PRIME]; char * string_copy (char *str) { char *p; p = (char *)malloc (strlen(str)+1); strcpy(p,str); return p; } struct node * make_node (char *file, int size, int inode) { struct node *p; p = (struct node *) malloc (sizeof(struct node)); p->file = string_copy(file); p->size = size; p->inode = inode; p->next = 0; return p; } init_table() { int i; for (i=0; i<sizeof(table); i++) table[i] = 0; } free_node (struct node *p) { if (!p) return; free (p->file); free (p); } free_table() { struct node *p, *q; int i; for (i=0; i<sizeof(table); i++) { p = table[i]; while (p) { q = p; p = p->next; free_node(q); } table[i] = 0; } } is_tiff_file(char *fname) { int l; return (l=strlen(fname)) > 4 && !strcmp(&(fname[l-5]), ".tiff"); } link_files (char *file1, char *file2) { unlink (file2); link (file1, file2); printf("Files %s and %s hard linked.\n", file1, file2); } do_diff(char *file1, char *file2) { FILE *fp; int i; char buff[256]; sprintf(buff,"diff \"%s\" \"%s\"",file1,file2); fp = popen(buff,"r"); i = (int)fgets(buff, sizeof(buff), fp); pclose(fp); return (i == 0) ? 1 : 0; } do_file (char *fname) { char buff[256]; struct stat s; DIR *dp; struct direct *p; if (lstat(fname,&s) == -1) { fprintf(stderr, "File %s not found.\n", fname); return; } if ((s.st_mode & S_IFMT) == S_IFLNK) { if (is_tiff_file(fname)) printf("Ignoring symbolic link at %s\n", fname); else if (stat(fname,&s) == -1) fprintf(stderr, "Could not follow link at %s\n", fname); else if ((s.st_mode & S_IFMT) == S_IFDIR) printf("Ignoring symbolic link at %s\n", fname); return; } if ((s.st_mode & S_IFMT) == S_IFDIR) { if (!(dp=opendir(fname))) { fprintf (stderr, "Failed to open directory %s\n", fname); return; } while (p=readdir(dp)) if (strcmp(p->d_name,".") && strcmp(p->d_name,"..")) { sprintf(buff,"%s/%s", fname, p->d_name); do_file(buff); } closedir(dp); return; } if (is_tiff_file(fname)) { struct node **q, *r; q = &(table[s.st_size % PRIME]); while (*q && s.st_size < (*q)->size && s.st_ino < (*q)->inode) q = &((*q)->next); r = (*q); while (*q && s.st_size == (*q)->size && s.st_ino < (*q)->inode) q = &((*q)->next); if (*q && s.st_ino == (*q)->inode) { printf("%s and %s already hard linked.\n", (*q)->file, fname); return; } while (r && s.st_size == r->size) { if (do_diff(r->file, fname)) { link_files(r->file, fname); return; } r = r->next; } r = make_node(fname,s.st_size,s.st_ino); r->next = *q; *q = r; } } main(int argc, char **argv) { if (argc == 1) { fprintf(stderr, "usage: %s file1 [file2 file3 ...]\n", argv[0]); fprintf(stderr, " %s all\n", argv[0]); exit(1); } init_table(); if (argc == 2 && !strcmp(argv[1], "all")) do_file("."); else for (; argc > 1; argc--, argv++) do_file (argv[1]); free_table(); printf("Done.\n"); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.