|
|
1.1 root 1: /* delfiles.c */
2:
3: /* Program to delete expired files from a Synchronet file database */
4:
1.1.1.2 ! root 5: /* $Id: delfiles.c,v 1.6 2008/06/04 04:38:47 deuce 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 2008 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 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: /****************************************************************************/
1.1.1.2 ! root 76: int lprintf(const char *fmat, ...)
1.1 root 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: dirnum=libnum=-1;
137: if(argv[1][0]=='*')
138: misc|=ALL;
139: else if(argv[1][0]!='/' && argv[1][0]!='-') {
140: strupr(argv[1]);
141: for(i=0;i<cfg.total_dirs;i++)
142: if(!stricmp(argv[1],cfg.dir[i]->code))
143: break;
144: if(i>=cfg.total_dirs) {
145: printf("\nDirectory code '%s' not found.\n",argv[1]);
146: return(1); }
147: dirnum=i; }
148: for(i=1;i<argc;i++) {
149: if(!stricmp(argv[i]+1,"LIB")) {
150: if(dirnum!=-1) {
151: printf("\nBoth directory code and /LIB parameters were used.\n");
152: return(1); }
153: i++;
154: if(i>=argc) {
155: printf("\nLibrary short name must follow /LIB parameter.\n");
156: return(1); }
157: strupr(argv[i]);
158: for(j=0;j<cfg.total_libs;j++)
159: if(!stricmp(cfg.lib[j]->sname,argv[i]))
160: break;
161: if(j>=cfg.total_libs) {
162: printf("\nLibrary short name '%s' not found.\n",argv[i]);
163: return(1); }
164: libnum=j; }
165: else if(!stricmp(argv[i]+1,"NOT")) {
166: if(nots>=MAX_NOTS) {
167: printf("\nMaximum number of /NOT options (%u) exceeded.\n"
168: ,MAX_NOTS);
169: return(1); }
170: i++;
171: if(i>=argc) {
172: printf("\nDirectory internal code must follow /NOT parameter.\n");
173: return(1); }
174: sprintf(not[nots++],"%.8s",argv[i]); }
175: else if(!stricmp(argv[i]+1,"OFF"))
176: misc|=OFFLINE;
177: else if(!stricmp(argv[i]+1,"NOL"))
178: misc|=NO_LINK;
179: else if(!stricmp(argv[i]+1,"RPT"))
180: misc|=REPORT;
181: else if(!stricmp(argv[i]+1,"ALL")) {
182: if(dirnum!=-1) {
183: printf("\nBoth directory code and /ALL parameters were used.\n");
184: return(1); }
185: if(libnum!=-1) {
186: printf("\nBoth library name and /ALL parameters were used.\n");
187: return(1); }
188: misc|=ALL; } }
189:
190: for(i=0;i<cfg.total_dirs;i++) {
191: if(!(misc&ALL) && i!=dirnum && cfg.dir[i]->lib!=libnum)
192: continue;
193: for(j=0;j<nots;j++)
194: if(!stricmp(not[j],cfg.dir[i]->code))
195: break;
196: if(j<nots)
197: continue;
198:
199: if(misc&NO_LINK && cfg.dir[i]->misc&DIR_FCHK) {
200: strcpy(tmp,cfg.dir[i]->path);
201: sprintf(str,"%s*.*",tmp);
202: printf("\nSearching %s for unlinked files\n",str);
203: if(!glob(str, GLOB_MARK, NULL, &gl)) {
204: for(j=0; j<(int)gl.gl_pathc; j++) {
205: /* emulate _A_NORMAL */
206: if(isdir(gl.gl_pathv[j]))
207: continue;
208: if(access(gl.gl_pathv[j], R_OK|W_OK))
209: continue;
210: padfname(gl.gl_pathv[j],str);
211: /* strupr(str); */
212: if(!findfile(&cfg, i,str)) {
213: sprintf(str,"%s%s",tmp,gl.gl_pathv[j]);
214: printf("Removing %s (not in database)\n",gl.gl_pathv);
215: if(!(misc&REPORT) && remove(str))
216: printf("Error removing %s\n",str); } } }
217: globfree(&gl);
218: }
219:
220: if(!cfg.dir[i]->maxage && !(misc&OFFLINE))
221: continue;
222:
223: printf("\nScanning %s %s\n",cfg.lib[cfg.dir[i]->lib]->sname,cfg.dir[i]->lname);
224:
225: sprintf(str,"%s%s.ixb",cfg.dir[i]->data_dir,cfg.dir[i]->code);
226: if((file=nopen(str,O_RDONLY|O_BINARY))==-1)
227: continue;
228: l=filelength(file);
229: if(!l) {
230: close(file);
231: continue; }
232: if((ixbbuf=(char *)malloc(l))==NULL) {
233: close(file);
234: printf("\7ERR_ALLOC %s %lu\n",str,l);
235: continue; }
236: if(read(file,ixbbuf,l)!=(int)l) {
237: close(file);
238: printf("\7ERR_READ %s %lu\n",str,l);
239: free((char *)ixbbuf);
240: continue; }
241: close(file);
242:
243: m=0L;
244: now=time(NULL);
245: while(m<l) {
246: memset(&workfile,0,sizeof(file_t));
247: for(j=0;j<12 && m<l;j++)
248: if(j==8)
249: fname[j]='.';
250: else
251: fname[j]=ixbbuf[m++];
252: fname[j]=0;
253: strcpy(workfile.name,fname);
254: unpadfname(workfile.name,fname);
255: workfile.dir=i;
256: sprintf(str,"%s%s"
257: ,workfile.altpath>0 && workfile.altpath<=cfg.altpaths
258: ? cfg.altpath[workfile.altpath-1]
259: : cfg.dir[workfile.dir]->path,fname);
260: workfile.datoffset=ixbbuf[m]|((long)ixbbuf[m+1]<<8)
261: |((long)ixbbuf[m+2]<<16);
262: workfile.dateuled=(ixbbuf[m+3]|((long)ixbbuf[m+4]<<8)
263: |((long)ixbbuf[m+5]<<16)|((long)ixbbuf[m+6]<<24));
264: workfile.datedled=(ixbbuf[m+7]|((long)ixbbuf[m+8]<<8)
265: |((long)ixbbuf[m+9]<<16)|((long)ixbbuf[m+10]<<24));
266: m+=11;
267: if(cfg.dir[i]->maxage && cfg.dir[i]->misc&DIR_SINCEDL && workfile.datedled
268: && (now-workfile.datedled)/86400L>cfg.dir[i]->maxage) {
269: printf("Deleting %s (%ld days since last download)\n",fname
270: ,(now-workfile.datedled)/86400L);
271: getfiledat(&cfg, &workfile);
272: if(!(misc&REPORT)) {
273: removefiledat(&cfg, &workfile);
274: if(remove(str))
275: printf("Error removing %s\n",str); } }
276: else if(cfg.dir[i]->maxage
277: && !(workfile.datedled && cfg.dir[i]->misc&DIR_SINCEDL)
278: && (now-workfile.dateuled)/86400L>cfg.dir[i]->maxage) {
279: printf("Deleting %s (uploaded %ld days ago)\n",fname
280: ,(now-workfile.dateuled)/86400L);
281: getfiledat(&cfg, &workfile);
282: if(!(misc&REPORT)) {
283: removefiledat(&cfg, &workfile);
284: if(remove(str))
285: printf("Error removing %s\n",str); } }
286: else if(misc&OFFLINE && cfg.dir[i]->misc&DIR_FCHK && !fexist(str)) {
287: printf("Removing %s (doesn't exist)\n",fname);
288: getfiledat(&cfg, &workfile);
289: if(!(misc&REPORT))
290: removefiledat(&cfg, &workfile); } }
291:
292: free((char *)ixbbuf); }
293:
294: return(0);
295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.