|
|
1.1 root 1: /* fixsmb.c */
2:
3: /* Synchronet message base (SMB) index re-generator */
4:
1.1.1.2 ! root 5: /* $Id: fixsmb.c,v 1.34 2011/09/05 19:52:52 deuce Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 11: * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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 <stdio.h>
39: #include <stdlib.h> /* atoi, qsort */
40: #include <string.h> /* strnicmp */
41: #include <ctype.h> /* toupper */
42:
43: #include "smblib.h"
44: #include "genwrap.h" /* PLATFORM_DESC */
45: #include "str_list.h" /* strList API */
46: #include "crc16.h"
47:
48: smb_t smb;
49: BOOL renumber=FALSE;
1.1.1.2 ! root 50: BOOL smb_undelete=FALSE;
! 51: char* usage="usage: fixsmb [-renumber] [-undelete] <smb_file> [[smb_file] [...]]\n";
1.1 root 52:
53: int compare_index(const idxrec_t* idx1, const idxrec_t* idx2)
54: {
55: return(idx1->number - idx2->number);
56: }
57:
58: void sort_index(smb_t* smb)
59: {
60: ulong l;
61: idxrec_t* idx;
62:
63: printf("Sorting index... ");
64: if((idx=malloc(sizeof(idxrec_t)*smb->status.total_msgs))==NULL) {
65: perror("malloc");
66: return;
67: }
68:
69: rewind(smb->sid_fp);
70: for(l=0;l<smb->status.total_msgs;l++)
71: if(fread(&idx[l],sizeof(idxrec_t),1,smb->sid_fp)<1) {
72: perror("reading index");
73: break;
74: }
75:
76: qsort(idx,l,sizeof(idxrec_t)
77: ,(int(*)(const void*, const void*))compare_index);
78:
79: rewind(smb->sid_fp);
80: chsize(fileno(smb->sid_fp),0L); /* Truncate the index */
81:
82: printf("\nRe-writing index... \n");
83: smb->status.total_msgs=l;
84: for(l=0;l<smb->status.total_msgs;l++)
85: if(fwrite(&idx[l],sizeof(idxrec_t),1,smb->sid_fp)<1) {
86: perror("writing index");
87: break;
88: }
89:
90: free(idx);
91: printf("\n");
92: }
93:
94: void unlock_msgbase(void)
95: {
96: int i;
97: if(smb_islocked(&smb) && (i=smb_unlock(&smb))!=0)
98: printf("smb_unlock returned %d: %s\n",i,smb.last_error);
99: }
100:
101: int fixsmb(char* sub)
102: {
103: char* p;
104: char* text;
105: char c;
106: int i,w;
107: ulong l,length,size,n;
108: smbmsg_t msg;
109:
110: memset(&smb,0,sizeof(smb));
111:
112: SAFECOPY(smb.file,sub);
113:
114: if((p=getfext(smb.file))!=NULL && stricmp(p,".shd")==0)
115: *p=0; /* Chop off .shd extension, if supplied on command-line */
116:
117: printf("Opening %s\n",smb.file);
118:
119: if((i=smb_open(&smb))!=0) {
120: printf("smb_open returned %d: %s\n",i,smb.last_error);
121: exit(1);
122: }
123:
124: if((i=smb_lock(&smb))!=0) {
125: printf("smb_lock returned %d: %s\n",i,smb.last_error);
126: exit(1);
127: }
128:
129: if((i=smb_locksmbhdr(&smb))!=0) {
130: smb_close(&smb);
131: printf("smb_locksmbhdr returned %d: %s\n",i,smb.last_error);
132: exit(1);
133: }
134:
135: if((i=smb_getstatus(&smb))!=0) {
136: smb_unlocksmbhdr(&smb);
137: smb_close(&smb);
138: printf("smb_getstatus returned %d: %s\n",i,smb.last_error);
139: exit(1);
140: }
141:
142: if(!(smb.status.attr&SMB_HYPERALLOC)) {
143:
144: if((i=smb_open_ha(&smb))!=0) {
145: smb_close(&smb);
146: printf("smb_open_ha returned %d: %s\n",i,smb.last_error);
147: exit(1);
148: }
149:
150: if((i=smb_open_da(&smb))!=0) {
151: smb_close(&smb);
152: printf("smb_open_da returned %d: %s\n",i,smb.last_error);
153: exit(1);
154: }
155:
156: rewind(smb.sha_fp);
157: chsize(fileno(smb.sha_fp),0L); /* Truncate the header allocation file */
158: rewind(smb.sda_fp);
159: chsize(fileno(smb.sda_fp),0L); /* Truncate the data allocation file */
160: }
161:
162: rewind(smb.sid_fp);
163: chsize(fileno(smb.sid_fp),0L); /* Truncate the index */
164:
165:
166: if(!(smb.status.attr&SMB_HYPERALLOC)) {
167: length=filelength(fileno(smb.sdt_fp));
1.1.1.2 ! root 168: /* TODO: LE Only */
1.1 root 169: w=0;
170: for(l=0;l<length;l+=SDT_BLOCK_LEN) /* Init .SDA file to NULL */
171: fwrite(&w,2,1,smb.sda_fp);
172:
173: length=filelength(fileno(smb.shd_fp));
174: c=0;
175: for(l=0;l<length;l+=SHD_BLOCK_LEN) /* Init .SHD file to NULL */
176: fwrite(&c,1,1,smb.sha_fp);
177: } else
178: length=filelength(fileno(smb.shd_fp));
179:
180: n=0; /* messsage offset */
181: for(l=smb.status.header_offset;l<length;l+=size) {
182: size=SHD_BLOCK_LEN;
183: printf("\r%2lu%% ",(long)(100.0/((float)length/l)));
1.1.1.2 ! root 184: fflush(stdout);
1.1 root 185: msg.idx.offset=l;
186: if((i=smb_lockmsghdr(&smb,&msg))!=0) {
187: printf("\n(%06lX) smb_lockmsghdr returned %d:\n%s\n",l,i,smb.last_error);
188: continue;
189: }
190: i=smb_getmsghdr(&smb,&msg);
191: smb_unlockmsghdr(&smb,&msg);
192: if(i!=0) {
193: printf("\n(%06lX) smb_getmsghdr returned %d:\n%s\n",l,i,smb.last_error);
194: continue;
195: }
196: size=smb_hdrblocks(smb_getmsghdrlen(&msg))*SHD_BLOCK_LEN;
197: printf("#%-5lu (%06lX) %-25.25s ",msg.hdr.number,l,msg.from);
198:
1.1.1.2 ! root 199: if(smb_undelete)
! 200: msg.hdr.attr&=~MSG_DELETE;
! 201:
1.1 root 202: /* Create hash record */
203: if(msg.hdr.attr&MSG_DELETE)
204: text=NULL;
205: else
206: text=smb_getmsgtxt(&smb,&msg,GETMSGTXT_BODY_ONLY);
207: i=smb_hashmsg(&smb,&msg,text,TRUE /* update */);
208: if(i!=SMB_SUCCESS)
209: printf("!ERROR %d hashing message\n", i);
210: if(text!=NULL)
211: free(text);
212:
213: /* Index the header */
214: if(msg.hdr.attr&MSG_DELETE)
215: printf("Not indexing deleted message\n");
216: else if(msg.hdr.number==0)
217: printf("Not indexing invalid message number (0)!\n");
218: else {
219: msg.offset=n;
220: if(renumber)
221: msg.hdr.number=n+1;
222: if(msg.hdr.netattr&MSG_INTRANSIT) {
223: printf("Removing 'in transit' attribute\n");
224: msg.hdr.netattr&=~MSG_INTRANSIT;
225: }
226: if((i=smb_putmsg(&smb,&msg))!=0) {
227: printf("\nsmb_putmsg returned %d: %s\n",i,smb.last_error);
228: continue;
229: }
230: n++;
231: }
232:
233: if(!(smb.status.attr&SMB_HYPERALLOC)) {
234: /**************************/
235: /* Allocate header blocks */
236: /**************************/
237: fseek(smb.sha_fp,(l-smb.status.header_offset)/SHD_BLOCK_LEN,SEEK_SET);
238: if(msg.hdr.attr&MSG_DELETE) c=0; /* mark as free */
239: else c=1; /* or allocated */
240:
241: for(i=0;i<(int)(size/SHD_BLOCK_LEN);i++)
242: fputc(c,smb.sha_fp);
243:
244: /************************/
245: /* Allocate data blocks */
246: /************************/
247:
248: if(!(msg.hdr.attr&MSG_DELETE))
249: smb_incmsg_dfields(&smb,&msg,1);
250: }
251:
252: smb_freemsgmem(&msg);
253: }
254: printf("\r%79s\r100%%\n","");
255: smb.status.total_msgs=n;
256: if(renumber)
257: smb.status.last_msg=n;
258: else
259: sort_index(&smb);
260: printf("Saving message base status (%lu total messages).\n",n);
261: if((i=smb_putstatus(&smb))!=0)
262: printf("\nsmb_putstatus returned %d: %s\n",i,smb.last_error);
263: smb_unlocksmbhdr(&smb);
264: printf("Closing message base.\n");
265: smb_close(&smb);
266: unlock_msgbase();
267: printf("Done.\n");
268: return(0);
269: }
270:
271: int main(int argc, char **argv)
272: {
273: char revision[16];
274: int i;
275: str_list_t list;
276:
1.1.1.2 ! root 277: sscanf("$Revision: 1.34 $", "%*s %s", revision);
1.1 root 278:
279: printf("\nFIXSMB v2.10-%s (rev %s) SMBLIB %s - Rebuild Synchronet Message Base\n\n"
280: ,PLATFORM_DESC,revision,smb_lib_ver());
281:
282: list=strListInit();
283:
284: for(i=1;i<argc;i++) {
285: if(argv[i][0]=='-') {
286: if(!stricmp(argv[i],"-renumber"))
287: renumber=TRUE;
1.1.1.2 ! root 288: else if(!stricmp(argv[i],"-undelete"))
! 289: smb_undelete=TRUE;
1.1 root 290: } else
291: strListPush(&list,argv[i]);
292: }
293:
294: if(!strListCount(list)) {
295: printf(usage);
296: exit(1);
297: }
298:
299: atexit(unlock_msgbase);
300:
301: for(i=0;list[i]!=NULL;i++)
302: fixsmb(list[i]);
303:
304: return(0);
305: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.