|
|
1.1 ! root 1: /* delfiles.c */ ! 2: ! 3: /* Program to delete expired files from a Synchronet file database */ ! 4: ! 5: /* $Id: delfiles.c,v 1.4 2006/04/26 19:23:18 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: ! 40: #define DELFILES_VER "1.01" ! 41: ! 42: char tmp[256]; ! 43: char *crlf="\r\n"; ! 44: ! 45: #define MAX_NOTS 25 ! 46: ! 47: #define ALL (1L<<0) ! 48: #define OFFLINE (1L<<1) ! 49: #define NO_LINK (1L<<2) ! 50: #define REPORT (1L<<3) ! 51: ! 52: void bail(int code) ! 53: { ! 54: exit(code); ! 55: } ! 56: ! 57: long lputs(char *str) ! 58: { ! 59: char tmp[256]; ! 60: int i,j,k; ! 61: ! 62: j=strlen(str); ! 63: for(i=k=0;i<j;i++) /* remove CRs */ ! 64: if(str[i]==CR && str[i+1]==LF) ! 65: continue; ! 66: else ! 67: tmp[k++]=str[i]; ! 68: tmp[k]=0; ! 69: return(fputs(tmp,stdout)); ! 70: } ! 71: ! 72: /****************************************************************************/ ! 73: /* Performs printf() through local assembly routines */ ! 74: /* Called from everywhere */ ! 75: /****************************************************************************/ ! 76: int lprintf(char *fmat, ...) ! 77: { ! 78: va_list argptr; ! 79: char sbuf[256]; ! 80: int chcount; ! 81: ! 82: va_start(argptr,fmat); ! 83: chcount=vsprintf(sbuf,fmat,argptr); ! 84: va_end(argptr); ! 85: lputs(sbuf); ! 86: return(chcount); ! 87: } ! 88: ! 89: int main(int argc, char **argv) ! 90: { ! 91: char str[256],fname[MAX_PATH+1],not[MAX_NOTS][9],nots=0,*p; ! 92: int i,j,dirnum,libnum,file; ! 93: ulong l,m; ! 94: long misc=0; ! 95: time_t now; ! 96: file_t workfile; ! 97: scfg_t cfg; ! 98: glob_t gl; ! 99: uchar *ixbbuf; ! 100: ! 101: setvbuf(stdout,NULL,_IONBF,0); ! 102: ! 103: fprintf(stderr,"\nDELFILES Version %s (%s) - Removes files from Synchronet " ! 104: "Filebase\n" ,DELFILES_VER, PLATFORM_DESC ); ! 105: ! 106: if(argc<2) { ! 107: printf("\n usage: DELFILES <dir_code or * for ALL> [switches]\n"); ! 108: printf("\nswitches: -LIB name All directories of specified library\n"); ! 109: printf(" -NOT code Exclude specific directory\n"); ! 110: printf(" -OFF Remove files that are offline " ! 111: "(don't exist on disk)\n"); ! 112: printf(" -NOL Remove files with no link " ! 113: "(don't exist in database)\n"); ! 114: printf(" -RPT Report findings only " ! 115: "(don't delete any files)\n"); ! 116: return(0); } ! 117: ! 118: p=getenv("SBBSCTRL"); ! 119: if(p==NULL) { ! 120: printf("\nSBBSCTRL environment variable not set.\n"); ! 121: #ifdef __unix__ ! 122: printf("\nExample: export SBBSCTRL=/sbbs/ctrl\n"); ! 123: #else ! 124: printf("\nExample: SET SBBSCTRL=C:\\SBBS\\CTRL\n"); ! 125: #endif ! 126: return(1); } ! 127: ! 128: memset(&cfg, 0, sizeof(cfg)); ! 129: cfg.size=sizeof(cfg); ! 130: SAFECOPY(cfg.ctrl_dir, p); ! 131: backslash(cfg.ctrl_dir); ! 132: ! 133: load_cfg(&cfg, NULL, TRUE, str); ! 134: chdir(cfg.ctrl_dir); ! 135: ! 136: if(!(cfg.sys_misc&SM_LOCAL_TZ)) ! 137: putenv("TZ=UTC0"); ! 138: ! 139: dirnum=libnum=-1; ! 140: if(argv[1][0]=='*') ! 141: misc|=ALL; ! 142: else if(argv[1][0]!='/' && argv[1][0]!='-') { ! 143: strupr(argv[1]); ! 144: for(i=0;i<cfg.total_dirs;i++) ! 145: if(!stricmp(argv[1],cfg.dir[i]->code)) ! 146: break; ! 147: if(i>=cfg.total_dirs) { ! 148: printf("\nDirectory code '%s' not found.\n",argv[1]); ! 149: return(1); } ! 150: dirnum=i; } ! 151: for(i=1;i<argc;i++) { ! 152: if(!stricmp(argv[i]+1,"LIB")) { ! 153: if(dirnum!=-1) { ! 154: printf("\nBoth directory code and /LIB parameters were used.\n"); ! 155: return(1); } ! 156: i++; ! 157: if(i>=argc) { ! 158: printf("\nLibrary short name must follow /LIB parameter.\n"); ! 159: return(1); } ! 160: strupr(argv[i]); ! 161: for(j=0;j<cfg.total_libs;j++) ! 162: if(!stricmp(cfg.lib[j]->sname,argv[i])) ! 163: break; ! 164: if(j>=cfg.total_libs) { ! 165: printf("\nLibrary short name '%s' not found.\n",argv[i]); ! 166: return(1); } ! 167: libnum=j; } ! 168: else if(!stricmp(argv[i]+1,"NOT")) { ! 169: if(nots>=MAX_NOTS) { ! 170: printf("\nMaximum number of /NOT options (%u) exceeded.\n" ! 171: ,MAX_NOTS); ! 172: return(1); } ! 173: i++; ! 174: if(i>=argc) { ! 175: printf("\nDirectory internal code must follow /NOT parameter.\n"); ! 176: return(1); } ! 177: sprintf(not[nots++],"%.8s",argv[i]); } ! 178: else if(!stricmp(argv[i]+1,"OFF")) ! 179: misc|=OFFLINE; ! 180: else if(!stricmp(argv[i]+1,"NOL")) ! 181: misc|=NO_LINK; ! 182: else if(!stricmp(argv[i]+1,"RPT")) ! 183: misc|=REPORT; ! 184: else if(!stricmp(argv[i]+1,"ALL")) { ! 185: if(dirnum!=-1) { ! 186: printf("\nBoth directory code and /ALL parameters were used.\n"); ! 187: return(1); } ! 188: if(libnum!=-1) { ! 189: printf("\nBoth library name and /ALL parameters were used.\n"); ! 190: return(1); } ! 191: misc|=ALL; } } ! 192: ! 193: for(i=0;i<cfg.total_dirs;i++) { ! 194: if(!(misc&ALL) && i!=dirnum && cfg.dir[i]->lib!=libnum) ! 195: continue; ! 196: for(j=0;j<nots;j++) ! 197: if(!stricmp(not[j],cfg.dir[i]->code)) ! 198: break; ! 199: if(j<nots) ! 200: continue; ! 201: ! 202: if(misc&NO_LINK && cfg.dir[i]->misc&DIR_FCHK) { ! 203: strcpy(tmp,cfg.dir[i]->path); ! 204: sprintf(str,"%s*.*",tmp); ! 205: printf("\nSearching %s for unlinked files\n",str); ! 206: if(!glob(str, GLOB_MARK, NULL, &gl)) { ! 207: for(j=0; j<(int)gl.gl_pathc; j++) { ! 208: /* emulate _A_NORMAL */ ! 209: if(isdir(gl.gl_pathv[j])) ! 210: continue; ! 211: if(access(gl.gl_pathv[j], R_OK|W_OK)) ! 212: continue; ! 213: padfname(gl.gl_pathv[j],str); ! 214: /* strupr(str); */ ! 215: if(!findfile(&cfg, i,str)) { ! 216: sprintf(str,"%s%s",tmp,gl.gl_pathv[j]); ! 217: printf("Removing %s (not in database)\n",gl.gl_pathv); ! 218: if(!(misc&REPORT) && remove(str)) ! 219: printf("Error removing %s\n",str); } } } ! 220: globfree(&gl); ! 221: } ! 222: ! 223: if(!cfg.dir[i]->maxage && !(misc&OFFLINE)) ! 224: continue; ! 225: ! 226: printf("\nScanning %s %s\n",cfg.lib[cfg.dir[i]->lib]->sname,cfg.dir[i]->lname); ! 227: ! 228: sprintf(str,"%s%s.ixb",cfg.dir[i]->data_dir,cfg.dir[i]->code); ! 229: if((file=nopen(str,O_RDONLY|O_BINARY))==-1) ! 230: continue; ! 231: l=filelength(file); ! 232: if(!l) { ! 233: close(file); ! 234: continue; } ! 235: if((ixbbuf=(char *)malloc(l))==NULL) { ! 236: close(file); ! 237: printf("\7ERR_ALLOC %s %lu\n",str,l); ! 238: continue; } ! 239: if(read(file,ixbbuf,l)!=(int)l) { ! 240: close(file); ! 241: printf("\7ERR_READ %s %lu\n",str,l); ! 242: free((char *)ixbbuf); ! 243: continue; } ! 244: close(file); ! 245: ! 246: m=0L; ! 247: now=time(NULL); ! 248: while(m<l) { ! 249: memset(&workfile,0,sizeof(file_t)); ! 250: for(j=0;j<12 && m<l;j++) ! 251: if(j==8) ! 252: fname[j]='.'; ! 253: else ! 254: fname[j]=ixbbuf[m++]; ! 255: fname[j]=0; ! 256: strcpy(workfile.name,fname); ! 257: unpadfname(workfile.name,fname); ! 258: workfile.dir=i; ! 259: sprintf(str,"%s%s" ! 260: ,workfile.altpath>0 && workfile.altpath<=cfg.altpaths ! 261: ? cfg.altpath[workfile.altpath-1] ! 262: : cfg.dir[workfile.dir]->path,fname); ! 263: workfile.datoffset=ixbbuf[m]|((long)ixbbuf[m+1]<<8) ! 264: |((long)ixbbuf[m+2]<<16); ! 265: workfile.dateuled=(ixbbuf[m+3]|((long)ixbbuf[m+4]<<8) ! 266: |((long)ixbbuf[m+5]<<16)|((long)ixbbuf[m+6]<<24)); ! 267: workfile.datedled=(ixbbuf[m+7]|((long)ixbbuf[m+8]<<8) ! 268: |((long)ixbbuf[m+9]<<16)|((long)ixbbuf[m+10]<<24)); ! 269: m+=11; ! 270: if(cfg.dir[i]->maxage && cfg.dir[i]->misc&DIR_SINCEDL && workfile.datedled ! 271: && (now-workfile.datedled)/86400L>cfg.dir[i]->maxage) { ! 272: printf("Deleting %s (%ld days since last download)\n",fname ! 273: ,(now-workfile.datedled)/86400L); ! 274: getfiledat(&cfg, &workfile); ! 275: if(!(misc&REPORT)) { ! 276: removefiledat(&cfg, &workfile); ! 277: if(remove(str)) ! 278: printf("Error removing %s\n",str); } } ! 279: else if(cfg.dir[i]->maxage ! 280: && !(workfile.datedled && cfg.dir[i]->misc&DIR_SINCEDL) ! 281: && (now-workfile.dateuled)/86400L>cfg.dir[i]->maxage) { ! 282: printf("Deleting %s (uploaded %ld days ago)\n",fname ! 283: ,(now-workfile.dateuled)/86400L); ! 284: getfiledat(&cfg, &workfile); ! 285: if(!(misc&REPORT)) { ! 286: removefiledat(&cfg, &workfile); ! 287: if(remove(str)) ! 288: printf("Error removing %s\n",str); } } ! 289: else if(misc&OFFLINE && cfg.dir[i]->misc&DIR_FCHK && !fexist(str)) { ! 290: printf("Removing %s (doesn't exist)\n",fname); ! 291: getfiledat(&cfg, &workfile); ! 292: if(!(misc&REPORT)) ! 293: removefiledat(&cfg, &workfile); } } ! 294: ! 295: free((char *)ixbbuf); } ! 296: ! 297: return(0); ! 298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.