|
|
1.1 root 1: /* addfiles.c */
2:
3: /* Program to add files to a Synchronet file database */
4:
1.1.1.2 ! root 5: /* $Id: addfiles.c,v 1.46 2010/05/24 05:19:48 rswindell Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 11: * Copyright 2009 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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: /****************************************************************************/
1.1.1.2 ! root 69: int lprintf(int level, const char *fmat, ...)
1.1 root 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;
1.1.1.2 ! root 187: uint32_t l;
1.1 root 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++)
1.1.1.2 ! root 269: if(!stricmp(scfg.fextr[i]->ext,f.name+9) && chk_ar(&scfg,scfg.fextr[i]->ar,/* user: */NULL, /* client: */NULL))
1.1 root 270: break;
271: if(i<scfg.total_fextrs) {
272: sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
1.1.1.2 ! root 273: removecase(tmp);
1.1 root 274: system(mycmdstr(scfg.fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
275: if(!fexistcase(tmp)) {
276: sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
1.1.1.2 ! root 277: removecase(tmp);
1.1 root 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)
1.1.1.2 ! root 289: strip_exascii(ext, ext);
1.1 root 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)
1.1.1.2 ! root 310: strip_exascii(f.desc, f.desc);
1.1 root 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++)
1.1.1.2 ! root 472: if(!stricmp(scfg.fextr[i]->ext,f.name+9) && chk_ar(&scfg,scfg.fextr[i]->ar,/* user: */NULL, /* client: */NULL))
1.1 root 473: break;
474: if(i<scfg.total_fextrs) {
475: sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
1.1.1.2 ! root 476: removecase(tmp);
1.1 root 477: system(mycmdstr(scfg.fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
478: if(!fexistcase(tmp)) {
479: sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
1.1.1.2 ! root 480: removecase(tmp);
1.1 root 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)
1.1.1.2 ! root 492: strip_exascii(ext, ext);
1.1 root 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)
1.1.1.2 ! root 515: strip_exascii(f.desc, f.desc);
1.1 root 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:"
1.1.1.2 ! root 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)"
1.1 root 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:
1.1.1.2 ! root 678: sscanf("$Revision: 1.46 $", "%*s %s", revision);
1.1 root 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(argv[1][0]=='*' || argv[1][0]=='-') {
715: if(argv[1][1]=='?') {
716: printf(usage);
717: exit(0);
718: }
719: if(argv[1][1])
720: SAFECOPY(auto_name,argv[1]+1);
721: mode|=AUTO_ADD;
722: i=0;
723: } else {
724: if(!isalnum(argv[1][0]) && argc==2) {
725: printf(usage);
726: return(1);
727: }
728:
729: for(i=0;i<scfg.total_dirs;i++)
730: if(!stricmp(scfg.dir[i]->code,argv[1])) /* use matchmatchi() instead? */
731: break;
732:
733: if(i>=scfg.total_dirs) {
734: printf("Directory code '%s' not found.\n",argv[1]);
735: exit(1);
736: }
737: }
738:
739: memset(&f,0,sizeof(file_t));
740: f.dir=i;
741: strcpy(f.uler,"-> ADDFILES <-");
742:
743: for(j=2;j<argc;j++) {
744: if(argv[j][0]=='*') /* set the uploader name (legacy) */
745: SAFECOPY(f.uler,argv[j]+1);
746: else
747: if(argv[j][0]=='-'
748: || argv[j][0]=='/'
749: ) { /* options */
750: for(i=1;argv[j][i];i++)
751: switch(toupper(argv[j][i])) {
752: case 'A':
753: mode|=ASCII_ONLY;
754: break;
755: case 'B':
756: mode|=(SYNC_LIST|NO_UPDATE);
757: break;
758: case 'C':
759: mode|=KEEP_SPACE;
760: break;
761: case 'D':
762: mode|=DEL_LIST;
763: break;
764: case 'E':
765: mode|=NO_EXTEND;
766: break;
767: case 'I':
768: mode|=UL_STATS;
769: break;
770: case 'L':
771: j++;
772: if(argv[j]==NULL) {
773: printf(usage);
774: return(-1);
775: }
776: SAFECOPY(lib,argv[j]);
777: i=strlen(argv[j])-1;
778: break;
779: case 'X':
780: j++;
781: if(argv[j]==NULL) {
782: printf(usage);
783: return(-1);
784: }
785: SAFECOPY(f.uler,argv[j]);
786: i=strlen(argv[j])-1;
787: break;
788: case 'Z':
789: mode|=FILE_ID;
790: break;
791: case 'K':
792: mode|=KEEP_DESC; /* Don't use DIZ for short desc */
793: break;
794: case 'N':
795: mode|=NO_UPDATE;
796: break;
797: case 'O':
798: mode|=ULDATE_ONLY;
799: break;
800: case 'U':
801: mode|=NO_NEWDATE;
802: break;
803: case 'F':
804: mode|=FILE_DATE;
805: break;
806: case 'T':
807: mode|=TODAYS_DATE;
808: break;
809: case 'S':
810: mode|=SEARCH_DIR;
811: break;
812: default:
813: printf(usage);
814: return(1);
815: }
816: }
817: else if(isdigit(argv[j][0])) {
818: if(desc_offset==0)
819: desc_offset=atoi(argv[j]);
820: else
821: size_offset=atoi(argv[j]);
822: continue;
823: }
824: else if(argv[j][0]=='+') { /* filelist - FILES.BBS */
825: listgiven=1;
826: if(argc > j+1
827: && isdigit(argv[j+1][0])) { /* skip x characters before description */
828: if(argc > j+2
829: && isdigit(argv[j+2][0])) { /* skip x characters before size */
830: addlist(argv[j]+1,f,atoi(argv[j+1]),atoi(argv[j+2]));
831: j+=2;
832: }
833: else {
834: addlist(argv[j]+1,f,atoi(argv[j+1]),0);
835: j++;
836: }
837: }
838: else
839: addlist(argv[j]+1,f,0,0);
840: if(mode&SYNC_LIST)
841: synclist(argv[j]+1,f.dir);
842: }
843: else if(argv[j][0]=='.') { /* alternate file path */
844: cur_altpath=atoi(argv[j]+1);
845: if(cur_altpath>scfg.altpaths) {
846: printf("Invalid alternate path.\n");
847: exit(1);
848: }
849: }
850: else {
851: namegiven=1;
852: padfname(argv[j],f.name);
853: f.desc[0]=0;
854: #if 0
855: strupr(f.name);
856: #endif
857: if(j+1==argc) {
858: printf("%s no description given.\n",f.name);
859: continue;
860: }
861: sprintf(str,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
862: : scfg.dir[f.dir]->path,argv[j]);
863: if(mode&FILE_DATE)
864: sprintf(f.desc,"%s ",unixtodstr(&scfg,fdate(str),tmp));
865: if(mode&TODAYS_DATE)
866: sprintf(f.desc,"%s ",unixtodstr(&scfg,time(NULL),tmp));
867: sprintf(tmp,"%.*s",(int)(LEN_FDESC-strlen(f.desc)),argv[++j]);
868: strcpy(f.desc,tmp);
869: l=flength(str);
870: if(l==-1) {
871: printf("%s not found.\n",str);
872: continue;
873: }
874: exist=findfile(&scfg,f.dir,f.name);
875: if(exist) {
876: if(mode&NO_UPDATE)
877: continue;
878: getfileixb(&scfg,&f);
879: if(mode&ULDATE_ONLY) {
880: f.dateuled=time(NULL);
881: update_uldate(&scfg, &f);
882: continue;
883: }
884: }
885: f.cdt=l;
886: f.dateuled=time(NULL);
887: f.altpath=cur_altpath;
888: prep_desc(f.desc);
889: if(mode&ASCII_ONLY)
1.1.1.2 ! root 890: strip_exascii(f.desc, f.desc);
1.1 root 891: printf("%s %7lu %s\n",f.name,f.cdt,f.desc);
892: if(mode&FILE_ID) {
893: for(i=0;i<scfg.total_fextrs;i++)
1.1.1.2 ! root 894: if(!stricmp(scfg.fextr[i]->ext,f.name+9) && chk_ar(&scfg,scfg.fextr[i]->ar,/* user: */NULL, /* client: */NULL))
1.1 root 895: break;
896: if(i<scfg.total_fextrs) {
897: sprintf(tmp,"%sFILE_ID.DIZ",scfg.temp_dir);
1.1.1.2 ! root 898: removecase(tmp);
1.1 root 899: system(mycmdstr(scfg.fextr[i]->cmd,str,"FILE_ID.DIZ",NULL));
900: if(!fexistcase(tmp)) {
901: sprintf(tmp,"%sDESC.SDI",scfg.temp_dir);
1.1.1.2 ! root 902: removecase(tmp);
1.1 root 903: system(mycmdstr(scfg.fextr[i]->cmd,str,"DESC.SDI",NULL));
904: fexistcase(tmp);
905: }
906: if((file=nopen(tmp,O_RDONLY|O_BINARY))!=-1) {
907: memset(ext,0,513);
908: read(file,ext,512);
909: if(!(mode&KEEP_DESC)) {
910: sprintf(f.desc,"%.*s",LEN_FDESC,ext);
911: for(i=0;f.desc[i]>=' ' && i<LEN_FDESC;i++)
912: ;
913: f.desc[i]=0;
914: }
915: close(file);
916: f.misc|=FM_EXTDESC;
917: }
918: }
919: }
920: if(exist) {
921: putfiledat(&scfg,&f);
922: if(!(mode&NO_NEWDATE))
923: update_uldate(&scfg, &f);
924: }
925: else
926: addfiledat(&scfg,&f);
927:
928: if(f.misc&FM_EXTDESC)
929: putextdesc(&scfg,f.dir,f.datoffset,ext);
930:
931: if(mode&UL_STATS)
932: updatestats(l);
933: files++;
934: }
935: }
936:
937: if(mode&AUTO_ADD) {
938: for(i=0;i<scfg.total_dirs;i++) {
939: if(lib[0] && stricmp(scfg.lib[scfg.dir[i]->lib]->sname,lib))
940: continue;
941: if(scfg.dir[i]->misc&DIR_NOAUTO)
942: continue;
943: f.dir=i;
944: if(mode&SEARCH_DIR) {
945: addlist("",f,desc_offset,size_offset);
946: continue;
947: }
948: sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path,scfg.dir[f.dir]->code);
949: if(fexistcase(str) && flength(str)>0L) {
950: printf("Auto-adding %s\n",str);
951: addlist(str,f,desc_offset,size_offset);
952: if(mode&SYNC_LIST)
953: synclist(str,i);
954: continue;
955: }
956: sprintf(str,"%s%s",scfg.dir[f.dir]->path,auto_name);
957: if(fexistcase(str) && flength(str)>0L) {
958: printf("Auto-adding %s\n",str);
959: addlist(str,f,desc_offset,size_offset);
960: if(mode&SYNC_LIST)
961: synclist(str,i);
962: continue;
963: }
964: }
965: }
966:
967: else {
968: if(!listgiven && !namegiven) {
969: sprintf(str,"%s%s.lst",scfg.dir[f.dir]->path, scfg.dir[f.dir]->code);
970: if(!fexistcase(str) || flength(str)<=0L)
971: sprintf(str,"%s%s",scfg.dir[f.dir]->path, auto_name);
972: addlist(str,f,desc_offset,size_offset);
973: if(mode&SYNC_LIST)
974: synclist(str,f.dir);
975: }
976: }
977:
978: printf("\n%lu file(s) added.",files);
979: if(removed)
980: printf("\n%lu files(s) removed.",removed);
981: printf("\n");
982: return(0);
983: }
984:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.