|
|
1.1 ! root 1: /* filelist.c */ ! 2: ! 3: /* Utility to create list of files from Synchronet file directories */ ! 4: /* Default list format is FILES.BBS, but file size, uploader, upload date */ ! 5: /* and other information can be included. */ ! 6: ! 7: /* $Id: filelist.c,v 1.12 2005/09/20 03:39:51 deuce Exp $ */ ! 8: ! 9: /**************************************************************************** ! 10: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 11: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 12: * * ! 13: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * ! 14: * * ! 15: * This program is free software; you can redistribute it and/or * ! 16: * modify it under the terms of the GNU General Public License * ! 17: * as published by the Free Software Foundation; either version 2 * ! 18: * of the License, or (at your option) any later version. * ! 19: * See the GNU General Public License for more details: gpl.txt or * ! 20: * http://www.fsf.org/copyleft/gpl.html * ! 21: * * ! 22: * Anonymous FTP access to the most recent released source is available at * ! 23: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 24: * * ! 25: * Anonymous CVS access to the development source and modification history * ! 26: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 28: * (just hit return, no password is necessary) * ! 29: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 30: * * ! 31: * For Synchronet coding style and modification guidelines, see * ! 32: * http://www.synchro.net/source.html * ! 33: * * ! 34: * You are encouraged to submit any modifications (preferably in Unix diff * ! 35: * format) via e-mail to [email protected] * ! 36: * * ! 37: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 38: ****************************************************************************/ ! 39: ! 40: #include "sbbs.h" ! 41: ! 42: #define FILELIST_VER "3.00" ! 43: ! 44: #define MAX_NOTS 25 ! 45: ! 46: scfg_t scfg; ! 47: ! 48: char *crlf="\r\n"; ! 49: ! 50: /****************************************************************************/ ! 51: /****************************************************************************/ ! 52: int lprintf(int level, char *fmat, ...) ! 53: { ! 54: va_list argptr; ! 55: char sbuf[256]; ! 56: int chcount; ! 57: ! 58: va_start(argptr,fmat); ! 59: chcount=vsprintf(sbuf,fmat,argptr); ! 60: va_end(argptr); ! 61: truncsp(sbuf); ! 62: printf("%s\n",sbuf); ! 63: return(chcount); ! 64: } ! 65: ! 66: void stripctrlz(char *str) ! 67: { ! 68: char tmp[1024]; ! 69: int i,j,k; ! 70: ! 71: k=strlen(str); ! 72: for(i=j=0;i<k;i++) ! 73: if(str[i]!=0x1a) ! 74: tmp[j++]=str[i]; ! 75: tmp[j]=0; ! 76: strcpy(str,tmp); ! 77: } ! 78: ! 79: ! 80: #define ALL (1L<<0) ! 81: #define PAD (1L<<1) ! 82: #define HDR (1L<<2) ! 83: #define CDT_ (1L<<3) ! 84: #define EXT (1L<<4) ! 85: #define ULN (1L<<5) ! 86: #define ULD (1L<<6) ! 87: #define DLS (1L<<7) ! 88: #define DLD (1L<<8) ! 89: #define NOD (1L<<9) ! 90: #define PLUS (1L<<10) ! 91: #define MINUS (1L<<11) ! 92: #define JST (1L<<12) ! 93: #define NOE (1L<<13) ! 94: #define DFD (1L<<14) ! 95: #define TOT (1L<<15) ! 96: #define AUTO (1L<<16) ! 97: ! 98: /*********************/ ! 99: /* Entry point (duh) */ ! 100: /*********************/ ! 101: int main(int argc, char **argv) ! 102: { ! 103: char revision[16]; ! 104: char error[512]; ! 105: char *p,str[256],fname[256],ext,not[MAX_NOTS][9]; ! 106: uchar *datbuf,*ixbbuf; ! 107: int i,j,file,dirnum,libnum,desc_off,lines,nots=0 ! 108: ,omode=O_WRONLY|O_CREAT|O_TRUNC; ! 109: ulong l,m,n,cdt,misc=0,total_cdt=0,total_files=0,datbuflen; ! 110: time_t uld,dld; ! 111: FILE *in,*out=NULL; ! 112: ! 113: sscanf("$Revision: 1.12 $", "%*s %s", revision); ! 114: ! 115: fprintf(stderr,"\nFILELIST v%s-%s (rev %s) - Generate Synchronet File " ! 116: "Directory Lists\n" ! 117: ,FILELIST_VER ! 118: ,PLATFORM_DESC ! 119: ,revision ! 120: ); ! 121: ! 122: if(argc<2 ! 123: || strcmp(argv[1],"-?")==0 ! 124: || strcmp(argv[1],"-help")==0 ! 125: || strcmp(argv[1],"--help")==0 ! 126: || strcmp(argv[1],"/?")==0 ! 127: ) { ! 128: printf("\n usage: FILELIST <dir_code or * for ALL> [switches] [outfile]\n"); ! 129: printf("\n"); ! 130: printf("switches: -lib name All directories of specified library\n"); ! 131: printf(" -not code Exclude specific directory\n"); ! 132: printf(" -cat Concatenate to existing outfile\n"); ! 133: printf(" -pad Pad filename with spaces\n"); ! 134: printf(" -hdr Include directory headers\n"); ! 135: printf(" -cdt Include credit value\n"); ! 136: printf(" -tot Include credit totals\n"); ! 137: printf(" -uln Include uploader's name\n"); ! 138: printf(" -uld Include upload date\n"); ! 139: printf(" -dfd Include DOS file date\n"); ! 140: printf(" -dld Include download date\n"); ! 141: printf(" -dls Include total downloads\n"); ! 142: printf(" -nod Exclude normal descriptions\n"); ! 143: printf(" -noe Exclude normal descriptions, if extended " ! 144: "exists\n"); ! 145: printf(" -ext Include extended descriptions\n"); ! 146: printf(" -jst Justify extended descriptions under normal\n"); ! 147: printf(" -+ Include extended description indicator (+)\n"); ! 148: printf(" -- Include offline file indicator (-)\n"); ! 149: printf(" -* Short-hand for -pad -hdr -cdt -+ --\n"); ! 150: exit(0); } ! 151: ! 152: p=getenv("SBBSCTRL"); ! 153: if(p==NULL) { ! 154: printf("\nSBBSCTRL environment variable not set.\n"); ! 155: printf("\nExample: SET SBBSCTRL=/sbbs/ctrl\n"); ! 156: exit(1); ! 157: } ! 158: ! 159: memset(&scfg,0,sizeof(scfg)); ! 160: scfg.size=sizeof(scfg); ! 161: SAFECOPY(scfg.ctrl_dir,p); ! 162: ! 163: if(chdir(scfg.ctrl_dir)!=0) ! 164: fprintf(stderr,"!ERROR changing directory to: %s", scfg.ctrl_dir); ! 165: ! 166: printf("\nLoading configuration files from %s\n",scfg.ctrl_dir); ! 167: if(!load_cfg(&scfg,NULL,TRUE,error)) { ! 168: fprintf(stderr,"!ERROR loading configuration files: %s\n",error); ! 169: exit(1); ! 170: } ! 171: SAFECOPY(scfg.temp_dir,"../temp"); ! 172: prep_dir(scfg.ctrl_dir, scfg.temp_dir, sizeof(scfg.temp_dir)); ! 173: ! 174: if(!(scfg.sys_misc&SM_LOCAL_TZ)) ! 175: putenv("TZ=UTC0"); ! 176: ! 177: dirnum=libnum=-1; ! 178: if(argv[1][0]=='*') ! 179: misc|=ALL; ! 180: else if(argv[1][0]!='-') { ! 181: strupr(argv[1]); ! 182: for(i=0;i<scfg.total_dirs;i++) ! 183: if(!stricmp(argv[1],scfg.dir[i]->code)) ! 184: break; ! 185: if(i>=scfg.total_dirs) { ! 186: printf("\nDirectory code '%s' not found.\n",argv[1]); ! 187: exit(1); } ! 188: dirnum=i; } ! 189: for(i=1;i<argc;i++) { ! 190: if(!stricmp(argv[i],"-lib")) { ! 191: if(dirnum!=-1) { ! 192: printf("\nBoth directory code and -lib parameters were used.\n"); ! 193: exit(1); } ! 194: i++; ! 195: if(i>=argc) { ! 196: printf("\nLibrary short name must follow -lib parameter.\n"); ! 197: exit(1); } ! 198: strupr(argv[i]); ! 199: for(j=0;j<scfg.total_libs;j++) ! 200: if(!stricmp(scfg.lib[j]->sname,argv[i])) ! 201: break; ! 202: if(j>=scfg.total_libs) { ! 203: printf("\nLibrary short name '%s' not found.\n",argv[i]); ! 204: exit(1); } ! 205: libnum=j; } ! 206: else if(!stricmp(argv[i],"-not")) { ! 207: if(nots>=MAX_NOTS) { ! 208: printf("\nMaximum number of -not options (%u) exceeded.\n" ! 209: ,MAX_NOTS); ! 210: exit(1); } ! 211: i++; ! 212: if(i>=argc) { ! 213: printf("\nDirectory internal code must follow -not parameter.\n"); ! 214: exit(1); } ! 215: sprintf(not[nots++],"%.8s",argv[i]); } ! 216: else if(!stricmp(argv[i],"-all")) { ! 217: if(dirnum!=-1) { ! 218: printf("\nBoth directory code and -all parameters were used.\n"); ! 219: exit(1); } ! 220: if(libnum!=-1) { ! 221: printf("\nBoth library name and -all parameters were used.\n"); ! 222: exit(1); } ! 223: misc|=ALL; } ! 224: else if(!stricmp(argv[i],"-pad")) ! 225: misc|=PAD; ! 226: else if(!stricmp(argv[i],"-cat")) ! 227: omode=O_WRONLY|O_CREAT|O_APPEND; ! 228: else if(!stricmp(argv[i],"-hdr")) ! 229: misc|=HDR; ! 230: else if(!stricmp(argv[i],"-cdt")) ! 231: misc|=CDT_; ! 232: else if(!stricmp(argv[i],"-tot")) ! 233: misc|=TOT; ! 234: else if(!stricmp(argv[i],"-ext")) ! 235: misc|=EXT; ! 236: else if(!stricmp(argv[i],"-uln")) ! 237: misc|=ULN; ! 238: else if(!stricmp(argv[i],"-uld")) ! 239: misc|=ULD; ! 240: else if(!stricmp(argv[i],"-dld")) ! 241: misc|=DLD; ! 242: else if(!stricmp(argv[i],"-dfd")) ! 243: misc|=DFD; ! 244: else if(!stricmp(argv[i],"-dls")) ! 245: misc|=DLS; ! 246: else if(!stricmp(argv[i],"-nod")) ! 247: misc|=NOD; ! 248: else if(!stricmp(argv[i],"-jst")) ! 249: misc|=(EXT|JST); ! 250: else if(!stricmp(argv[i],"-noe")) ! 251: misc|=(EXT|NOE); ! 252: else if(!stricmp(argv[i],"-+")) ! 253: misc|=PLUS; ! 254: else if(!stricmp(argv[i],"--")) ! 255: misc|=MINUS; ! 256: else if(!stricmp(argv[i],"-*")) ! 257: misc|=(HDR|PAD|CDT_|PLUS|MINUS); ! 258: ! 259: else if(i!=1) { ! 260: if(argv[i][0]=='*') { ! 261: misc|=AUTO; ! 262: continue; } ! 263: if((j=nopen(argv[i],omode))==-1) { ! 264: printf("\nError opening/creating %s for output.\n",argv[i]); ! 265: exit(1); } ! 266: out=fdopen(j,"wb"); } } ! 267: ! 268: if(!out && !(misc&AUTO)) { ! 269: printf("\nOutput file not specified, using FILES.BBS in each " ! 270: "directory.\n"); ! 271: misc|=AUTO; } ! 272: ! 273: for(i=0;i<scfg.total_dirs;i++) { ! 274: if(!(misc&ALL) && i!=dirnum && scfg.dir[i]->lib!=libnum) ! 275: continue; ! 276: for(j=0;j<nots;j++) ! 277: if(!stricmp(not[j],scfg.dir[i]->code)) ! 278: break; ! 279: if(j<nots) ! 280: continue; ! 281: if(misc&AUTO && scfg.dir[i]->seqdev) /* CD-ROM */ ! 282: continue; ! 283: printf("\n%-*s %s",LEN_GSNAME,scfg.lib[scfg.dir[i]->lib]->sname,scfg.dir[i]->lname); ! 284: sprintf(str,"%s%s.ixb",scfg.dir[i]->data_dir,scfg.dir[i]->code); ! 285: if((file=nopen(str,O_RDONLY))==-1) ! 286: continue; ! 287: l=filelength(file); ! 288: if(misc&AUTO) { ! 289: sprintf(str,"%sFILES.BBS",scfg.dir[i]->path); ! 290: if((j=nopen(str,omode))==-1) { ! 291: printf("\nError opening/creating %s for output.\n",str); ! 292: exit(1); } ! 293: out=fdopen(j,"wb"); } ! 294: if(misc&HDR) { ! 295: sprintf(fname,"%-*s %-*s Files: %4lu" ! 296: ,LEN_GSNAME,scfg.lib[scfg.dir[i]->lib]->sname ! 297: ,LEN_SLNAME,scfg.dir[i]->lname,l/F_IXBSIZE); ! 298: fprintf(out,"%s\r\n",fname); ! 299: memset(fname,'-',strlen(fname)); ! 300: fprintf(out,"%s\r\n",fname); } ! 301: if(!l) { ! 302: close(file); ! 303: if(misc&AUTO) fclose(out); ! 304: continue; } ! 305: if((ixbbuf=(char *)malloc(l))==NULL) { ! 306: close(file); ! 307: if(misc&AUTO) fclose(out); ! 308: printf("\7ERR_ALLOC %s %lu\n",str,l); ! 309: continue; } ! 310: if(read(file,ixbbuf,l)!=(int)l) { ! 311: close(file); ! 312: if(misc&AUTO) fclose(out); ! 313: printf("\7ERR_READ %s %lu\n",str,l); ! 314: free((char *)ixbbuf); ! 315: continue; } ! 316: close(file); ! 317: sprintf(str,"%s%s.dat",scfg.dir[i]->data_dir,scfg.dir[i]->code); ! 318: if((file=nopen(str,O_RDONLY))==-1) { ! 319: printf("\7ERR_OPEN %s %u\n",str,O_RDONLY); ! 320: free((char *)ixbbuf); ! 321: if(misc&AUTO) fclose(out); ! 322: continue; } ! 323: datbuflen=filelength(file); ! 324: if((datbuf=malloc(datbuflen))==NULL) { ! 325: close(file); ! 326: printf("\7ERR_ALLOC %s %lu\n",str,datbuflen); ! 327: free((char *)ixbbuf); ! 328: if(misc&AUTO) fclose(out); ! 329: continue; } ! 330: if(read(file,datbuf,datbuflen)!=(int)datbuflen) { ! 331: close(file); ! 332: printf("\7ERR_READ %s %lu\n",str,datbuflen); ! 333: free((char *)datbuf); ! 334: free((char *)ixbbuf); ! 335: if(misc&AUTO) fclose(out); ! 336: continue; } ! 337: close(file); ! 338: m=0L; ! 339: while(m<l && !ferror(out)) { ! 340: for(j=0;j<12 && m<l;j++) ! 341: if(j==8) ! 342: str[j]=ixbbuf[m]>' ' ? '.' : ' '; ! 343: else ! 344: str[j]=ixbbuf[m++]; /* Turns FILENAMEEXT into FILENAME.EXT */ ! 345: str[j]=0; ! 346: unpadfname(str,fname); ! 347: fprintf(out,"%-12.12s",misc&PAD ? str : fname); ! 348: total_files++; ! 349: n=ixbbuf[m]|((long)ixbbuf[m+1]<<8)|((long)ixbbuf[m+2]<<16); ! 350: uld=(ixbbuf[m+3]|((long)ixbbuf[m+4]<<8)|((long)ixbbuf[m+5]<<16) ! 351: |((long)ixbbuf[m+6]<<24)); ! 352: dld=(ixbbuf[m+7]|((long)ixbbuf[m+8]<<8)|((long)ixbbuf[m+9]<<16) ! 353: |((long)ixbbuf[m+10]<<24)); ! 354: m+=11; ! 355: ! 356: if(n>=datbuflen /* index out of bounds */ ! 357: || datbuf[n+F_DESC+LEN_FDESC]!=CR) { /* corrupted data */ ! 358: fprintf(stderr,"\n\7%s%s is corrupted!\n" ! 359: ,scfg.dir[i]->data_dir,scfg.dir[i]->code); ! 360: exit(-1); } ! 361: ! 362: ! 363: if(misc&PLUS && datbuf[n+F_MISC]!=ETX ! 364: && (datbuf[n+F_MISC]-' ')&FM_EXTDESC) ! 365: fputc('+',out); ! 366: else ! 367: fputc(' ',out); ! 368: ! 369: desc_off=12; ! 370: if(misc&(CDT_|TOT)) { ! 371: getrec((char *)&datbuf[n],F_CDT,LEN_FCDT,str); ! 372: cdt=atol(str); ! 373: total_cdt+=cdt; ! 374: if(misc&CDT_) { ! 375: fprintf(out,"%7lu",cdt); ! 376: desc_off+=7; } } ! 377: ! 378: if(misc&MINUS) { ! 379: sprintf(str,"%s%s",scfg.dir[i]->path,fname); ! 380: if(!fexistcase(str)) ! 381: fputc('-',out); ! 382: else ! 383: fputc(' ',out); } ! 384: else ! 385: fputc(' ',out); ! 386: desc_off++; ! 387: ! 388: if(misc&DFD) { ! 389: sprintf(str,"%s%s",scfg.dir[i]->path,fname); ! 390: fprintf(out,"%s ",unixtodstr(&scfg,fdate(str),str)); ! 391: desc_off+=9; } ! 392: ! 393: if(misc&ULD) { ! 394: fprintf(out,"%s ",unixtodstr(&scfg,uld,str)); ! 395: desc_off+=9; } ! 396: ! 397: if(misc&ULN) { ! 398: getrec((char *)&datbuf[n],F_ULER,25,str); ! 399: fprintf(out,"%-25s ",str); ! 400: desc_off+=26; } ! 401: ! 402: if(misc&DLD) { ! 403: fprintf(out,"%s ",unixtodstr(&scfg,dld,str)); ! 404: desc_off+=9; } ! 405: ! 406: if(misc&DLS) { ! 407: getrec((char *)&datbuf[n],F_TIMESDLED,5,str); ! 408: j=atoi(str); ! 409: fprintf(out,"%5u ",j); ! 410: desc_off+=6; } ! 411: ! 412: if(datbuf[n+F_MISC]!=ETX && (datbuf[n+F_MISC]-' ')&FM_EXTDESC) ! 413: ext=1; /* extended description exists */ ! 414: else ! 415: ext=0; /* it doesn't */ ! 416: ! 417: if(!(misc&NOD) && !(misc&NOE && ext)) { ! 418: getrec((char *)&datbuf[n],F_DESC,LEN_FDESC,str); ! 419: fprintf(out,"%s",str); } ! 420: ! 421: if(misc&EXT && ext) { /* Print ext desc */ ! 422: ! 423: sprintf(str,"%s%s.exb",scfg.dir[i]->data_dir,scfg.dir[i]->code); ! 424: if(!fexist(str)) ! 425: continue; ! 426: if((j=nopen(str,O_RDONLY))==-1) { ! 427: printf("\7ERR_OPEN %s %u\n",str,O_RDONLY); ! 428: continue; } ! 429: if((in=fdopen(j,"rb"))==NULL) { ! 430: close(j); ! 431: continue; } ! 432: fseek(in,(n/F_LEN)*512L,SEEK_SET); ! 433: lines=0; ! 434: if(!(misc&NOE)) { ! 435: fprintf(out,"\r\n"); ! 436: lines++; } ! 437: while(!feof(in) && !ferror(in) ! 438: && ftell(in)<(long)((n/F_LEN)+1)*512L) { ! 439: if(!fgets(str,128,in) || !str[0]) ! 440: break; ! 441: stripctrlz(str); ! 442: if(lines) { ! 443: if(misc&JST) ! 444: fprintf(out,"%*s",desc_off,""); ! 445: fputc(' ',out); /* indent one character */ } ! 446: fprintf(out,"%s",str); ! 447: lines++; } ! 448: fclose(in); } ! 449: fprintf(out,"\r\n"); } ! 450: free((char *)datbuf); ! 451: free((char *)ixbbuf); ! 452: fprintf(out,"\r\n"); /* blank line at end of dir */ ! 453: if(misc&AUTO) fclose(out); } ! 454: ! 455: if(misc&TOT && !(misc&AUTO)) ! 456: fprintf(out,"TOTALS\n------\n%lu credits/bytes in %lu files.\r\n" ! 457: ,total_cdt,total_files); ! 458: printf("\nDone.\n"); ! 459: return(0); ! 460: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.