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