filedat.c 21.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/* filedat.c */

/* Synchronet file database-related exported functions */

/* $Id$ */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
11
 * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html		*
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 *																			*
 * 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										*
 *																			*
 * Anonymous FTP access to the most recent released source is available at	*
 * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
 *																			*
 * Anonymous CVS access to the development source and modification history	*
 * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
 *     (just hit return, no password is necessary)							*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * You are encouraged to submit any modifications (preferably in Unix diff	*
 * format) via e-mail to mods@synchro.net									*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#include "sbbs.h"

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

51
	SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
52
53
54
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
		return(FALSE); 
	}
55
	length=(long)filelength(file);
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
	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);

	if(!f->size) {					/* only read disk if this is null */
76
			getfilepath(cfg,f,str);
77
			if((f->size=(long)flength(str))>=0)
78
				f->date=(time32_t)fdate(str);
79
80
81
82
	/*
			}
		else {
			f->size=f->cdt;
83
84
			f->date=0; 
			}
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
	*/
			}
#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)
101
		f->misc=buf[F_MISC]-' ';
102
103
104
105
106
107
108
109
110
	else
		f->misc=0;
	return(TRUE);
}

/****************************************************************************/
/* Puts filedata into DIR_code.DAT file                                     */
/* Called from removefiles                                                  */
/****************************************************************************/
111
BOOL DLLCALL putfiledat(scfg_t* cfg, file_t* f)
112
{
113
    char buf[F_LEN+1],str[MAX_PATH+1],tmp[128];
114
115
116
117
118
119
120
121
    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);
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]=(char)f->misc+' ';
127
128
	putrec(buf,F_ALTPATH,2,hexplus(f->altpath,tmp));
	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
131
132
	if((file=sopen(str,O_WRONLY|O_BINARY,SH_DENYRW))==-1) {
		return(FALSE); 
	}
133
	length=(long)filelength(file);
134
135
136
137
138
139
140
141
142
143
144
145
146
	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); 
	}
147
	length=(long)filelength(file);
148
149
150
151
152
153
154
155
156
157
158
159
	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.								*/
/****************************************************************************/
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];
deuce's avatar
deuce committed
164
	uchar	*ixbbuf,idx[3];
165
166
167
168
169
170
171
172
    int		i,file;
	long	l,length;
	time_t	now;
	time_t	uldate;

	/************************/
	/* Add data to DAT File */
	/************************/
173
	SAFEPRINTF2(str,"%s%s.dat",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
174
	if((file=sopen(str,O_RDWR|O_BINARY|O_CREAT,SH_DENYRW,DEFFILEMODE))==-1) {
175
176
		return(FALSE); 
	}
177
	length=(long)filelength(file);
178
179
180
181
182
183
184
185
186
187
188
189
	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; 
		}
190
		if(l/F_LEN>=MAX_FILES) {
191
192
193
194
195
196
197
198
199
200
201
			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);
202
	putrec(fdat,F_OPENCOUNT,3,ultoa(f->opencount,tmp,10));
203
	putrec(fdat,F_OPENCOUNT+3,2,crlf);
204
	fdat[F_MISC]=(char)f->misc+' ';
205
206
207
208
209
210
211
212
213
214
215
	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); 
	}
216
	length=(long)filelength(file);
217
218
219
220
221
222
223
224
	close(file);
	if(length%F_LEN) {
		return(FALSE);
	}

	/*******************************************/
	/* Update last upload date/time stamp file */
	/*******************************************/
225
	SAFEPRINTF2(str,"%s%s.dab",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
226
	if((file=sopen(str,O_WRONLY|O_CREAT|O_BINARY,SH_DENYRW,DEFFILEMODE))!=-1) {
227
		now=time(NULL);
deuce's avatar
64-bit    
deuce committed
228
		/* TODO: 32-bit *or* LE required */
229
230
231
232
233
234
235
		write(file,&now,4);
		close(file); 
	}

	/************************/
	/* Add data to IXB File */
	/************************/
236
	SAFECOPY(fname,f->name);
237
238
	for(i=8;i<12;i++)   /* Turn FILENAME.EXT into FILENAMEEXT */
		fname[i]=fname[i+1];
239
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
240
	if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW,DEFFILEMODE))==-1) {
241
242
		return(FALSE); 
	}
243
	length=(long)filelength(file);
244
245
246
247
248
	if(length) {    /* IXB file isn't empty */
		if(length%F_IXBSIZE) {
			close(file);
			return(FALSE); 
		}
deuce's avatar
deuce committed
249
		if((ixbbuf=(uchar *)malloc(length))==NULL) {
250
251
252
253
254
			close(file);
			return(FALSE); 
		}
		if(lread(file,ixbbuf,length)!=length) {
			close(file);
deuce's avatar
deuce committed
255
			free((char *)ixbbuf);
256
257
258
259
260
261
262
			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) {
263
				for(i=0;i<12 && toupper(fname[i])==toupper(ixbbuf[l+i]);i++);
264
265
				if(i==12) {     /* file already in directory index */
					close(file);
deuce's avatar
deuce committed
266
					free((char *)ixbbuf);
267
268
					return(FALSE); 
				}
269
270
				if(cfg->dir[f->dir]->sort==SORT_NAME_A 
					&& toupper(fname[i])<toupper(ixbbuf[l+i]))
271
					break;
272
273
				if(cfg->dir[f->dir]->sort==SORT_NAME_D 
					&& toupper(fname[i])>toupper(ixbbuf[l+i]))
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
					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);
deuce's avatar
deuce committed
290
			free((char *)ixbbuf);
291
292
293
294
			return(FALSE); 
		}
		if(write(file,idx,3)!=3) {  /* Write DAT offset into IXB file */
			close(file);
deuce's avatar
deuce committed
295
			free((char *)ixbbuf);
296
297
			return(FALSE); 
		}
deuce's avatar
64-bit    
deuce committed
298
		write(file,&f->dateuled,4);
299
300
301
		write(file,&f->datedled,4);              /* Write 0 for datedled */
		if(lwrite(file,&ixbbuf[l],length-l)!=length-l) { /* Write rest of IXB */
			close(file);
deuce's avatar
deuce committed
302
			free((char *)ixbbuf);
303
304
			return(FALSE); 
		}
305
306
		free((char *)ixbbuf); 
	}
307
308
309
310
311
312
313
314
315
	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
316
		write(file,&f->dateuled,4);
317
318
		write(file,&f->datedled,4); 
	}
319
	length=(long)filelength(file);
320
321
322
323
324
	close(file);
	return(TRUE);
}

/****************************************************************************/
325
/* Gets file data from dircode.ixb file										*/
326
327
328
/* Need fields .name and .dir filled.                                       */
/* only fills .offset, .dateuled, and .datedled                             */
/****************************************************************************/
329
BOOL DLLCALL getfileixb(scfg_t* cfg, file_t* f)
330
{
331
	char			str[MAX_PATH+1],fname[13];
deuce's avatar
deuce committed
332
	uchar *	ixbbuf;
333
334
335
	int				file;
	long			l,length;

336
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
337
338
339
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
		return(FALSE); 
	}
340
	length=(long)filelength(file);
341
342
343
344
	if(length%F_IXBSIZE) {
		close(file);
		return(FALSE); 
	}
deuce's avatar
deuce committed
345
	if((ixbbuf=(uchar *)malloc(length))==NULL) {
346
347
348
349
350
		close(file);
		return(FALSE); 
	}
	if(lread(file,ixbbuf,length)!=length) {
		close(file);
deuce's avatar
deuce committed
351
		free((char *)ixbbuf);
352
353
354
		return(FALSE); 
	}
	close(file);
355
	SAFECOPY(fname,f->name);
356
357
358
	for(l=8;l<12;l++)	/* Turn FILENAME.EXT into FILENAMEEXT */
		fname[l]=fname[l+1];
	for(l=0;l<length;l+=F_IXBSIZE) {
359
		SAFEPRINTF(str,"%11.11s",ixbbuf+l);
360
		if(!stricmp(str,fname))
361
362
363
			break; 
	}
	if(l>=length) {
deuce's avatar
deuce committed
364
		free((char *)ixbbuf);
365
366
367
368
369
370
371
372
		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);
deuce's avatar
deuce committed
373
	free((char *)ixbbuf);
374
375
376
	return(TRUE);
}

377
378
379
380
381
382
383
384
385
386
387
388
389
390
/****************************************************************************/
/* 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); 
	}
391
	length=(long)filelength(file);
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
	if(length%F_IXBSIZE) {
		close(file);
		return(FALSE); 
	}
	if((ixbbuf=(uchar *)malloc(length))==NULL) {
		close(file);
		return(FALSE); 
	}
	if(lread(file,ixbbuf,length)!=length) {
		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
422
423
	write(file,&f->dateuled,4);
	write(file,&f->datedled,4);
424
425
426
427
428
429
430

	close(file);

	return(TRUE);
}


431
432
433
/****************************************************************************/
/* Removes DAT and IXB entries for the file in the struct 'f'               */
/****************************************************************************/
434
BOOL DLLCALL removefiledat(scfg_t* cfg, file_t* f)
435
{
deuce's avatar
deuce committed
436
	char	c,str[MAX_PATH+1],ixbname[12],*ixbbuf,fname[13];
437
    int		i,file;
438
439
	long	l,length;

440
	SAFECOPY(fname,f->name);
441
442
	for(i=8;i<12;i++)   /* Turn FILENAME.EXT into FILENAMEEXT */
		fname[i]=fname[i+1];
443
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
444
445
446
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
		return(FALSE); 
	}
447
	length=(long)filelength(file);
448
449
450
451
	if(!length) {
		close(file);
		return(FALSE); 
	}
deuce's avatar
deuce committed
452
	if((ixbbuf=(char *)malloc(length))==0) {
453
454
455
456
457
		close(file);
		return(FALSE); 
	}
	if(lread(file,ixbbuf,length)!=length) {
		close(file);
deuce's avatar
deuce committed
458
		free((char *)ixbbuf);
459
460
461
462
463
464
465
		return(FALSE); 
	}
	close(file);
	if((file=sopen(str,O_WRONLY|O_TRUNC|O_BINARY,SH_DENYRW))==-1) {
		return(FALSE); 
	}
	for(l=0;l<length;l+=F_IXBSIZE) {
466
467
468
		for(i=0;i<11;i++)
			ixbname[i]=ixbbuf[l+i];
		ixbname[i]=0;
469
		if(stricmp(ixbname,fname))
470
471
			if(lwrite(file,&ixbbuf[l],F_IXBSIZE)!=F_IXBSIZE) {
				close(file);
deuce's avatar
deuce committed
472
				free((char *)ixbbuf);
473
474
475
				return(FALSE); 
		} 
	}
deuce's avatar
deuce committed
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
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
	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                                        */
/****************************************************************************/
499
BOOL DLLCALL findfile(scfg_t* cfg, uint dirnum, char *filename)
500
{
deuce's avatar
deuce committed
501
	char str[MAX_PATH+1],fname[13],*ixbbuf;
502
    int i,file;
503
504
    long length,l;

505
	SAFECOPY(fname,filename);
506
	strupr(fname);
507
508
	for(i=8;i<12;i++)   /* Turn FILENAME.EXT into FILENAMEEXT */
		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);
511
	length=(long)filelength(file);
512
513
	if(!length) {
		close(file);
514
515
		return(FALSE); 
	}
deuce's avatar
deuce committed
516
	if((ixbbuf=(char *)malloc(length))==NULL) {
517
		close(file);
518
519
		return(FALSE); 
	}
520
521
	if(lread(file,ixbbuf,length)!=length) {
		close(file);
deuce's avatar
deuce committed
522
		free((char *)ixbbuf);
523
524
		return(FALSE); 
	}
525
526
	close(file);
	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;
529
530
		if(i==11) break; 
	}
deuce's avatar
deuce committed
531
	free((char *)ixbbuf);
532
533
534
535
536
537
538
539
	if(l!=length)
		return(TRUE);
	return(FALSE);
}

/****************************************************************************/
/* Turns FILE.EXT into FILE    .EXT                                         */
/****************************************************************************/
540
char* DLLCALL padfname(const char *filename, char *str)
541
{
542
    int c,d;
543
544
545
546
547
548
549

	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)
550
551
552
553
554
		str[d++]=' ';
	if(filename[c]>' ')	/* Change "FILE" to "FILE        " */
		str[d++]='.';	/* (don't add a dot if there's no extension) */
	else
		str[d++]=' ';
555
556
557
558
	while(d<12)
		if(!filename[c]) break;
		else str[d++]=filename[c++];
	while(d<12)
559
		str[d++]=' ';
560
561
562
563
564
565
566
	str[d]=0;
	return(str);
}

/****************************************************************************/
/* Turns FILE    .EXT into FILE.EXT                                         */
/****************************************************************************/
567
char* DLLCALL unpadfname(const char *filename, char *str)
568
{
569
    int c,d;
570
571

	for(c=0,d=0;filename[c];c++)
572
		if(filename[c]!=' ') str[d++]=filename[c];
573
574
575
576
577
578
579
580
	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.  */
/****************************************************************************/
581
BOOL DLLCALL rmuserxfers(scfg_t* cfg, int fromuser, int destuser, char *fname)
582
{
583
    char str[MAX_PATH+1],*ixtbuf;
584
585
586
    int file;
    long l,length;

587
	SAFEPRINTF(str,"%sxfer.ixt", cfg->data_dir);
588
589
590
591
592
593
	if(!fexist(str))
		return(FALSE);
	if(!flength(str)) {
		remove(str);
		return(FALSE); 
	}
594
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
595
596
		return(FALSE); 
	}
597
	length=(long)filelength(file);
deuce's avatar
deuce committed
598
	if((ixtbuf=(char *)malloc(length))==NULL) {
599
600
601
602
603
		close(file);
		return(FALSE); 
	}
	if(read(file,ixtbuf,length)!=length) {
		close(file);
deuce's avatar
deuce committed
604
		free(ixtbuf);
605
606
607
608
		return(FALSE); 
	}
	close(file);
	if((file=sopen(str,O_WRONLY|O_TRUNC|O_BINARY,SH_DENYRW))==-1) {
deuce's avatar
deuce committed
609
		free(ixtbuf);
610
611
612
613
614
615
616
		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)
617
618
						continue;                   /* both match */
				}
619
620
				else if(fromuser) {                 /* from user */
					if(atoi(ixtbuf+l+18)==fromuser) /* matches */
621
622
						continue; 
				}
623
624
				else if(destuser) {                 /* dest user */
					if(atoi(ixtbuf+l)==destuser)    /* matches */
625
626
627
628
629
						continue; 
				}
				else continue;		                /* no users, so match */
			}
		}
630
631
		else if(destuser && fromuser) {
			if(atoi(ixtbuf+l+18)==fromuser && atoi(ixtbuf+l)==destuser)
632
633
				continue; 
		}
634
635
636
637
		else if(destuser && atoi(ixtbuf+l)==destuser)
			continue;
		else if(fromuser && atoi(ixtbuf+l+18)==fromuser)
			continue;
638
639
		write(file,ixtbuf+l,24); 
	}
640
	close(file);
deuce's avatar
deuce committed
641
	free(ixtbuf);
642
643
644
645

	return(TRUE);
}

646
647
void DLLCALL getextdesc(scfg_t* cfg, uint dirnum, ulong datoffset, char *ext)
{
648
	char str[MAX_PATH+1];
649
650
	int file;

651
	memset(ext,0,F_EXBSIZE+1);
652
	SAFEPRINTF2(str,"%s%s.exb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code);
653
654
	if((file=nopen(str,O_RDONLY))==-1)
		return;
655
656
	lseek(file,(datoffset/F_LEN)*F_EXBSIZE,SEEK_SET);
	read(file,ext,F_EXBSIZE);
657
658
659
660
661
	close(file);
}

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

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
669
670
	if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
		return;
	lseek(file,0L,SEEK_END);
671
672
673
674
	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);
675
676
	close(file);
}
677
678
679
680
681
682

/****************************************************************************/
/* Update the upload date for the file 'f'                                  */
/****************************************************************************/
int DLLCALL update_uldate(scfg_t* cfg, file_t* f)
{
683
	char str[MAX_PATH+1],fname[13];
684
685
686
687
688
689
	int i,file;
	long l,length;

	/*******************/
	/* Update IXB File */
	/*******************/
690
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
691
692
	if((file=nopen(str,O_RDWR))==-1)
		return(errno); 
693
	length=(long)filelength(file);
694
695
696
697
	if(length%F_IXBSIZE) {
		close(file);
		return(-1); 
	}
698
	SAFECOPY(fname,f->name);
699
700
701
702
703
	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;
704
		if(!stricmp(fname,str)) break; 
705
	}
706
707
708
709
710
711
712
713
714
715
716
	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 */
	/*******************************************/
717
	SAFEPRINTF2(str,"%s%s.dab",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
718
719
720
721
722
723
724
	if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
		return(errno);

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

/****************************************************************************/
727
/* Returns full (case-corrected) path to specified file						*/
728
729
730
731
732
733
/****************************************************************************/
char* DLLCALL getfilepath(scfg_t* cfg, file_t* f, char* path)
{
	char	fname[MAX_PATH+1];

	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
739
			? cfg->altpath[f->altpath-1] : cfg->dir[f->dir]->path
			,fname);
740
	fexistcase(path);
741
742
	return(path);
}