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.