|
|
1.1 root 1: /* sortdir.cpp */
2:
3: /* Synchronet file database sorting routines */
4:
5: /* $Id: sortdir.cpp,v 1.3 2000/12/11 23:21:12 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 2000 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: /* Re-sorts file directory 'dirnum' according to dir[dirnum]->sort type */
42: /****************************************************************************/
43: void sbbs_t::resort(uint dirnum)
44: {
45: char str[25],ixbfname[128],datfname[128],exbfname[128],txbfname[128]
46: ,ext[512],nulbuf[512];
47: char tmp[512];
48: uchar* ixbbuf, *datbuf;
49: uchar* ixbptr[MAX_FILES];
50: int ixbfile,datfile,exbfile,txbfile,i,j;
51: long ixblen,datlen,offset,newoffset,l;
52:
53: memset(nulbuf,0,512);
54: bprintf(text[ResortLineFmt],cfg.lib[cfg.dir[dirnum]->lib]->sname,cfg.dir[dirnum]->sname);
55: sprintf(ixbfname,"%s%s.ixb",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
56: sprintf(datfname,"%s%s.dat",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
57: sprintf(exbfname,"%s%s.exb",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
58: sprintf(txbfname,"%s%s.txb",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code);
59:
60: if(flength(ixbfname)<1L || flength(datfname)<1L) {
61: remove(exbfname);
62: remove(txbfname);
63: remove(ixbfname);
64: remove(datfname);
65: bputs(text[ResortEmptyDir]);
66: return; }
67: bputs(text[Sorting]);
68: if((ixbfile=nopen(ixbfname,O_RDONLY))==-1) {
69: errormsg(WHERE,ERR_OPEN,ixbfname,O_RDONLY);
70: return; }
71: if((datfile=nopen(datfname,O_RDONLY))==-1) {
72: close(ixbfile);
73: errormsg(WHERE,ERR_OPEN,datfname,O_RDONLY);
74: return; }
75: ixblen=filelength(ixbfile);
76: datlen=filelength(datfile);
77: if((ixbbuf=(uchar *)MALLOC(ixblen))==NULL) {
78: close(ixbfile);
79: close(datfile);
80: errormsg(WHERE,ERR_ALLOC,ixbfname,ixblen);
81: return; }
82: if((datbuf=(uchar *)MALLOC(datlen))==NULL) {
83: close(ixbfile);
84: close(datfile);
85: FREE((char *)ixbbuf);
86: errormsg(WHERE,ERR_ALLOC,datfname,datlen);
87: return; }
88: if(lread(ixbfile,ixbbuf,ixblen)!=ixblen) {
89: close(ixbfile);
90: close(datfile);
91: FREE((char *)ixbbuf);
92: FREE((char *)datbuf);
93: errormsg(WHERE,ERR_READ,ixbfname,ixblen);
94: return; }
95: if(lread(datfile,datbuf,datlen)!=datlen) {
96: close(ixbfile);
97: close(datfile);
98: FREE((char *)ixbbuf);
99: FREE((char *)datbuf);
100: errormsg(WHERE,ERR_READ,datfname,datlen);
101: return; }
102: close(ixbfile);
103: close(datfile);
104: if((ixbfile=nopen(ixbfname,O_WRONLY|O_TRUNC))==-1) {
105: FREE((char *)ixbbuf);
106: FREE((char *)datbuf);
107: errormsg(WHERE,ERR_OPEN,ixbfname,O_WRONLY|O_TRUNC);
108: return; }
109: if((datfile=nopen(datfname,O_WRONLY|O_TRUNC))==-1) {
110: close(ixbfile);
111: FREE((char *)ixbbuf);
112: FREE((char *)datbuf);
113: errormsg(WHERE,ERR_OPEN,datfname,O_WRONLY|O_TRUNC);
114: return; }
115: for(l=0,i=0;l<ixblen && i<MAX_FILES;l+=F_IXBSIZE,i++)
116: ixbptr[i]=ixbbuf+l;
117: switch(cfg.dir[dirnum]->sort) {
118: case SORT_NAME_A:
119: qsort((void *)ixbptr,ixblen/F_IXBSIZE,sizeof(ixbptr[0])
120: ,(int(*)(const void*, const void*))fnamecmp_a);
121: break;
122: case SORT_NAME_D:
123: qsort((void *)ixbptr,ixblen/F_IXBSIZE,sizeof(ixbptr[0])
124: ,(int(*)(const void*, const void*))fnamecmp_d);
125: break;
126: case SORT_DATE_A:
127: qsort((void *)ixbptr,ixblen/F_IXBSIZE,sizeof(ixbptr[0])
128: ,(int(*)(const void*, const void*))fdatecmp_a);
129: break;
130: case SORT_DATE_D:
131: qsort((void *)ixbptr,ixblen/F_IXBSIZE,sizeof(ixbptr[0])
132: ,(int(*)(const void*, const void*))fdatecmp_d);
133: break; }
134:
135: if((exbfile=nopen(exbfname,O_RDWR|O_CREAT))==-1) {
136: close(ixbfile);
137: close(datfile);
138: FREE((char *)ixbbuf);
139: FREE((char *)datbuf);
140: errormsg(WHERE,ERR_OPEN,exbfname,O_RDWR|O_CREAT);
141: return; }
142: if((txbfile=nopen(txbfname,O_RDWR|O_CREAT))==-1) {
143: close(exbfile);
144: close(datfile);
145: close(exbfile);
146: FREE((char *)ixbbuf);
147: FREE((char *)datbuf);
148: errormsg(WHERE,ERR_OPEN,txbfname,O_RDWR|O_CREAT);
149: return; }
150:
151: for(i=0;i<ixblen/F_IXBSIZE;i++) {
152: offset=ixbptr[i][11]|((long)ixbptr[i][12]<<8)|((long)ixbptr[i][13]<<16);
153: lwrite(datfile,&datbuf[offset],F_LEN);
154:
155: newoffset=(ulong)i*(ulong)F_LEN;
156:
157: j=datbuf[offset+F_MISC]; /* misc bits */
158: if(j!=ETX) j-=SP;
159: if(j&FM_EXTDESC) { /* extended description */
160: lseek(exbfile,(offset/F_LEN)*512L,SEEK_SET);
161: memset(ext,0,512);
162: read(exbfile,ext,512);
163: while(filelength(txbfile)<(newoffset/F_LEN)*512L) {
164: // lseek(txbfile,0L,SEEK_END);
165: write(txbfile,nulbuf,512); }
166: lseek(txbfile,(newoffset/F_LEN)*512L,SEEK_SET);
167: write(txbfile,ext,512); }
168:
169: str[0]=newoffset&0xff; /* Get offset within DAT file for IXB file */
170: str[1]=(newoffset>>8)&0xff;
171: str[2]=(newoffset>>16)&0xff;
172: lwrite(ixbfile,ixbptr[i],11); /* filename */
173: lwrite(ixbfile,str,3); /* offset */
174: lwrite(ixbfile,ixbptr[i]+14,8); } /* upload and download times */
175: close(exbfile);
176: close(txbfile);
177: close(ixbfile);
178: close(datfile);
179: remove(exbfname);
180: rename(txbfname,exbfname);
181: if(!flength(exbfname))
182: remove(exbfname);
183: FREE((char *)ixbbuf);
184: FREE((char *)datbuf);
185: if(ixblen/F_IXBSIZE==datlen/F_LEN)
186: bputs(text[Sorted]);
187: else
188: bprintf(text[Compressed]
189: ,(uint)((datlen/F_LEN)-(ixblen/F_IXBSIZE))
190: ,ultoac(((datlen/F_LEN)-(ixblen/F_IXBSIZE))*F_LEN,tmp));
191: }
192:
193: /****************************************************************************/
194: /* Compares filenames for ascending name sort */
195: /****************************************************************************/
196: int fnamecmp_a(char **str1, char **str2)
197: {
198: return(strncmp(*str1,*str2,11));
199: }
200:
201: /****************************************************************************/
202: /* Compares filenames for descending name sort */
203: /****************************************************************************/
204: int fnamecmp_d(char **str1, char **str2)
205: {
206: return(strncmp(*str2,*str1,11));
207: }
208:
209: /****************************************************************************/
210: /* Compares file upload dates for ascending date sort */
211: /****************************************************************************/
212: int fdatecmp_a(uchar **buf1, uchar **buf2)
213: {
214: time_t date1,date2;
215:
216: date1=((*buf1)[14]|((long)(*buf1)[15]<<8)|((long)(*buf1)[16]<<16)
217: |((long)(*buf1)[17]<<24));
218: date2=((*buf2)[14]|((long)(*buf2)[15]<<8)|((long)(*buf2)[16]<<16)
219: |((long)(*buf2)[17]<<24));
220: if(date1>date2) return(1);
221: if(date1<date2) return(-1);
222: return(0);
223: }
224:
225: /****************************************************************************/
226: /* Compares file upload dates for descending date sort */
227: /****************************************************************************/
228: int fdatecmp_d(uchar **buf1, uchar **buf2)
229: {
230: time_t date1,date2;
231:
232: date1=((*buf1)[14]|((long)(*buf1)[15]<<8)|((long)(*buf1)[16]<<16)
233: |((long)(*buf1)[17]<<24));
234: date2=((*buf2)[14]|((long)(*buf2)[15]<<8)|((long)(*buf2)[16]<<16)
235: |((long)(*buf2)[17]<<24));
236: if(date1>date2) return(-1);
237: if(date1<date2) return(1);
238: return(0);
239: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.