home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / ADDFILES / ADDFILES.C next >
Encoding:
C/C++ Source or Header  |  1997-05-18  |  46.7 KB  |  1,669 lines

  1. /* ADDFILES.C */
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. /* Program to add files to a Synchronet file database */
  6.  
  7. #include "sbbs.h"
  8.  
  9. #define ADDFILES_VER "2.23"
  10.  
  11. char tmp[256];
  12. char *crlf="\r\n";
  13.  
  14. #ifdef __TURBOC__
  15. unsigned _stklen=16000;
  16. #else
  17. unsigned _stacksize=16000;
  18. #endif
  19.  
  20. int cur_altpath=0;
  21.  
  22. long files=0,removed=0,mode=0;
  23.  
  24. #define DEL_LIST    (1L<<0)
  25. #define NO_EXTEND    (1L<<1)
  26. #define FILE_DATE    (1L<<2)
  27. #define TODAYS_DATE (1L<<3)
  28. #define FILE_ID     (1L<<4)
  29. #define NO_UPDATE    (1L<<5)
  30. #define NO_NEWDATE    (1L<<6)
  31. #define ASCII_ONLY    (1L<<7)
  32. #define UL_STATS    (1L<<8)
  33. #define ULDATE_ONLY (1L<<9)
  34. #define KEEP_DESC    (1L<<10)
  35. #define AUTO_ADD    (1L<<11)
  36. #define SEARCH_DIR    (1L<<12)
  37. #define SYNC_LIST    (1L<<13)
  38. #define KEEP_SPACE    (1L<<14)
  39.  
  40. #ifndef __FLAT__
  41. /****************************************************************************/
  42. /* This function reads files that are potentially larger than 32k.          */
  43. /* Up to one megabyte of data can be read with each call.                   */
  44. /****************************************************************************/
  45. long lread(int file, char HUGE16 *buf,long bytes)
  46. {
  47.     long count;
  48.  
  49. for(count=bytes;count>32767;count-=32767,buf+=32767)
  50.     if(read(file,(char *)buf,32767)!=32767)
  51.         return(-1L);
  52. if(read(file,(char *)buf,(int)count)!=count)
  53.     return(-1L);
  54. return(bytes);
  55. }
  56.  
  57. /****************************************************************************/
  58. /* This function writes files that are potentially larger than 32767 bytes  */
  59. /* Up to one megabytes of data can be written with each call.                */
  60. /****************************************************************************/
  61. long lwrite(int file, char HUGE16 *buf, long bytes)
  62. {
  63.  
  64.     long count;
  65.  
  66. for(count=bytes;count>32767;count-=32767,buf+=32767)
  67.     if(write(file,(char *)buf,32767)!=32767)
  68.         return(-1L);
  69. if(write(file,(char *)buf,(int)count)!=count)
  70.     return(-1L);
  71. return(bytes);
  72. }
  73. #endif
  74.  
  75. long lputs(char FAR16 *str)
  76. {
  77.     char tmp[256];
  78.     int i,j,k;
  79.  
  80. j=strlen(str);
  81. for(i=k=0;i<j;i++)      /* remove CRs */
  82.     if(str[i]==CR && str[i+1]==LF)
  83.         continue;
  84.     else
  85.         tmp[k++]=str[i];
  86. tmp[k]=0;
  87. return(fputs(tmp,stdout));
  88. }
  89.  
  90. /****************************************************************************/
  91. /* Returns string for 2 digit hex+ numbers up to 575                        */
  92. /****************************************************************************/
  93. char *hexplus(uint num, char *str)
  94. {
  95. sprintf(str,"%03x",num);
  96. str[0]=num/0x100 ? 'f'+(num/0x10)-0xf : str[1];
  97. str[1]=str[2];
  98. str[2]=0;
  99. return(str);
  100. }
  101.  
  102.  
  103. /****************************************************************************/
  104. /* Places into 'strout', 'strin' starting at 'start' and ending at            */
  105. /* 'start'+'length'                                                           */
  106. /****************************************************************************/
  107. void putrec(char *strout,int start,int length,char *strin)
  108. {
  109.     int i=0,j;
  110.  
  111. j=strlen(strin);
  112. while(i<j && i<length)
  113.     strout[start++]=strin[i++];
  114. while(i++<length)
  115.     strout[start++]=ETX;
  116. }
  117.  
  118. /****************************************************************************/
  119. /* Performs printf() through local assembly routines                        */
  120. /* Called from everywhere                                                   */
  121. /****************************************************************************/
  122. int lprintf(char *fmat, ...)
  123. {
  124.     va_list argptr;
  125.     char sbuf[256];
  126.     int chcount;
  127.  
  128. va_start(argptr,fmat);
  129. chcount=vsprintf(sbuf,fmat,argptr);
  130. va_end(argptr);
  131. lputs(sbuf);
  132. return(chcount);
  133. }
  134.  
  135. /****************************************************************************/
  136. /* Truncates white-space chars off end of 'str' and terminates at first tab */
  137. /****************************************************************************/
  138. void truncsp(char *str)
  139. {
  140.     int c;
  141.  
  142. str[strcspn(str,"\t")]=0;
  143. c=strlen(str);
  144. while(c && (uchar)str[c-1]<=SP) c--;
  145. str[c]=0;
  146. }
  147.  
  148. /****************************************************************************/
  149. /* Puts a backslash on path strings                                         */
  150. /****************************************************************************/
  151. void backslash(char *str)
  152. {
  153.     int i;
  154.  
  155. i=strlen(str);
  156. if(i && str[i-1]!='\\') {
  157.     str[i]='\\'; str[i+1]=0; }
  158. }
  159.  
  160. /****************************************************************************/
  161. /* Checks the disk drive for the existence of a file. Returns 1 if it       */
  162. /* exists, 0 if it doesn't.                                                 */
  163. /****************************************************************************/
  164. char fexist(char *filespec)
  165. {
  166.     struct find_t f;
  167.     uint i;
  168.  
  169. i=_dos_findfirst(filespec,_A_NORMAL,&f);
  170. #ifdef __WATCOMC__
  171. _dos_findclose(&f);
  172. #endif
  173. if(!i)
  174.     return(1);
  175. return(0);
  176. }
  177.  
  178. /****************************************************************************/
  179. /* Returns the time/date of the file in 'filespec' in time_t (unix) format  */
  180. /****************************************************************************/
  181. long fdate(char *filespec)
  182. {
  183.     int     file;
  184.     ushort    fd,ft;
  185.     struct    tm t;
  186.  
  187. if((file=nopen(filespec,O_RDONLY))==-1)
  188.     return(0);
  189. _dos_getftime(file,&fd,&ft);
  190. close(file);
  191. memset(&t,0,sizeof(t));
  192. t.tm_year=((fd&0xfe00)>>9)+80;
  193. t.tm_mon=((fd&0x01e0)>>5)-1;
  194. t.tm_mday=fd&0x1f;
  195. t.tm_hour=(ft&0xf800)>>11;
  196. t.tm_min=(ft&0x07e0)>>5;
  197. t.tm_sec=(ft&0x001f)<<1;
  198. return(mktime(&t));
  199. }
  200.  
  201. /*****************************************************************************/
  202. /* Returns command line generated from instr with %c replacments             */
  203. /*****************************************************************************/
  204. char *cmdstr(char *instr, char *fpath, char *fspec, char *outstr)
  205. {
  206.     static char cmd[128];
  207.     char str[256];
  208.     int i,j,len;
  209.  
  210. len=strlen(instr);
  211. for(i=j=0;i<len && j<128;i++) {
  212.     if(instr[i]=='%') {
  213.         i++;
  214.         cmd[j]=0;
  215.         switch(toupper(instr[i])) {
  216.             case 'F':   /* File path */
  217.                 strcat(cmd,fpath);
  218.                 break;
  219.             case 'G':   /* Temp directory */
  220.                 if(temp_dir[0]!='\\' && temp_dir[1]!=':')
  221.                     strcat(cmd,node_dir);
  222.                 strcat(cmd,temp_dir);
  223.                 break;
  224.             case 'N':   /* Node Directory (same as SBBSNODE environment var) */
  225.                 strcat(cmd,node_dir);
  226.                 break;
  227.             case 'S':   /* File Spec */
  228.                 strcat(cmd,fspec);
  229.                 break;
  230.             case '!':   /* EXEC Directory */
  231.                 if(exec_dir[0]!='\\' && exec_dir[1]!=':')
  232.                     strcat(cmd,node_dir);
  233.                 strcat(cmd,exec_dir);
  234.                 break;
  235.             case '#':   /* Node number (same as SBBSNNUM environment var) */
  236.                 sprintf(str,"%d",node_num);
  237.                 strcat(cmd,str);
  238.                 break;
  239.             case '%':   /* %% for percent sign */
  240.                 strcat(cmd,"%");
  241.                 break;
  242.             default:    /* unknown specification */
  243.                 break; }
  244.         j=strlen(cmd); }
  245.     else
  246.         cmd[j++]=instr[i]; }
  247. cmd[j]=0;
  248.  
  249. return(cmd);
  250. }
  251.  
  252.  
  253. /****************************************************************************/
  254. /* Converts unix time format (long - time_t) into a char str MM/DD/YY        */
  255. /****************************************************************************/
  256. char *unixtodstr(time_t unix, char *str)
  257. {
  258.     struct tm *t;
  259.  
  260. if(!unix)
  261.     strcpy(str,"00/00/00");
  262. else {
  263.     t=gmtime(&unix);
  264.     sprintf(str,"%02u/%02u/%02u",t->tm_mon+1,t->tm_mday
  265.         ,t->tm_year); }
  266. return(str);
  267. }
  268.  
  269. /****************************************************************************/
  270. /* Network open function. Opens all files DENYALL and retries LOOP_NOPEN    */
  271. /* number of times if the attempted file is already open or denying access    */
  272. /* for some other reason.    All files are opened in BINARY mode.            */
  273. /****************************************************************************/
  274. int nopen(char *str, int access)
  275. {
  276.     char logstr[256];
  277.     int file,share,count=0;
  278.  
  279. if(access==O_RDONLY) share=SH_DENYWR;
  280.     else share=SH_DENYRW;
  281. while(((file=sopen(str,O_BINARY|access,share,S_IWRITE))==-1)
  282.     && errno==EACCES && count++<LOOP_NOPEN);
  283. if(file==-1 && errno==EACCES)
  284.     lputs("\7\r\nNOPEN: ACCESS DENIED\r\n\7");
  285. return(file);
  286. }
  287.  
  288. /****************************************************************************/
  289. /* This function performs an nopen, but returns a file stream with a buffer */
  290. /* allocated.                                                                */
  291. /****************************************************************************/
  292. FILE *fnopen(int *file, char *str, int access)
  293. {
  294.     char mode[128];
  295.     FILE *stream;
  296.  
  297. if(access&O_WRONLY) access|=O_RDWR;     /* fdopen can't open WRONLY */
  298.  
  299. if(((*file)=nopen(str,access))==-1)
  300.     return(NULL);
  301.  
  302. if(access&O_APPEND) {
  303.     if(access&(O_RDONLY|O_RDWR))
  304.         strcpy(mode,"a+");
  305.     else
  306.         strcpy(mode,"a"); }
  307. else {
  308.     if(access&(O_WRONLY|O_RDWR))
  309.         strcpy(mode,"r+");
  310.     else
  311.         strcpy(mode,"r"); }
  312. stream=fdopen((*file),mode);
  313. if(stream==NULL) {
  314.     close(*file);
  315.     return(NULL); }
  316. setvbuf(stream,NULL,_IOFBF,16*1024);
  317. return(stream);
  318. }
  319.  
  320. void allocfail(uint size)
  321. {
  322. lprintf("\7Error allocating %u bytes of memory.\r\n",size);
  323. bail(1);
  324. }
  325.  
  326. void bail(int code)
  327. {
  328. exit(code);
  329. }
  330.  
  331. /****************************************************************************/
  332. /* Returns the length of the file in 'filespec'                             */
  333. /****************************************************************************/
  334. long flength(char *filespec)
  335. {
  336.     struct find_t f;
  337.     uint i;
  338.  
  339. i=_dos_findfirst(filespec,_A_NORMAL,&f);
  340. #ifdef __WATCOMC__
  341. _dos_findclose(&f);
  342. #endif
  343. if(!i)
  344.     return(f.size);
  345. return(-1L);
  346. }
  347.  
  348. /****************************************************************************/
  349. /* Turns FILE.EXT into FILE    .EXT                                         */
  350. /* Called from upload                                                       */
  351. /****************************************************************************/
  352. char *padfname(char *filename, char *str)
  353. {
  354.     char c,d;
  355.  
  356. for(c=0;c<8;c++)
  357.     if(filename[c]=='.' || !filename[c]) break;
  358.     else str[c]=filename[c];
  359. d=c;
  360. if(filename[c]=='.') c++;
  361. while(d<8)
  362.     str[d++]=SP;
  363. str[d++]='.';
  364. while(d<12)
  365.     if(!filename[c]) break;
  366.     else str[d++]=filename[c++];
  367. while(d<12)
  368.     str[d++]=SP;
  369. str[d]=0;
  370. return(str);
  371. }
  372.  
  373. /****************************************************************************/
  374. /* Turns FILE    .EXT into FILE.EXT                                         */
  375. /****************************************************************************/
  376. char *unpadfname(char *filename, char *str)
  377. {
  378.     char c,d;
  379.  
  380. for(c=0,d=0;c<strlen(filename);c++)
  381.     if(filename[c]!=SP) str[d++]=filename[c];
  382. str[d]=0;
  383. return(str);
  384. }
  385.  
  386. /****************************************************************************/
  387. /* Checks  directory data file for 'filename' (must be padded). If found,   */
  388. /* it returns the 1, else returns 0.                                        */
  389. /* Called from upload and bulkupload                                        */
  390. /****************************************************************************/
  391. char findfile(uint dirnum, char *filename)
  392. {
  393.     char str[256],c,fname[128],HUGE16 *ixbbuf;
  394.     int file;
  395.     ulong length,l;
  396.  
  397. strcpy(fname,filename);
  398. for(c=8;c<12;c++)   /* Turn FILENAME.EXT into FILENAMEEXT */
  399.     fname[c]=fname[c+1];
  400. sprintf(str,"%s%s.IXB",dir[dirnum]->data_dir,dir[dirnum]->code);
  401. if((file=nopen(str,O_RDONLY))==-1) return(0);
  402. length=filelength(file);
  403. if(!length) {
  404.     close(file);
  405.     return(0); }
  406. if((ixbbuf=(char *)MALLOC(length))==NULL) {
  407.     close(file);
  408.     printf("ERR_ALLOC %s %lu\n",str,length);
  409.     return(0); }
  410. if(lread(file,ixbbuf,length)!=length) {
  411.     close(file);
  412.     FREE((char *)ixbbuf);
  413.     return(0); }
  414. close(file);
  415. for(l=0;l<length;l+=F_IXBSIZE) {
  416.     for(c=0;c<11;c++)
  417.         if(fname[c]!=ixbbuf[l+c]) break;
  418.     if(c==11) break; }
  419. FREE((char *)ixbbuf);
  420. if(l<length)
  421.     return(1);
  422. return(0);
  423. }
  424.  
  425.  
  426. /****************************************************************************/
  427. /* Adds the data for struct filedat to the directory's data base.           */
  428. /* changes the .datoffset field only                                        */
  429. /****************************************************************************/
  430. char addfiledat(file_t *f)
  431. {
  432.     char str[256],fdat[F_LEN+1],fname[128],idx[128],c,HUGE16 *ixbbuf;
  433.     int i,file;
  434.     ulong length,l,uldate;
  435.  
  436. /************************/
  437. /* Add data to DAT File */
  438. /************************/
  439. sprintf(str,"%s%s.DAT",dir[f->dir]->data_dir,dir[f->dir]->code);
  440. if((file=nopen(str,O_RDWR|O_CREAT))==-1) {
  441.     printf("ERROR opening %s\n",str);
  442.     return(0); }
  443. length=filelength(file);
  444. if(length==0L)
  445.     l=0L;
  446. else {
  447.     if(length%F_LEN) {
  448.         close(file);
  449.         printf("ERR_LEN %s %lu\n",str,length);
  450.         return(0); }
  451.     for(l=0;l<length;l+=F_LEN) {    /* Find empty slot */
  452.         lseek(file,l,SEEK_SET);
  453.         read(file,&c,1);
  454.         if(c==ETX) break; } }
  455. putrec(fdat,F_CDT,7,ultoa(f->cdt,tmp,10));
  456. putrec(fdat,F_CDT+7,2,crlf);
  457. putrec(fdat,F_DESC,LEN_FDESC,f->desc);
  458. putrec(fdat,F_DESC+LEN_FDESC,2,crlf);
  459. putrec(fdat,F_ULER,LEN_ALIAS+5,f->uler);
  460. putrec(fdat,F_ULER+LEN_ALIAS+5,2,crlf);
  461. putrec(fdat,F_TIMESDLED,5,ultoa(f->timesdled,tmp,10));
  462. putrec(fdat,F_TIMESDLED+5,2,crlf);
  463. putrec(fdat,F_OPENCOUNT,3,itoa(f->opencount,tmp,10));
  464. putrec(fdat,F_OPENCOUNT+3,2,crlf);
  465. fdat[F_MISC]=f->misc+SP;
  466. putrec(fdat,F_ALTPATH,2,hexplus(f->altpath,tmp));
  467. putrec(fdat,F_ALTPATH+2,2,crlf);
  468. f->datoffset=l;
  469. idx[0]=l&0xff;          /* Get offset within DAT file for IXB file */
  470. idx[1]=(l>>8)&0xff;
  471. idx[2]=(l>>16)&0xff;
  472. lseek(file,l,SEEK_SET);
  473. if(write(file,fdat,F_LEN)!=F_LEN) {
  474.     close(file);
  475.     return(0); }
  476. length=filelength(file);
  477. close(file);
  478. if(length%F_LEN)
  479.     printf("ERR_LEN %s %lu\n",str,length);
  480.  
  481. /*******************************************/
  482. /* Update last upload date/time stamp file */
  483. /*******************************************/
  484. sprintf(str,"%s%s.DAB",dir[f->dir]->data_dir,dir[f->dir]->code);
  485. if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
  486.     printf("ERR_OPEN %s\r\n",str);
  487. else {
  488.     uldate=time(NULL);
  489.     write(file,&uldate,4);
  490.     close(file); }
  491.  
  492. /************************/
  493. /* Add data to IXB File */
  494. /************************/
  495. strcpy(fname,f->name);
  496. for(i=8;i<12;i++)   /* Turn FILENAME.EXT into FILENAMEEXT */
  497.     fname[i]=fname[i+1];
  498. sprintf(str,"%s%s.IXB",dir[f->dir]->data_dir,dir[f->dir]->code);
  499. if((file=nopen(str,O_RDWR|O_CREAT))==-1) {
  500.     printf("ERR_OPEN %s\n",str);
  501.     return(0); }
  502. length=filelength(file);
  503. if(length) {    /* IXB file isn't empty */
  504.     if(length%F_IXBSIZE) {
  505.         close(file);
  506.         printf("ERR_LEN %s %lu\n",str,length);
  507.         return(0); }
  508.     if((ixbbuf=(char *)MALLOC(length))==NULL) {
  509.         close(file);
  510.         printf("ERR_ALLOC %s %lu\n",str,length);
  511.         return(0); }
  512.     if(lread(file,ixbbuf,length)!=length) {
  513.         close(file);
  514.         printf("ERR_READ %s %lu\n",str,length);
  515.         FREE((char *)ixbbuf);
  516.         return(0); }
  517. /************************************************/
  518. /* Sort by Name or Date, Assending or Decending */
  519. /************************************************/
  520.     if(dir[f->dir]->sort==SORT_NAME_A || dir[f->dir]->sort==SORT_NAME_D) {
  521.         for(l=0;l<length;l+=F_IXBSIZE) {
  522.             for(i=0;i<12 && fname[i]==ixbbuf[l+i];i++);
  523.             if(i==12) {     /* file already in directory index */
  524.                 close(file);
  525.                 printf("ERR_CHK %s\n",fname);
  526.                 FREE((char *)ixbbuf);
  527.                 return(0); }
  528.             if(dir[f->dir]->sort==SORT_NAME_A && fname[i]<ixbbuf[l+i])
  529.                 break;
  530.             if(dir[f->dir]->sort==SORT_NAME_D && fname[i]>ixbbuf[l+i])
  531.                 break; } }
  532.     else {  /* sort by date */
  533.         for(l=0;l<length;l+=F_IXBSIZE) {
  534.             uldate=(ixbbuf[l+15]|((long)ixbbuf[l+16]<<8)
  535.                 |((long)ixbbuf[l+17]<<16)|((long)ixbbuf[l+18]<<24));
  536.             if(dir[f->dir]->sort==SORT_DATE_A && f->dateuled>uldate)
  537.                 break;
  538.             if(dir[f->dir]->sort==SORT_DATE_D && f->dateuled<uldate)
  539.                 break; } }
  540.     lseek(file,l,SEEK_SET);
  541.     if(write(file,fname,11)!=11) {  /* Write filename to IXB file */
  542.         close(file);
  543.         FREE((char *)ixbbuf);
  544.         return(0); }
  545.     if(write(file,idx,3)!=3) {  /* Write DAT offset into IXB file */
  546.         close(file);
  547.         FREE((char *)ixbbuf);
  548.         return(0); }
  549.     write(file,&f->dateuled,sizeof(time_t));
  550.     write(file,&f->datedled,4);              /* Write 0 for datedled */
  551.     if(lwrite(file,&ixbbuf[l],length-l)!=length-l) { /* Write rest of IXB */
  552.         close(file);
  553.         FREE((char *)ixbbuf);
  554.         return(0); }
  555.     FREE((char *)ixbbuf); }
  556. else {              /* IXB file is empty... No files */
  557.     if(write(file,fname,11)!=11) {  /* Write filename it IXB file */
  558.         close(file);
  559.         return(0); }
  560.     if(write(file,idx,3)!=3) {  /* Write DAT offset into IXB file */
  561.         close(file);
  562.         return(0); }
  563.     write(file,&f->dateuled,sizeof(time_t));
  564.     write(file,&f->datedled,4); }
  565. length=filelength(file);
  566. close(file);
  567. if(length%F_IXBSIZE)
  568.     printf("ERR_LEN %s %lu\n",str,length);
  569. return(1);
  570. }
  571.  
  572. void putextdesc(uint dirnum, ulong datoffset, char *ext)
  573. {
  574.     char str[256],nulbuf[512];
  575.     int file;
  576.  
  577. sprintf(str,"%s%s.EXB",dir[dirnum]->data_dir,dir[dirnum]->code);
  578. if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
  579.     return;
  580. lseek(file,0L,SEEK_END);
  581. while(filelength(file)<(datoffset/F_LEN)*512L)
  582.     write(file,nulbuf,512);
  583. lseek(file,(datoffset/F_LEN)*512L,SEEK_SET);
  584. write(file,ext,512);
  585. close(file);
  586. }
  587.  
  588. /****************************************************************************/
  589. /* Gets file data from dircode.IXB file                                        */
  590. /* Need fields .name and .dir filled.                                       */
  591. /* only fills .offset, .dateuled, and .datedled                             */
  592. /****************************************************************************/
  593. void getfileixb(file_t *f)
  594. {
  595.     uchar HUGE16 *ixbbuf,str[256],fname[128];
  596.     int file;
  597.     ulong l,length;
  598.  
  599. sprintf(str,"%s%s.IXB",dir[f->dir]->data_dir,dir[f->dir]->code);
  600. if((file=nopen(str,O_RDONLY))==-1) {
  601.     printf("ERR_OPEN %s\n",str);
  602.     return; }
  603. length=filelength(file);
  604. if(length%F_IXBSIZE) {
  605.     close(file);
  606.     printf("ERR_LEN %s\n");
  607.     return; }
  608. if((ixbbuf=(uchar HUGE16 *)MALLOC(length))==NULL) {
  609.     close(file);
  610.     printf("ERR_ALLOC %s\n",str);
  611.     return; }
  612. if(lread(file,ixbbuf,length)!=length) {
  613.     close(file);
  614.     FREE((char *)ixbbuf);
  615.     printf("ERR_READ %s\n",str);
  616.     return; }
  617. close(file);
  618. strcpy(fname,f->name);
  619. for(l=8;l<12;l++)    /* Turn FILENAME.EXT into FILENAMEEXT */
  620.     fname[l]=fname[l+1];
  621. for(l=0;l<length;l+=F_IXBSIZE) {
  622.     sprintf(str,"%11.11s",ixbbuf+l);
  623.     if(!strcmp(str,fname))
  624.         break; }
  625. if(l>=length) {
  626.     printf("getfileixb: ERR_CHK %s\n",fname);
  627.     FREE((char *)ixbbuf);
  628.     return; }
  629. l+=11;
  630. f->datoffset=ixbbuf[l]|((long)ixbbuf[l+1]<<8)|((long)ixbbuf[l+2]<<16);
  631. f->dateuled=ixbbuf[l+3]|((long)ixbbuf[l+4]<<8)
  632.     |((long)ixbbuf[l+5]<<16)|((long)ixbbuf[l+6]<<24);
  633. f->datedled=ixbbuf[l+7]|((long)ixbbuf[l+8]<<8)
  634.     |((long)ixbbuf[l+9]<<16)|((long)ixbbuf[l+10]<<24);
  635. FREE((char *)ixbbuf);
  636. }
  637.  
  638. /****************************************************************************/
  639. /* Puts filedata into DIR_code.DAT file                                     */
  640. /* Called from removefiles                                                  */
  641. /****************************************************************************/
  642. void putfiledat(file_t f)
  643. {
  644.     char buf[F_LEN+1],str[256];
  645.     int file;
  646.     long length;
  647.  
  648. putrec(buf,F_CDT,7,ultoa(f.cdt,tmp,10));
  649. putrec(buf,F_CDT+7,2,crlf);
  650. putrec(buf,F_DESC,LEN_FDESC,f.desc);
  651. putrec(buf,F_DESC+LEN_FDESC,2,crlf);
  652. putrec(buf,F_ULER,LEN_ALIAS+5,f.uler);
  653. putrec(buf,F_ULER+LEN_ALIAS+5,2,crlf);
  654. putrec(buf,F_TIMESDLED,5,itoa(f.timesdled,tmp,10));
  655. putrec(buf,F_TIMESDLED+5,2,crlf);
  656. putrec(buf,F_OPENCOUNT,3,itoa(f.opencount,tmp,10));
  657. putrec(buf,F_OPENCOUNT+3,2,crlf);
  658. buf[F_MISC]=f.misc+SP;
  659. putrec(buf,F_ALTPATH,2,hexplus(f.altpath,tmp));
  660. putrec(buf,F_ALTPATH+2,2,crlf);
  661. sprintf(str,"%s%s.DAT",dir[f.dir]->data_dir,dir[f.dir]->code);
  662. if((file=nopen(str,O_WRONLY))==-1) {
  663.     printf("ERR_OPEN %s\n",str);
  664.     return; }
  665. length=filelength(file);
  666. if(length%F_LEN) {
  667.     close(file);
  668.     printf("ERR_LEN %s\n",str);
  669.     return; }
  670. if(f.datoffset>length) {
  671.     close(file);
  672.     printf("ERR_LEN %s\n",str);
  673.     return; }
  674. lseek(file,f.datoffset,SEEK_SET);
  675. if(write(file,buf,F_LEN)!=F_LEN) {
  676.     close(file);
  677.     printf("ERR_WRITE %s\n",str);
  678.     return; }
  679. length=filelength(file);
  680. close(file);
  681. if(length%F_LEN)
  682.     printf("ERR_LEN %s\n",str);
  683. }
  684.  
  685. /****************************************************************************/
  686. /* Update the upload date for the file 'f'                                  */
  687. /****************************************************************************/
  688. void update_uldate(file_t f)
  689. {
  690.     char str[256],fname[128];
  691.     int i,file;
  692.     long l,length;
  693.  
  694. /*******************/
  695. /* Update IXB File */
  696. /*******************/
  697. sprintf(str,"%s%s.IXB",dir[f.dir]->data_dir,dir[f.dir]->code);
  698. if((file=nopen(str,O_RDWR))==-1) {
  699.     printf("ERR_OPEN %s\n",str);
  700.     return; }
  701. length=filelength(file);
  702. if(length%F_IXBSIZE) {
  703.     close(file);
  704.     printf("ERR_LEN %s\n",str);
  705.     return; }
  706. strcpy(fname,f.name);
  707. for(i=8;i<12;i++)   /* Turn FILENAME.EXT into FILENAMEEXT */
  708.     fname[i]=fname[i+1];
  709. for(l=0;l<length;l+=F_IXBSIZE) {
  710.     read(file,str,F_IXBSIZE);      /* Look for the filename in the IXB file */
  711.     str[11]=0;
  712.     if(!strcmp(fname,str)) break; }
  713. if(l>=length) {
  714.     close(file);
  715.     printf("ERR_CHK %s\n",f.name);
  716.     return; }
  717. lseek(file,l+14,SEEK_SET);
  718. write(file,&f.dateuled,4);    /* Write the current time stamp for datedled */
  719. close(file);
  720.  
  721. /*******************************************/
  722. /* Update last upload date/time stamp file */
  723. /*******************************************/
  724. sprintf(str,"%s%s.DAB",dir[f.dir]->data_dir,dir[f.dir]->code);
  725. if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
  726.     printf("ERR_OPEN %s\r\n",str);
  727. else {
  728.     write(file,&f.dateuled,4);
  729.     close(file); }
  730.  
  731. }
  732.  
  733.  
  734. void strip_ctrl(char *str)
  735. {
  736.     char tmp[1024];
  737.     int i,j,k;
  738.  
  739. k=strlen(str);
  740. for(i=j=0;i<k;i++)
  741.     if(j && str[i]==SP && tmp[j-1]==SP && (mode&KEEP_SPACE))
  742.         tmp[j++]=str[i];
  743.     else if(j && str[i]<=SP && tmp[j-1]==SP)
  744.         continue;
  745.     else if(i && !isalnum(str[i]) && str[i]==str[i-1])
  746.         continue;
  747.     else if((uchar)str[i]>=SP)
  748.         tmp[j++]=str[i];
  749.     else if(str[i]==TAB || (str[i]==CR && str[i+1]==LF))
  750.         tmp[j++]=SP;
  751. tmp[j]=0;
  752. strcpy(str,tmp);
  753. }
  754.  
  755.  
  756. void strip_exascii(char *str)
  757. {
  758.     char tmp[1024];
  759.     int i,j,k;
  760.  
  761. k=strlen(str);
  762. for(i=j=0;i<k;i++)
  763.     if(!(str[i]&0x80))
  764.         tmp[j++]=str[i];
  765. tmp[j]=0;
  766. strcpy(str,tmp);
  767. }
  768.  
  769. /****************************************************************************/
  770. /* Updates dstst.dab file                                                    */
  771. /****************************************************************************/
  772. void updatestats(ulong size)
  773. {
  774.     char str[256];
  775.     int i,file;
  776.     ulong l;
  777.  
  778. sprintf(str,"%sDSTS.DAB",ctrl_dir);
  779. if((file=nopen(str,O_RDWR))==-1) {
  780.     printf("ERR_OPEN %s\n",str);
  781.     return; }
  782. lseek(file,20L,SEEK_SET);    /* Skip timestamp, logons and logons today */
  783. read(file,&l,4);            /* Uploads today         */
  784. l++;
  785. lseek(file,-4L,SEEK_CUR);
  786. write(file,&l,4);
  787. read(file,&l,4);            /* Upload bytes today     */
  788. l+=size;
  789. lseek(file,-4L,SEEK_CUR);
  790. write(file,&l,4);
  791. close(file);
  792. }
  793.  
  794. void addlist(char *inpath, file_t f, char dskip, char sskip)
  795. {
  796.     uchar str[256],fname[256],listpath[256],filepath[256]
  797.         ,curline[256],nextline[256],*p,exist,ext[1024],tmpext[513];
  798.     int i,file;
  799.     long l;
  800.     FILE *stream;
  801.     struct find_t ff;
  802.  
  803. if(mode&SEARCH_DIR) {
  804.     strcpy(str,cur_altpath ? altpath[cur_altpath-1] : dir[f.dir]->path);
  805.     if(str[0]=='.') {
  806.         sprintf(tmp,"%s%s",node_dir,str);
  807.         strcpy(str,tmp); }
  808.     strcat(str,"*.*");
  809.     printf("Searching %s\n\n",str);
  810.     for(i=_dos_findfirst(str,0,&ff);!i;i=_dos_findnext(&ff)) {
  811.         strupr(ff.name);
  812.         sprintf(filepath,"%s%s",cur_altpath ? altpath[cur_altpath-1]
  813.             : dir[f.dir]->path,ff.name);
  814.         if(filepath[0]=='.') { /* relative path */
  815.             sprintf(tmp,"%s%s",node_dir,filepath);
  816.             strcpy(filepath,tmp); }
  817.         f.misc=0;
  818.         f.desc[0]=0;
  819.         f.cdt=flength(filepath);
  820.         padfname(ff.name,f.name);
  821.         printf("%s  %10lu  %s\n"
  822.             ,f.name,f.cdt,unixtodstr(fdate(filepath),str));
  823.         exist=findfile(f.dir,f.name);
  824.         if(exist) {
  825.             if(mode&NO_UPDATE)
  826.                 continue;
  827.             getfileixb(&f);
  828.             if(mode&ULDATE_ONLY) {
  829.                 f.dateuled=time(NULL);
  830.                 update_uldate(f);
  831.                 continue; } }
  832.  
  833.         if(mode&FILE_DATE) {        /* get the file date and put into desc */
  834.             unixtodstr(fdate(filepath),f.desc);
  835.             strcat(f.desc,"  "); }
  836.  
  837.         if(mode&TODAYS_DATE) {        /* put today's date in desc */
  838.             unixtodstr(time(NULL),f.desc);
  839.             strcat(f.desc,"  "); }
  840.  
  841.         if(mode&FILE_ID) {
  842.             for(i=0;i<total_fextrs;i++)
  843.                 if(!stricmp(fextr[i]->ext,f.name+9))
  844.                     break;
  845.             if(i<total_fextrs) {
  846.                 sprintf(tmp,"%sFILE_ID.DIZ",temp_dir);
  847.                 remove(tmp);
  848.                 system(cmdstr(fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
  849.                 if(!fexist(tmp)) {
  850.                     sprintf(tmp,"%sDESC.SDI",temp_dir);
  851.                     remove(tmp);
  852.                     system(cmdstr(fextr[i]->cmd,filepath,"DESC.SDI",NULL)); }
  853.                 if((file=nopen(tmp,O_RDONLY))!=-1) {
  854.                     memset(ext,0,513);
  855.                     read(file,ext,512);
  856.                     for(i=512;i;i--)
  857.                         if(ext[i-1]>SP)
  858.                             break;
  859.                     ext[i]=0;
  860.                     if(mode&ASCII_ONLY)
  861.                         strip_exascii(ext);
  862.                     if(!(mode&KEEP_DESC)) {
  863.                         sprintf(tmpext,"%.256s",ext);
  864.                         strip_ctrl(tmpext);
  865.                         for(i=0;tmpext[i];i++)
  866.                             if(isalpha(tmpext[i]))
  867.                                 break;
  868.                         sprintf(f.desc,"%.*s",LEN_FDESC,tmpext+i);
  869.                         for(i=0;f.desc[i]>=SP && i<LEN_FDESC;i++)
  870.                             ;
  871.                         f.desc[i]=0; }
  872.                     close(file);
  873.                     f.misc|=FM_EXTDESC; } } }
  874.  
  875.         f.dateuled=time(NULL);
  876.         f.altpath=cur_altpath;
  877.         strip_ctrl(f.desc);
  878.         if(mode&ASCII_ONLY)
  879.             strip_exascii(f.desc);
  880.         if(exist) {
  881.             putfiledat(f);
  882.             if(!(mode&NO_NEWDATE))
  883.                 update_uldate(f); }
  884.         else
  885.             addfiledat(&f);
  886.         if(f.misc&FM_EXTDESC) {
  887.             truncsp(ext);
  888.             putextdesc(f.dir,f.datoffset,ext); }
  889.  
  890.         if(mode&UL_STATS)
  891.             updatestats(f.cdt);
  892.         files++; }
  893. #ifdef __WATCOMC__
  894.    _dos_findclose(&ff);
  895. #endif
  896.     return; }
  897.  
  898.  
  899. strcpy(listpath,inpath);
  900. if((stream=fnopen(&file,listpath,O_RDONLY))==NULL) {
  901.     sprintf(listpath,"%s%s",cur_altpath ? altpath[cur_altpath-1]
  902.             : dir[f.dir]->path,inpath);
  903.     if(listpath[0]=='.') { /* relative path */
  904.         sprintf(str,"%s%s",node_dir,listpath);
  905.         strcpy(listpath,str); }
  906.     if((stream=fnopen(&file,listpath,O_RDONLY))==NULL) {
  907.         printf("Can't open: %s\n"
  908.                "        or: %s\n",inpath,listpath);
  909.         return; } }
  910.  
  911. printf("Adding %s to %s %s\n\n"
  912.     ,listpath,lib[dir[f.dir]->lib]->sname,dir[f.dir]->sname);
  913.  
  914. fgets(nextline,255,stream);
  915. while(!feof(stream) && !ferror(stream)) {
  916.     f.misc=0;
  917.     f.desc[0]=0;
  918.     strcpy(curline,nextline);
  919.     nextline[0]=0;
  920.     fgets(nextline,255,stream);
  921.     truncsp(curline);
  922.     if(curline[0]<=SP || (uchar)curline[0]>=0x7e)
  923.         continue;
  924.     printf("%s\n",curline);
  925.     strcpy(fname,curline);
  926.  
  927.     p=strchr(fname,'.');
  928.     if(!p || p==fname || p>fname+8)    /* no dot or invalid dot location */
  929.         continue;
  930.     p=strchr(p,SP);
  931.     if(p) *p=0;
  932.     else                   /* no space after filename? */
  933.         continue;
  934.     strupr(fname);
  935.     strcpy(fname,unpadfname(fname,tmp));
  936.  
  937.     padfname(fname,f.name);
  938.     if(strcspn(f.name,"\\/|<>+[]:=\";,")!=strlen(f.name))
  939.         continue;
  940.  
  941.     for(i=0;i<12;i++)
  942.         if(f.name[i]<SP || (uchar)f.name[i]>0x7e)
  943.             break;
  944.  
  945.     if(i<12)                    /* Ctrl chars or EX-ASCII in filename? */
  946.         continue;
  947.     exist=findfile(f.dir,f.name);
  948.     if(exist) {
  949.         if(mode&NO_UPDATE)
  950.             continue;
  951.         getfileixb(&f);
  952.         if(mode&ULDATE_ONLY) {
  953.             f.dateuled=time(NULL);
  954.             update_uldate(f);
  955.             continue; } }
  956.  
  957.     sprintf(filepath,"%s%s",cur_altpath ? altpath[cur_altpath-1]
  958.         : dir[f.dir]->path,fname);
  959.     if(filepath[0]=='.') { /* relative path */
  960.         sprintf(tmp,"%s%s",node_dir,filepath);
  961.         strcpy(filepath,tmp); }
  962.  
  963.     if(mode&FILE_DATE) {        /* get the file date and put into desc */
  964.         l=fdate(filepath);
  965.         unixtodstr(l,f.desc);
  966.         strcat(f.desc,"  "); }
  967.  
  968.     if(mode&TODAYS_DATE) {        /* put today's date in desc */
  969.         l=time(NULL);
  970.         unixtodstr(l,f.desc);
  971.         strcat(f.desc,"  "); }
  972.  
  973.     if(dskip && strlen(curline)>=dskip) p=curline+dskip;
  974.     else {
  975.         p++;
  976.         while(*p==SP) p++; }
  977.     sprintf(tmp,"%.*s",LEN_FDESC-strlen(f.desc),p);
  978.     strcat(f.desc,tmp);
  979.  
  980.     if(nextline[0]==SP || strlen(p)>LEN_FDESC) {    /* ext desc */
  981.         if(!(mode&NO_EXTEND)) {
  982.             memset(ext,0,513);
  983.             f.misc|=FM_EXTDESC;
  984.             sprintf(ext,"%s\r\n",p); }
  985.  
  986.         if(nextline[0]==SP) {
  987.             strcpy(str,nextline);                   /* tack on to end of desc */
  988.             p=str+dskip;
  989.             i=LEN_FDESC-strlen(f.desc);
  990.             if(i>1) {
  991.                 p[i-1]=0;
  992.                 truncsp(p);
  993.                 if(p[0]) {
  994.                     strcat(f.desc," ");
  995.                     strcat(f.desc,p); } } }
  996.  
  997.         while(!feof(stream) && !ferror(stream) && strlen(ext)<512) {
  998.             if(nextline[0]!=SP)
  999.                 break;
  1000.             truncsp(nextline);
  1001.             printf("%s\n",nextline);
  1002.             if(!(mode&NO_EXTEND)) {
  1003.                 f.misc|=FM_EXTDESC;
  1004.                 p=nextline+dskip;
  1005.                 while(*p==SP) p++;
  1006.                 strcat(ext,p);
  1007.                 strcat(ext,"\r\n"); }
  1008.             nextline[0]=0;
  1009.             fgets(nextline,255,stream); } }
  1010.  
  1011.  
  1012.     if(sskip) l=atol(fname+sskip);
  1013.     else {
  1014.         l=flength(filepath);
  1015.         if(l<1L) {
  1016.             printf("%s not found.\n",filepath);
  1017.             continue; } }
  1018.  
  1019.     if(mode&FILE_ID) {
  1020.         for(i=0;i<total_fextrs;i++)
  1021.             if(!stricmp(fextr[i]->ext,f.name+9))
  1022.                 break;
  1023.         if(i<total_fextrs) {
  1024.             sprintf(tmp,"%sFILE_ID.DIZ",temp_dir);
  1025.             remove(tmp);
  1026.             system(cmdstr(fextr[i]->cmd,filepath,"FILE_ID.DIZ",NULL));
  1027.             if(!fexist(tmp)) {
  1028.                 sprintf(tmp,"%sDESC.SDI",temp_dir);
  1029.                 remove(tmp);
  1030.                 system(cmdstr(fextr[i]->cmd,filepath,"DESC.SDI",NULL)); }
  1031.             if((file=nopen(tmp,O_RDONLY))!=-1) {
  1032.                 memset(ext,0,513);
  1033.                 read(file,ext,512);
  1034.                 for(i=512;i;i--)
  1035.                     if(ext[i-1]>SP)
  1036.                         break;
  1037.                 ext[i]=0;
  1038.                 if(mode&ASCII_ONLY)
  1039.                     strip_exascii(ext);
  1040.                 if(!(mode&KEEP_DESC)) {
  1041.                     sprintf(tmpext,"%.256s",ext);
  1042.                     strip_ctrl(tmpext);
  1043.                     for(i=0;tmpext[i];i++)
  1044.                         if(isalpha(tmpext[i]))
  1045.                             break;
  1046.                     sprintf(f.desc,"%.*s",LEN_FDESC,tmpext+i);
  1047.                     for(i=0;f.desc[i]>=SP && i<LEN_FDESC;i++)
  1048.                         ;
  1049.                     f.desc[i]=0; }
  1050.                 close(file);
  1051.                 f.misc|=FM_EXTDESC; } } }
  1052.  
  1053.     f.cdt=l;
  1054.     f.dateuled=time(NULL);
  1055.     f.altpath=cur_altpath;
  1056.     strip_ctrl(f.desc);
  1057.     if(mode&ASCII_ONLY)
  1058.         strip_exascii(f.desc);
  1059.     if(exist) {
  1060.         putfiledat(f);
  1061.         if(!(mode&NO_NEWDATE))
  1062.             update_uldate(f); }
  1063.     else
  1064.         addfiledat(&f);
  1065.     if(f.misc&FM_EXTDESC) {
  1066.         truncsp(ext);
  1067.         putextdesc(f.dir,f.datoffset,ext); }
  1068.  
  1069.     if(mode&UL_STATS)
  1070.         updatestats(l);
  1071.     files++; }
  1072. fclose(stream);
  1073. if(mode&DEL_LIST && !(mode&SYNC_LIST)) {
  1074.     printf("\nDeleting %s\n",listpath);
  1075.     remove(listpath); }
  1076.  
  1077. }
  1078.  
  1079. /***********************/
  1080. /* Hex-plus to integer */
  1081. /***********************/
  1082. uint hptoi(char *str)
  1083. {
  1084.     char tmp[128];
  1085.     uint i;
  1086.  
  1087. if(!str[1] || toupper(str[0])<='F')
  1088.     return(strtol(str,0,16));
  1089. strcpy(tmp,str);
  1090. tmp[0]='F';
  1091. i=strtol(tmp,0,16)+((toupper(str[0])-'F')*0x10);
  1092. return(i);
  1093. }
  1094.  
  1095. /****************************************************************************/
  1096. /* Places into 'strout' CR or ETX terminated string starting at             */
  1097. /* 'start' and ending at 'start'+'length' or terminator from 'strin'        */
  1098. /****************************************************************************/
  1099. void getrec(char *strin,int start,int length,char *strout)
  1100. {
  1101.     int i=0,stop;
  1102.  
  1103. stop=start+length;
  1104. while(start<stop) {
  1105.     if(strin[start]==ETX)
  1106.         break;
  1107.     strout[i++]=strin[start++]; }
  1108. strout[i]=0;
  1109. }
  1110.  
  1111.  
  1112. /****************************************************************************/
  1113. /* Gets filedata from dircode.DAT file                                        */
  1114. /* Need fields .name ,.dir and .offset to get other info                    */
  1115. /* Does not fill .dateuled or .datedled fields.                             */
  1116. /****************************************************************************/
  1117. void getfiledat(file_t *f)
  1118. {
  1119.     char buf[F_LEN+1],str[256];
  1120.     int file;
  1121.     long length;
  1122.  
  1123. sprintf(str,"%s%s.DAT",dir[f->dir]->data_dir,dir[f->dir]->code);
  1124. if((file=nopen(str,O_RDONLY))==-1) {
  1125.     printf("ERR_OPEN %s\n",str);
  1126.     return; }
  1127. length=filelength(file);
  1128. if(f->datoffset>length) {
  1129.     close(file);
  1130.     printf("ERR_LEN %s %lu\n",str,length);
  1131.     return; }
  1132. if(length%F_LEN) {
  1133.     close(file);
  1134.     printf("ERR_LEN %s %lu\n",str,length);
  1135.     return; }
  1136. lseek(file,f->datoffset,SEEK_SET);
  1137. if(read(file,buf,F_LEN)!=F_LEN) {
  1138.     close(file);
  1139.     printf("ERR_READ %s %lu\n",str,F_LEN);
  1140.     return; }
  1141. close(file);
  1142. getrec(buf,F_ALTPATH,2,str);
  1143. f->altpath=hptoi(str);
  1144. getrec(buf,F_CDT,7,str);
  1145. f->cdt=atol(str);
  1146. f->timetodl=0;
  1147.  
  1148. getrec(buf,F_DESC,LEN_FDESC,f->desc);
  1149. getrec(buf,F_ULER,LEN_ALIAS,f->uler);
  1150. getrec(buf,F_TIMESDLED,5,str);
  1151. f->timesdled=atoi(str);
  1152. getrec(buf,F_OPENCOUNT,3,str);
  1153. f->opencount=atoi(str);
  1154. if(buf[F_MISC]!=ETX)
  1155.     f->misc=buf[F_MISC]-SP;
  1156. else
  1157.     f->misc=0;
  1158. }
  1159.  
  1160. /****************************************************************************/
  1161. /* Removes any files in the user transfer index (XFER.IXT) that match the   */
  1162. /* specifications of dest, or source user, or filename or any combination.  */
  1163. /****************************************************************************/
  1164. void rmuserxfers(int fromuser, int destuser, char *fname)
  1165. {
  1166.     char str[256],*ixtbuf;
  1167.     int file;
  1168.     long l,length;
  1169.  
  1170. sprintf(str,"%sXFER.IXT",data_dir);
  1171. if(!fexist(str))
  1172.     return;
  1173. if(!flength(str)) {
  1174.     remove(str);
  1175.     return; }
  1176. if((file=nopen(str,O_RDONLY))==-1) {
  1177.     printf("ERR_OPEN %s\n",str);
  1178.     return; }
  1179. length=filelength(file);
  1180. if((ixtbuf=(char *)MALLOC(length))==NULL) {
  1181.     close(file);
  1182.     printf("ERR_ALLOC %s\n",str,length);
  1183.     return; }
  1184. if(read(file,ixtbuf,length)!=length) {
  1185.     close(file);
  1186.     FREE(ixtbuf);
  1187.     printf("ERR_READ %s %lu\n",str,length);
  1188.     return; }
  1189. close(file);
  1190. if((file=nopen(str,O_WRONLY|O_TRUNC))==-1) {
  1191.     FREE(ixtbuf);
  1192.     printf("ERR_OPEN %s\n",str);
  1193.     return; }
  1194. for(l=0;l<length;l+=24) {
  1195.     if(fname!=NULL && fname[0]) {               /* fname specified */
  1196.         if(!strncmp(ixtbuf+l+5,fname,12)) {     /* this is the file */
  1197.             if(destuser && fromuser) {          /* both dest and from user */
  1198.                 if(atoi(ixtbuf+l)==destuser && atoi(ixtbuf+l+18)==fromuser)
  1199.                     continue; }                 /* both match */
  1200.             else if(fromuser) {                 /* from user */
  1201.                 if(atoi(ixtbuf+l+18)==fromuser) /* matches */
  1202.                     continue; }
  1203.             else if(destuser) {                 /* dest user */
  1204.                 if(atoi(ixtbuf+l)==destuser)    /* matches */
  1205.                     continue; }
  1206.             else continue; } }                  /* no users, so match */
  1207.     else if(destuser && fromuser) {
  1208.         if(atoi(ixtbuf+l+18)==fromuser && atoi(ixtbuf+l)==destuser)
  1209.             continue; }
  1210.     else if(destuser && atoi(ixtbuf+l)==destuser)
  1211.         continue;
  1212.     else if(fromuser && atoi(ixtbuf+l+18)==fromuser)
  1213.         continue;
  1214.     write(file,ixtbuf+l,24); }
  1215. close(file);
  1216. FREE(ixtbuf);
  1217. }
  1218.  
  1219.  
  1220.  
  1221. /****************************************************************************/
  1222. /* Removes DAT and IXB entries for the file in the struct 'f'               */
  1223. /****************************************************************************/
  1224. void removefiledat(file_t f)
  1225. {
  1226.     char c,str[256],ixbname[12],HUGE16 *ixbbuf,fname[13];
  1227.     int file;
  1228.     ulong l,length;
  1229.  
  1230. strcpy(fname,f.name);
  1231. for(c=8;c<12;c++)   /* Turn FILENAME.EXT into FILENAMEEXT */
  1232.     fname[c]=fname[c+1];
  1233. sprintf(str,"%s%s.IXB",dir[f.dir]->data_dir,dir[f.dir]->code);
  1234. if((file=nopen(str,O_RDONLY))==-1) {
  1235.     printf("ERR_OPEN %s\n",str);
  1236.     return; }
  1237. length=filelength(file);
  1238. if(!length) {
  1239.     close(file);
  1240.     return; }
  1241. if((ixbbuf=(char *)MALLOC(length))==0) {
  1242.     close(file);
  1243.     printf("ERR_ALLOC %s %lu\n",str,length);
  1244.     return; }
  1245. if(lread(file,ixbbuf,length)!=length) {
  1246.     close(file);
  1247.     printf("ERR_READ %s %lu\n",str,length);
  1248.     FREE((char *)ixbbuf);
  1249.     return; }
  1250. close(file);
  1251. if((file=nopen(str,O_WRONLY|O_TRUNC))==-1) {
  1252.     printf("ERR_OPEN %s\n",str);
  1253.     return; }
  1254. for(l=0;l<length;l+=F_IXBSIZE) {
  1255.     for(c=0;c<11;c++)
  1256.         ixbname[c]=ixbbuf[l+c];
  1257.     ixbname[c]=0;
  1258.     if(strcmp(ixbname,fname))
  1259.         if(lwrite(file,&ixbbuf[l],F_IXBSIZE)!=F_IXBSIZE) {
  1260.             close(file);
  1261.             printf("ERR_WRITE %s %lu\n",str,F_IXBSIZE);
  1262.             FREE((char *)ixbbuf);
  1263.             return; } }
  1264. FREE((char *)ixbbuf);
  1265. close(file);
  1266. sprintf(str,"%s%s.DAT",dir[f.dir]->data_dir,dir[f.dir]->code);
  1267. if((file=nopen(str,O_WRONLY))==-1) {
  1268.     printf("ERR_OPEN %s\n",str);
  1269.     return; }
  1270. lseek(file,f.datoffset,SEEK_SET);
  1271. c=ETX;          /* If first char of record is ETX, record is unused */
  1272. if(write(file,&c,1)!=1) { /* So write a D_T on the first byte of the record */
  1273.     close(file);
  1274.     printf("ERR_WRITE %s 1",str);
  1275.     return; }
  1276. close(file);
  1277. if(f.dir==user_dir)  /* remove file from index */
  1278.     rmuserxfers(0,0,f.name);
  1279.  
  1280. }
  1281.  
  1282.  
  1283. void synclist(char *inpath, int dirnum)
  1284. {
  1285.     uchar str[1024],fname[256],listpath[256], HUGE16 *ixbbuf,*p;
  1286.     int i,file,found;
  1287.     long l,m,length;
  1288.     FILE *stream;
  1289.     file_t f;
  1290.  
  1291. sprintf(str,"%s%s.IXB",dir[dirnum]->data_dir,dir[dirnum]->code);
  1292. if((file=nopen(str,O_RDONLY))==-1) {
  1293.     printf("ERR_OPEN %s\n",str);
  1294.     return; }
  1295. length=filelength(file);
  1296. if(length%F_IXBSIZE) {
  1297.     close(file);
  1298.     printf("ERR_LEN %s\n");
  1299.     return; }
  1300. if((ixbbuf=(uchar HUGE16 *)MALLOC(length))==NULL) {
  1301.     close(file);
  1302.     printf("ERR_ALLOC %s\n",str);
  1303.     return; }
  1304. if(lread(file,ixbbuf,length)!=length) {
  1305.     close(file);
  1306.     FREE((char *)ixbbuf);
  1307.     printf("ERR_READ %s\n",str);
  1308.     return; }
  1309. close(file);
  1310.  
  1311. strcpy(listpath,inpath);
  1312. if((stream=fnopen(&file,listpath,O_RDONLY))==NULL) {
  1313.     sprintf(listpath,"%s%s",cur_altpath ? altpath[cur_altpath-1]
  1314.             : dir[dirnum]->path,inpath);
  1315.     if(listpath[0]=='.') { /* relative path */
  1316.         sprintf(str,"%s%s",node_dir,listpath);
  1317.         strcpy(listpath,str); }
  1318.     if((stream=fnopen(&file,listpath,O_RDONLY))==NULL) {
  1319.         printf("Can't open: %s\n"
  1320.                "        or: %s\n",inpath,listpath);
  1321.         return; } }
  1322.  
  1323. printf("\nSynchronizing %s with %s %s\n\n"
  1324.     ,listpath,lib[dir[dirnum]->lib]->sname,dir[dirnum]->sname);
  1325.  
  1326. for(l=0;l<length;l+=F_IXBSIZE) {
  1327.     m=l;
  1328.     for(i=0;i<12 && l<length;i++)
  1329.         if(i==8)
  1330.             str[i]='.';
  1331.         else
  1332.             str[i]=ixbbuf[m++];     /* Turns FILENAMEEXT into FILENAME.EXT */
  1333.     str[i]=0;
  1334.     unpadfname(str,fname);
  1335.     rewind(stream);
  1336.     found=0;
  1337.     while(!found) {
  1338.         if(!fgets(str,1000,stream))
  1339.             break;
  1340.         truncsp(str);
  1341.         p=strchr(str,SP);
  1342.         if(p) *p=0;
  1343.         if(!stricmp(str,fname))
  1344.             found=1; }
  1345.     if(found)
  1346.         continue;
  1347.     padfname(fname,f.name);
  1348.     printf("%s not found in list - ",f.name);
  1349.     f.dir=dirnum;
  1350.     f.datoffset=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16);
  1351.     getfiledat(&f);
  1352.     if(f.opencount) {
  1353.         printf("currently OPEN by %u users\n",f.opencount);
  1354.         continue; }
  1355.     removefiledat(f);
  1356.     sprintf(str,"%s%s"
  1357.         ,f.altpath>0 && f.altpath<=altpaths ? altpath[f.altpath-1]
  1358.         : dir[f.dir]->path,fname);
  1359.     if(str[0]=='.') {
  1360.         sprintf(tmp,"%s%s",node_dir,str);
  1361.         strcpy(str,tmp); }
  1362.     if(remove(str))
  1363.         printf("Error removing %s\n",str);
  1364.     removed++;
  1365.     printf("Removed from database\n"); }
  1366.  
  1367. if(mode&DEL_LIST) {
  1368.     printf("\nDeleting %s\n",listpath);
  1369.     remove(listpath); }
  1370. }
  1371.  
  1372. char *usage="\nusage: addfiles code [.alt_path] [/opts] [\"*user\"] +list "
  1373.              "[desc_off] [size_off]"
  1374.     "\n   or: addfiles code [.alt_path] [/opts] [\"*user\"]  file "
  1375.         "\"description\"\n"
  1376.     "\navailable opts:"
  1377.     "\n       a    import ASCII only (no extended ASCII)"
  1378.     "\n       b    synchronize database with file list (use with caution)"
  1379.     "\n       c    do not remove extra spaces from file description"
  1380.     "\n       d    delete list after import"
  1381.     "\n       e    do not import extended descriptions"
  1382.     "\n       f    include file date in descriptions"
  1383.     "\n       t    include today's date in descriptions"
  1384.     "\n       i    include added files in upload statistics"
  1385.     "\n       n    do not update information for existing files"
  1386.     "\n       o    update upload date only for existing files"
  1387.     "\n       u    do not update upload date for existing files"
  1388.     "\n       z    check for and import FILE_ID.DIZ and DESC.SDI"
  1389.     "\n       k    keep original short description (not DIZ)"
  1390.     "\n       s    search directory for files (no file list)"
  1391.     "\n"
  1392.     "\nAuto-ADD:   use * in place of code for Auto-ADD of FILES.BBS"
  1393.     "\n            use *filename to Auto-ADD a different filename"
  1394.     "\n"
  1395.     ;
  1396.  
  1397. /*********************/
  1398. /* Entry point (duh) */
  1399. /*********************/
  1400. int main(int argc, char **argv)
  1401. {
  1402.     uchar str[256],str2[256],*p,exist,listgiven=0,namegiven=0,ext[513]
  1403.         ,auto_name[13]="FILES.BBS";
  1404.     int i,j,k,file;
  1405.     long l;
  1406.     read_cfg_text_t txt;
  1407.     file_t f;
  1408.  
  1409. putenv("TZ=UCT0");
  1410. _fmode=O_BINARY;
  1411. setvbuf(stdout,NULL,_IONBF,0);
  1412.  
  1413. fprintf(stderr,"\nADDFILES Version %s (%s) - Adds files to Synchronet "
  1414.     "Filebase\n"
  1415.     ,ADDFILES_VER
  1416. #if defined(__OS2__)
  1417.     ,"OS/2"
  1418. #elif defined(__NT__)
  1419.     ,"Win32"
  1420. #elif defined(__DOS4G__)
  1421.     ,"DOS4G"
  1422. #elif defined(__FLAT__)
  1423.     ,"DOS32"
  1424. #else
  1425.     ,"DOS16"
  1426. #endif
  1427.     );
  1428.  
  1429. if(argc<2) {
  1430.     printf(usage);
  1431.     return(1); }
  1432.  
  1433. p=getenv("SBBSNODE");
  1434. if(p==NULL) {
  1435.     printf("\nSBBSNODE environment variable not set.\n");
  1436.     printf("\nExample: SET SBBSNODE=C:\\SBBS\\NODE1\n");
  1437.     exit(1); }
  1438.  
  1439. putenv("TZ=UCT0");
  1440.  
  1441. strcpy(node_dir,p);
  1442. if(node_dir[strlen(node_dir)-1]!='\\')
  1443.     strcat(node_dir,"\\");
  1444.  
  1445. txt.openerr="\7\nError opening %s for read.\n";
  1446. txt.reading="\nReading %s...";
  1447. txt.readit="\rRead %s       ";
  1448. txt.allocerr="\7\nError allocating %u bytes of memory\n";
  1449. txt.error="\7\nERROR: Offset %lu in %s\r\n\n";
  1450.  
  1451. read_node_cfg(txt);
  1452. if(ctrl_dir[0]=='.') {   /* Relative path */
  1453.     strcpy(str,ctrl_dir);
  1454.     sprintf(ctrl_dir,"%s%s",node_dir,str); }
  1455. read_main_cfg(txt);
  1456. if(data_dir[0]=='.') {   /* Relative path */
  1457.     strcpy(str,data_dir);
  1458.     sprintf(data_dir,"%s%s",node_dir,str); }
  1459. if(temp_dir[1]!=':' && temp_dir[0]!='\\') {
  1460.     strcpy(str,temp_dir);
  1461.     sprintf(temp_dir,"%s%s",node_dir,str); }
  1462. read_file_cfg(txt);
  1463. printf("\n\n");
  1464.  
  1465. if(argv[1][0]=='*') {
  1466.     if(argv[1][1])
  1467.         sprintf(auto_name,"%.12s",argv[1]+1);
  1468.     mode|=AUTO_ADD;
  1469.     i=0; }
  1470. else {
  1471.     for(i=0;i<total_dirs;i++)
  1472.         if(!stricmp(dir[i]->code,argv[1]))
  1473.             break;
  1474.  
  1475.     if(i>=total_dirs) {
  1476.         printf("Directory code '%s' not found.\n",argv[1]);
  1477.         exit(1); } }
  1478.  
  1479. memset(&f,0,sizeof(file_t));
  1480. f.dir=i;
  1481. strcpy(f.uler,"-> ADDFILES <-");
  1482.  
  1483. for(j=2;j<argc;j++) {
  1484.     if(argv[j][0]=='*')     /* set the uploader name */
  1485.         sprintf(f.uler,"%.25s",argv[j]+1);
  1486.     else if(argv[j][0]=='/') {      /* options */
  1487.         for(i=1;i<strlen(argv[j]);i++)
  1488.             switch(toupper(argv[j][i])) {
  1489.                 case 'A':
  1490.                     mode|=ASCII_ONLY;
  1491.                     break;
  1492.                 case 'B':
  1493.                     mode|=(SYNC_LIST|NO_UPDATE);
  1494.                     break;
  1495.                 case 'C':
  1496.                     mode|=KEEP_SPACE;
  1497.                     break;
  1498.                 case 'D':
  1499.                     mode|=DEL_LIST;
  1500.                     break;
  1501.                 case 'E':
  1502.                     mode|=NO_EXTEND;
  1503.                     break;
  1504.                 case 'I':
  1505.                     mode|=UL_STATS;
  1506.                     break;
  1507.                 case 'Z':
  1508.                     mode|=FILE_ID;
  1509.                     break;
  1510.                 case 'K':
  1511.                     mode|=KEEP_DESC;     /* Don't use DIZ for short desc */
  1512.                     break;
  1513.                 case 'N':
  1514.                     mode|=NO_UPDATE;
  1515.                     break;
  1516.                 case 'O':
  1517.                     mode|=ULDATE_ONLY;
  1518.                     break;
  1519.                 case 'U':
  1520.                     mode|=NO_NEWDATE;
  1521.                     break;
  1522.                 case 'F':
  1523.                     mode|=FILE_DATE;
  1524.                     break;
  1525.                 case 'T':
  1526.                     mode|=TODAYS_DATE;
  1527.                     break;
  1528.                 case 'S':
  1529.                     mode|=SEARCH_DIR;
  1530.                     break;
  1531.                 default:
  1532.                     printf(usage);
  1533.                     return(1); } }
  1534.     else if(argv[j][0]=='+') {      /* filelist - FILES.BBS */
  1535.         listgiven=1;
  1536.         if(isdigit(argv[j+1][0])) { /* skip x characters before description */
  1537.             if(isdigit(argv[j+2][0])) { /* skip x characters before size */
  1538.                 addlist(argv[j]+1,f,atoi(argv[j+1]),atoi(argv[j+2]));
  1539.                 j+=2; }
  1540.             else {
  1541.                 addlist(argv[j]+1,f,atoi(argv[j+1]),0);
  1542.                 j++; } }
  1543.         else
  1544.             addlist(argv[j]+1,f,0,0);
  1545.         if(mode&SYNC_LIST)
  1546.             synclist(argv[j]+1,f.dir); }
  1547.     else if(argv[j][0]=='.') {      /* alternate file path */
  1548.         cur_altpath=atoi(argv[j]+1);
  1549.         if(cur_altpath>altpaths) {
  1550.             printf("Invalid alternate path.\n");
  1551.             exit(1); } }
  1552.     else {
  1553.         namegiven=1;
  1554.         padfname(argv[j],f.name);
  1555.         f.desc[0]=0;
  1556.         strupr(f.name);
  1557.         if(j+1==argc) {
  1558.             printf("%s no description given.\n",f.name);
  1559.             continue; }
  1560.         sprintf(str,"%s%s",cur_altpath ? altpath[cur_altpath-1]
  1561.             : dir[f.dir]->path,argv[j]);
  1562.         if(str[0]=='.') {
  1563.             sprintf(tmp,"%s%s",node_dir,str);
  1564.             strcpy(str,tmp); }
  1565.         if(mode&FILE_DATE)
  1566.             sprintf(f.desc,"%s  ",unixtodstr(fdate(str),tmp));
  1567.         if(mode&TODAYS_DATE)
  1568.             sprintf(f.desc,"%s  ",unixtodstr(time(NULL),tmp));
  1569.         sprintf(tmp,"%.*s",LEN_FDESC-strlen(f.desc),argv[++j]);
  1570.         strcpy(f.desc,tmp);
  1571.         l=flength(str);
  1572.         if(l==-1) {
  1573.             printf("%s not found.\n",str);
  1574.             continue; }
  1575.         exist=findfile(f.dir,f.name);
  1576.         if(exist) {
  1577.             if(mode&NO_UPDATE)
  1578.                 continue;
  1579.             getfileixb(&f);
  1580.             if(mode&ULDATE_ONLY) {
  1581.                 f.dateuled=time(NULL);
  1582.                 update_uldate(f);
  1583.                 continue; } }
  1584.         f.cdt=l;
  1585.         f.dateuled=time(NULL);
  1586.         f.altpath=cur_altpath;
  1587.         strip_ctrl(f.desc);
  1588.         if(mode&ASCII_ONLY)
  1589.             strip_exascii(f.desc);
  1590.         printf("%s %7lu %s\n",f.name,f.cdt,f.desc);
  1591.         if(mode&FILE_ID) {
  1592.             for(i=0;i<total_fextrs;i++)
  1593.                 if(!stricmp(fextr[i]->ext,f.name+9))
  1594.                     break;
  1595.             if(i<total_fextrs) {
  1596.                 sprintf(tmp,"%sFILE_ID.DIZ",temp_dir);
  1597.                 remove(tmp);
  1598.                 system(cmdstr(fextr[i]->cmd,str,"FILE_ID.DIZ",NULL));
  1599.                 if(!fexist(tmp)) {
  1600.                     sprintf(tmp,"%sDESC.SDI",temp_dir);
  1601.                     remove(tmp);
  1602.                     system(cmdstr(fextr[i]->cmd,str,"DESC.SDI",NULL)); }
  1603.                 if((file=nopen(tmp,O_RDONLY))!=-1) {
  1604.                     memset(ext,0,513);
  1605.                     read(file,ext,512);
  1606.                     if(!(mode&KEEP_DESC)) {
  1607.                         sprintf(f.desc,"%.*s",LEN_FDESC,ext);
  1608.                         for(i=0;f.desc[i]>=SP && i<LEN_FDESC;i++)
  1609.                             ;
  1610.                         f.desc[i]=0; }
  1611.                     close(file);
  1612.                     f.misc|=FM_EXTDESC; } } }
  1613.         if(exist) {
  1614.             putfiledat(f);
  1615.             if(!(mode&NO_NEWDATE))
  1616.                 update_uldate(f); }
  1617.         else
  1618.             addfiledat(&f);
  1619.  
  1620.         if(f.misc&FM_EXTDESC)
  1621.             putextdesc(f.dir,f.datoffset,ext);
  1622.  
  1623.         if(mode&UL_STATS)
  1624.             updatestats(l);
  1625.         files++; } }
  1626.  
  1627. if(mode&AUTO_ADD) {
  1628.     for(i=0;i<total_dirs;i++) {
  1629.         if(dir[i]->misc&DIR_NOAUTO)
  1630.             continue;
  1631.         f.dir=i;
  1632.         if(mode&SEARCH_DIR) {
  1633.             addlist("",f,0,0);
  1634.             continue; }
  1635.         sprintf(str,"%s.LST",dir[f.dir]->code);
  1636.         if(flength(str)>0L) {
  1637.             printf("Auto-adding %s\n",str);
  1638.             addlist(str,f,0,0);
  1639.             if(mode&SYNC_LIST)
  1640.                 synclist(str,i);
  1641.             continue; }
  1642.         sprintf(str,"%s%s",dir[f.dir]->path,auto_name);
  1643.         if(str[0]=='.') {
  1644.             sprintf(tmp,"%s%s",node_dir,str);
  1645.             strcpy(str,tmp); }
  1646.         if(flength(str)>0L) {
  1647.             printf("Auto-adding %s\n",str);
  1648.             addlist(str,f,0,0);
  1649.             if(mode&SYNC_LIST)
  1650.                 synclist(str,i);
  1651.             continue; } } }
  1652.  
  1653. else {
  1654.     if(!listgiven && !namegiven) {
  1655.         sprintf(str,"%s.LST",dir[f.dir]->code);
  1656.         if(flength(str)<=0L)
  1657.             strcpy(str,"FILES.BBS");
  1658.         addlist(str,f,0,0);
  1659.         if(mode&SYNC_LIST)
  1660.             synclist(str,f.dir); } }
  1661.  
  1662. printf("\n%lu file(s) added.",files);
  1663. if(removed)
  1664.     printf("\n%lu files(s) removed.",removed);
  1665. printf("\n");
  1666. return(0);
  1667. }
  1668.  
  1669.