home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
RENUM.ZIP
/
RENUM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-10
|
17KB
|
509 lines
/************************************************************************
* *
* RENUM.C - FidoNet *.MSG Renumberer *
* *
* (c) Copyright 1991 by Ron Bemis, All Rights Reserved *
* *
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define INCL_DOSFILEMGR
#include <os2.h>
#define MAX_MSGS 2048
static const unsigned char version[] = "V1.3";
unsigned short msglist[MAX_MSGS];
unsigned short msgcount;
/************************************************************************
* *
* qsort() function to compare two items *
* *
************************************************************************/
static int compare(unsigned short *x1, unsigned short *x2) {
if (*x1 > *x2) {
return(1);
}
if (*x1 < *x2) {
return(-1);
}
return(0);
} /* compare() */
/************************************************************************
* *
* relink() function to find determine new message number *
* *
************************************************************************/
static int relink(unsigned short *num) {
unsigned i;
/* if no existing link, don't change it */
if (!*num) {
return(0);
}
/* adjust the link if possible */
for (i=0; i<msgcount; i++) {
if (msglist[i] == *num) {
if (*num != i+1) {
*num = i+1;
return(1);
} else {
return(0);
}
}
}
/* if higher than highest message, set it to the highest */
if (*num > msglist[msgcount-1]) {
*num = msgcount;
return(1);
}
/* remove the link if nothing found */
*num = 0;
return(1);
} /* relink() */
/************************************************************************
* *
* renumber a message area *
* *
************************************************************************/
renum(unsigned char *dirptr, unsigned short savelow, unsigned short savemax) {
unsigned i;
unsigned short done;
unsigned short highest = 0;
static char buffer[80];
static char newname[80];
HDIR hdir = HDIR_SYSTEM;
USHORT SearchCount;
FILEFINDBUF findbuf;
HFILE hf;
USHORT action;
ULONG newloc;
USHORT count;
ULONG filesize;
unsigned short msgnum;
struct {
unsigned short himsg;
unsigned short lastmsg;
} opus;
struct {
unsigned short reply;
unsigned short attrib;
unsigned short up;
} info;
printf("\nRenumbering %s\n",dirptr);
sprintf(buffer,"%s\\*.MSG",dirptr);
msgcount = 0;
SearchCount = 1;
done = DosFindFirst(buffer,&hdir,FILE_NORMAL,&findbuf,sizeof(findbuf),
&SearchCount,0L);
if (done) {
printf("No messages\n");
return(0);
}
while (!done) {
i = (signed)atoi(findbuf.achName);
sprintf(buffer,"%u.MSG",i);
/* exclude 0.MSG and funny files */
if (i && !strcmp(findbuf.achName,buffer)) {
if (msgcount+1 >= MAX_MSGS) {
printf("Can't handle over %u messages\n",MAX_MSGS);
break;
}
msglist[msgcount] = i;
if (i > highest) {
highest = i;
}
msgcount++;
}
SearchCount = 1;
done = DosFindNext(hdir,&findbuf,sizeof(findbuf),&SearchCount);
}
DosFindClose(hdir);
if (!highest) {
return(1);
}
printf("%u message%s\n",msgcount,(msgcount==1)?"":"s");
qsort(&msglist,msgcount,sizeof(msglist[0]),compare);
if ((msglist[msgcount-1] == msgcount) &&
(msgcount <= savemax)) {
printf("Renumbering not needed\n");
return(0);
}
while (msgcount > savemax) {
printf("Deleting msg #%u\r",msglist[savelow]);
sprintf(buffer,"%s\\%u.MSG",dirptr,msglist[savelow]);
if (DosDelete(buffer,0L)) {
printf("Can't delete %s\n",buffer);
}
msgcount--;
for (i=savelow; i<msgcount; i++) {
msglist[i] = msglist[i+1];
}
}
printf("\n");
for (i=0; i<msgcount; i++) {
if (msglist[i] != i+1) {
printf("Renaming msg #%u -> #%u\r",msglist[i],i+1);
sprintf(buffer,"%s\\%u.MSG",dirptr,msglist[i]);
sprintf(newname,"%s\\%u.MSG",dirptr,i+1);
if (DosMove(buffer,newname,0L)) {
printf("Can't rename %s to %s\n",buffer,newname);
}
}
}
printf("\n");
/****************************************************************
* *
* Fix up reply links *
* *
****************************************************************/
for (i=0; i<msgcount; i++) {
sprintf(buffer,"%s\\%u.MSG",dirptr,i+1);
if (DosOpen(buffer,&hf,&action,0L,FILE_NORMAL,FILE_OPEN,
OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYWRITE,0L)) {
printf("Can't open %s\n",buffer);
continue;
}
if (DosChgFilePtr(hf,184L,FILE_BEGIN,&newloc) ||
(newloc != 184L)) {
printf("Can't seek in %s\n",buffer);
DosClose(hf);
continue;
}
printf("Reading %s\r",buffer);
if (DosRead(hf,&info,sizeof(info),&count) ||
(count != sizeof(info))) {
printf("Can't read %s\n",buffer);
DosClose(hf);
continue;
}
if (relink(&info.reply) | relink(&info.up)) {
if (DosChgFilePtr(hf,184L,FILE_BEGIN,&newloc) ||
(newloc != 184L)) {
printf("Can't re-seek in %s\n",buffer);
DosClose(hf);
continue;
}
printf("Writing %s\r",buffer);
if (DosWrite(hf,&info,sizeof(info),&count) ||
(count != sizeof(info))) {
printf("Can't write to %s\n",buffer);
DosClose(hf);
continue;
}
}
if (DosClose(hf)) {
printf("Can't close %s\n",buffer);
continue;
}
}
printf("\n");
/****************************************************************
* *
* Fix up LASTREAD if it exists *
* *
****************************************************************/
for (;;) {
sprintf(buffer,"%s\\LASTREAD",dirptr);
if (DosOpen(buffer,&hf,&action,0L,FILE_NORMAL,FILE_OPEN,
OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYWRITE,0L)) {
break;
}
printf("Fixing %s\r",buffer);
if (DosChgFilePtr(hf,0L,FILE_END,&filesize)) {
printf("Can't seek to end of %s\n",buffer);
DosClose(hf);
break;
}
for (i=0; i<(unsigned)filesize; i+=2) {
if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
(newloc != (unsigned long)i)) {
printf("Can't seek in %s\n",buffer);
break;
}
if (DosRead(hf,&msgnum,sizeof(msgnum),&count) ||
(count != sizeof(msgnum))) {
printf("Can't read %s\n",buffer);
break;
}
if (relink(&msgnum)) {
if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
(newloc != (unsigned long)i)) {
printf("Can't re-seek in %s\n",buffer);
break;
}
if (DosWrite(hf,&msgnum,sizeof(msgnum),&count) ||
(count != sizeof(msgnum))) {
printf("Can't write to %s\n",buffer);
break;
}
}
}
if (DosClose(hf)) {
printf("Can't close %s\n",buffer);
break;
}
printf("\n");
break;
}
/****************************************************************
* *
* Fix up LASTREAD.BBS (MAXIMUS) if it exists *
* *
****************************************************************/
for (;;) {
sprintf(buffer,"%s\\LASTREAD.BBS",dirptr);
if (DosOpen(buffer,&hf,&action,0L,FILE_NORMAL,FILE_OPEN,
OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYWRITE,0L)) {
break;
}
printf("Fixing %s\r",buffer);
if (DosChgFilePtr(hf,0L,FILE_END,&filesize)) {
printf("Can't seek to end of %s\n",buffer);
DosClose(hf);
break;
}
for (i=0; i<(unsigned)filesize; i+=2) {
if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
(newloc != (unsigned long)i)) {
printf("Can't seek in %s\n",buffer);
break;
}
if (DosRead(hf,&msgnum,sizeof(msgnum),&count) ||
(count != sizeof(msgnum))) {
printf("Can't read %s\n",buffer);
break;
}
if (relink(&msgnum)) {
if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
(newloc != (unsigned long)i)) {
printf("Can't re-seek in %s\n",buffer);
break;
}
if (DosWrite(hf,&msgnum,sizeof(msgnum),&count) ||
(count != sizeof(msgnum))) {
printf("Can't write to %s\n",buffer);
break;
}
}
}
if (DosClose(hf)) {
printf("Can't close %s\n",buffer);
break;
}
printf("\n");
break;
}
/****************************************************************
* *
* Fix up LREAD.DAT (OPUS) if it exists *
* *
****************************************************************/
for (;;) {
sprintf(buffer,"%s\\LREAD.DAT",dirptr);
if (DosOpen(buffer,&hf,&action,0L,FILE_NORMAL,FILE_OPEN,
OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYWRITE,0L)) {
break;
}
printf("Fixing %s\r",buffer);
if (DosChgFilePtr(hf,0L,FILE_END,&filesize)) {
printf("Can't seek to end of %s\n",buffer);
DosClose(hf);
break;
}
for (i=4; i<(unsigned)filesize; i+=8) {
if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
(newloc != (unsigned long)i)) {
printf("Can't seek in %s\n",buffer);
break;
}
if (DosRead(hf,&opus,sizeof(opus),&count) ||
(count != sizeof(opus))) {
printf("Can't read %s\n",buffer);
break;
}
if (relink(&opus.himsg) | relink(&opus.lastmsg)) {
if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
(newloc != (unsigned long)i)) {
printf("Can't re-seek in %s\n",buffer);
break;
}
if (DosWrite(hf,&opus,sizeof(opus),&count) ||
(count != sizeof(opus))) {
printf("Can't write to %s\n",buffer);
break;
}
}
}
if (DosClose(hf)) {
printf("Can't close %s\n",buffer);
break;
}
printf("\n");
break;
}
} /* renum() */
/************************************************************************
* *
* main function *
* *
************************************************************************/
main (int argc, char *argv[]) {
unsigned savelow = 1;
unsigned savemax = (unsigned)-1;
unsigned i;
static unsigned char line[300];
static unsigned char dir[80];
FILE *fptr;
/* check arguments */
if (argc < 2) {
printf("\nRENUM %s Copyright 1991 by Ron Bemis\n",version);
printf("From Nibbles & Bytes, Node 1:124/1113, 214-231-3841\n");
printf("Created %s at %s\n\n",__DATE__,__TIME__);
printf("Usage: RENUM [-N save1 save2] [directory...] [+AREAS.BBS]\n");
return(1);
}
for (argv++, argc--; argc; argv++, argc--) {
if ((argv[0][0] == '-') || (argv[0][0] == '/')) {
switch (toupper(argv[0][1])) {
case 'N':
if (argc >= 3) {
savelow = atoi(argv[1]);
savemax = atoi(argv[2]);
if (!savelow) {
printf("You must save at least 1 low message\n");
return(1);
}
if (!savemax) {
printf("Invalid maximum message number\n");
return(1);
}
if (savelow > savemax) {
savemax = savelow;
}
argv += 2;
argc -= 2;
}
break;
default:
printf("Unknown option '%s'\n",argv[0]);
return(1);
}
} else if (argv[0][0] == '+') {
printf("\nReading %s\n",argv[0]+1);
fptr = fopen(argv[0]+1,"rt");
if (!fptr) {
printf("Can't find %s\n",argv[0]+1);
return(1);
}
if (!fgets(line,sizeof(line),fptr)) {
printf("Can't read %s\n",argv[0]+1);
fclose(fptr);
return(1);
}
while (fgets(line,sizeof(line),fptr)) {
i = line[0];
/* ignore comments, blank lines, and control info */
if ((i == ';') || (i == '\n') || (i == '-')) {
continue;
}
i = sscanf(line,"%s",dir);
if (i != 1) {
printf("Invalid line in %s:\n%s",argv[0]+1,line);
continue;
}
/* strip flags from front of directory */
while (*dir && !isalpha(*dir)) {
strcpy(dir,dir+1);
}
/* make sure there's something left */
if (!*dir) {
printf("Invalid directory in %s:\n%s\n",argv[0]+1,line);
continue;
}
renum(dir,savelow,savemax);
}
fclose(fptr);
} else {
renum(argv[0],savelow,savemax);
}
}
} /* main() */