dupefind.c 6.14 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
 *																			*
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/
deuce's avatar
deuce committed
19

20
21
22
#include "scfgdefs.h"
#include "str_util.h"
#include "load_cfg.h"
23
#include "smblib.h"
24
#include "nopen.h"
deuce's avatar
deuce committed
25
#include "crc32.h"
26
#include <stdarg.h>
deuce's avatar
deuce committed
27

28
#define DUPEFIND_VER "3.19"
deuce's avatar
deuce committed
29

30
31
char* crlf="\r\n";

deuce's avatar
deuce committed
32
33
void bail(int code)
{
34
	exit(code);
deuce's avatar
deuce committed
35
36
}

deuce's avatar
deuce committed
37
long lputs(char *str)
deuce's avatar
deuce committed
38
39
40
41
{
    char tmp[256];
    int i,j,k;

42
43
44
45
46
47
48
49
	j=strlen(str);
	for(i=k=0;i<j;i++)      /* remove CRs */
		if(str[i]==CR && str[i+1]==LF)
			continue;
		else
			tmp[k++]=str[i];
	tmp[k]=0;
	return(fputs(tmp,stderr));
deuce's avatar
deuce committed
50
51
52
53
54
55
}

/****************************************************************************/
/* Performs printf() through local assembly routines                        */
/* Called from everywhere                                                   */
/****************************************************************************/
56
int lprintf(const char *fmat, ...)
deuce's avatar
deuce committed
57
58
59
60
61
{
	va_list argptr;
	char sbuf[256];
	int chcount;

62
63
64
65
66
	va_start(argptr,fmat);
	chcount=vsprintf(sbuf,fmat,argptr);
	va_end(argptr);
	lputs(sbuf);
	return(chcount);
deuce's avatar
deuce committed
67
68
}

69
char *display_filename(scfg_t *cfg, uint dirnum, uint32_t fil_off)
deuce's avatar
deuce committed
70
71
{
	static char str[256];
72
73
74
75
76
77
78
79
80
81
82
83
	static smb_t smb;
	if(smb_open_dir(cfg, &smb, dirnum) != SMB_SUCCESS)
		return smb.last_error;
	smb_fseek(smb.sid_fp, (fil_off - 1) * sizeof(fileidxrec_t), SEEK_SET);
	fileidxrec_t idx;
	if(smb_fread(&smb, &idx, sizeof(idx), smb.sid_fp) != sizeof(idx)) {
		smb_close(&smb);
		return smb.last_error;
	}
	smb_close(&smb);
	SAFECOPY(str, idx.name);
	return str;
deuce's avatar
deuce committed
84
85
86
87
}

int main(int argc,char **argv)
{
88
89
	char str[256];
	const char *p;
90
91
	uint32_t **fcrc,*foundcrc;
	ulong total_found=0L;
92
	ulong g;
93
	uint i,j,k,h,start_lib=0,end_lib=0,found=-1;
deuce's avatar
deuce committed
94
95
	scfg_t cfg;

96
	setvbuf(stdout,NULL,_IONBF,0);
deuce's avatar
deuce committed
97

98
99
100
101
	char revision[16];
	sscanf("$Revision: 1.54 $", "%*s %s", revision);
	fprintf(stderr,"\nDUPEFIND v%s-%s (rev %s) - Synchronet Duplicate File "
		"Finder\n", DUPEFIND_VER, PLATFORM_DESC, revision);
deuce's avatar
deuce committed
102

103
    p = get_ctrl_dir(/* warn: */TRUE);
deuce's avatar
deuce committed
104
105
106

	if(argc>1 && (!stricmp(argv[1],"/?") || !stricmp(argv[1],"?") || !stricmp(argv[1],"-?"))) {
		fprintf(stderr,"\n");
107
		fprintf(stderr,"usage: %s [start] [end]\n", argv[0]);
deuce's avatar
deuce committed
108
109
		fprintf(stderr,"where: [start] is the starting library number to check\n");
		fprintf(stderr,"       [end]   is the final library number to check\n");
110
111
		return(0); 
	}
deuce's avatar
deuce committed
112
113
114
115
116

	memset(&cfg,0,sizeof(cfg));
	cfg.size=sizeof(cfg);
	SAFECOPY(cfg.ctrl_dir,p);

117
	if(!load_cfg(&cfg, /* text: */NULL, /* prep: */TRUE, /* node: */FALSE, str, sizeof(str))) {
deuce's avatar
deuce committed
118
119
120
		fprintf(stderr,"!ERROR loading configuration files: %s\n",str);
		return(1);
	}
121
	(void)chdir(cfg.ctrl_dir);
deuce's avatar
deuce committed
122
123
124
125
126
127
128
129
130
131

	lputs("\n");

	start_lib=0;
	end_lib=cfg.total_libs-1;
	if(argc>1)
		start_lib=end_lib=atoi(argv[1])-1;
	if(argc>2)
        end_lib=atoi(argv[2])-1;

132
	if((fcrc = malloc(cfg.total_dirs*sizeof(uint32_t *)))==NULL) {
deuce's avatar
deuce committed
133
		printf("Not enough memory for CRCs.\r\n");
134
135
		return(1); 
	}
136
	memset(fcrc, 0, cfg.total_dirs*sizeof(uint32_t *));
deuce's avatar
deuce committed
137
138

	for(i=0;i<cfg.total_dirs;i++) {
139
140
141
142
143
144
145
146
147
		if(cfg.dir[i]->lib < start_lib || cfg.dir[i]->lib > end_lib)
			continue;
		printf("Reading directory %u of %u\r",i+1,cfg.total_dirs);
		smb_t smb;
		int result = smb_open_dir(&cfg, &smb, i);
		if(result != SMB_SUCCESS) {
			fprintf(stderr, "!ERROR %d (%s) opening %s\n"
				,result, smb.last_error, smb.file);
			continue;
148
		}
149
150
151
		if(smb.status.total_files < 1) {
			smb_close(&smb);
			continue;
152
		}
153
		if((fcrc[i] = malloc((smb.status.total_files + 1) * sizeof(uint32_t)))==NULL) {
deuce's avatar
deuce committed
154
            printf("Not enough memory for CRCs.\r\n");
155
156
            return(1); 
		}
157
158
159
160
161
162
163
164
165
166
		j=0;
		fcrc[i][j++] = smb.status.total_files;
		rewind(smb.sid_fp);
		while(!feof(smb.sid_fp)) {
			fileidxrec_t idx;
			if(smb_fread(&smb, &idx, sizeof(idx), smb.sid_fp) != sizeof(idx))
				break;
			char filename[sizeof(idx.name) + 1];
			SAFECOPY(filename, idx.name);
			fcrc[i][j++]=crc32(filename, 0);
167
		}
168
		smb_close(&smb);
169
	}
deuce's avatar
deuce committed
170
171
	lputs("\n");

172
	foundcrc = NULL;
deuce's avatar
deuce committed
173
174
175
176
	for(i=0;i<cfg.total_dirs;i++) {
		if(cfg.dir[i]->lib<start_lib || cfg.dir[i]->lib>end_lib)
			continue;
		lprintf("Scanning %s %s\n",cfg.lib[cfg.dir[i]->lib]->sname,cfg.dir[i]->sname);
177
178
		if(fcrc[i] == NULL)
			continue;
deuce's avatar
deuce committed
179
180
181
182
		for(k=1;k<fcrc[i][0];k++) {
			for(j=i+1;j<cfg.total_dirs;j++) {
				if(cfg.dir[j]->lib<start_lib || cfg.dir[j]->lib>end_lib)
					continue;
183
184
				if(fcrc[j] == NULL)
					continue;
deuce's avatar
deuce committed
185
186
187
188
189
190
				for(h=1;h<fcrc[j][0];h++) {
					if(fcrc[i][k]==fcrc[j][h]) {
						if(found!=k) {
							found=k;
							for(g=0;g<total_found;g++) {
								if(foundcrc[g]==fcrc[i][k])
191
									break; 
192
							}
deuce's avatar
deuce committed
193
194
							if(g==total_found) {
								++total_found;
195
196
197
198
								if((foundcrc = realloc(foundcrc
									,total_found*sizeof(uint32_t)))==NULL) {
									printf("Out of memory reallocating\r\n");
									return(1); 
199
200
								} 
							}
deuce's avatar
deuce committed
201
202
203
204
205
206
207
208
209
210
211
212
							else
								found=0;
							printf("\n%-12s is located in : %-*s  %s\n"
								   "%-12s           and : %-*s  %s\n"
								,display_filename(&cfg,i,k)
								,LEN_GSNAME
								,cfg.lib[cfg.dir[i]->lib]->sname
								,cfg.dir[i]->sname
								,""
								,LEN_GSNAME
								,cfg.lib[cfg.dir[j]->lib]->sname
								,cfg.dir[j]->sname
213
214
								); 
						}
deuce's avatar
deuce committed
215
216
217
218
219
220
						else
							printf("%-12s           and : %-*s  %s\n"
								,""
								,LEN_GSNAME
								,cfg.lib[cfg.dir[j]->lib]->sname
								,cfg.dir[j]->sname
221
222
223
224
225
226
								); 
					} 
				} 
			} 
		} 
	}
deuce's avatar
deuce committed
227
228
229
	return(0);
}