|
|
1.1 root 1: /* DUPEFIND.C */
2:
3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
4:
5: #include "sbbs.h"
6: #include "crc32.h"
7:
8: #define DUPEFIND_VER "1.01"
9:
10: void bail(int code)
11: {
12: exit(code);
13: }
14: /****************************************************************************/
15: /* Returns 32-crc of string (not counting terminating NULL) */
16: /****************************************************************************/
17: ulong crc32(char *str)
18: {
19: int i=0;
20: ulong crc=0xffffffffUL;
21:
22: while(str[i])
23: crc=ucrc32(str[i++],crc);
24: crc=~crc;
25: return(crc);
26: }
27: long lputs(char FAR16 *str)
28: {
29: char tmp[256];
30: int i,j,k;
31:
32: j=strlen(str);
33: for(i=k=0;i<j;i++) /* remove CRs */
34: if(str[i]==CR && str[i+1]==LF)
35: continue;
36: else
37: tmp[k++]=str[i];
38: tmp[k]=0;
39: return(fputs(tmp,stderr));
40: }
41:
42: /****************************************************************************/
43: /* Network open function. Opens all files DENYALL and retries LOOP_NOPEN */
44: /* number of times if the attempted file is already open or denying access */
45: /* for some other reason. All files are opened in BINARY mode. */
46: /****************************************************************************/
47: int nopen(char *str, int access)
48: {
49: char logstr[256];
50: int file,share,count=0;
51:
52: if(access==O_RDONLY) share=SH_DENYWR;
53: else share=SH_DENYRW;
54: while(((file=sopen(str,O_BINARY|access,share,S_IWRITE))==-1)
55: && errno==EACCES && count++<LOOP_NOPEN);
56: if(file==-1 && errno==EACCES)
57: lputs("\7\r\nNOPEN: ACCESS DENIED\r\n\7");
58: return(file);
59: }
60:
61: /****************************************************************************/
62: /* Performs printf() through local assembly routines */
63: /* Called from everywhere */
64: /****************************************************************************/
65: int lprintf(char *fmat, ...)
66: {
67: va_list argptr;
68: char sbuf[256];
69: int chcount;
70:
71: va_start(argptr,fmat);
72: chcount=vsprintf(sbuf,fmat,argptr);
73: va_end(argptr);
74: lputs(sbuf);
75: return(chcount);
76: }
77:
78: /****************************************************************************/
79: /* This function performs an nopen, but returns a file stream with a buffer */
80: /* allocated. */
81: /****************************************************************************/
82: FILE *fnopen(int *file, char *str, int access)
83: {
84: char mode[128];
85: FILE *stream;
86:
87: if(access&O_WRONLY) access|=O_RDWR; /* fdopen can't open WRONLY */
88:
89: if(((*file)=nopen(str,access))==-1)
90: return(NULL);
91:
92: if(access&O_APPEND) {
93: if(access&(O_RDONLY|O_RDWR))
94: strcpy(mode,"a+");
95: else
96: strcpy(mode,"a"); }
97: else {
98: if(access&(O_WRONLY|O_RDWR))
99: strcpy(mode,"r+");
100: else
101: strcpy(mode,"r"); }
102: stream=fdopen((*file),mode);
103: if(stream==NULL) {
104: close(*file);
105: return(NULL); }
106: setvbuf(stream,NULL,_IOFBF,16*1024);
107: return(stream);
108: }
109:
110: /****************************************************************************/
111: /* Puts a backslash on path strings */
112: /****************************************************************************/
113: void backslash(char *str)
114: {
115: int i;
116:
117: i=strlen(str);
118: if(i && str[i-1]!='\\') {
119: str[i]='\\'; str[i+1]=0; }
120: }
121: /****************************************************************************/
122: /* Truncates white-space chars off end of 'str' and terminates at first tab */
123: /****************************************************************************/
124: void truncsp(char *str)
125: {
126: int c;
127:
128: str[strcspn(str,"\t")]=0;
129: c=strlen(str);
130: while(c && (uchar)str[c-1]<=SP) c--;
131: str[c]=0;
132: }
133: char *display_filename(ushort dir_num,ushort fil_off)
134: {
135: static char str[256];
136: char fname[13];
137: int file;
138:
139: sprintf(str,"%s%s.IXB",dir[dir_num]->data_dir,dir[dir_num]->code);
140: if((file=nopen(str,O_RDONLY))==-1)
141: return("UNKNOWN");
142: lseek(file,(long)(22*(fil_off-1)),SEEK_SET);
143: read(file,fname,11);
144: close(file);
145:
146: sprintf(str,"%-8.8s.%c%c%c",fname,fname[8],fname[9],fname[10]);
147: return(str);
148: }
149:
150: void main(int argc,char **argv)
151: {
152: char str[256],*ixbbuf,*p;
153: ulong **fcrc,*foundcrc,total_found=0L;
154: ushort i,j,k,h,g,start_lib=0,end_lib=0,found=-1;
155: int file;
156: long l,m;
157: read_cfg_text_t txt;
158:
159: putenv("TZ=UCT0");
160: _fmode=O_BINARY;
161: setvbuf(stdout,NULL,_IONBF,0);
162:
163: fprintf(stderr,"\nDUPEFIND Version %s (%s) - Synchronet Duplicate File "
164: "Finder\n"
165: ,DUPEFIND_VER
166: #if defined(__OS2__)
167: ,"OS/2"
168: #elif defined(__NT__)
169: ,"Win32"
170: #elif defined(__DOS4G__)
171: ,"DOS4G"
172: #elif defined(__FLAT__)
173: ,"DOS32"
174: #else
175: ,"DOS16"
176: #endif
177: );
178:
179: p=getenv("SBBSNODE");
180: if(p==NULL) {
181: fprintf(stderr,"\nSBBSNODE environment variable must be set.\n");
182: fprintf(stderr,"\nExample: SET SBBSNODE=C:\\SBBS\\NODE1\n");
183: exit(1); }
184:
185: if(!stricmp(argv[1],"/?") || !stricmp(argv[1],"?")) {
186: fprintf(stderr,"\n");
187: fprintf(stderr,"usage: DUPEFIND [start] [end]\n");
188: fprintf(stderr,"where: [start] is the starting library number to check\n");
189: fprintf(stderr," [end] is the final library number to check\n");
190: return; }
191:
192:
193: strcpy(node_dir,p);
194: if(node_dir[strlen(node_dir)-1]!='\\')
195: strcat(node_dir,"\\");
196:
197: txt.openerr="\7\nError opening %s for read.\n";
198: txt.reading="\nReading %s...";
199: txt.readit="\rRead %s ";
200: txt.allocerr="\7\nError allocating %u bytes of memory\n";
201: txt.error="\7\nERROR: Offset %lu in %s\r\n\n";
202:
203: read_node_cfg(txt);
204: if(ctrl_dir[0]=='.') {
205: strcpy(str,ctrl_dir);
206: sprintf(ctrl_dir,"%s%s",node_dir,str);
207: if(_fullpath(str,ctrl_dir,40))
208: strcpy(ctrl_dir,str); }
209: backslash(ctrl_dir);
210: read_main_cfg(txt);
211: if(data_dir[0]=='.') {
212: strcpy(str,data_dir);
213: sprintf(data_dir,"%s%s",node_dir,str);
214: if(_fullpath(str,data_dir,40))
215: strcpy(data_dir,str); }
216: backslash(data_dir);
217: read_file_cfg(txt);
218: lputs("\n");
219:
220: start_lib=0;
221: end_lib=total_libs-1;
222: if(argc>1)
223: start_lib=end_lib=atoi(argv[1])-1;
224: if(argc>2)
225: end_lib=atoi(argv[2])-1;
226:
227: if((fcrc=(ulong **)MALLOC(total_dirs*sizeof(ulong *)))==NULL) {
228: printf("Not enough memory for CRCs.\r\n");
229: exit(1); }
230:
231: for(i=0;i<total_dirs;i++) {
232: fprintf(stderr,"Reading directory index %u of %u\r",i+1,total_dirs);
233: sprintf(str,"%s%s.IXB",dir[i]->data_dir,dir[i]->code);
234: if((file=nopen(str,O_RDONLY))==-1) {
235: fcrc[i]=(ulong *)MALLOC(1*sizeof(ulong));
236: fcrc[i][0]=0;
237: continue; }
238: l=filelength(file);
239: if(!l || (dir[i]->lib<start_lib || dir[i]->lib>end_lib)) {
240: close(file);
241: fcrc[i]=(ulong *)MALLOC(1*sizeof(ulong));
242: fcrc[i][0]=0;
243: continue; }
244: if((fcrc[i]=(ulong *)MALLOC((l/22+2)*sizeof(ulong)))==NULL) {
245: printf("Not enough memory for CRCs.\r\n");
246: exit(1); }
247: fcrc[i][0]=(ulong)(l/22);
248: if((ixbbuf=(char *)MALLOC(l))==NULL) {
249: close(file);
250: printf("\7Error allocating memory for index %s.\r\n",str);
251: continue; }
252: if(read(file,ixbbuf,l)!=l) {
253: close(file);
254: printf("\7Error reading %s.\r\n",str);
255: FREE(ixbbuf);
256: continue; }
257: close(file);
258: j=1;
259: m=0L;
260: while(m<l) {
261: sprintf(str,"%-11.11s",(ixbbuf+m));
262: strupr(str);
263: fcrc[i][j++]=crc32(str);
264: m+=22; }
265: FREE(ixbbuf); }
266: lputs("\n");
267:
268: foundcrc=0L;
269: for(i=0;i<total_dirs;i++) {
270: if(dir[i]->lib<start_lib || dir[i]->lib>end_lib)
271: continue;
272: lprintf("Scanning %s %s\n",lib[dir[i]->lib]->sname,dir[i]->sname);
273: for(k=1;k<fcrc[i][0];k++) {
274: for(j=i+1;j<total_dirs;j++) {
275: if(dir[j]->lib<start_lib || dir[j]->lib>end_lib)
276: continue;
277: for(h=1;h<fcrc[j][0];h++) {
278: if(fcrc[i][k]==fcrc[j][h]) {
279: if(found!=k) {
280: found=k;
281: for(g=0;g<total_found;g++) {
282: if(foundcrc[g]==fcrc[i][k])
283: g=total_found+1; }
284: if(g==total_found) {
285: ++total_found;
286: if((foundcrc=(ulong *)REALLOC(foundcrc
287: ,total_found*sizeof(ulong)))==NULL) {
288: printf("Out of memory reallocating\r\n");
289: exit(1); } }
290: else
291: found=0;
292: printf("\n%-12s is located in : %-*s %s\n"
293: "%-12s and : %-*s %s\n"
294: ,display_filename(i,k)
295: ,LEN_GSNAME
296: ,lib[dir[i]->lib]->sname
297: ,dir[i]->sname
298: ,""
299: ,LEN_GSNAME
300: ,lib[dir[j]->lib]->sname
301: ,dir[j]->sname
302: ); }
303: else
304: printf("%-12s and : %-*s %s\n"
305: ,""
306: ,LEN_GSNAME
307: ,lib[dir[j]->lib]->sname
308: ,dir[j]->sname
309: ); } } } } }
310: }
311:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.