|
|
1.1 root 1: /* addfiles.c */
2:
3: /* Program to add files to a Synchronet file database */
4:
5: /* $Id: addfiles.c,v 1.39 2006/04/28 21:13:57 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "sbbs.h"
39:
40: #define ADDFILES_VER "3.02"
41:
42: scfg_t scfg;
43:
44: int cur_altpath=0;
45:
46: long files=0,removed=0,mode=0;
47:
48: char lib[LEN_GSNAME+1];
49:
50: #define DEL_LIST (1L<<0)
51: #define NO_EXTEND (1L<<1)
52: #define FILE_DATE (1L<<2)
53: #define TODAYS_DATE (1L<<3)
54: #define FILE_ID (1L<<4)
55: #define NO_UPDATE (1L<<5)
56: #define NO_NEWDATE (1L<<6)
57: #define ASCII_ONLY (1L<<7)
58: #define UL_STATS (1L<<8)
59: #define ULDATE_ONLY (1L<<9)
60: #define KEEP_DESC (1L<<10)
61: #define AUTO_ADD (1L<<11)
62: #define SEARCH_DIR (1L<<12)
63: #define SYNC_LIST (1L<<13)
64: #define KEEP_SPACE (1L<<14)
65:
66: /****************************************************************************/
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: int chcount;
74:
75: va_start(argptr,fmat);
76: chcount=vsprintf(sbuf,fmat,argptr);
77: va_end(argptr);
78: truncsp(sbuf);
79: printf("%s\n",sbuf);
80: return(chcount);
81: }
82:
83: void prep_desc(uchar *str)
84: {
85: char tmp[1024];
86: int i,j;
87:
88: 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: continue;
93: else if(i && !isalnum(str[i]) && str[i]==str[i-1])
94: continue;
95: else if(str[i]>=' ')
96: tmp[j++]=str[i];
97: else if(str[i]==TAB || (str[i]==CR && str[i+1]==LF))
98: tmp[j++]=' ';
99: }
100: tmp[j]=0;
101: strcpy(str,tmp);
102: }
103:
104: /*****************************************************************************/
105: /* Returns command line generated from instr with %c replacments */
106: /*****************************************************************************/
107: char *mycmdstr(char *instr, char *fpath, char *fspec, char *outstr)
108: {
109: static char cmd[MAX_PATH+1];
110: char str[MAX_PATH+1];
111: int i,j,len;
112: #ifdef _WIN32
113: char sfpath[MAX_PATH+1];
114: #endif
115:
116: len=strlen(instr);
117: for(i=j=0;i<len && j<128;i++) {
118: if(instr[i]=='%') {
119: i++;
120: cmd[j]=0;
121: switch(toupper(instr[i])) {
122: case 'F': /* File path */
123: strcat(cmd,fpath);
124: break;
125: case '~': /* DOS-compatible (8.3) filename */
126: #ifdef _WIN32
127: SAFECOPY(sfpath,fpath);
128: GetShortPathName(fpath,sfpath,sizeof(sfpath));
129: strcat(cmd,sfpath);
130: #else
131: strcat(cmd,fpath);
132: #endif
133: break;
134: case 'G': /* Temp directory */
135: strcat(cmd,scfg.temp_dir);
136: break;
137: case 'J':
138: strcat(cmd,scfg.data_dir);
139: break;
140: case 'K':
141: strcat(cmd,scfg.ctrl_dir);
142: break;
143: case 'N': /* Node Directory (same as SBBSNODE environment var) */
144: strcat(cmd,scfg.node_dir);
145: break;
146: case 'S': /* File Spec */
147: strcat(cmd,fspec);
148: break;
149: case 'Z':
150: strcat(cmd,scfg.text_dir);
151: break;
152: case '!': /* EXEC Directory */
153: strcat(cmd,scfg.exec_dir);
154: break;
155: case '@': /* EXEC Directory for DOS/OS2/Win32, blank for Unix */
156: #ifndef __unix__
157: strcat(cmd,scfg.exec_dir);
158: #endif
159: break;
160: case '#': /* Node number (same as SBBSNNUM environment var) */
161: sprintf(str,"%d",scfg.node_num);
162: strcat(cmd,str);
163: break;
164: case '%': /* %% for percent sign */
165: strcat(cmd,"%");
166: break;
167: default: /* unknown specification */
168: break;
169: }
170: j=strlen(cmd);
171: }
172: else
173: cmd[j++]=instr[i];
174: }
175: cmd[j]=0;
176:
177: return(cmd);
178: }
179:
180: /****************************************************************************/
181: /* Updates dstst.dab file */
182: /****************************************************************************/
183: void updatestats(ulong size)
184: {
185: char str[MAX_PATH+1];
186: int file;
187: ulong l;
188:
189: sprintf(str,"%sdsts.dab",scfg.ctrl_dir);
190: if((file=nopen(str,O_RDWR|O_BINARY))==-1) {
191: printf("ERR_OPEN %s\n",str);
192: return;
193: }
194: lseek(file,20L,SEEK_SET); /* Skip timestamp, logons and logons today */
195: read(file,&l,4); /* Uploads today */
196: l++;
197: lseek(file,-4L,SEEK_CUR);
198: write(file,&l,4);
199: read(file,&l,4); /* Upload bytes today */
200: l+=size;
201: lseek(file,-4L,SEEK_CUR);
202: write(file,&l,4);
203: close(file);
204: }
205:
206: void addlist(char *inpath, file_t f, uint dskip, uint sskip)
207: {
208: char str[MAX_PATH+1];
209: char tmp[MAX_PATH+1];
210: char fname[MAX_PATH+1];
211: char listpath[MAX_PATH+1];
212: char filepath[MAX_PATH+1];
213: char curline[256],nextline[256];
214: char *p;
215: uchar ext[1024],tmpext[513];
216: int i,file;
217: long l;
218: BOOL exist;
219: FILE *stream;
220: DIR* dir;
221: DIRENT* dirent;
222:
223: if(mode&SEARCH_DIR) {
224: strcpy(str,cur_altpath ? scfg.altpath[cur_altpath-1] : scfg.dir[f.dir]->path);
225: printf("Searching %s\n\n",str);
226: dir=opendir(str);
227:
228: while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
229: sprintf(tmp,"%s%s"
230: ,cur_altpath ? scfg.altpath[cur_altpath-1] : scfg.dir[f.dir]->path
231: ,dirent->d_name);
232: if(isdir(tmp))
233: continue;
234: #ifdef _WIN32
235: GetShortPathName(tmp, filepath, sizeof(filepath));
236: #else
237: strcpy(filepath,tmp);
238: #endif
239: f.misc=0;
240: f.desc[0]=0;
241: f.cdt=flength(filepath);
242: padfname(getfname(filepath),f.name);
243: printf("%s %10lu %s\n"
244: ,f.name,f.cdt,unixtodstr(&scfg,fdate(filepath),str));
245: exist=findfile(&scfg,f.dir,f.name);
246: if(exist) {
247: if(mode&NO_UPDATE)
248: continue;
249: getfileixb(&scfg,&f);
250: if(mode&ULDATE_ONLY) {
251: f.dateuled=time(NULL);
252: update_uldate(&scfg, &f);
253: continue;
254: }
255: }
256:
257: if(mode&FILE_DATE) { /* get the file date and put into desc */
258: unixtodstr(&scfg,fdate(filepath),f.desc);
259: strcat(f.desc," ");
260: }
261:
262: if(mode&TODAYS_DATE) { /* put today's date in desc */
263: unixtodstr(&scfg,time(NULL),f.desc);
264: strcat(f.desc," ");
265: }
266:
267: if(mode&FILE_ID) {
268: for(i=0;i<scfg.total_fextrs;i++)
269: if(!stricmp(scfg.fextr[i]->ext,f.name+9) && chk_ar(&scfg,scfg.fextr[i]->ar,NULL))
270: break;
271: if(i<scfg.total_fextrs) {
272: sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
273: remove(tmp);
274: system(mycmdstr(scfg.fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
275: if(!fexistcase(tmp)) {
276: sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
277: remove(tmp);
278: system(mycmdstr(scfg.fextr[i]->cmd,filepath,"DESC.SDI",NULL));
279: fexistcase(tmp);
280: }
281: if((file=nopen(tmp,O_RDONLY|O_BINARY))!=-1) {
282: memset(ext,0,513);
283: read(file,ext,512);
284: for(i=512;i;i--)
285: if(ext[i-1]>' ')
286: break;
287: ext[i]=0;
288: if(mode&ASCII_ONLY)
289: strip_exascii(ext);
290: if(!(mode&KEEP_DESC)) {
291: sprintf(tmpext,"%.256s",ext);
292: prep_desc(tmpext);
293: for(i=0;tmpext[i];i++)
294: if(isalpha(tmpext[i]))
295: break;
296: sprintf(f.desc,"%.*s",LEN_FDESC,tmpext+i);
297: for(i=0;f.desc[i]>=' ' && i<LEN_FDESC;i++)
298: ;
299: f.desc[i]=0; }
300: close(file);
301: f.misc|=FM_EXTDESC;
302: }
303: }
304: }
305:
306: f.dateuled=time(NULL);
307: f.altpath=cur_altpath;
308: prep_desc(f.desc);
309: if(mode&ASCII_ONLY)
310: strip_exascii(f.desc);
311: if(exist) {
312: putfiledat(&scfg,&f);
313: if(!(mode&NO_NEWDATE))
314: update_uldate(&scfg, &f);
315: }
316: else
317: addfiledat(&scfg,&f);
318: if(f.misc&FM_EXTDESC) {
319: truncsp(ext);
320: putextdesc(&scfg,f.dir,f.datoffset,ext);
321: }
322: if(mode&UL_STATS)
323: updatestats(f.cdt);
324: files++;
325: }
326: if(dir!=NULL)
327: closedir(dir);
328: return;
329: }
330:
331:
332: strcpy(listpath,inpath);
333: fexistcase(listpath);
334: if((stream=fopen(listpath,"r"))==NULL) {
335: fprintf(stderr,"Error %d (%s) opening %s\n"
336: ,errno,strerror(errno),listpath);
337: sprintf(listpath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
338: : scfg.dir[f.dir]->path,inpath);
339: fexistcase(listpath);
340: if((stream=fopen(listpath,"r"))==NULL) {
341: printf("Can't open: %s\n"
342: " or: %s\n",inpath,listpath);
343: return;
344: }
345: }
346:
347: printf("Adding %s to %s %s\n\n"
348: ,listpath,scfg.lib[scfg.dir[f.dir]->lib]->sname,scfg.dir[f.dir]->sname);
349:
350: fgets(nextline,255,stream);
351: while(!feof(stream) && !ferror(stream)) {
352: f.misc=0;
353: f.desc[0]=0;
354: strcpy(curline,nextline);
355: nextline[0]=0;
356: fgets(nextline,255,stream);
357: truncsp(curline);
358: if(curline[0]<=' ' || (mode&ASCII_ONLY && (uchar)curline[0]>=0x7e))
359: continue;
360: printf("%s\n",curline);
361: strcpy(fname,curline);
362:
363: p=strchr(fname,'.');
364: if(!p || p==fname || p>fname+8) /* no dot or invalid dot location */
365: continue;
366: p=strchr(p,' ');
367: if(p) *p=0;
368: else /* no space after filename? */
369: continue;
370: #if 0
371: strupr(fname);
372: #endif
373: strcpy(fname,unpadfname(fname,tmp));
374:
375: padfname(fname,f.name);
376: if(strcspn(f.name,"\\/|<>+[]:=\";,")!=strlen(f.name))
377: continue;
378:
379: for(i=0;i<12;i++)
380: if(f.name[i]<' ' || (mode&ASCII_ONLY && (uchar)f.name[i]>0x7e))
381: break;
382:
383: if(i<12) /* Ctrl chars or EX-ASCII in filename? */
384: continue;
385: exist=findfile(&scfg,f.dir,f.name);
386: if(exist) {
387: if(mode&NO_UPDATE)
388: continue;
389: getfileixb(&scfg,&f);
390: if(mode&ULDATE_ONLY) {
391: f.dateuled=time(NULL);
392: update_uldate(&scfg, &f);
393: continue;
394: }
395: }
396:
397: sprintf(filepath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
398: : scfg.dir[f.dir]->path,fname);
399:
400: if(mode&FILE_DATE) { /* get the file date and put into desc */
401: l=fdate(filepath);
402: unixtodstr(&scfg,l,f.desc);
403: strcat(f.desc," ");
404: }
405:
406: if(mode&TODAYS_DATE) { /* put today's date in desc */
407: l=time(NULL);
408: unixtodstr(&scfg,l,f.desc);
409: strcat(f.desc," ");
410: }
411:
412: if(dskip && strlen(curline)>=dskip) p=curline+dskip;
413: else {
414: p++;
415: while(*p==' ') p++;
416: }
417: SAFECOPY(tmp,p);
418: prep_desc(tmp);
419: sprintf(f.desc+strlen(f.desc),"%.*s",(int)(LEN_FDESC-strlen(f.desc)),tmp);
420:
421: if(nextline[0]==' ' || strlen(p)>LEN_FDESC) { /* ext desc */
422: if(!(mode&NO_EXTEND)) {
423: memset(ext,0,513);
424: f.misc|=FM_EXTDESC;
425: sprintf(ext,"%s\r\n",p);
426: }
427:
428: if(nextline[0]==' ') {
429: strcpy(str,nextline); /* tack on to end of desc */
430: p=str+dskip;
431: while(*p && *p<=' ') p++;
432: i=LEN_FDESC-strlen(f.desc);
433: if(i>1) {
434: p[i-1]=0;
435: truncsp(p);
436: if(p[0]) {
437: strcat(f.desc," ");
438: strcat(f.desc,p);
439: }
440: }
441: }
442:
443: while(!feof(stream) && !ferror(stream) && strlen(ext)<512) {
444: if(nextline[0]!=' ')
445: break;
446: truncsp(nextline);
447: printf("%s\n",nextline);
448: if(!(mode&NO_EXTEND)) {
449: f.misc|=FM_EXTDESC;
450: p=nextline+dskip;
451: while(*p==' ') p++;
452: strcat(ext,p);
453: strcat(ext,"\r\n");
454: }
455: nextline[0]=0;
456: fgets(nextline,255,stream);
457: }
458: }
459:
460:
461: if(sskip) l=atol(fname+sskip);
462: else {
463: l=flength(filepath);
464: if(l<1L) {
465: printf("%s not found.\n",filepath);
466: continue;
467: }
468: }
469:
470: if(mode&FILE_ID) {
471: for(i=0;i<scfg.total_fextrs;i++)
472: if(!stricmp(scfg.fextr[i]->ext,f.name+9) && chk_ar(&scfg,scfg.fextr[i]->ar,NULL))
473: break;
474: if(i<scfg.total_fextrs) {
475: sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
476: remove(tmp);
477: system(mycmdstr(scfg.fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
478: if(!fexistcase(tmp)) {
479: sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
480: remove(tmp);
481: system(mycmdstr(scfg.fextr[i]->cmd,filepath,"DESC.SDI",NULL));
482: fexistcase(tmp);
483: }
484: if((file=nopen(tmp,O_RDONLY|O_BINARY))!=-1) {
485: memset(ext,0,513);
486: read(file,ext,512);
487: for(i=512;i;i--)
488: if(ext[i-1]>' ')
489: break;
490: ext[i]=0;
491: if(mode&ASCII_ONLY)
492: strip_exascii(ext);
493: if(!(mode&KEEP_DESC)) {
494: sprintf(tmpext,"%.256s",ext);
495: prep_desc(tmpext);
496: for(i=0;tmpext[i];i++)
497: if(isalpha(tmpext[i]))
498: break;
499: sprintf(f.desc,"%.*s",LEN_FDESC,tmpext+i);
500: for(i=0;f.desc[i]>=' ' && i<LEN_FDESC;i++)
501: ;
502: f.desc[i]=0;
503: }
504: close(file);
505: f.misc|=FM_EXTDESC;
506: }
507: }
508: }
509:
510: f.cdt=l;
511: f.dateuled=time(NULL);
512: f.altpath=cur_altpath;
513: prep_desc(f.desc);
514: if(mode&ASCII_ONLY)
515: strip_exascii(f.desc);
516: if(exist) {
517: putfiledat(&scfg,&f);
518: if(!(mode&NO_NEWDATE))
519: update_uldate(&scfg, &f);
520: }
521: else
522: addfiledat(&scfg,&f);
523: if(f.misc&FM_EXTDESC) {
524: truncsp(ext);
525: putextdesc(&scfg,f.dir,f.datoffset,ext);
526: }
527:
528: if(mode&UL_STATS)
529: updatestats(l);
530: files++;
531: }
532: fclose(stream);
533: if(mode&DEL_LIST && !(mode&SYNC_LIST)) {
534: printf("\nDeleting %s\n",listpath);
535: remove(listpath);
536: }
537:
538: }
539:
540: void synclist(char *inpath, int dirnum)
541: {
542: uchar str[1024];
543: char fname[MAX_PATH+1];
544: char listpath[MAX_PATH+1];
545: uchar* ixbbuf;
546: uchar* p;
547: int i,file,found;
548: long l,m,length;
549: FILE* stream;
550: file_t f;
551:
552: sprintf(str,"%s%s.ixb",scfg.dir[dirnum]->data_dir,scfg.dir[dirnum]->code);
553: if((file=nopen(str,O_RDONLY|O_BINARY))==-1) {
554: printf("ERR_OPEN %s\n",str);
555: return;
556: }
557: length=filelength(file);
558: if(length%F_IXBSIZE) {
559: close(file);
560: printf("ERR_LEN (%ld) of %s\n",length,str);
561: return;
562: }
563: if((ixbbuf=(uchar *)malloc(length))==NULL) {
564: close(file);
565: printf("ERR_ALLOC %s\n",str);
566: return;
567: }
568: if(lread(file,ixbbuf,length)!=length) {
569: close(file);
570: free((char *)ixbbuf);
571: printf("ERR_READ %s\n",str);
572: return;
573: }
574: close(file);
575:
576: strcpy(listpath,inpath);
577: if((stream=fopen(listpath,"r"))==NULL) {
578: sprintf(listpath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
579: : scfg.dir[dirnum]->path,inpath);
580: if((stream=fopen(listpath,"r"))==NULL) {
581: printf("Can't open: %s\n"
582: " or: %s\n",inpath,listpath);
583: return;
584: }
585: }
586:
587: printf("\nSynchronizing %s with %s %s\n\n"
588: ,listpath,scfg.lib[scfg.dir[dirnum]->lib]->sname,scfg.dir[dirnum]->sname);
589:
590: for(l=0;l<length;l+=F_IXBSIZE) {
591: m=l;
592: for(i=0;i<12 && l<length;i++)
593: if(i==8)
594: str[i]=ixbbuf[m]>' ' ? '.' : ' ';
595: else
596: str[i]=ixbbuf[m++]; /* Turns FILENAMEEXT into FILENAME.EXT */
597: str[i]=0;
598: unpadfname(str,fname);
599: rewind(stream);
600: found=0;
601: while(!found) {
602: if(!fgets(str,1000,stream))
603: break;
604: truncsp(str);
605: p=strchr(str,' ');
606: if(p) *p=0;
607: if(!stricmp(str,fname))
608: found=1;
609: }
610: if(found)
611: continue;
612: padfname(fname,f.name);
613: printf("%s not found in list - ",f.name);
614: f.dir=dirnum;
615: f.datoffset=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16);
616: getfiledat(&scfg,&f);
617: if(f.opencount) {
618: printf("currently OPEN by %u users\n",f.opencount);
619: continue;
620: }
621: removefiledat(&scfg,&f);
622: if(remove(getfilepath(&scfg,&f,str)))
623: printf("Error removing %s\n",str);
624: removed++;
625: printf("Removed from database\n");
626: }
627:
628: if(mode&DEL_LIST) {
629: printf("\nDeleting %s\n",listpath);
630: remove(listpath);
631: }
632: }
633:
634: char *usage="\nusage: addfiles code [.alt_path] [-opts] +list "
635: "[desc_off] [size_off]"
636: "\n or: addfiles code [.alt_path] [-opts] file "
637: "\"description\"\n"
638: "\navailable opts:"
639: "\n a import ASCII only (no extended ASCII)"
640: "\n b synchronize database with file list (use with caution)"
641: "\n c do not remove extra spaces from file description"
642: "\n d delete list after import"
643: "\n e do not import extended descriptions"
644: "\n f include file date in descriptions"
645: "\n t include today's date in descriptions"
646: "\n i include added files in upload statistics"
647: "\n n do not update information for existing files"
648: "\n o update upload date only for existing files"
649: "\n u do not update upload date for existing files"
650: "\n z check for and import FILE_ID.DIZ and DESC.SDI"
651: "\n k keep original short description (not DIZ)"
652: "\n s search directory for files (no file list)"
653: "\n l<lib> specify library (short name) to Auto-ADD"
654: "\n x<name> specify uploader's user name (may require quotes)"
655: "\n"
656: "\nAuto-ADD: use - in place of code for Auto-ADD of FILES.BBS"
657: "\n use -filename to Auto-ADD a different filename"
658: "\n use -l \"libname\" to only Auto-ADD files to a specific library"
659: "\n"
660: ;
661:
662: /*********************/
663: /* Entry point (duh) */
664: /*********************/
665: int main(int argc, char **argv)
666: {
667: char error[512];
668: char revision[16];
669: char str[MAX_PATH+1];
670: char tmp[MAX_PATH+1];
671: uchar *p,exist,listgiven=0,namegiven=0,ext[513]
672: ,auto_name[MAX_PATH+1]="FILES.BBS";
673: int i,j,file;
674: uint desc_offset=0, size_offset=0;
675: long l;
676: file_t f;
677:
678: sscanf("$Revision: 1.39 $", "%*s %s", revision);
679:
680: fprintf(stderr,"\nADDFILES v%s-%s (rev %s) - Adds Files to Synchronet "
681: "Filebase\n"
682: ,ADDFILES_VER
683: ,PLATFORM_DESC
684: ,revision
685: );
686:
687: if(argc<2) {
688: printf(usage);
689: return(1);
690: }
691:
692: p=getenv("SBBSCTRL");
693: if(p==NULL) {
694: printf("\nSBBSCTRL environment variable not set.\n");
695: printf("\nExample: SET SBBSCTRL=/sbbs/ctrl\n");
696: exit(1);
697: }
698:
699: memset(&scfg,0,sizeof(scfg));
700: scfg.size=sizeof(scfg);
701: SAFECOPY(scfg.ctrl_dir,p);
702:
703: if(chdir(scfg.ctrl_dir)!=0)
704: fprintf(stderr,"!ERROR changing directory to: %s", scfg.ctrl_dir);
705:
706: printf("\nLoading configuration files from %s\n",scfg.ctrl_dir);
707: if(!load_cfg(&scfg,NULL,TRUE,error)) {
708: fprintf(stderr,"!ERROR loading configuration files: %s\n",error);
709: exit(1);
710: }
711: SAFECOPY(scfg.temp_dir,"../temp");
712: prep_dir(scfg.ctrl_dir, scfg.temp_dir, sizeof(scfg.temp_dir));
713:
714: if(!(scfg.sys_misc&SM_LOCAL_TZ))
715: putenv("TZ=UTC0");
716:
717: if(argv[1][0]=='*' || argv[1][0]=='-') {
718: if(argv[1][1]=='?') {
719: printf(usage);
720: exit(0);
721: }
722: if(argv[1][1])
723: SAFECOPY(auto_name,argv[1]+1);
724: mode|=AUTO_ADD;
725: i=0;
726: } else {
727: if(!isalnum(argv[1][0]) && argc==2) {
728: printf(usage);
729: return(1);
730: }
731:
732: for(i=0;i<scfg.total_dirs;i++)
733: if(!stricmp(scfg.dir[i]->code,argv[1])) /* use matchmatchi() instead? */
734: break;
735:
736: if(i>=scfg.total_dirs) {
737: printf("Directory code '%s' not found.\n",argv[1]);
738: exit(1);
739: }
740: }
741:
742: memset(&f,0,sizeof(file_t));
743: f.dir=i;
744: strcpy(f.uler,"-> ADDFILES <-");
745:
746: for(j=2;j<argc;j++) {
747: if(argv[j][0]=='*') /* set the uploader name (legacy) */
748: SAFECOPY(f.uler,argv[j]+1);
749: else
750: if(argv[j][0]=='-'
751: || argv[j][0]=='/'
752: ) { /* options */
753: for(i=1;argv[j][i];i++)
754: switch(toupper(argv[j][i])) {
755: case 'A':
756: mode|=ASCII_ONLY;
757: break;
758: case 'B':
759: mode|=(SYNC_LIST|NO_UPDATE);
760: break;
761: case 'C':
762: mode|=KEEP_SPACE;
763: break;
764: case 'D':
765: mode|=DEL_LIST;
766: break;
767: case 'E':
768: mode|=NO_EXTEND;
769: break;
770: case 'I':
771: mode|=UL_STATS;
772: break;
773: case 'L':
774: j++;
775: if(argv[j]==NULL) {
776: printf(usage);
777: return(-1);
778: }
779: SAFECOPY(lib,argv[j]);
780: i=strlen(argv[j])-1;
781: break;
782: case 'X':
783: j++;
784: if(argv[j]==NULL) {
785: printf(usage);
786: return(-1);
787: }
788: SAFECOPY(f.uler,argv[j]);
789: i=strlen(argv[j])-1;
790: break;
791: case 'Z':
792: mode|=FILE_ID;
793: break;
794: case 'K':
795: mode|=KEEP_DESC; /* Don't use DIZ for short desc */
796: break;
797: case 'N':
798: mode|=NO_UPDATE;
799: break;
800: case 'O':
801: mode|=ULDATE_ONLY;
802: break;
803: case 'U':
804: mode|=NO_NEWDATE;
805: break;
806: case 'F':
807: mode|=FILE_DATE;
808: break;
809: case 'T':
810: mode|=TODAYS_DATE;
811: break;
812: case 'S':
813: mode|=SEARCH_DIR;
814: break;
815: default:
816: printf(usage);
817: return(1);
818: }
819: }
820: else if(isdigit(argv[j][0])) {
821: if(desc_offset==0)
822: desc_offset=atoi(argv[j]);
823: else
824: size_offset=atoi(argv[j]);
825: continue;
826: }
827: else if(argv[j][0]=='+') { /* filelist - FILES.BBS */
828: listgiven=1;
829: if(argc > j+1
830: && isdigit(argv[j+1][0])) { /* skip x characters before description */
831: if(argc > j+2
832: && isdigit(argv[j+2][0])) { /* skip x characters before size */
833: addlist(argv[j]+1,f,atoi(argv[j+1]),atoi(argv[j+2]));
834: j+=2;
835: }
836: else {
837: addlist(argv[j]+1,f,atoi(argv[j+1]),0);
838: j++;
839: }
840: }
841: else
842: addlist(argv[j]+1,f,0,0);
843: if(mode&SYNC_LIST)
844: synclist(argv[j]+1,f.dir);
845: }
846: else if(argv[j][0]=='.') { /* alternate file path */
847: cur_altpath=atoi(argv[j]+1);
848: if(cur_altpath>scfg.altpaths) {
849: printf("Invalid alternate path.\n");
850: exit(1);
851: }
852: }
853: else {
854: namegiven=1;
855: padfname(argv[j],f.name);
856: f.desc[0]=0;
857: #if 0
858: strupr(f.name);
859: #endif
860: if(j+1==argc) {
861: printf("%s no description given.\n",f.name);
862: continue;
863: }
864: sprintf(str,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
865: : scfg.dir[f.dir]->path,argv[j]);
866: if(mode&FILE_DATE)
867: sprintf(f.desc,"%s ",unixtodstr(&scfg,fdate(str),tmp));
868: if(mode&TODAYS_DATE)
869: sprintf(f.desc,"%s ",unixtodstr(&scfg,time(NULL),tmp));
870: sprintf(tmp,"%.*s",(int)(LEN_FDESC-strlen(f.desc)),argv[++j]);
871: strcpy(f.desc,tmp);
872: l=flength(str);
873: if(l==-1) {
874: printf("%s not found.\n",str);
875: continue;
876: }
877: exist=findfile(&scfg,f.dir,f.name);
878: if(exist) {
879: if(mode&NO_UPDATE)
880: continue;
881: getfileixb(&scfg,&f);
882: if(mode&ULDATE_ONLY) {
883: f.dateuled=time(NULL);
884: update_uldate(&scfg, &f);
885: continue;
886: }
887: }
888: f.cdt=l;
889: f.dateuled=time(NULL);
890: f.altpath=cur_altpath;
891: prep_desc(f.desc);
892: if(mode&ASCII_ONLY)
893: strip_exascii(f.desc);
894: printf("%s %7lu %s\n",f.name,f.cdt,f.desc);
895: if(mode&FILE_ID) {
896: for(i=0;i<scfg.total_fextrs;i++)
897: if(!stricmp(scfg.fextr[i]->ext,f.name+9) && chk_ar(&scfg,scfg.fextr[i]->ar,NULL))
898: break;
899: if(i<scfg.total_fextrs) {
900: sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
901: remove(tmp);
902: system(mycmdstr(scfg.fextr[i]->cmd,str,"FILE_ID.DIZ",NULL));
903: if(!fexistcase(tmp)) {
904: sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
905: remove(tmp);
906: system(mycmdstr(scfg.fextr[i]->cmd,str,"DESC.SDI",NULL));
907: fexistcase(tmp);
908: }
909: if((file=nopen(tmp,O_RDONLY|O_BINARY))!=-1) {
910: memset(ext,0,513);
911: read(file,ext,512);
912: if(!(mode&KEEP_DESC)) {
913: sprintf(f.desc,"%.*s",LEN_FDESC,ext);
914: for(i=0;f.desc[i]>=' ' && i<LEN_FDESC;i++)
915: ;
916: f.desc[i]=0;
917: }
918: close(file);
919: f.misc|=FM_EXTDESC;
920: }
921: }
922: }
923: if(exist) {
924: putfiledat(&scfg,&f);
925: if(!(mode&NO_NEWDATE))
926: update_uldate(&scfg, &f);
927: }
928: else
929: addfiledat(&scfg,&f);
930:
931: if(f.misc&FM_EXTDESC)
932: putextdesc(&scfg,f.dir,f.datoffset,ext);
933:
934: if(mode&UL_STATS)
935: updatestats(l);
936: files++;
937: }
938: }
939:
940: if(mode&AUTO_ADD) {
941: for(i=0;i<scfg.total_dirs;i++) {
942: if(lib[0] && stricmp(scfg.lib[scfg.dir[i]->lib]->sname,lib))
943: continue;
944: if(scfg.dir[i]->misc&DIR_NOAUTO)
945: continue;
946: f.dir=i;
947: if(mode&SEARCH_DIR) {
948: addlist("",f,desc_offset,size_offset);
949: continue;
950: }
951: sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path,scfg.dir[f.dir]->code);
952: if(fexistcase(str) && flength(str)>0L) {
953: printf("Auto-adding %s\n",str);
954: addlist(str,f,desc_offset,size_offset);
955: if(mode&SYNC_LIST)
956: synclist(str,i);
957: continue;
958: }
959: sprintf(str,"%s%s",scfg.dir[f.dir]->path,auto_name);
960: if(fexistcase(str) && flength(str)>0L) {
961: printf("Auto-adding %s\n",str);
962: addlist(str,f,desc_offset,size_offset);
963: if(mode&SYNC_LIST)
964: synclist(str,i);
965: continue;
966: }
967: }
968: }
969:
970: else {
971: if(!listgiven && !namegiven) {
972: sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path, scfg.dir[f.dir]->code);
973: if(!fexistcase(str) || flength(str)<=0L)
974: sprintf(str,"%s%s",scfg.dir[f.dir]->path, auto_name);
975: addlist(str,f,desc_offset,size_offset);
976: if(mode&SYNC_LIST)
977: synclist(str,f.dir);
978: }
979: }
980:
981: printf("\n%lu file(s) added.",files);
982: if(removed)
983: printf("\n%lu files(s) removed.",removed);
984: printf("\n");
985: return(0);
986: }
987:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.