filedat.c 20.8 KB
Newer Older
1
2
3
4
5
6
/* Synchronet file database-related exported functions */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
7
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 *																			*
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

22
23
24
25
26
27
28
#include "filedat.h"
#include "dat_rec.h"
#include "datewrap.h"	// time32()
#include "str_util.h"
#include "nopen.h"

static char* crlf = "\r\n";
29
30
31
32
33
34

/****************************************************************************/
/* Gets filedata from dircode.DAT file										*/
/* Need fields .name ,.dir and .offset to get other info    				*/
/* Does not fill .dateuled or .datedled fields.                             */
/****************************************************************************/
35
BOOL DLLCALL getfiledat(scfg_t* cfg, file_t* f)
36
{
37
	char buf[F_LEN+1],str[MAX_PATH+1];
38
39
40
	int file;
	long length;

41
	SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
42
43
44
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
		return(FALSE); 
	}
45
	length=(long)filelength(file);
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
	if(f->datoffset>length) {
		close(file);
		return(FALSE); 
	}
	if(length%F_LEN) {
		close(file);
		return(FALSE); 
	}
	lseek(file,f->datoffset,SEEK_SET);
	if(read(file,buf,F_LEN)!=F_LEN) {
		close(file);
		return(FALSE); 
	}
	close(file);
	getrec(buf,F_ALTPATH,2,str);
	f->altpath=hptoi(str);
	getrec(buf,F_CDT,LEN_FCDT,str);
	f->cdt=atol(str);

rswindell's avatar
rswindell committed
65
66
67
68
69
70
71
72
73
	if(f->size == 0) {					// only read disk if f->size == 0
		struct stat st;
		getfilepath(cfg,f,str);
		if(stat(str, &st) == 0) {
			f->size = st.st_size;
			f->date = (time32_t)st.st_mtime;
		} else
			f->size = -1;	// indicates file does not exist
	}
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#if 0
	if((f->size>0L) && cur_cps)
		f->timetodl=(ushort)(f->size/(ulong)cur_cps);
	else
#endif
		f->timetodl=0;

	getrec(buf,F_DESC,LEN_FDESC,f->desc);
	getrec(buf,F_ULER,LEN_ALIAS,f->uler);
	getrec(buf,F_TIMESDLED,5,str);
	f->timesdled=atoi(str);
	getrec(buf,F_OPENCOUNT,3,str);
	f->opencount=atoi(str);
	if(buf[F_MISC]!=ETX)
88
		f->misc=buf[F_MISC]-' ';
89
90
91
92
93
94
95
96
97
	else
		f->misc=0;
	return(TRUE);
}

/****************************************************************************/
/* Puts filedata into DIR_code.DAT file                                     */
/* Called from removefiles                                                  */
/****************************************************************************/
98
BOOL DLLCALL putfiledat(scfg_t* cfg, file_t* f)
99
{
100
    char buf[F_LEN+1],str[MAX_PATH+1],tmp[128];
101
102
103
104
105
106
107
108
    int file;
    long length;

	putrec(buf,F_CDT,LEN_FCDT,ultoa(f->cdt,tmp,10));
	putrec(buf,F_DESC,LEN_FDESC,f->desc);
	putrec(buf,F_DESC+LEN_FDESC,2,crlf);
	putrec(buf,F_ULER,LEN_ALIAS+5,f->uler);
	putrec(buf,F_ULER+LEN_ALIAS+5,2,crlf);
109
	putrec(buf,F_TIMESDLED,5,ultoa(f->timesdled,tmp,10));
110
	putrec(buf,F_TIMESDLED+5,2,crlf);
111
	putrec(buf,F_OPENCOUNT,3,ultoa(f->opencount,tmp,10));
112
	putrec(buf,F_OPENCOUNT+3,2,crlf);
113
	buf[F_MISC]=(char)f->misc+' ';
114
115
	putrec(buf,F_ALTPATH,2,hexplus(f->altpath,tmp));
	putrec(buf,F_ALTPATH+2,2,crlf);
116
	SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
117
118
119
	if((file=sopen(str,O_WRONLY|O_BINARY,SH_DENYRW))==-1) {
		return(FALSE); 
	}
120
	length=(long)filelength(file);
121
122
123
124
125
126
127
128
129
130
131
132
133
	if(length%F_LEN) {
		close(file);
		return(FALSE); 
	}
	if(f->datoffset>length) {
		close(file);
		return(FALSE); 
	}
	lseek(file,f->datoffset,SEEK_SET);
	if(write(file,buf,F_LEN)!=F_LEN) {
		close(file);
		return(FALSE); 
	}
134
	length=(long)filelength(file);
135
136
137
138
139
140
141
142
143
144
145
146
	close(file);
	if(length%F_LEN) {
		return(FALSE);
	}
	return(TRUE);
}

/****************************************************************************/
/* Adds the data for struct filedat to the directory's data base.           */
/* changes the .datoffset field only                                        */
/* returns 1 if added successfully, 0 if not.								*/
/****************************************************************************/
147
BOOL DLLCALL addfiledat(scfg_t* cfg, file_t* f)
148
{
149
	char	str[MAX_PATH+1],fname[13],c,fdat[F_LEN+1];
150
	char	tmp[128];
deuce's avatar
deuce committed
151
	uchar	*ixbbuf,idx[3];
152
153
154
155
156
157
158
    int		i,file;
	long	l,length;
	time_t	uldate;

	/************************/
	/* Add data to DAT File */
	/************************/
159
	SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
160
	if((file=sopen(str,O_RDWR|O_BINARY|O_CREAT,SH_DENYRW,DEFFILEMODE))==-1) {
161
162
		return(FALSE); 
	}
163
	length=(long)filelength(file);
164
165
166
167
168
169
170
171
172
173
174
175
	if(length==0L)
		l=0L;
	else {
		if(length%F_LEN) {
			close(file);
			return(FALSE); 
		}
		for(l=0;l<length;l+=F_LEN) {    /* Find empty slot */
			lseek(file,l,SEEK_SET);
			read(file,&c,1);
			if(c==ETX) break; 
		}
176
		if(l/F_LEN>=MAX_FILES) {
177
178
179
180
181
182
183
184
185
186
187
			close(file);
			return(FALSE); 
		} 
	}
	putrec(fdat,F_CDT,LEN_FCDT,ultoa(f->cdt,tmp,10));
	putrec(fdat,F_DESC,LEN_FDESC,f->desc);
	putrec(fdat,F_DESC+LEN_FDESC,2,crlf);
	putrec(fdat,F_ULER,LEN_ALIAS+5,f->uler);
	putrec(fdat,F_ULER+LEN_ALIAS+5,2,crlf);
	putrec(fdat,F_TIMESDLED,5,ultoa(f->timesdled,tmp,10));
	putrec(fdat,F_TIMESDLED+5,2,crlf);
188
	putrec(fdat,F_OPENCOUNT,3,ultoa(f->opencount,tmp,10));
189
	putrec(fdat,F_OPENCOUNT+3,2,crlf);
190
	fdat[F_MISC]=(char)f->misc+' ';
191
192
193
194
195
196
197
198
199
200
201
	putrec(fdat,F_ALTPATH,2,hexplus(f->altpath,tmp));
	putrec(fdat,F_ALTPATH+2,2,crlf);
	f->datoffset=l;
	idx[0]=(uchar)(l&0xff);          /* Get offset within DAT file for IXB file */
	idx[1]=(uchar)((l>>8)&0xff);
	idx[2]=(uchar)((l>>16)&0xff);
	lseek(file,l,SEEK_SET);
	if(write(file,fdat,F_LEN)!=F_LEN) {
		close(file);
		return(FALSE); 
	}
202
	length=(long)filelength(file);
203
204
205
206
207
208
209
210
	close(file);
	if(length%F_LEN) {
		return(FALSE);
	}

	/*******************************************/
	/* Update last upload date/time stamp file */
	/*******************************************/
211
	SAFEPRINTF2(str,"%s%s.dab",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
212
	if((file=sopen(str,O_WRONLY|O_CREAT|O_BINARY,SH_DENYRW,DEFFILEMODE))!=-1) {
213
214
215
		time32_t now=time32(NULL);
		/* TODO: LE required */
		write(file,&now,sizeof(time32_t));
216
217
218
219
220
221
		close(file); 
	}

	/************************/
	/* Add data to IXB File */
	/************************/
222
	SAFECOPY(fname,f->name);
223
224
	for(i=8;i<12;i++)   /* Turn FILENAME.EXT into FILENAMEEXT */
		fname[i]=fname[i+1];
225
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
226
	if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW,DEFFILEMODE))==-1) {
227
228
		return(FALSE); 
	}
229
	length=(long)filelength(file);
230
231
232
233
234
	if(length) {    /* IXB file isn't empty */
		if(length%F_IXBSIZE) {
			close(file);
			return(FALSE); 
		}
deuce's avatar
deuce committed
235
		if((ixbbuf=(uchar *)malloc(length))==NULL) {
236
237
238
			close(file);
			return(FALSE); 
		}
239
		if(read(file,ixbbuf,length)!=length) {
240
			close(file);
241
			free(ixbbuf);
242
243
244
245
246
247
248
			return(FALSE); 
		}
	/************************************************/
	/* Sort by Name or Date, Assending or Decending */
	/************************************************/
		if(cfg->dir[f->dir]->sort==SORT_NAME_A || cfg->dir[f->dir]->sort==SORT_NAME_D) {
			for(l=0;l<length;l+=F_IXBSIZE) {
249
				for(i=0;i<12 && toupper(fname[i])==toupper(ixbbuf[l+i]);i++);
250
251
				if(i==12) {     /* file already in directory index */
					close(file);
252
					free(ixbbuf);
253
254
					return(FALSE); 
				}
255
256
				if(cfg->dir[f->dir]->sort==SORT_NAME_A 
					&& toupper(fname[i])<toupper(ixbbuf[l+i]))
257
					break;
258
259
				if(cfg->dir[f->dir]->sort==SORT_NAME_D 
					&& toupper(fname[i])>toupper(ixbbuf[l+i]))
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
					break; 
			} 
		}
		else {  /* sort by date */
			for(l=0;l<length;l+=F_IXBSIZE) {
				uldate=(ixbbuf[l+14]|((long)ixbbuf[l+15]<<8)
					|((long)ixbbuf[l+16]<<16)|((long)ixbbuf[l+17]<<24));
				if(cfg->dir[f->dir]->sort==SORT_DATE_A && f->dateuled<uldate)
					break;
				if(cfg->dir[f->dir]->sort==SORT_DATE_D && f->dateuled>uldate)
					break; 
			} 
		}
		lseek(file,l,SEEK_SET);
		if(write(file,fname,11)!=11) {  /* Write filename to IXB file */
			close(file);
276
			free(ixbbuf);
277
278
279
280
			return(FALSE); 
		}
		if(write(file,idx,3)!=3) {  /* Write DAT offset into IXB file */
			close(file);
281
			free(ixbbuf);
282
283
			return(FALSE); 
		}
deuce's avatar
64-bit    
deuce committed
284
		write(file,&f->dateuled,4);
285
		write(file,&f->datedled,4);              /* Write 0 for datedled */
286
		if(write(file,&ixbbuf[l],length-l)!=length-l) { /* Write rest of IXB */
287
			close(file);
288
			free(ixbbuf);
289
290
			return(FALSE); 
		}
291
		free(ixbbuf); 
292
	}
293
294
295
296
297
298
299
300
301
	else {              /* IXB file is empty... No files */
		if(write(file,fname,11)!=11) {  /* Write filename it IXB file */
			close(file);
			return(FALSE); 
		}
		if(write(file,idx,3)!=3) {  /* Write DAT offset into IXB file */
			close(file);
			return(FALSE); 
		}
deuce's avatar
64-bit    
deuce committed
302
		write(file,&f->dateuled,4);
303
304
		write(file,&f->datedled,4); 
	}
305
	length=(long)filelength(file);
306
307
308
309
310
	close(file);
	return(TRUE);
}

/****************************************************************************/
311
/* Gets file data from dircode.ixb file										*/
312
313
314
/* Need fields .name and .dir filled.                                       */
/* only fills .offset, .dateuled, and .datedled                             */
/****************************************************************************/
315
BOOL DLLCALL getfileixb(scfg_t* cfg, file_t* f)
316
{
317
	char			str[MAX_PATH+1],fname[13];
deuce's avatar
deuce committed
318
	uchar *	ixbbuf;
319
320
321
	int				file;
	long			l,length;

322
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
323
324
325
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
		return(FALSE); 
	}
326
	length=(long)filelength(file);
327
328
329
330
	if(length%F_IXBSIZE) {
		close(file);
		return(FALSE); 
	}
deuce's avatar
deuce committed
331
	if((ixbbuf=(uchar *)malloc(length))==NULL) {
332
333
334
		close(file);
		return(FALSE); 
	}
335
	if(read(file,ixbbuf,length)!=length) {
336
		close(file);
337
		free(ixbbuf);
338
339
340
		return(FALSE); 
	}
	close(file);
341
	SAFECOPY(fname,f->name);
342
343
344
	for(l=8;l<12;l++)	/* Turn FILENAME.EXT into FILENAMEEXT */
		fname[l]=fname[l+1];
	for(l=0;l<length;l+=F_IXBSIZE) {
345
		SAFEPRINTF(str,"%11.11s",ixbbuf+l);
346
		if(!stricmp(str,fname))
347
348
349
			break; 
	}
	if(l>=length) {
350
		free(ixbbuf);
351
352
353
354
355
356
357
358
		return(FALSE); 
	}
	l+=11;
	f->datoffset=ixbbuf[l]|((long)ixbbuf[l+1]<<8)|((long)ixbbuf[l+2]<<16);
	f->dateuled=ixbbuf[l+3]|((long)ixbbuf[l+4]<<8)
		|((long)ixbbuf[l+5]<<16)|((long)ixbbuf[l+6]<<24);
	f->datedled=ixbbuf[l+7]|((long)ixbbuf[l+8]<<8)
		|((long)ixbbuf[l+9]<<16)|((long)ixbbuf[l+10]<<24);
359
	free(ixbbuf);
360
361
362
	return(TRUE);
}

363
364
365
366
367
368
369
370
371
372
373
374
375
376
/****************************************************************************/
/* Updates the datedled and dateuled index record fields for a file			*/
/****************************************************************************/
BOOL DLLCALL putfileixb(scfg_t* cfg, file_t* f)
{
	char	str[MAX_PATH+1],fname[13];
	uchar*	ixbbuf;
	int		file;
	long	l,length;

	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
	if((file=sopen(str,O_RDWR|O_BINARY,SH_DENYRW))==-1) {
		return(FALSE); 
	}
377
	length=(long)filelength(file);
378
379
380
381
382
383
384
385
	if(length%F_IXBSIZE) {
		close(file);
		return(FALSE); 
	}
	if((ixbbuf=(uchar *)malloc(length))==NULL) {
		close(file);
		return(FALSE); 
	}
386
	if(read(file,ixbbuf,length)!=length) {
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
		close(file);
		free(ixbbuf);
		return(FALSE); 
	}
	SAFECOPY(fname,f->name);
	for(l=8;l<12;l++)	/* Turn FILENAME.EXT into FILENAMEEXT */
		fname[l]=fname[l+1];
	for(l=0;l<length;l+=F_IXBSIZE) {
		SAFEPRINTF(str,"%11.11s",ixbbuf+l);
		if(!stricmp(str,fname))
			break; 
	}
	free(ixbbuf);

	if(l>=length) {
		close(file);
		return(FALSE); 
	}
	
	lseek(file,l+11+3,SEEK_SET);

deuce's avatar
64-bit    
deuce committed
408
409
	write(file,&f->dateuled,4);
	write(file,&f->datedled,4);
410
411
412
413
414
415
416

	close(file);

	return(TRUE);
}


417
418
419
/****************************************************************************/
/* Removes DAT and IXB entries for the file in the struct 'f'               */
/****************************************************************************/
420
BOOL DLLCALL removefiledat(scfg_t* cfg, file_t* f)
421
{
deuce's avatar
deuce committed
422
	char	c,str[MAX_PATH+1],ixbname[12],*ixbbuf,fname[13];
423
    int		i,file;
424
425
	long	l,length;

426
	SAFECOPY(fname,f->name);
427
428
	for(i=8;i<12;i++)   /* Turn FILENAME.EXT into FILENAMEEXT */
		fname[i]=fname[i+1];
429
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
430
431
432
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
		return(FALSE); 
	}
433
	length=(long)filelength(file);
434
435
436
437
	if(!length) {
		close(file);
		return(FALSE); 
	}
deuce's avatar
deuce committed
438
	if((ixbbuf=(char *)malloc(length))==0) {
439
440
441
		close(file);
		return(FALSE); 
	}
442
	if(read(file,ixbbuf,length)!=length) {
443
		close(file);
444
		free(ixbbuf);
445
446
447
448
		return(FALSE); 
	}
	close(file);
	if((file=sopen(str,O_WRONLY|O_TRUNC|O_BINARY,SH_DENYRW))==-1) {
449
		free(ixbbuf);
450
451
452
		return(FALSE); 
	}
	for(l=0;l<length;l+=F_IXBSIZE) {
453
454
455
		for(i=0;i<11;i++)
			ixbname[i]=ixbbuf[l+i];
		ixbname[i]=0;
456
		if(stricmp(ixbname,fname))
457
			if(write(file,&ixbbuf[l],F_IXBSIZE)!=F_IXBSIZE) {
458
				close(file);
459
				free(ixbbuf);
460
461
462
				return(FALSE); 
		} 
	}
463
	free(ixbbuf);
464
	close(file);
465
	SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
	if((file=sopen(str,O_WRONLY|O_BINARY,SH_DENYRW))==-1) {
		return(FALSE); 
	}
	lseek(file,f->datoffset,SEEK_SET);
	c=ETX;          /* If first char of record is ETX, record is unused */
	if(write(file,&c,1)!=1) { /* So write a D_T on the first byte of the record */
		close(file);
		return(FALSE); 
	}
	close(file);
	if(f->dir==cfg->user_dir)  /* remove file from index */
		rmuserxfers(cfg,0,0,f->name);
	return(TRUE);
}

/****************************************************************************/
/* Checks  directory data file for 'filename' (must be padded). If found,   */
/* it returns the 1, else returns 0.                                        */
/* Called from upload and bulkupload                                        */
/****************************************************************************/
486
BOOL DLLCALL findfile(scfg_t* cfg, uint dirnum, char *filename)
487
{
deuce's avatar
deuce committed
488
	char str[MAX_PATH+1],fname[13],*ixbbuf;
489
    int i,file;
490
491
    long length,l;

492
	SAFECOPY(fname,filename);
493
	strupr(fname);
494
495
	for(i=8;i<12;i++)   /* Turn FILENAME.EXT into FILENAMEEXT */
		fname[i]=fname[i+1];
496
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code);
497
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) return(FALSE);
498
	length=(long)filelength(file);
499
500
	if(!length) {
		close(file);
501
502
		return(FALSE); 
	}
deuce's avatar
deuce committed
503
	if((ixbbuf=(char *)malloc(length))==NULL) {
504
		close(file);
505
506
		return(FALSE); 
	}
507
	if(read(file,ixbbuf,length)!=length) {
508
		close(file);
509
		free(ixbbuf);
510
511
		return(FALSE); 
	}
512
513
	close(file);
	for(l=0;l<length;l+=F_IXBSIZE) {
514
		for(i=0;i<11;i++)
515
			if(toupper(fname[i])!=toupper(ixbbuf[l+i])) break;
516
517
		if(i==11) break; 
	}
518
	free(ixbbuf);
519
520
521
522
523
524
525
526
	if(l!=length)
		return(TRUE);
	return(FALSE);
}

/****************************************************************************/
/* Turns FILE.EXT into FILE    .EXT                                         */
/****************************************************************************/
527
char* DLLCALL padfname(const char *filename, char *str)
528
{
529
    int c,d;
530
531
532
533
534
535
536

	for(c=0;c<8;c++)
		if(filename[c]=='.' || !filename[c]) break;
		else str[c]=filename[c];
	d=c;
	if(filename[c]=='.') c++;
	while(d<8)
537
538
539
540
541
		str[d++]=' ';
	if(filename[c]>' ')	/* Change "FILE" to "FILE        " */
		str[d++]='.';	/* (don't add a dot if there's no extension) */
	else
		str[d++]=' ';
542
543
544
545
	while(d<12)
		if(!filename[c]) break;
		else str[d++]=filename[c++];
	while(d<12)
546
		str[d++]=' ';
547
548
549
550
551
552
553
	str[d]=0;
	return(str);
}

/****************************************************************************/
/* Turns FILE    .EXT into FILE.EXT                                         */
/****************************************************************************/
554
char* DLLCALL unpadfname(const char *filename, char *str)
555
{
556
    int c,d;
557
558

	for(c=0,d=0;filename[c];c++)
559
		if(filename[c]!=' ') str[d++]=filename[c];
560
561
562
563
564
565
566
567
	str[d]=0;
	return(str);
}

/****************************************************************************/
/* Removes any files in the user transfer index (XFER.IXT) that match the   */
/* specifications of dest, or source user, or filename or any combination.  */
/****************************************************************************/
568
BOOL DLLCALL rmuserxfers(scfg_t* cfg, int fromuser, int destuser, char *fname)
569
{
570
    char str[MAX_PATH+1],*ixtbuf;
571
572
573
    int file;
    long l,length;

574
	SAFEPRINTF(str,"%sxfer.ixt", cfg->data_dir);
575
576
577
578
579
580
	if(!fexist(str))
		return(FALSE);
	if(!flength(str)) {
		remove(str);
		return(FALSE); 
	}
581
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
582
583
		return(FALSE); 
	}
584
	length=(long)filelength(file);
deuce's avatar
deuce committed
585
	if((ixtbuf=(char *)malloc(length))==NULL) {
586
587
588
589
590
		close(file);
		return(FALSE); 
	}
	if(read(file,ixtbuf,length)!=length) {
		close(file);
deuce's avatar
deuce committed
591
		free(ixtbuf);
592
593
594
595
		return(FALSE); 
	}
	close(file);
	if((file=sopen(str,O_WRONLY|O_TRUNC|O_BINARY,SH_DENYRW))==-1) {
deuce's avatar
deuce committed
596
		free(ixtbuf);
597
598
599
600
601
602
603
		return(FALSE); 
	}
	for(l=0;l<length;l+=24) {
		if(fname!=NULL && fname[0]) {               /* fname specified */
			if(!strncmp(ixtbuf+l+5,fname,12)) {     /* this is the file */
				if(destuser && fromuser) {          /* both dest and from user */
					if(atoi(ixtbuf+l)==destuser && atoi(ixtbuf+l+18)==fromuser)
604
605
						continue;                   /* both match */
				}
606
607
				else if(fromuser) {                 /* from user */
					if(atoi(ixtbuf+l+18)==fromuser) /* matches */
608
609
						continue; 
				}
610
611
				else if(destuser) {                 /* dest user */
					if(atoi(ixtbuf+l)==destuser)    /* matches */
612
613
614
615
616
						continue; 
				}
				else continue;		                /* no users, so match */
			}
		}
617
618
		else if(destuser && fromuser) {
			if(atoi(ixtbuf+l+18)==fromuser && atoi(ixtbuf+l)==destuser)
619
620
				continue; 
		}
621
622
623
624
		else if(destuser && atoi(ixtbuf+l)==destuser)
			continue;
		else if(fromuser && atoi(ixtbuf+l+18)==fromuser)
			continue;
625
626
		write(file,ixtbuf+l,24); 
	}
627
	close(file);
deuce's avatar
deuce committed
628
	free(ixtbuf);
629
630
631
632

	return(TRUE);
}

633
634
void DLLCALL getextdesc(scfg_t* cfg, uint dirnum, ulong datoffset, char *ext)
{
635
	char str[MAX_PATH+1];
636
637
	int file;

638
	memset(ext,0,F_EXBSIZE+1);
639
	SAFEPRINTF2(str,"%s%s.exb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code);
640
641
	if((file=nopen(str,O_RDONLY))==-1)
		return;
642
643
	lseek(file,(datoffset/F_LEN)*F_EXBSIZE,SEEK_SET);
	read(file,ext,F_EXBSIZE);
644
645
646
647
648
	close(file);
}

void DLLCALL putextdesc(scfg_t* cfg, uint dirnum, ulong datoffset, char *ext)
{
649
	char str[MAX_PATH+1],nulbuf[F_EXBSIZE];
650
651
	int file;

652
	strip_ansi(ext);
653
	strip_invalid_attr(ext);	/* eliminate bogus ctrl-a codes */
654
	memset(nulbuf,0,sizeof(nulbuf));
655
	SAFEPRINTF2(str,"%s%s.exb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code);
656
657
658
	if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
		return;
	lseek(file,0L,SEEK_END);
659
660
661
662
	while(filelength(file)<(long)(datoffset/F_LEN)*F_EXBSIZE)
		write(file,nulbuf,sizeof(nulbuf));
	lseek(file,(datoffset/F_LEN)*F_EXBSIZE,SEEK_SET);
	write(file,ext,F_EXBSIZE);
663
664
	close(file);
}
665
666
667
668
669
670

/****************************************************************************/
/* Update the upload date for the file 'f'                                  */
/****************************************************************************/
int DLLCALL update_uldate(scfg_t* cfg, file_t* f)
{
671
	char str[MAX_PATH+1],fname[13];
672
673
674
675
676
677
	int i,file;
	long l,length;

	/*******************/
	/* Update IXB File */
	/*******************/
678
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
679
680
	if((file=nopen(str,O_RDWR))==-1)
		return(errno); 
681
	length=(long)filelength(file);
682
683
684
685
	if(length%F_IXBSIZE) {
		close(file);
		return(-1); 
	}
686
	SAFECOPY(fname,f->name);
687
688
689
690
691
	for(i=8;i<12;i++)   /* Turn FILENAME.EXT into FILENAMEEXT */
		fname[i]=fname[i+1];
	for(l=0;l<length;l+=F_IXBSIZE) {
		read(file,str,F_IXBSIZE);      /* Look for the filename in the IXB file */
		str[11]=0;
692
		if(!stricmp(fname,str)) break; 
693
	}
694
695
696
697
698
699
700
701
702
703
704
	if(l>=length) {
		close(file);
		return(-2); 
	}
	lseek(file,l+14,SEEK_SET);
	write(file,&f->dateuled,4);
	close(file);

	/*******************************************/
	/* Update last upload date/time stamp file */
	/*******************************************/
705
	SAFEPRINTF2(str,"%s%s.dab",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
706
707
708
709
710
711
712
	if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
		return(errno);

	write(file,&f->dateuled,4);
	close(file); 
	return(0);
}
713
714

/****************************************************************************/
715
/* Returns full (case-corrected) path to specified file						*/
716
717
718
719
720
721
/****************************************************************************/
char* DLLCALL getfilepath(scfg_t* cfg, file_t* f, char* path)
{
	char	fname[MAX_PATH+1];

	unpadfname(f->name,fname);
722
	if(f->dir>=cfg->total_dirs)
723
		safe_snprintf(path,MAX_PATH,"%s%s",cfg->temp_dir,fname);
724
	else
725
		safe_snprintf(path,MAX_PATH,"%s%s",f->altpath>0 && f->altpath<=cfg->altpaths 
726
727
			? cfg->altpath[f->altpath-1] : cfg->dir[f->dir]->path
			,fname);
728
	fexistcase(path);
729
730
	return(path);
}