addfiles.c 23.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
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
40
41
/* 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)		*
 *																			*
 * Copyright 2000 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										*
 *																			*
 * 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"

#define ADDFILES_VER "3.00"

42
char *crlf="\r\n";
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

scfg_t scfg;

int cur_altpath=0;

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

#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)

long lputs(char FAR16 *str)
{
68
    char tmp[512];
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    int i,j,k;

	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,stdout));
}

/****************************************************************************/
/* Performs printf() through local assembly routines                        */
/* Called from everywhere                                                   */
/****************************************************************************/
int lprintf(char *fmat, ...)
{
	va_list argptr;
88
	char sbuf[512];
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
	int chcount;

	va_start(argptr,fmat);
	chcount=vsprintf(sbuf,fmat,argptr);
	va_end(argptr);
	lputs(sbuf);
	return(chcount);
}

/*****************************************************************************/
/* Returns command line generated from instr with %c replacments             */
/*****************************************************************************/
char *cmdstr(char *instr, char *fpath, char *fspec, char *outstr)
{
    static char cmd[MAX_PATH+1];
    char str[MAX_PATH+1];
    int i,j,len;
rswindell's avatar
rswindell committed
106
107
108
#ifdef _WIN32
	char sfpath[MAX_PATH+1];
#endif
109
110
111
112
113
114
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

	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;

178
	sprintf(str,"%sdsts.dab",scfg.ctrl_dir);
179
	if((file=nopen(str,O_RDWR|O_BINARY))==-1) {
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
		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)
{
197
198
199
200
201
202
	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];
203
204
	char *p;
	uchar ext[1024],tmpext[513];
205
206
	int i,file;
	long l;
207
	BOOL exist;
208
209
210
211
212
213
214
215
216
217
	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) {
218
219
220
221
222
223
224
225
			sprintf(tmp,"%s%s",str,dirent->d_name);
			if(isdir(tmp))
				continue;
#ifdef _WIN32
			GetShortPathName(tmp, filepath, sizeof(filepath));
#else
			strcpy(filepath,tmp);
#endif
226
227
228
			f.misc=0;
			f.desc[0]=0;
			f.cdt=flength(filepath);
229
			padfname(getfname(filepath),f.name);
230
231
232
233
234
235
236
237
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
264
265
266
267
			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++)
					if(!stricmp(scfg.fextr[i]->ext,f.name+9))
						break;
				if(i<scfg.total_fextrs) {
					sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
					remove(tmp);
					system(cmdstr(scfg.fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
					if(!fexistcase(tmp)) {
						sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
						remove(tmp);
						system(cmdstr(scfg.fextr[i]->cmd,filepath,"DESC.SDI",NULL)); 
						fexistcase(tmp);
					}
268
					if((file=nopen(tmp,O_RDONLY|O_BINARY))!=-1) {
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
						memset(ext,0,513);
						read(file,ext,512);
						for(i=512;i;i--)
							if(ext[i-1]>SP)
								break;
						ext[i]=0;
						if(mode&ASCII_ONLY)
							strip_exascii(ext);
						if(!(mode&KEEP_DESC)) {
							sprintf(tmpext,"%.256s",ext);
							strip_ctrl(tmpext);
							for(i=0;tmpext[i];i++)
								if(isalpha(tmpext[i]))
									break;
							sprintf(f.desc,"%.*s",LEN_FDESC,tmpext+i);
							for(i=0;f.desc[i]>=SP && i<LEN_FDESC;i++)
								;
							f.desc[i]=0; }
						close(file);
						f.misc|=FM_EXTDESC; 
					} 
				} 
			}

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


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

	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);
		if(curline[0]<=SP || (uchar)curline[0]>=0x7e)
			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;
		p=strchr(p,SP);
		if(p) *p=0;
		else				   /* no space after filename? */
			continue;
357
#if 0
358
		strupr(fname);
359
#endif
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
		strcpy(fname,unpadfname(fname,tmp));

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

		for(i=0;i<12;i++)
			if(f.name[i]<SP || (uchar)f.name[i]>0x7e)
				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);
380
381
382
				continue; 
			} 
		}
383
384
385
386
387
388
389

		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);
390
391
			strcat(f.desc,"  "); 
		}
392
393
394
395

		if(mode&TODAYS_DATE) {		/* put today's date in desc */
			l=time(NULL);
			unixtodstr(&scfg,l,f.desc);
396
397
			strcat(f.desc,"  "); 
		}
398
399
400
401

		if(dskip && strlen(curline)>=dskip) p=curline+dskip;
		else {
			p++;
402
403
			while(*p==SP) p++; 
		}
rswindell's avatar
rswindell committed
404
		sprintf(tmp,"%.*s",(int)(LEN_FDESC-strlen(f.desc)),p);
405
406
407
408
409
410
		strcat(f.desc,tmp);

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

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

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


		if(sskip) l=atol(fname+sskip);
		else {
			l=flength(filepath);
			if(l<1L) {
				printf("%s not found.\n",filepath);
451
452
453
				continue; 
			} 
		}
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468

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

		f.cdt=l;
		f.dateuled=time(NULL);
		f.altpath=cur_altpath;
		strip_ctrl(f.desc);
		if(mode&ASCII_ONLY)
			strip_exascii(f.desc);
		if(exist) {
			putfiledat(&scfg,&f);
			if(!(mode&NO_NEWDATE))
504
505
				update_uldate(&scfg, &f); 
		}
506
507
508
509
		else
			addfiledat(&scfg,&f);
		if(f.misc&FM_EXTDESC) {
			truncsp(ext);
510
511
			putextdesc(&scfg,f.dir,f.datoffset,ext); 
		}
512
513
514

		if(mode&UL_STATS)
			updatestats(l);
515
516
		files++; 
	}
517
518
519
	fclose(stream);
	if(mode&DEL_LIST && !(mode&SYNC_LIST)) {
		printf("\nDeleting %s\n",listpath);
520
521
		remove(listpath); 
	}
522
523
524
525
526

}

void synclist(char *inpath, int dirnum)
{
527
528
529
530
531
532
533
534
535
	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;
536

537
	sprintf(str,"%s%s.ixb",scfg.dir[dirnum]->data_dir,scfg.dir[dirnum]->code);
538
	if((file=nopen(str,O_RDONLY|O_BINARY))==-1) {
539
		printf("ERR_OPEN %s\n",str);
540
541
		return; 
	}
542
543
544
	length=filelength(file);
	if(length%F_IXBSIZE) {
		close(file);
rswindell's avatar
rswindell committed
545
		printf("ERR_LEN (%ld) of %s\n",length,str);
546
547
		return; 
	}
548
549
550
	if((ixbbuf=(uchar HUGE16 *)MALLOC(length))==NULL) {
		close(file);
		printf("ERR_ALLOC %s\n",str);
551
552
		return; 
	}
553
554
555
556
	if(lread(file,ixbbuf,length)!=length) {
		close(file);
		FREE((char *)ixbbuf);
		printf("ERR_READ %s\n",str);
557
558
		return; 
	}
559
560
561
	close(file);

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

	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)
				str[i]='.';
			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);
			p=strchr(str,SP);
			if(p) *p=0;
			if(!stricmp(str,fname))
593
594
				found=1; 
		}
595
596
597
598
599
600
601
602
603
		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);
604
605
			continue; 
		}
606
607
608
609
610
611
612
		removefiledat(&scfg,&f);
		sprintf(str,"%s%s"
			,f.altpath>0 && f.altpath<=scfg.altpaths ? scfg.altpath[f.altpath-1]
			: scfg.dir[f.dir]->path,fname);
		if(remove(str))
			printf("Error removing %s\n",str);
		removed++;
613
614
		printf("Removed from database\n"); 
	}
615
616
617

	if(mode&DEL_LIST) {
		printf("\nDeleting %s\n",listpath);
618
619
		remove(listpath); 
	}
620
621
}

622
char *usage="\nusage: addfiles code [.alt_path] [-opts] [\"*user\"] +list "
623
			 "[desc_off] [size_off]"
624
	"\n   or: addfiles code [.alt_path] [-opts] [\"*user\"]  file "
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
		"\"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)"
	"\n"
	"\nAuto-ADD:   use * in place of code for Auto-ADD of FILES.BBS"
	"\n            use *filename to Auto-ADD a different filename"
	"\n"
	;

/*********************/
/* Entry point (duh) */
/*********************/
int main(int argc, char **argv)
{
	char error[512];
653
	char revision[16];
654
655
656
657
	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";
658
	int i,j,file;
659
	uint desc_offset=0, size_offset=0;
660
661
662
	long l;
	file_t	f;

663
664
	sscanf("$Revision$" + 11, "%s", revision);

665
	fprintf(stderr,"\nADDFILES v%s-%s (rev %s) - Adds Files to Synchronet "
666
667
668
		"Filebase\n"
		,ADDFILES_VER
		,PLATFORM_DESC
669
		,revision
670
671
672
673
		);

	if(argc<2) {
		printf(usage);
674
675
		return(1); 
	}
676
677
678
679
680
681
682
683

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

684
685
	memset(&scfg,0,sizeof(scfg));
	scfg.size=sizeof(scfg);
686
	SAFECOPY(scfg.ctrl_dir,p);
687
688
689
690
691

	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);
692
693
694
695
	if(!load_cfg(&scfg,NULL,TRUE,error)) {
		fprintf(stderr,"!ERROR loading configuration files: %s\n",error);
		exit(1);
	}
696
	prep_dir(scfg.data_dir, scfg.temp_dir);
697

rswindell's avatar
rswindell committed
698
699
700
	if(!(scfg.sys_misc&SM_LOCAL_TZ))
		putenv("TZ=UTC0");

701
702
	if(argv[1][0]=='*') {
		if(argv[1][1])
703
			SAFECOPY(auto_name,argv[1]+1);
704
		mode|=AUTO_ADD;
705
706
707
708
709
710
711
		i=0; 
	} else {
		if(!isalnum(argv[1][0]) && argc==2) {
			printf(usage);
			return(1); 
		}

712
713
714
715
716
717
		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]);
718
719
720
			exit(1); 
		} 
	}
721
722
723
724
725
726
727
728

	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);
729
730
731
732
		else 
			if(argv[j][0]=='-'
			|| argv[j][0]=='/'
			) {      /* options */
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
			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;
					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);
779
780
781
						return(1); 
			} 
		}
782
783
784
785
786
787
788
		else if(isdigit(argv[j][0])) {
			if(desc_offset==0)
				desc_offset=atoi(argv[j]);
			else
				size_offset=atoi(argv[j]);
			continue;
		}
789
790
		else if(argv[j][0]=='+') {      /* filelist - FILES.BBS */
			listgiven=1;
rswindell's avatar
rswindell committed
791
792
793
794
			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 */
795
					addlist(argv[j]+1,f,atoi(argv[j+1]),atoi(argv[j+2]));
796
797
					j+=2; 
				}
798
799
				else {
					addlist(argv[j]+1,f,atoi(argv[j+1]),0);
800
801
802
					j++; 
				} 
			}
803
804
805
			else
				addlist(argv[j]+1,f,0,0);
			if(mode&SYNC_LIST)
806
807
				synclist(argv[j]+1,f.dir); 
		}
808
809
810
811
		else if(argv[j][0]=='.') {      /* alternate file path */
			cur_altpath=atoi(argv[j]+1);
			if(cur_altpath>scfg.altpaths) {
				printf("Invalid alternate path.\n");
812
813
814
				exit(1); 
			} 
		}
815
816
817
818
		else {
			namegiven=1;
			padfname(argv[j],f.name);
			f.desc[0]=0;
819
#if 0
820
			strupr(f.name);
821
#endif
822
823
			if(j+1==argc) {
				printf("%s no description given.\n",f.name);
824
825
				continue; 
			}
826
827
828
829
830
831
			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
832
			sprintf(tmp,"%.*s",(int)(LEN_FDESC-strlen(f.desc)),argv[++j]);
833
834
835
836
			strcpy(f.desc,tmp);
			l=flength(str);
			if(l==-1) {
				printf("%s not found.\n",str);
837
838
				continue; 
			}
839
840
841
842
843
844
845
846
			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);
847
848
849
					continue; 
				} 
			}
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
			f.cdt=l;
			f.dateuled=time(NULL);
			f.altpath=cur_altpath;
			strip_ctrl(f.desc);
			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++)
					if(!stricmp(scfg.fextr[i]->ext,f.name+9))
						break;
				if(i<scfg.total_fextrs) {
					sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
					remove(tmp);
					system(cmdstr(scfg.fextr[i]->cmd,str,"FILE_ID.DIZ",NULL));
865
					if(!fexistcase(tmp)) {
866
867
						sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
						remove(tmp);
868
869
870
						system(cmdstr(scfg.fextr[i]->cmd,str,"DESC.SDI",NULL)); 
						fexistcase(tmp);
					}
871
					if((file=nopen(tmp,O_RDONLY|O_BINARY))!=-1) {
872
873
874
875
876
877
						memset(ext,0,513);
						read(file,ext,512);
						if(!(mode&KEEP_DESC)) {
							sprintf(f.desc,"%.*s",LEN_FDESC,ext);
							for(i=0;f.desc[i]>=SP && i<LEN_FDESC;i++)
								;
878
879
							f.desc[i]=0; 
						}
880
						close(file);
881
882
883
884
						f.misc|=FM_EXTDESC; 
					} 
				} 
			}
885
886
887
			if(exist) {
				putfiledat(&scfg,&f);
				if(!(mode&NO_NEWDATE))
888
889
					update_uldate(&scfg, &f); 
			}
890
891
892
893
894
895
896
897
			else
				addfiledat(&scfg,&f);

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

			if(mode&UL_STATS)
				updatestats(l);
898
899
900
			files++; 
		} 
	}
901
902
903
904
905
906
907

	if(mode&AUTO_ADD) {
		for(i=0;i<scfg.total_dirs;i++) {
			if(scfg.dir[i]->misc&DIR_NOAUTO)
				continue;
			f.dir=i;
			if(mode&SEARCH_DIR) {
908
				addlist("",f,desc_offset,size_offset);
909
910
				continue; 
			}
911
			sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path,scfg.dir[f.dir]->code);
912
			if(fexistcase(str) && flength(str)>0L) {
913
				printf("Auto-adding %s\n",str);
914
				addlist(str,f,desc_offset,size_offset);
915
916
				if(mode&SYNC_LIST)
					synclist(str,i);
917
918
				continue; 
			}
919
			sprintf(str,"%s%s",scfg.dir[f.dir]->path,auto_name);
920
			if(fexistcase(str) && flength(str)>0L) {
921
				printf("Auto-adding %s\n",str);
922
				addlist(str,f,desc_offset,size_offset);
923
924
				if(mode&SYNC_LIST)
					synclist(str,i);
925
926
927
928
				continue; 
			} 
		} 
	}
929
930
931

	else {
		if(!listgiven && !namegiven) {
932
			sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path, scfg.dir[f.dir]->code);
933
			if(!fexistcase(str) || flength(str)<=0L)
934
				sprintf(str,"%s%s",scfg.dir[f.dir]->path, auto_name);
935
			addlist(str,f,desc_offset,size_offset);
936
			if(mode&SYNC_LIST)
937
938
939
				synclist(str,f.dir); 
		} 
	}
940
941
942
943
944
945
946
947

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