|
|
1.1 root 1: /* filedat.c */
2:
3: /* Synchronet file database-related exported functions */
4:
1.1.1.2 ! root 5: /* $Id: filedat.c,v 1.35 2011/08/06 21:14:14 rswindell Exp $ */
1.1 root 6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
1.1.1.2 ! root 11: * Copyright 2011 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: /****************************************************************************/
41: /* Gets filedata from dircode.DAT file */
42: /* Need fields .name ,.dir and .offset to get other info */
43: /* Does not fill .dateuled or .datedled fields. */
44: /****************************************************************************/
45: BOOL DLLCALL getfiledat(scfg_t* cfg, file_t* f)
46: {
47: char buf[F_LEN+1],str[MAX_PATH+1];
48: int file;
49: long length;
50:
51: SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
52: if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
53: return(FALSE);
54: }
1.1.1.2 ! root 55: length=(long)filelength(file);
1.1 root 56: if(f->datoffset>length) {
57: close(file);
58: return(FALSE);
59: }
60: if(length%F_LEN) {
61: close(file);
62: return(FALSE);
63: }
64: lseek(file,f->datoffset,SEEK_SET);
65: if(read(file,buf,F_LEN)!=F_LEN) {
66: close(file);
67: return(FALSE);
68: }
69: close(file);
70: getrec(buf,F_ALTPATH,2,str);
71: f->altpath=hptoi(str);
72: getrec(buf,F_CDT,LEN_FCDT,str);
73: f->cdt=atol(str);
74:
75: if(!f->size) { /* only read disk if this is null */
76: getfilepath(cfg,f,str);
1.1.1.2 ! root 77: if((f->size=(long)flength(str))>=0)
! 78: f->date=fdate(str);
1.1 root 79: /*
80: }
81: else {
82: f->size=f->cdt;
1.1.1.2 ! root 83: f->date=0;
! 84: }
1.1 root 85: */
86: }
87: #if 0
88: if((f->size>0L) && cur_cps)
89: f->timetodl=(ushort)(f->size/(ulong)cur_cps);
90: else
91: #endif
92: f->timetodl=0;
93:
94: getrec(buf,F_DESC,LEN_FDESC,f->desc);
95: getrec(buf,F_ULER,LEN_ALIAS,f->uler);
96: getrec(buf,F_TIMESDLED,5,str);
97: f->timesdled=atoi(str);
98: getrec(buf,F_OPENCOUNT,3,str);
99: f->opencount=atoi(str);
100: if(buf[F_MISC]!=ETX)
101: f->misc=buf[F_MISC]-' ';
102: else
103: f->misc=0;
104: return(TRUE);
105: }
106:
107: /****************************************************************************/
108: /* Puts filedata into DIR_code.DAT file */
109: /* Called from removefiles */
110: /****************************************************************************/
111: BOOL DLLCALL putfiledat(scfg_t* cfg, file_t* f)
112: {
113: char buf[F_LEN+1],str[MAX_PATH+1],tmp[128];
114: int file;
115: long length;
116:
117: putrec(buf,F_CDT,LEN_FCDT,ultoa(f->cdt,tmp,10));
118: putrec(buf,F_DESC,LEN_FDESC,f->desc);
119: putrec(buf,F_DESC+LEN_FDESC,2,crlf);
120: putrec(buf,F_ULER,LEN_ALIAS+5,f->uler);
121: putrec(buf,F_ULER+LEN_ALIAS+5,2,crlf);
122: putrec(buf,F_TIMESDLED,5,ultoa(f->timesdled,tmp,10));
123: putrec(buf,F_TIMESDLED+5,2,crlf);
124: putrec(buf,F_OPENCOUNT,3,ultoa(f->opencount,tmp,10));
125: putrec(buf,F_OPENCOUNT+3,2,crlf);
126: buf[F_MISC]=f->misc+' ';
127: putrec(buf,F_ALTPATH,2,hexplus(f->altpath,tmp));
128: putrec(buf,F_ALTPATH+2,2,crlf);
129: SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
130: if((file=sopen(str,O_WRONLY|O_BINARY,SH_DENYRW))==-1) {
131: return(FALSE);
132: }
1.1.1.2 ! root 133: length=(long)filelength(file);
1.1 root 134: if(length%F_LEN) {
135: close(file);
136: return(FALSE);
137: }
138: if(f->datoffset>length) {
139: close(file);
140: return(FALSE);
141: }
142: lseek(file,f->datoffset,SEEK_SET);
143: if(write(file,buf,F_LEN)!=F_LEN) {
144: close(file);
145: return(FALSE);
146: }
1.1.1.2 ! root 147: length=(long)filelength(file);
1.1 root 148: close(file);
149: if(length%F_LEN) {
150: return(FALSE);
151: }
152: return(TRUE);
153: }
154:
155: /****************************************************************************/
156: /* Adds the data for struct filedat to the directory's data base. */
157: /* changes the .datoffset field only */
158: /* returns 1 if added successfully, 0 if not. */
159: /****************************************************************************/
160: BOOL DLLCALL addfiledat(scfg_t* cfg, file_t* f)
161: {
162: char str[MAX_PATH+1],fname[13],c,fdat[F_LEN+1];
163: char tmp[128];
164: uchar *ixbbuf,idx[3];
165: int i,file;
166: long l,length;
167: time_t now;
168: time_t uldate;
169:
170: /************************/
171: /* Add data to DAT File */
172: /************************/
173: SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
1.1.1.2 ! root 174: if((file=sopen(str,O_RDWR|O_BINARY|O_CREAT,SH_DENYRW,DEFFILEMODE))==-1) {
1.1 root 175: return(FALSE);
176: }
1.1.1.2 ! root 177: length=(long)filelength(file);
1.1 root 178: if(length==0L)
179: l=0L;
180: else {
181: if(length%F_LEN) {
182: close(file);
183: return(FALSE);
184: }
185: for(l=0;l<length;l+=F_LEN) { /* Find empty slot */
186: lseek(file,l,SEEK_SET);
187: read(file,&c,1);
188: if(c==ETX) break;
189: }
1.1.1.2 ! root 190: if(l/F_LEN>=MAX_FILES) {
1.1 root 191: close(file);
192: return(FALSE);
193: }
194: }
195: putrec(fdat,F_CDT,LEN_FCDT,ultoa(f->cdt,tmp,10));
196: putrec(fdat,F_DESC,LEN_FDESC,f->desc);
197: putrec(fdat,F_DESC+LEN_FDESC,2,crlf);
198: putrec(fdat,F_ULER,LEN_ALIAS+5,f->uler);
199: putrec(fdat,F_ULER+LEN_ALIAS+5,2,crlf);
200: putrec(fdat,F_TIMESDLED,5,ultoa(f->timesdled,tmp,10));
201: putrec(fdat,F_TIMESDLED+5,2,crlf);
202: putrec(fdat,F_OPENCOUNT,3,ultoa(f->opencount,tmp,10));
203: putrec(fdat,F_OPENCOUNT+3,2,crlf);
204: fdat[F_MISC]=f->misc+' ';
205: putrec(fdat,F_ALTPATH,2,hexplus(f->altpath,tmp));
206: putrec(fdat,F_ALTPATH+2,2,crlf);
207: f->datoffset=l;
208: idx[0]=(uchar)(l&0xff); /* Get offset within DAT file for IXB file */
209: idx[1]=(uchar)((l>>8)&0xff);
210: idx[2]=(uchar)((l>>16)&0xff);
211: lseek(file,l,SEEK_SET);
212: if(write(file,fdat,F_LEN)!=F_LEN) {
213: close(file);
214: return(FALSE);
215: }
1.1.1.2 ! root 216: length=(long)filelength(file);
1.1 root 217: close(file);
218: if(length%F_LEN) {
219: return(FALSE);
220: }
221:
222: /*******************************************/
223: /* Update last upload date/time stamp file */
224: /*******************************************/
225: SAFEPRINTF2(str,"%s%s.dab",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
1.1.1.2 ! root 226: if((file=sopen(str,O_WRONLY|O_CREAT|O_BINARY,SH_DENYRW,DEFFILEMODE))!=-1) {
1.1 root 227: now=time(NULL);
1.1.1.2 ! root 228: /* TODO: 32-bit *or* LE required */
1.1 root 229: write(file,&now,4);
230: close(file);
231: }
232:
233: /************************/
234: /* Add data to IXB File */
235: /************************/
236: SAFECOPY(fname,f->name);
237: for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */
238: fname[i]=fname[i+1];
239: SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
1.1.1.2 ! root 240: if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW,DEFFILEMODE))==-1) {
1.1 root 241: return(FALSE);
242: }
1.1.1.2 ! root 243: length=(long)filelength(file);
1.1 root 244: if(length) { /* IXB file isn't empty */
245: if(length%F_IXBSIZE) {
246: close(file);
247: return(FALSE);
248: }
249: if((ixbbuf=(uchar *)malloc(length))==NULL) {
250: close(file);
251: return(FALSE);
252: }
253: if(lread(file,ixbbuf,length)!=length) {
254: close(file);
255: free((char *)ixbbuf);
256: return(FALSE);
257: }
258: /************************************************/
259: /* Sort by Name or Date, Assending or Decending */
260: /************************************************/
261: if(cfg->dir[f->dir]->sort==SORT_NAME_A || cfg->dir[f->dir]->sort==SORT_NAME_D) {
262: for(l=0;l<length;l+=F_IXBSIZE) {
263: for(i=0;i<12 && toupper(fname[i])==toupper(ixbbuf[l+i]);i++);
264: if(i==12) { /* file already in directory index */
265: close(file);
266: free((char *)ixbbuf);
267: return(FALSE);
268: }
269: if(cfg->dir[f->dir]->sort==SORT_NAME_A
270: && toupper(fname[i])<toupper(ixbbuf[l+i]))
271: break;
272: if(cfg->dir[f->dir]->sort==SORT_NAME_D
273: && toupper(fname[i])>toupper(ixbbuf[l+i]))
274: break;
275: }
276: }
277: else { /* sort by date */
278: for(l=0;l<length;l+=F_IXBSIZE) {
279: uldate=(ixbbuf[l+14]|((long)ixbbuf[l+15]<<8)
280: |((long)ixbbuf[l+16]<<16)|((long)ixbbuf[l+17]<<24));
281: if(cfg->dir[f->dir]->sort==SORT_DATE_A && f->dateuled<uldate)
282: break;
283: if(cfg->dir[f->dir]->sort==SORT_DATE_D && f->dateuled>uldate)
284: break;
285: }
286: }
287: lseek(file,l,SEEK_SET);
288: if(write(file,fname,11)!=11) { /* Write filename to IXB file */
289: close(file);
290: free((char *)ixbbuf);
291: return(FALSE);
292: }
293: if(write(file,idx,3)!=3) { /* Write DAT offset into IXB file */
294: close(file);
295: free((char *)ixbbuf);
296: return(FALSE);
297: }
1.1.1.2 ! root 298: write(file,&f->dateuled,4);
1.1 root 299: write(file,&f->datedled,4); /* Write 0 for datedled */
300: if(lwrite(file,&ixbbuf[l],length-l)!=length-l) { /* Write rest of IXB */
301: close(file);
302: free((char *)ixbbuf);
303: return(FALSE);
304: }
1.1.1.2 ! root 305: free((char *)ixbbuf);
! 306: }
1.1 root 307: else { /* IXB file is empty... No files */
308: if(write(file,fname,11)!=11) { /* Write filename it IXB file */
309: close(file);
310: return(FALSE);
311: }
312: if(write(file,idx,3)!=3) { /* Write DAT offset into IXB file */
313: close(file);
314: return(FALSE);
315: }
1.1.1.2 ! root 316: write(file,&f->dateuled,4);
1.1 root 317: write(file,&f->datedled,4);
318: }
1.1.1.2 ! root 319: length=(long)filelength(file);
1.1 root 320: close(file);
321: return(TRUE);
322: }
323:
324: /****************************************************************************/
325: /* Gets file data from dircode.ixb file */
326: /* Need fields .name and .dir filled. */
327: /* only fills .offset, .dateuled, and .datedled */
328: /****************************************************************************/
329: BOOL DLLCALL getfileixb(scfg_t* cfg, file_t* f)
330: {
331: char str[MAX_PATH+1],fname[13];
332: uchar * ixbbuf;
333: int file;
334: long l,length;
335:
336: SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
337: if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
338: return(FALSE);
339: }
1.1.1.2 ! root 340: length=(long)filelength(file);
1.1 root 341: if(length%F_IXBSIZE) {
342: close(file);
343: return(FALSE);
344: }
345: if((ixbbuf=(uchar *)malloc(length))==NULL) {
346: close(file);
347: return(FALSE);
348: }
349: if(lread(file,ixbbuf,length)!=length) {
350: close(file);
351: free((char *)ixbbuf);
352: return(FALSE);
353: }
354: close(file);
355: SAFECOPY(fname,f->name);
356: for(l=8;l<12;l++) /* Turn FILENAME.EXT into FILENAMEEXT */
357: fname[l]=fname[l+1];
358: for(l=0;l<length;l+=F_IXBSIZE) {
359: SAFEPRINTF(str,"%11.11s",ixbbuf+l);
360: if(!stricmp(str,fname))
361: break;
362: }
363: if(l>=length) {
364: free((char *)ixbbuf);
365: return(FALSE);
366: }
367: l+=11;
368: f->datoffset=ixbbuf[l]|((long)ixbbuf[l+1]<<8)|((long)ixbbuf[l+2]<<16);
369: f->dateuled=ixbbuf[l+3]|((long)ixbbuf[l+4]<<8)
370: |((long)ixbbuf[l+5]<<16)|((long)ixbbuf[l+6]<<24);
371: f->datedled=ixbbuf[l+7]|((long)ixbbuf[l+8]<<8)
372: |((long)ixbbuf[l+9]<<16)|((long)ixbbuf[l+10]<<24);
373: free((char *)ixbbuf);
374: return(TRUE);
375: }
376:
377: /****************************************************************************/
378: /* Updates the datedled and dateuled index record fields for a file */
379: /****************************************************************************/
380: BOOL DLLCALL putfileixb(scfg_t* cfg, file_t* f)
381: {
382: char str[MAX_PATH+1],fname[13];
383: uchar* ixbbuf;
384: int file;
385: long l,length;
386:
387: SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
388: if((file=sopen(str,O_RDWR|O_BINARY,SH_DENYRW))==-1) {
389: return(FALSE);
390: }
1.1.1.2 ! root 391: length=(long)filelength(file);
1.1 root 392: if(length%F_IXBSIZE) {
393: close(file);
394: return(FALSE);
395: }
396: if((ixbbuf=(uchar *)malloc(length))==NULL) {
397: close(file);
398: return(FALSE);
399: }
400: if(lread(file,ixbbuf,length)!=length) {
401: close(file);
402: free(ixbbuf);
403: return(FALSE);
404: }
405: SAFECOPY(fname,f->name);
406: for(l=8;l<12;l++) /* Turn FILENAME.EXT into FILENAMEEXT */
407: fname[l]=fname[l+1];
408: for(l=0;l<length;l+=F_IXBSIZE) {
409: SAFEPRINTF(str,"%11.11s",ixbbuf+l);
410: if(!stricmp(str,fname))
411: break;
412: }
413: free(ixbbuf);
414:
415: if(l>=length) {
416: close(file);
417: return(FALSE);
418: }
419:
420: lseek(file,l+11+3,SEEK_SET);
421:
1.1.1.2 ! root 422: write(file,&f->dateuled,4);
! 423: write(file,&f->datedled,4);
1.1 root 424:
425: close(file);
426:
427: return(TRUE);
428: }
429:
430:
431: /****************************************************************************/
432: /* Removes DAT and IXB entries for the file in the struct 'f' */
433: /****************************************************************************/
434: BOOL DLLCALL removefiledat(scfg_t* cfg, file_t* f)
435: {
436: char c,str[MAX_PATH+1],ixbname[12],*ixbbuf,fname[13];
437: int i,file;
438: long l,length;
439:
440: SAFECOPY(fname,f->name);
441: for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */
442: fname[i]=fname[i+1];
443: SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
444: if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
445: return(FALSE);
446: }
1.1.1.2 ! root 447: length=(long)filelength(file);
1.1 root 448: if(!length) {
449: close(file);
450: return(FALSE);
451: }
452: if((ixbbuf=(char *)malloc(length))==0) {
453: close(file);
454: return(FALSE);
455: }
456: if(lread(file,ixbbuf,length)!=length) {
457: close(file);
458: free((char *)ixbbuf);
459: return(FALSE);
460: }
461: close(file);
462: if((file=sopen(str,O_WRONLY|O_TRUNC|O_BINARY,SH_DENYRW))==-1) {
463: return(FALSE);
464: }
465: for(l=0;l<length;l+=F_IXBSIZE) {
466: for(i=0;i<11;i++)
467: ixbname[i]=ixbbuf[l+i];
468: ixbname[i]=0;
469: if(stricmp(ixbname,fname))
470: if(lwrite(file,&ixbbuf[l],F_IXBSIZE)!=F_IXBSIZE) {
471: close(file);
472: free((char *)ixbbuf);
473: return(FALSE);
474: }
475: }
476: free((char *)ixbbuf);
477: close(file);
478: SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
479: if((file=sopen(str,O_WRONLY|O_BINARY,SH_DENYRW))==-1) {
480: return(FALSE);
481: }
482: lseek(file,f->datoffset,SEEK_SET);
483: c=ETX; /* If first char of record is ETX, record is unused */
484: if(write(file,&c,1)!=1) { /* So write a D_T on the first byte of the record */
485: close(file);
486: return(FALSE);
487: }
488: close(file);
489: if(f->dir==cfg->user_dir) /* remove file from index */
490: rmuserxfers(cfg,0,0,f->name);
491: return(TRUE);
492: }
493:
494: /****************************************************************************/
495: /* Checks directory data file for 'filename' (must be padded). If found, */
496: /* it returns the 1, else returns 0. */
497: /* Called from upload and bulkupload */
498: /****************************************************************************/
499: BOOL DLLCALL findfile(scfg_t* cfg, uint dirnum, char *filename)
500: {
501: char str[MAX_PATH+1],fname[13],*ixbbuf;
502: int i,file;
503: long length,l;
504:
505: SAFECOPY(fname,filename);
506: strupr(fname);
507: for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */
508: fname[i]=fname[i+1];
509: SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code);
510: if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) return(FALSE);
1.1.1.2 ! root 511: length=(long)filelength(file);
1.1 root 512: if(!length) {
513: close(file);
1.1.1.2 ! root 514: return(FALSE);
! 515: }
1.1 root 516: if((ixbbuf=(char *)malloc(length))==NULL) {
517: close(file);
1.1.1.2 ! root 518: return(FALSE);
! 519: }
1.1 root 520: if(lread(file,ixbbuf,length)!=length) {
521: close(file);
522: free((char *)ixbbuf);
1.1.1.2 ! root 523: return(FALSE);
! 524: }
1.1 root 525: close(file);
526: for(l=0;l<length;l+=F_IXBSIZE) {
527: for(i=0;i<11;i++)
528: if(toupper(fname[i])!=toupper(ixbbuf[l+i])) break;
1.1.1.2 ! root 529: if(i==11) break;
! 530: }
1.1 root 531: free((char *)ixbbuf);
532: if(l!=length)
533: return(TRUE);
534: return(FALSE);
535: }
536:
537: /****************************************************************************/
538: /* Turns FILE.EXT into FILE .EXT */
539: /****************************************************************************/
1.1.1.2 ! root 540: char* DLLCALL padfname(const char *filename, char *str)
1.1 root 541: {
542: int c,d;
543:
544: for(c=0;c<8;c++)
545: if(filename[c]=='.' || !filename[c]) break;
546: else str[c]=filename[c];
547: d=c;
548: if(filename[c]=='.') c++;
549: while(d<8)
550: str[d++]=' ';
551: if(filename[c]>' ') /* Change "FILE" to "FILE " */
552: str[d++]='.'; /* (don't add a dot if there's no extension) */
553: else
554: str[d++]=' ';
555: while(d<12)
556: if(!filename[c]) break;
557: else str[d++]=filename[c++];
558: while(d<12)
559: str[d++]=' ';
560: str[d]=0;
561: return(str);
562: }
563:
564: /****************************************************************************/
565: /* Turns FILE .EXT into FILE.EXT */
566: /****************************************************************************/
1.1.1.2 ! root 567: char* DLLCALL unpadfname(const char *filename, char *str)
1.1 root 568: {
569: int c,d;
570:
571: for(c=0,d=0;filename[c];c++)
572: if(filename[c]!=' ') str[d++]=filename[c];
573: str[d]=0;
574: return(str);
575: }
576:
577: /****************************************************************************/
578: /* Removes any files in the user transfer index (XFER.IXT) that match the */
579: /* specifications of dest, or source user, or filename or any combination. */
580: /****************************************************************************/
581: BOOL DLLCALL rmuserxfers(scfg_t* cfg, int fromuser, int destuser, char *fname)
582: {
583: char str[MAX_PATH+1],*ixtbuf;
584: int file;
585: long l,length;
586:
587: SAFEPRINTF(str,"%sxfer.ixt", cfg->data_dir);
588: if(!fexist(str))
589: return(FALSE);
590: if(!flength(str)) {
591: remove(str);
592: return(FALSE);
593: }
594: if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
595: return(FALSE);
596: }
1.1.1.2 ! root 597: length=(long)filelength(file);
1.1 root 598: if((ixtbuf=(char *)malloc(length))==NULL) {
599: close(file);
600: return(FALSE);
601: }
602: if(read(file,ixtbuf,length)!=length) {
603: close(file);
604: free(ixtbuf);
605: return(FALSE);
606: }
607: close(file);
608: if((file=sopen(str,O_WRONLY|O_TRUNC|O_BINARY,SH_DENYRW))==-1) {
609: free(ixtbuf);
610: return(FALSE);
611: }
612: for(l=0;l<length;l+=24) {
613: if(fname!=NULL && fname[0]) { /* fname specified */
614: if(!strncmp(ixtbuf+l+5,fname,12)) { /* this is the file */
615: if(destuser && fromuser) { /* both dest and from user */
616: if(atoi(ixtbuf+l)==destuser && atoi(ixtbuf+l+18)==fromuser)
1.1.1.2 ! root 617: continue; /* both match */
! 618: }
1.1 root 619: else if(fromuser) { /* from user */
620: if(atoi(ixtbuf+l+18)==fromuser) /* matches */
1.1.1.2 ! root 621: continue;
! 622: }
1.1 root 623: else if(destuser) { /* dest user */
624: if(atoi(ixtbuf+l)==destuser) /* matches */
1.1.1.2 ! root 625: continue;
! 626: }
! 627: else continue; /* no users, so match */
! 628: }
! 629: }
1.1 root 630: else if(destuser && fromuser) {
631: if(atoi(ixtbuf+l+18)==fromuser && atoi(ixtbuf+l)==destuser)
1.1.1.2 ! root 632: continue;
! 633: }
1.1 root 634: else if(destuser && atoi(ixtbuf+l)==destuser)
635: continue;
636: else if(fromuser && atoi(ixtbuf+l+18)==fromuser)
637: continue;
1.1.1.2 ! root 638: write(file,ixtbuf+l,24);
! 639: }
1.1 root 640: close(file);
641: free(ixtbuf);
642:
643: return(TRUE);
644: }
645:
646: void DLLCALL getextdesc(scfg_t* cfg, uint dirnum, ulong datoffset, char *ext)
647: {
648: char str[MAX_PATH+1];
649: int file;
650:
651: memset(ext,0,F_EXBSIZE+1);
652: SAFEPRINTF2(str,"%s%s.exb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code);
653: if((file=nopen(str,O_RDONLY))==-1)
654: return;
655: lseek(file,(datoffset/F_LEN)*F_EXBSIZE,SEEK_SET);
656: read(file,ext,F_EXBSIZE);
657: close(file);
658: }
659:
660: void DLLCALL putextdesc(scfg_t* cfg, uint dirnum, ulong datoffset, char *ext)
661: {
662: char str[MAX_PATH+1],nulbuf[F_EXBSIZE];
663: int file;
664:
665: strip_invalid_attr(ext); /* eliminate bogus ctrl-a codes */
666: memset(nulbuf,0,sizeof(nulbuf));
667: SAFEPRINTF2(str,"%s%s.exb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code);
668: if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
669: return;
670: lseek(file,0L,SEEK_END);
671: while(filelength(file)<(long)(datoffset/F_LEN)*F_EXBSIZE)
672: write(file,nulbuf,sizeof(nulbuf));
673: lseek(file,(datoffset/F_LEN)*F_EXBSIZE,SEEK_SET);
674: write(file,ext,F_EXBSIZE);
675: close(file);
676: }
677:
678: /****************************************************************************/
679: /* Update the upload date for the file 'f' */
680: /****************************************************************************/
681: int DLLCALL update_uldate(scfg_t* cfg, file_t* f)
682: {
683: char str[MAX_PATH+1],fname[13];
684: int i,file;
685: long l,length;
686:
687: /*******************/
688: /* Update IXB File */
689: /*******************/
690: SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
691: if((file=nopen(str,O_RDWR))==-1)
692: return(errno);
1.1.1.2 ! root 693: length=(long)filelength(file);
1.1 root 694: if(length%F_IXBSIZE) {
695: close(file);
696: return(-1);
697: }
698: SAFECOPY(fname,f->name);
699: for(i=8;i<12;i++) /* Turn FILENAME.EXT into FILENAMEEXT */
700: fname[i]=fname[i+1];
701: for(l=0;l<length;l+=F_IXBSIZE) {
702: read(file,str,F_IXBSIZE); /* Look for the filename in the IXB file */
703: str[11]=0;
1.1.1.2 ! root 704: if(!stricmp(fname,str)) break;
! 705: }
1.1 root 706: if(l>=length) {
707: close(file);
708: return(-2);
709: }
710: lseek(file,l+14,SEEK_SET);
711: write(file,&f->dateuled,4);
712: close(file);
713:
714: /*******************************************/
715: /* Update last upload date/time stamp file */
716: /*******************************************/
717: SAFEPRINTF2(str,"%s%s.dab",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
718: if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
719: return(errno);
720:
721: write(file,&f->dateuled,4);
722: close(file);
723: return(0);
724: }
725:
726: /****************************************************************************/
727: /* Returns full path to specified file */
728: /****************************************************************************/
729: char* DLLCALL getfilepath(scfg_t* cfg, file_t* f, char* path)
730: {
731: char fname[MAX_PATH+1];
732:
733: unpadfname(f->name,fname);
734: if(f->dir>=cfg->total_dirs)
735: safe_snprintf(path,MAX_PATH,"%s%s",cfg->temp_dir,fname);
736: else
737: safe_snprintf(path,MAX_PATH,"%s%s",f->altpath>0 && f->altpath<=cfg->altpaths
738: ? cfg->altpath[f->altpath-1] : cfg->dir[f->dir]->path
739: ,fname);
740:
741: return(path);
742: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.