addfiles.c 23.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/* addfiles.c */

/* Program to add files to a Synchronet file database */

/* $Id$ */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
11
 * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html		*
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 *																			*
 * 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										*
 *																			*
 * Anonymous FTP access to the most recent released source is available at	*
 * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
 *																			*
 * Anonymous CVS access to the development source and modification history	*
 * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
 *     (just hit return, no password is necessary)							*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * You are encouraged to submit any modifications (preferably in Unix diff	*
 * format) via e-mail to mods@synchro.net									*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#include "sbbs.h"

40
#define ADDFILES_VER "3.01"
41
42
43
44
45
46
47

scfg_t scfg;

int cur_altpath=0;

long files=0,removed=0,mode=0;

48
49
char lib[LEN_GSNAME+1];

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#define DEL_LIST	(1L<<0)
#define NO_EXTEND	(1L<<1)
#define FILE_DATE	(1L<<2)
#define TODAYS_DATE (1L<<3)
#define FILE_ID 	(1L<<4)
#define NO_UPDATE	(1L<<5)
#define NO_NEWDATE	(1L<<6)
#define ASCII_ONLY	(1L<<7)
#define UL_STATS	(1L<<8)
#define ULDATE_ONLY (1L<<9)
#define KEEP_DESC	(1L<<10)
#define AUTO_ADD	(1L<<11)
#define SEARCH_DIR	(1L<<12)
#define SYNC_LIST	(1L<<13)
#define KEEP_SPACE	(1L<<14)

/****************************************************************************/
67
/* This is needed by load_cfg.c												*/
68
/****************************************************************************/
69
int lprintf(int level, char *fmat, ...)
70
71
{
	va_list argptr;
72
	char sbuf[512];
73
74
75
76
77
	int chcount;

	va_start(argptr,fmat);
	chcount=vsprintf(sbuf,fmat,argptr);
	va_end(argptr);
78
79
	truncsp(sbuf);
	printf("%s\n",sbuf);
80
81
82
	return(chcount);
}

83
void prep_desc(uchar *str)
84
85
86
87
88
{
	char tmp[1024];
	int i,j;

	for(i=j=0;str[i] && j < sizeof(tmp)-1;i++) {
89
		if(j && str[i]==' ' && tmp[j-1]==' ' && (mode&KEEP_SPACE))
90
			tmp[j++]=str[i];
91
		else if(j && str[i]<=' ' && tmp[j-1]==' ')
92
93
94
			continue;
		else if(i && !isalnum(str[i]) && str[i]==str[i-1])
			continue;
95
		else if(str[i]>=' ')
96
97
			tmp[j++]=str[i];
		else if(str[i]==TAB || (str[i]==CR && str[i+1]==LF))
98
			tmp[j++]=' ';
99
100
101
102
103
	}
	tmp[j]=0;
	strcpy(str,tmp);
}

104
105
106
/*****************************************************************************/
/* Returns command line generated from instr with %c replacments             */
/*****************************************************************************/
107
char *mycmdstr(char *instr, char *fpath, char *fspec, char *outstr)
108
109
110
111
{
    static char cmd[MAX_PATH+1];
    char str[MAX_PATH+1];
    int i,j,len;
rswindell's avatar
rswindell committed
112
113
114
#ifdef _WIN32
	char sfpath[MAX_PATH+1];
#endif
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

	len=strlen(instr);
	for(i=j=0;i<len && j<128;i++) {
		if(instr[i]=='%') {
			i++;
			cmd[j]=0;
			switch(toupper(instr[i])) {
				case 'F':   /* File path */
					strcat(cmd,fpath);
					break;
				case '~':	/* DOS-compatible (8.3) filename */
#ifdef _WIN32
					SAFECOPY(sfpath,fpath);
					GetShortPathName(fpath,sfpath,sizeof(sfpath));
					strcat(cmd,sfpath);
#else
                    strcat(cmd,fpath);
#endif			
					break;
				case 'G':   /* Temp directory */
					strcat(cmd,scfg.temp_dir);
					break;
                case 'J':
                    strcat(cmd,scfg.data_dir);
                    break;
                case 'K':
                    strcat(cmd,scfg.ctrl_dir);
                    break;
				case 'N':   /* Node Directory (same as SBBSNODE environment var) */
					strcat(cmd,scfg.node_dir);
					break;
				case 'S':   /* File Spec */
					strcat(cmd,fspec);
					break;
                case 'Z':
                    strcat(cmd,scfg.text_dir);
                    break;
				case '!':   /* EXEC Directory */
					strcat(cmd,scfg.exec_dir);
					break;
				case '#':   /* Node number (same as SBBSNNUM environment var) */
					sprintf(str,"%d",scfg.node_num);
					strcat(cmd,str);
					break;
				case '%':   /* %% for percent sign */
					strcat(cmd,"%");
					break;
				default:    /* unknown specification */
					break; 
			}
			j=strlen(cmd); 
		}
		else
			cmd[j++]=instr[i]; 
	}
	cmd[j]=0;

	return(cmd);
}

/****************************************************************************/
/* Updates dstst.dab file													*/
/****************************************************************************/
void updatestats(ulong size)
{
    char	str[MAX_PATH+1];
    int		file;
	ulong	l;

184
	sprintf(str,"%sdsts.dab",scfg.ctrl_dir);
185
	if((file=nopen(str,O_RDWR|O_BINARY))==-1) {
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
		printf("ERR_OPEN %s\n",str);
		return; 
	}
	lseek(file,20L,SEEK_SET);	/* Skip timestamp, logons and logons today */
	read(file,&l,4);			/* Uploads today		 */
	l++;
	lseek(file,-4L,SEEK_CUR);
	write(file,&l,4);
	read(file,&l,4);			/* Upload bytes today	 */
	l+=size;
	lseek(file,-4L,SEEK_CUR);
	write(file,&l,4);
	close(file);
}

void addlist(char *inpath, file_t f, uint dskip, uint sskip)
{
203
204
205
206
207
208
	char str[MAX_PATH+1];
	char tmp[MAX_PATH+1];
	char fname[MAX_PATH+1];
	char listpath[MAX_PATH+1];
	char filepath[MAX_PATH+1];
	char curline[256],nextline[256];
209
210
	char *p;
	uchar ext[1024],tmpext[513];
211
212
	int i,file;
	long l;
213
	BOOL exist;
214
215
216
217
218
219
220
221
222
223
	FILE *stream;
	DIR*	dir;
	DIRENT*	dirent;

	if(mode&SEARCH_DIR) {
		strcpy(str,cur_altpath ? scfg.altpath[cur_altpath-1] : scfg.dir[f.dir]->path);
		printf("Searching %s\n\n",str);
		dir=opendir(str);

		while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
rswindell's avatar
rswindell committed
224
225
226
			sprintf(tmp,"%s%s"
				,cur_altpath ? scfg.altpath[cur_altpath-1] : scfg.dir[f.dir]->path
				,dirent->d_name);
227
228
229
230
231
232
233
			if(isdir(tmp))
				continue;
#ifdef _WIN32
			GetShortPathName(tmp, filepath, sizeof(filepath));
#else
			strcpy(filepath,tmp);
#endif
234
235
236
			f.misc=0;
			f.desc[0]=0;
			f.cdt=flength(filepath);
237
			padfname(getfname(filepath),f.name);
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
			printf("%s  %10lu  %s\n"
				,f.name,f.cdt,unixtodstr(&scfg,fdate(filepath),str));
			exist=findfile(&scfg,f.dir,f.name);
			if(exist) {
				if(mode&NO_UPDATE)
					continue;
				getfileixb(&scfg,&f);
				if(mode&ULDATE_ONLY) {
					f.dateuled=time(NULL);
					update_uldate(&scfg, &f);
					continue; 
				} 
			}

			if(mode&FILE_DATE) {		/* get the file date and put into desc */
				unixtodstr(&scfg,fdate(filepath),f.desc);
				strcat(f.desc,"  "); 
			}

			if(mode&TODAYS_DATE) {		/* put today's date in desc */
				unixtodstr(&scfg,time(NULL),f.desc);
				strcat(f.desc,"  "); 
			}

			if(mode&FILE_ID) {
				for(i=0;i<scfg.total_fextrs;i++)
264
					if(!stricmp(scfg.fextr[i]->ext,f.name+9) && chk_ar(&scfg,scfg.fextr[i]->ar,NULL))
265
266
267
268
						break;
				if(i<scfg.total_fextrs) {
					sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
					remove(tmp);
269
					system(mycmdstr(scfg.fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
270
271
272
					if(!fexistcase(tmp)) {
						sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
						remove(tmp);
273
						system(mycmdstr(scfg.fextr[i]->cmd,filepath,"DESC.SDI",NULL)); 
274
275
						fexistcase(tmp);
					}
276
					if((file=nopen(tmp,O_RDONLY|O_BINARY))!=-1) {
277
278
279
						memset(ext,0,513);
						read(file,ext,512);
						for(i=512;i;i--)
280
							if(ext[i-1]>' ')
281
282
283
284
285
286
								break;
						ext[i]=0;
						if(mode&ASCII_ONLY)
							strip_exascii(ext);
						if(!(mode&KEEP_DESC)) {
							sprintf(tmpext,"%.256s",ext);
287
							prep_desc(tmpext);
288
289
290
291
							for(i=0;tmpext[i];i++)
								if(isalpha(tmpext[i]))
									break;
							sprintf(f.desc,"%.*s",LEN_FDESC,tmpext+i);
292
							for(i=0;f.desc[i]>=' ' && i<LEN_FDESC;i++)
293
294
295
296
297
298
299
300
301
302
								;
							f.desc[i]=0; }
						close(file);
						f.misc|=FM_EXTDESC; 
					} 
				} 
			}

			f.dateuled=time(NULL);
			f.altpath=cur_altpath;
303
			prep_desc(f.desc);
304
305
306
307
308
			if(mode&ASCII_ONLY)
				strip_exascii(f.desc);
			if(exist) {
				putfiledat(&scfg,&f);
				if(!(mode&NO_NEWDATE))
309
310
					update_uldate(&scfg, &f); 
			}
311
312
313
314
			else
				addfiledat(&scfg,&f);
			if(f.misc&FM_EXTDESC) {
				truncsp(ext);
315
316
				putextdesc(&scfg,f.dir,f.datoffset,ext); 
			}
317
318
319
320
321
322
323
324
325
326
327
			if(mode&UL_STATS)
				updatestats(f.cdt);
			files++; 
		}
		if(dir!=NULL)
			closedir(dir);
		return; 
	}


	strcpy(listpath,inpath);
328
	fexistcase(listpath);
329
	if((stream=fopen(listpath,"r"))==NULL) {
330
331
		fprintf(stderr,"Error %d (%s) opening %s\n"
			,errno,strerror(errno),listpath);
332
333
		sprintf(listpath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
				: scfg.dir[f.dir]->path,inpath);
334
		fexistcase(listpath);
335
		if((stream=fopen(listpath,"r"))==NULL) {
336
337
			printf("Can't open: %s\n"
				   "        or: %s\n",inpath,listpath);
338
339
340
			return; 
		} 
	}
341
342
343
344
345
346
347
348
349
350
351
352

	printf("Adding %s to %s %s\n\n"
		,listpath,scfg.lib[scfg.dir[f.dir]->lib]->sname,scfg.dir[f.dir]->sname);

	fgets(nextline,255,stream);
	while(!feof(stream) && !ferror(stream)) {
		f.misc=0;
		f.desc[0]=0;
		strcpy(curline,nextline);
		nextline[0]=0;
		fgets(nextline,255,stream);
		truncsp(curline);
353
		if(curline[0]<=' ' || (mode&ASCII_ONLY && (uchar)curline[0]>=0x7e))
354
355
356
357
358
359
360
			continue;
		printf("%s\n",curline);
		strcpy(fname,curline);

		p=strchr(fname,'.');
		if(!p || p==fname || p>fname+8)    /* no dot or invalid dot location */
			continue;
361
		p=strchr(p,' ');
362
363
364
		if(p) *p=0;
		else				   /* no space after filename? */
			continue;
365
#if 0
366
		strupr(fname);
367
#endif
368
369
370
371
372
373
374
		strcpy(fname,unpadfname(fname,tmp));

		padfname(fname,f.name);
		if(strcspn(f.name,"\\/|<>+[]:=\";,")!=strlen(f.name))
			continue;

		for(i=0;i<12;i++)
375
			if(f.name[i]<' ' || (mode&ASCII_ONLY && (uchar)f.name[i]>0x7e))
376
377
378
379
380
381
382
383
384
385
386
387
				break;

		if(i<12)					/* Ctrl chars or EX-ASCII in filename? */
			continue;
		exist=findfile(&scfg,f.dir,f.name);
		if(exist) {
			if(mode&NO_UPDATE)
				continue;
			getfileixb(&scfg,&f);
			if(mode&ULDATE_ONLY) {
				f.dateuled=time(NULL);
				update_uldate(&scfg, &f);
388
389
390
				continue; 
			} 
		}
391
392
393
394
395
396
397

		sprintf(filepath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
			: scfg.dir[f.dir]->path,fname);

		if(mode&FILE_DATE) {		/* get the file date and put into desc */
			l=fdate(filepath);
			unixtodstr(&scfg,l,f.desc);
398
399
			strcat(f.desc,"  "); 
		}
400
401
402
403

		if(mode&TODAYS_DATE) {		/* put today's date in desc */
			l=time(NULL);
			unixtodstr(&scfg,l,f.desc);
404
405
			strcat(f.desc,"  "); 
		}
406
407
408
409

		if(dskip && strlen(curline)>=dskip) p=curline+dskip;
		else {
			p++;
410
			while(*p==' ') p++; 
411
		}
412
413
414
		SAFECOPY(tmp,p);
		prep_desc(tmp);
		sprintf(f.desc+strlen(f.desc),"%.*s",(int)(LEN_FDESC-strlen(f.desc)),tmp);
415

416
		if(nextline[0]==' ' || strlen(p)>LEN_FDESC) {	/* ext desc */
417
418
419
			if(!(mode&NO_EXTEND)) {
				memset(ext,0,513);
				f.misc|=FM_EXTDESC;
420
421
				sprintf(ext,"%s\r\n",p); 
			}
422

423
			if(nextline[0]==' ') {
424
425
				strcpy(str,nextline);				   /* tack on to end of desc */
				p=str+dskip;
426
				while(*p && *p<=' ') p++;
427
428
429
430
431
432
				i=LEN_FDESC-strlen(f.desc);
				if(i>1) {
					p[i-1]=0;
					truncsp(p);
					if(p[0]) {
						strcat(f.desc," ");
433
434
435
436
						strcat(f.desc,p); 
					} 
				} 
			}
437
438

			while(!feof(stream) && !ferror(stream) && strlen(ext)<512) {
439
				if(nextline[0]!=' ')
440
441
442
443
444
445
					break;
				truncsp(nextline);
				printf("%s\n",nextline);
				if(!(mode&NO_EXTEND)) {
					f.misc|=FM_EXTDESC;
					p=nextline+dskip;
446
					while(*p==' ') p++;
447
					strcat(ext,p);
448
449
					strcat(ext,"\r\n"); 
				}
450
				nextline[0]=0;
451
452
453
				fgets(nextline,255,stream); 
			} 
		}
454
455
456
457
458
459
460


		if(sskip) l=atol(fname+sskip);
		else {
			l=flength(filepath);
			if(l<1L) {
				printf("%s not found.\n",filepath);
461
462
463
				continue; 
			} 
		}
464
465
466

		if(mode&FILE_ID) {
			for(i=0;i<scfg.total_fextrs;i++)
467
				if(!stricmp(scfg.fextr[i]->ext,f.name+9) && chk_ar(&scfg,scfg.fextr[i]->ar,NULL))
468
469
470
471
					break;
			if(i<scfg.total_fextrs) {
				sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
				remove(tmp);
472
				system(mycmdstr(scfg.fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
473
474
475
				if(!fexistcase(tmp)) {
					sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
					remove(tmp);
476
					system(mycmdstr(scfg.fextr[i]->cmd,filepath,"DESC.SDI",NULL)); 
477
478
					fexistcase(tmp);
				}
479
				if((file=nopen(tmp,O_RDONLY|O_BINARY))!=-1) {
480
481
482
					memset(ext,0,513);
					read(file,ext,512);
					for(i=512;i;i--)
483
						if(ext[i-1]>' ')
484
485
486
487
488
489
							break;
					ext[i]=0;
					if(mode&ASCII_ONLY)
						strip_exascii(ext);
					if(!(mode&KEEP_DESC)) {
						sprintf(tmpext,"%.256s",ext);
490
						prep_desc(tmpext);
491
492
493
494
						for(i=0;tmpext[i];i++)
							if(isalpha(tmpext[i]))
								break;
						sprintf(f.desc,"%.*s",LEN_FDESC,tmpext+i);
495
						for(i=0;f.desc[i]>=' ' && i<LEN_FDESC;i++)
496
							;
497
498
						f.desc[i]=0; 
					}
499
500
501
502
503
504
505
506
507
					close(file);
					f.misc|=FM_EXTDESC; 
				} 
			} 
		}

		f.cdt=l;
		f.dateuled=time(NULL);
		f.altpath=cur_altpath;
508
		prep_desc(f.desc);
509
510
511
512
513
		if(mode&ASCII_ONLY)
			strip_exascii(f.desc);
		if(exist) {
			putfiledat(&scfg,&f);
			if(!(mode&NO_NEWDATE))
514
515
				update_uldate(&scfg, &f); 
		}
516
517
518
519
		else
			addfiledat(&scfg,&f);
		if(f.misc&FM_EXTDESC) {
			truncsp(ext);
520
521
			putextdesc(&scfg,f.dir,f.datoffset,ext); 
		}
522
523
524

		if(mode&UL_STATS)
			updatestats(l);
525
526
		files++; 
	}
527
528
529
	fclose(stream);
	if(mode&DEL_LIST && !(mode&SYNC_LIST)) {
		printf("\nDeleting %s\n",listpath);
530
531
		remove(listpath); 
	}
532
533
534
535
536

}

void synclist(char *inpath, int dirnum)
{
537
538
539
540
541
542
543
544
545
	uchar	str[1024];
	char	fname[MAX_PATH+1];
	char	listpath[MAX_PATH+1];
	uchar*	ixbbuf;
	uchar*	p;
	int		i,file,found;
	long	l,m,length;
	FILE*	stream;
	file_t	f;
546

547
	sprintf(str,"%s%s.ixb",scfg.dir[dirnum]->data_dir,scfg.dir[dirnum]->code);
548
	if((file=nopen(str,O_RDONLY|O_BINARY))==-1) {
549
		printf("ERR_OPEN %s\n",str);
550
551
		return; 
	}
552
553
554
	length=filelength(file);
	if(length%F_IXBSIZE) {
		close(file);
rswindell's avatar
rswindell committed
555
		printf("ERR_LEN (%ld) of %s\n",length,str);
556
557
		return; 
	}
558
559
560
	if((ixbbuf=(uchar HUGE16 *)MALLOC(length))==NULL) {
		close(file);
		printf("ERR_ALLOC %s\n",str);
561
562
		return; 
	}
563
564
565
566
	if(lread(file,ixbbuf,length)!=length) {
		close(file);
		FREE((char *)ixbbuf);
		printf("ERR_READ %s\n",str);
567
568
		return; 
	}
569
570
571
	close(file);

	strcpy(listpath,inpath);
572
	if((stream=fopen(listpath,"r"))==NULL) {
573
574
		sprintf(listpath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
				: scfg.dir[dirnum]->path,inpath);
575
		if((stream=fopen(listpath,"r"))==NULL) {
576
577
			printf("Can't open: %s\n"
				   "        or: %s\n",inpath,listpath);
578
579
580
			return; 
		} 
	}
581
582
583
584
585
586
587
588

	printf("\nSynchronizing %s with %s %s\n\n"
		,listpath,scfg.lib[scfg.dir[dirnum]->lib]->sname,scfg.dir[dirnum]->sname);

	for(l=0;l<length;l+=F_IXBSIZE) {
		m=l;
		for(i=0;i<12 && l<length;i++)
			if(i==8)
589
				str[i]=ixbbuf[m]>' ' ? '.' : ' ';
590
591
592
593
594
595
596
597
598
599
			else
				str[i]=ixbbuf[m++]; 	/* Turns FILENAMEEXT into FILENAME.EXT */
		str[i]=0;
		unpadfname(str,fname);
		rewind(stream);
		found=0;
		while(!found) {
			if(!fgets(str,1000,stream))
				break;
			truncsp(str);
600
			p=strchr(str,' ');
601
602
			if(p) *p=0;
			if(!stricmp(str,fname))
603
604
				found=1; 
		}
605
606
607
608
609
610
611
612
613
		if(found)
			continue;
		padfname(fname,f.name);
		printf("%s not found in list - ",f.name);
		f.dir=dirnum;
		f.datoffset=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16);
		getfiledat(&scfg,&f);
		if(f.opencount) {
			printf("currently OPEN by %u users\n",f.opencount);
614
615
			continue; 
		}
616
		removefiledat(&scfg,&f);
617
		if(remove(getfilepath(&scfg,&f,str)))
618
619
			printf("Error removing %s\n",str);
		removed++;
620
621
		printf("Removed from database\n"); 
	}
622
623
624

	if(mode&DEL_LIST) {
		printf("\nDeleting %s\n",listpath);
625
626
		remove(listpath); 
	}
627
628
}

629
char *usage="\nusage: addfiles code [.alt_path] [-opts] [\"*user\"] +list "
630
			 "[desc_off] [size_off]"
631
	"\n   or: addfiles code [.alt_path] [-opts] [\"*user\"]  file "
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
		"\"description\"\n"
	"\navailable opts:"
	"\n       a    import ASCII only (no extended ASCII)"
	"\n       b    synchronize database with file list (use with caution)"
	"\n       c    do not remove extra spaces from file description"
	"\n       d    delete list after import"
	"\n       e    do not import extended descriptions"
	"\n       f    include file date in descriptions"
	"\n       t    include today's date in descriptions"
	"\n       i    include added files in upload statistics"
	"\n       n    do not update information for existing files"
	"\n       o    update upload date only for existing files"
	"\n       u    do not update upload date for existing files"
	"\n       z    check for and import FILE_ID.DIZ and DESC.SDI"
	"\n       k    keep original short description (not DIZ)"
	"\n       s    search directory for files (no file list)"
648
	"\n       l    specify library (short name) to Auto-ADD"
649
650
651
	"\n"
	"\nAuto-ADD:   use * in place of code for Auto-ADD of FILES.BBS"
	"\n            use *filename to Auto-ADD a different filename"
652
	"\n            use -l \"libname\" to only Auto-ADD files to a specific library"
653
654
655
656
657
658
659
660
661
	"\n"
	;

/*********************/
/* Entry point (duh) */
/*********************/
int main(int argc, char **argv)
{
	char error[512];
662
	char revision[16];
663
664
665
666
	char str[MAX_PATH+1];
	char tmp[MAX_PATH+1];
	uchar *p,exist,listgiven=0,namegiven=0,ext[513]
		,auto_name[MAX_PATH+1]="FILES.BBS";
667
	int i,j,file;
668
	uint desc_offset=0, size_offset=0;
669
670
671
	long l;
	file_t	f;

672
	sscanf("$Revision$", "%*s %s", revision);
673

674
	fprintf(stderr,"\nADDFILES v%s-%s (rev %s) - Adds Files to Synchronet "
675
676
677
		"Filebase\n"
		,ADDFILES_VER
		,PLATFORM_DESC
678
		,revision
679
680
681
682
		);

	if(argc<2) {
		printf(usage);
683
684
		return(1); 
	}
685
686
687
688
689
690
691
692

	p=getenv("SBBSCTRL");
	if(p==NULL) {
		printf("\nSBBSCTRL environment variable not set.\n");
		printf("\nExample: SET SBBSCTRL=/sbbs/ctrl\n");
		exit(1); 
	}

693
694
	memset(&scfg,0,sizeof(scfg));
	scfg.size=sizeof(scfg);
695
	SAFECOPY(scfg.ctrl_dir,p);
696
697
698
699
700

	if(chdir(scfg.ctrl_dir)!=0)
		fprintf(stderr,"!ERROR changing directory to: %s", scfg.ctrl_dir);

	printf("\nLoading configuration files from %s\n",scfg.ctrl_dir);
701
702
703
704
	if(!load_cfg(&scfg,NULL,TRUE,error)) {
		fprintf(stderr,"!ERROR loading configuration files: %s\n",error);
		exit(1);
	}
705
	prep_dir(scfg.data_dir, scfg.temp_dir, sizeof(scfg.temp_dir));
706

rswindell's avatar
rswindell committed
707
708
709
	if(!(scfg.sys_misc&SM_LOCAL_TZ))
		putenv("TZ=UTC0");

710
711
	if(argv[1][0]=='*') {
		if(argv[1][1])
712
			SAFECOPY(auto_name,argv[1]+1);
713
		mode|=AUTO_ADD;
714
715
716
717
718
719
720
		i=0; 
	} else {
		if(!isalnum(argv[1][0]) && argc==2) {
			printf(usage);
			return(1); 
		}

721
722
723
724
725
726
		for(i=0;i<scfg.total_dirs;i++)
			if(!stricmp(scfg.dir[i]->code,argv[1]))
				break;

		if(i>=scfg.total_dirs) {
			printf("Directory code '%s' not found.\n",argv[1]);
727
728
729
			exit(1); 
		} 
	}
730
731
732
733
734
735
736
737

	memset(&f,0,sizeof(file_t));
	f.dir=i;
	strcpy(f.uler,"-> ADDFILES <-");

	for(j=2;j<argc;j++) {
		if(argv[j][0]=='*')     /* set the uploader name */
			sprintf(f.uler,"%.25s",argv[j]+1);
738
739
740
741
		else 
			if(argv[j][0]=='-'
			|| argv[j][0]=='/'
			) {      /* options */
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
			for(i=1;argv[j][i];i++)
				switch(toupper(argv[j][i])) {
					case 'A':
						mode|=ASCII_ONLY;
						break;
					case 'B':
						mode|=(SYNC_LIST|NO_UPDATE);
						break;
					case 'C':
						mode|=KEEP_SPACE;
						break;
					case 'D':
						mode|=DEL_LIST;
						break;
					case 'E':
						mode|=NO_EXTEND;
						break;
					case 'I':
						mode|=UL_STATS;
						break;
762
763
764
765
766
767
768
769
770
					case 'L':
						j++;
						if(argv[j]==NULL) {
							printf(usage);
							return(-1);
						}
						SAFECOPY(lib,argv[j]);
						i=strlen(argv[j])-1;
						break;
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
					case 'Z':
						mode|=FILE_ID;
						break;
					case 'K':
						mode|=KEEP_DESC;	 /* Don't use DIZ for short desc */
						break;
					case 'N':
						mode|=NO_UPDATE;
						break;
					case 'O':
						mode|=ULDATE_ONLY;
						break;
					case 'U':
						mode|=NO_NEWDATE;
						break;
					case 'F':
						mode|=FILE_DATE;
						break;
					case 'T':
						mode|=TODAYS_DATE;
						break;
					case 'S':
						mode|=SEARCH_DIR;
						break;
					default:
						printf(usage);
797
798
799
						return(1); 
			} 
		}
800
801
802
803
804
805
806
		else if(isdigit(argv[j][0])) {
			if(desc_offset==0)
				desc_offset=atoi(argv[j]);
			else
				size_offset=atoi(argv[j]);
			continue;
		}
807
808
		else if(argv[j][0]=='+') {      /* filelist - FILES.BBS */
			listgiven=1;
rswindell's avatar
rswindell committed
809
810
811
812
			if(argc > j+1
				&& isdigit(argv[j+1][0])) { /* skip x characters before description */
				if(argc > j+2
					&& isdigit(argv[j+2][0])) { /* skip x characters before size */
813
					addlist(argv[j]+1,f,atoi(argv[j+1]),atoi(argv[j+2]));
814
815
					j+=2; 
				}
816
817
				else {
					addlist(argv[j]+1,f,atoi(argv[j+1]),0);
818
819
820
					j++; 
				} 
			}
821
822
823
			else
				addlist(argv[j]+1,f,0,0);
			if(mode&SYNC_LIST)
824
825
				synclist(argv[j]+1,f.dir); 
		}
826
827
828
829
		else if(argv[j][0]=='.') {      /* alternate file path */
			cur_altpath=atoi(argv[j]+1);
			if(cur_altpath>scfg.altpaths) {
				printf("Invalid alternate path.\n");
830
831
832
				exit(1); 
			} 
		}
833
834
835
836
		else {
			namegiven=1;
			padfname(argv[j],f.name);
			f.desc[0]=0;
837
#if 0
838
			strupr(f.name);
839
#endif
840
841
			if(j+1==argc) {
				printf("%s no description given.\n",f.name);
842
843
				continue; 
			}
844
845
846
847
848
849
			sprintf(str,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
				: scfg.dir[f.dir]->path,argv[j]);
			if(mode&FILE_DATE)
				sprintf(f.desc,"%s  ",unixtodstr(&scfg,fdate(str),tmp));
			if(mode&TODAYS_DATE)
				sprintf(f.desc,"%s  ",unixtodstr(&scfg,time(NULL),tmp));
rswindell's avatar
rswindell committed
850
			sprintf(tmp,"%.*s",(int)(LEN_FDESC-strlen(f.desc)),argv[++j]);
851
852
853
854
			strcpy(f.desc,tmp);
			l=flength(str);
			if(l==-1) {
				printf("%s not found.\n",str);
855
856
				continue; 
			}
857
858
859
860
861
862
863
864
			exist=findfile(&scfg,f.dir,f.name);
			if(exist) {
				if(mode&NO_UPDATE)
					continue;
				getfileixb(&scfg,&f);
				if(mode&ULDATE_ONLY) {
					f.dateuled=time(NULL);
					update_uldate(&scfg, &f);
865
866
867
					continue; 
				} 
			}
868
869
870
			f.cdt=l;
			f.dateuled=time(NULL);
			f.altpath=cur_altpath;
871
			prep_desc(f.desc);
872
873
874
875
876
			if(mode&ASCII_ONLY)
				strip_exascii(f.desc);
			printf("%s %7lu %s\n",f.name,f.cdt,f.desc);
			if(mode&FILE_ID) {
				for(i=0;i<scfg.total_fextrs;i++)
877
					if(!stricmp(scfg.fextr[i]->ext,f.name+9) && chk_ar(&scfg,scfg.fextr[i]->ar,NULL))
878
879
880
881
						break;
				if(i<scfg.total_fextrs) {
					sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
					remove(tmp);
882
					system(mycmdstr(scfg.fextr[i]->cmd,str,"FILE_ID.DIZ",NULL));
883
					if(!fexistcase(tmp)) {
884
885
						sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
						remove(tmp);
886
						system(mycmdstr(scfg.fextr[i]->cmd,str,"DESC.SDI",NULL)); 
887
888
						fexistcase(tmp);
					}
889
					if((file=nopen(tmp,O_RDONLY|O_BINARY))!=-1) {
890
891
892
893
						memset(ext,0,513);
						read(file,ext,512);
						if(!(mode&KEEP_DESC)) {
							sprintf(f.desc,"%.*s",LEN_FDESC,ext);
894
							for(i=0;f.desc[i]>=' ' && i<LEN_FDESC;i++)
895
								;
896
897
							f.desc[i]=0; 
						}
898
						close(file);
899
900
901
902
						f.misc|=FM_EXTDESC; 
					} 
				} 
			}
903
904
905
			if(exist) {
				putfiledat(&scfg,&f);
				if(!(mode&NO_NEWDATE))
906
907
					update_uldate(&scfg, &f); 
			}
908
909
910
911
912
913
914
915
			else
				addfiledat(&scfg,&f);

			if(f.misc&FM_EXTDESC)
				putextdesc(&scfg,f.dir,f.datoffset,ext);

			if(mode&UL_STATS)
				updatestats(l);
916
917
918
			files++; 
		} 
	}
919
920
921

	if(mode&AUTO_ADD) {
		for(i=0;i<scfg.total_dirs;i++) {
922
923
			if(lib[0] && stricmp(scfg.lib[scfg.dir[i]->lib]->sname,lib))
				continue;
924
925
926
927
			if(scfg.dir[i]->misc&DIR_NOAUTO)
				continue;
			f.dir=i;
			if(mode&SEARCH_DIR) {
928
				addlist("",f,desc_offset,size_offset);
929
930
				continue; 
			}
931
			sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path,scfg.dir[f.dir]->code);
932
			if(fexistcase(str) && flength(str)>0L) {
933
				printf("Auto-adding %s\n",str);
934
				addlist(str,f,desc_offset,size_offset);
935
936
				if(mode&SYNC_LIST)
					synclist(str,i);
937
938
				continue; 
			}
939
			sprintf(str,"%s%s",scfg.dir[f.dir]->path,auto_name);
940
			if(fexistcase(str) && flength(str)>0L) {
941
				printf("Auto-adding %s\n",str);
942
				addlist(str,f,desc_offset,size_offset);
943
944
				if(mode&SYNC_LIST)
					synclist(str,i);
945
946
947
948
				continue; 
			} 
		} 
	}
949
950
951

	else {
		if(!listgiven && !namegiven) {
952
			sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path, scfg.dir[f.dir]->code);
953
			if(!fexistcase(str) || flength(str)<=0L)
954
				sprintf(str,"%s%s",scfg.dir[f.dir]->path, auto_name);
955
			addlist(str,f,desc_offset,size_offset);
956
			if(mode&SYNC_LIST)
957
958
959
				synclist(str,f.dir); 
		} 
	}
960
961
962
963
964
965
966
967

	printf("\n%lu file(s) added.",files);
	if(removed)
		printf("\n%lu files(s) removed.",removed);
	printf("\n");
	return(0);
}