filedat.c 21.3 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 2008 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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
		return(FALSE); 
	}
	length=filelength(file);
	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
78
			if((f->size=flength(str))>=0)
				f->date=fdate(str);
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
	/*
			}
		else {
			f->size=f->cdt;
			f->date=0; }
	*/
			}
#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)
100
		f->misc=buf[F_MISC]-' ';
101
102
103
104
105
106
107
108
109
	else
		f->misc=0;
	return(TRUE);
}

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

	/************************/
	/* Add data to DAT File */
	/************************/
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,DEFFILEMODE))==-1) {
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
		return(FALSE); 
	}
	length=filelength(file);
	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; 
		}
		if(l/F_LEN>=MAX_FILES || l/F_LEN>=cfg->dir[f->dir]->maxfiles) {
			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);
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
	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); 
	}
	length=filelength(file);
	close(file);
	if(length%F_LEN) {
		return(FALSE);
	}

	/*******************************************/
	/* Update last upload date/time stamp file */
	/*******************************************/
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,DEFFILEMODE))!=-1) {
226
		now=time(NULL);
deuce's avatar
64-bit    
deuce committed
227
		/* TODO: 32-bit *or* LE required */
228
229
230
231
232
233
234
		write(file,&now,4);
		close(file); 
	}

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

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

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

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
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
/****************************************************************************/
/* 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); 
	}
	length=filelength(file);
	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
420
421
	write(file,&f->dateuled,4);
	write(file,&f->datedled,4);
422
423
424
425
426
427
428

	close(file);

	return(TRUE);
}


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

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

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

/****************************************************************************/
/* Turns FILE.EXT into FILE    .EXT                                         */
/****************************************************************************/
534
char* DLLCALL padfname(const char *filename, char *str)
535
{
536
    int c,d;
537
538
539
540
541
542
543

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

/****************************************************************************/
/* Turns FILE    .EXT into FILE.EXT                                         */
/****************************************************************************/
561
char* DLLCALL unpadfname(const char *filename, char *str)
562
{
563
    int c,d;
564
565

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

581
	SAFEPRINTF(str,"%sxfer.ixt", cfg->data_dir);
582
583
584
585
586
587
	if(!fexist(str))
		return(FALSE);
	if(!flength(str)) {
		remove(str);
		return(FALSE); 
	}
588
	if((file=sopen(str,O_RDONLY|O_BINARY,SH_DENYWR))==-1) {
589
590
591
		return(FALSE); 
	}
	length=filelength(file);
deuce's avatar
deuce committed
592
	if((ixtbuf=(char *)malloc(length))==NULL) {
593
594
595
596
597
		close(file);
		return(FALSE); 
	}
	if(read(file,ixtbuf,length)!=length) {
		close(file);
deuce's avatar
deuce committed
598
		free(ixtbuf);
599
600
601
602
		return(FALSE); 
	}
	close(file);
	if((file=sopen(str,O_WRONLY|O_TRUNC|O_BINARY,SH_DENYRW))==-1) {
deuce's avatar
deuce committed
603
		free(ixtbuf);
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
		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)
						continue; }                 /* both match */
				else if(fromuser) {                 /* from user */
					if(atoi(ixtbuf+l+18)==fromuser) /* matches */
						continue; }
				else if(destuser) {                 /* dest user */
					if(atoi(ixtbuf+l)==destuser)    /* matches */
						continue; }
				else continue; } }                  /* no users, so match */
		else if(destuser && fromuser) {
			if(atoi(ixtbuf+l+18)==fromuser && atoi(ixtbuf+l)==destuser)
				continue; }
		else if(destuser && atoi(ixtbuf+l)==destuser)
			continue;
		else if(fromuser && atoi(ixtbuf+l+18)==fromuser)
			continue;
		write(file,ixtbuf+l,24); }
	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_invalid_attr(ext);	/* eliminate bogus ctrl-a codes */
653
	memset(nulbuf,0,sizeof(nulbuf));
654
	SAFEPRINTF2(str,"%s%s.exb",cfg->dir[dirnum]->data_dir,cfg->dir[dirnum]->code);
655
656
657
	if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
		return;
	lseek(file,0L,SEEK_END);
658
659
660
661
	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);
662
663
	close(file);
}
664
665
666
667
668
669

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

	/*******************/
	/* Update IXB File */
	/*******************/
677
	SAFEPRINTF2(str,"%s%s.ixb",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
678
679
680
681
682
683
684
	if((file=nopen(str,O_RDWR))==-1)
		return(errno); 
	length=filelength(file);
	if(length%F_IXBSIZE) {
		close(file);
		return(-1); 
	}
685
	SAFECOPY(fname,f->name);
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
	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;
		if(!strcmp(fname,str)) break; }
	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 */
	/*******************************************/
703
	SAFEPRINTF2(str,"%s%s.dab",cfg->dir[f->dir]->data_dir,cfg->dir[f->dir]->code);
704
705
706
707
708
709
710
	if((file=nopen(str,O_WRONLY|O_CREAT))==-1)
		return(errno);

	write(file,&f->dateuled,4);
	close(file); 
	return(0);
}
711
712
713
714
715
716
717
718
719

/****************************************************************************/
/* Returns full path to specified file										*/
/****************************************************************************/
char* DLLCALL getfilepath(scfg_t* cfg, file_t* f, char* path)
{
	char	fname[MAX_PATH+1];

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

	return(path);
}