home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / RENUM.ZIP / RENUM.C < prev    next >
C/C++ Source or Header  |  1991-09-10  |  17KB  |  509 lines

  1. /************************************************************************
  2. *                                                                       *
  3. *       RENUM.C - FidoNet *.MSG Renumberer                              *
  4. *                                                                       *
  5. *       (c) Copyright 1991 by Ron Bemis, All Rights Reserved            *
  6. *                                                                       *
  7. ************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #define INCL_DOSFILEMGR
  14. #include <os2.h>
  15.  
  16. #define MAX_MSGS 2048
  17.  
  18. static const unsigned char version[] = "V1.3";
  19. unsigned short msglist[MAX_MSGS];
  20. unsigned short msgcount;
  21.  
  22. /************************************************************************
  23. *                                                                       *
  24. *       qsort() function to compare two items                           *
  25. *                                                                       *
  26. ************************************************************************/
  27.  
  28. static int compare(unsigned short *x1, unsigned short *x2) {
  29.  
  30.     if (*x1 > *x2) {
  31.         return(1);
  32.     }
  33.  
  34.     if (*x1 < *x2) {
  35.         return(-1);
  36.     }
  37.  
  38.     return(0);
  39.  
  40. }   /* compare() */
  41.  
  42. /************************************************************************
  43. *                                                                       *
  44. *       relink() function to find determine new message number          *
  45. *                                                                       *
  46. ************************************************************************/
  47.  
  48. static int relink(unsigned short *num) {
  49.  
  50.     unsigned i;
  51.  
  52.     /* if no existing link, don't change it */
  53.     if (!*num) {
  54.         return(0);
  55.     }
  56.  
  57.     /* adjust the link if possible */
  58.     for (i=0; i<msgcount; i++) {
  59.         if (msglist[i] == *num) {
  60.             if (*num != i+1) {
  61.                 *num = i+1;
  62.                 return(1);
  63.             } else {
  64.                 return(0);
  65.             }
  66.         }
  67.     }
  68.  
  69.     /* if higher than highest message, set it to the highest */
  70.     if (*num > msglist[msgcount-1]) {
  71.         *num = msgcount;
  72.         return(1);
  73.     }
  74.  
  75.     /* remove the link if nothing found */
  76.     *num = 0;
  77.     return(1);
  78.  
  79. }   /* relink() */
  80.  
  81. /************************************************************************
  82. *                                                                       *
  83. *       renumber a message area                                         *
  84. *                                                                       *
  85. ************************************************************************/
  86.  
  87. renum(unsigned char *dirptr, unsigned short savelow, unsigned short savemax) {
  88.  
  89.     unsigned i;
  90.     unsigned short done;
  91.     unsigned short highest = 0;
  92.     static char buffer[80];
  93.     static char newname[80];
  94.     HDIR hdir = HDIR_SYSTEM;
  95.     USHORT SearchCount;
  96.     FILEFINDBUF findbuf;
  97.     HFILE hf;
  98.     USHORT action;
  99.     ULONG newloc;
  100.     USHORT count;
  101.     ULONG filesize;
  102.     unsigned short msgnum;
  103.     struct {
  104.         unsigned short himsg;
  105.         unsigned short lastmsg;
  106.     } opus;
  107.     struct {
  108.         unsigned short reply;
  109.         unsigned short attrib;
  110.         unsigned short up;
  111.     } info;
  112.  
  113.     printf("\nRenumbering %s\n",dirptr);
  114.     sprintf(buffer,"%s\\*.MSG",dirptr);
  115.  
  116.     msgcount = 0;
  117.     SearchCount = 1;
  118.     done = DosFindFirst(buffer,&hdir,FILE_NORMAL,&findbuf,sizeof(findbuf),
  119.                      &SearchCount,0L);
  120.  
  121.     if (done) {
  122.         printf("No messages\n");
  123.         return(0);
  124.     }
  125.  
  126.     while (!done) {
  127.  
  128.         i = (signed)atoi(findbuf.achName);
  129.         sprintf(buffer,"%u.MSG",i);
  130.  
  131.         /* exclude 0.MSG and funny files */
  132.         if (i && !strcmp(findbuf.achName,buffer)) {
  133.  
  134.             if (msgcount+1 >= MAX_MSGS) {
  135.                 printf("Can't handle over %u messages\n",MAX_MSGS);
  136.                 break;
  137.             }
  138.  
  139.             msglist[msgcount] = i;
  140.             if (i > highest) {
  141.                 highest = i;
  142.             }
  143.  
  144.             msgcount++;
  145.  
  146.         }
  147.  
  148.         SearchCount = 1;
  149.         done = DosFindNext(hdir,&findbuf,sizeof(findbuf),&SearchCount);
  150.  
  151.     }
  152.  
  153.     DosFindClose(hdir);
  154.  
  155.     if (!highest) {
  156.         return(1);
  157.     }
  158.  
  159.     printf("%u message%s\n",msgcount,(msgcount==1)?"":"s");
  160.  
  161.     qsort(&msglist,msgcount,sizeof(msglist[0]),compare);
  162.  
  163.     if ((msglist[msgcount-1] == msgcount) &&
  164.         (msgcount <= savemax)) {
  165.         printf("Renumbering not needed\n");
  166.         return(0);
  167.     }
  168.  
  169.     while (msgcount > savemax) {
  170.         printf("Deleting msg #%u\r",msglist[savelow]);
  171.         sprintf(buffer,"%s\\%u.MSG",dirptr,msglist[savelow]);
  172.         if (DosDelete(buffer,0L)) {
  173.             printf("Can't delete %s\n",buffer);
  174.         }
  175.         msgcount--;
  176.         for (i=savelow; i<msgcount; i++) {
  177.             msglist[i] = msglist[i+1];
  178.         }
  179.     }
  180.     printf("\n");
  181.  
  182.     for (i=0; i<msgcount; i++) {
  183.         if (msglist[i] != i+1) {
  184.             printf("Renaming msg #%u -> #%u\r",msglist[i],i+1);
  185.             sprintf(buffer,"%s\\%u.MSG",dirptr,msglist[i]);
  186.             sprintf(newname,"%s\\%u.MSG",dirptr,i+1);
  187.             if (DosMove(buffer,newname,0L)) {
  188.                 printf("Can't rename %s to %s\n",buffer,newname);
  189.             }
  190.         }
  191.     }
  192.     printf("\n");
  193.  
  194.     /****************************************************************
  195.     *                                                               *
  196.     *   Fix up reply links                                          *
  197.     *                                                               *
  198.     ****************************************************************/
  199.  
  200.     for (i=0; i<msgcount; i++) {
  201.         sprintf(buffer,"%s\\%u.MSG",dirptr,i+1);
  202.         if (DosOpen(buffer,&hf,&action,0L,FILE_NORMAL,FILE_OPEN,
  203.                     OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYWRITE,0L)) {
  204.             printf("Can't open %s\n",buffer);
  205.             continue;
  206.         }
  207.         if (DosChgFilePtr(hf,184L,FILE_BEGIN,&newloc) ||
  208.             (newloc != 184L)) {
  209.             printf("Can't seek in %s\n",buffer);
  210.             DosClose(hf);
  211.             continue;
  212.         }
  213.         printf("Reading %s\r",buffer);
  214.         if (DosRead(hf,&info,sizeof(info),&count) ||
  215.             (count != sizeof(info))) {
  216.             printf("Can't read %s\n",buffer);
  217.             DosClose(hf);
  218.             continue;
  219.         }
  220.         if (relink(&info.reply) | relink(&info.up)) {
  221.             if (DosChgFilePtr(hf,184L,FILE_BEGIN,&newloc) ||
  222.                 (newloc != 184L)) {
  223.                 printf("Can't re-seek in %s\n",buffer);
  224.                 DosClose(hf);
  225.                 continue;
  226.             }
  227.             printf("Writing %s\r",buffer);
  228.             if (DosWrite(hf,&info,sizeof(info),&count) ||
  229.                 (count != sizeof(info))) {
  230.                 printf("Can't write to %s\n",buffer);
  231.                 DosClose(hf);
  232.                 continue;
  233.             }
  234.         }
  235.         if (DosClose(hf)) {
  236.             printf("Can't close %s\n",buffer);
  237.             continue;
  238.         }
  239.     }
  240.     printf("\n");
  241.  
  242.     /****************************************************************
  243.     *                                                               *
  244.     *   Fix up LASTREAD if it exists                                *
  245.     *                                                               *
  246.     ****************************************************************/
  247.  
  248.     for (;;) {
  249.  
  250.         sprintf(buffer,"%s\\LASTREAD",dirptr);
  251.         if (DosOpen(buffer,&hf,&action,0L,FILE_NORMAL,FILE_OPEN,
  252.                     OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYWRITE,0L)) {
  253.             break;
  254.         }
  255.         printf("Fixing %s\r",buffer);
  256.         if (DosChgFilePtr(hf,0L,FILE_END,&filesize)) {
  257.             printf("Can't seek to end of %s\n",buffer);
  258.             DosClose(hf);
  259.             break;
  260.         }
  261.         for (i=0; i<(unsigned)filesize; i+=2) {
  262.             if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
  263.                 (newloc != (unsigned long)i)) {
  264.                 printf("Can't seek in %s\n",buffer);
  265.                 break;
  266.             }
  267.             if (DosRead(hf,&msgnum,sizeof(msgnum),&count) ||
  268.                 (count != sizeof(msgnum))) {
  269.                 printf("Can't read %s\n",buffer);
  270.                 break;
  271.             }
  272.             if (relink(&msgnum)) {
  273.                 if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
  274.                     (newloc != (unsigned long)i)) {
  275.                     printf("Can't re-seek in %s\n",buffer);
  276.                     break;
  277.                 }
  278.                 if (DosWrite(hf,&msgnum,sizeof(msgnum),&count) ||
  279.                     (count != sizeof(msgnum))) {
  280.                     printf("Can't write to %s\n",buffer);
  281.                     break;
  282.                 }
  283.             }
  284.         }
  285.         if (DosClose(hf)) {
  286.             printf("Can't close %s\n",buffer);
  287.             break;
  288.         }
  289.         printf("\n");
  290.         break;
  291.     }
  292.  
  293.     /****************************************************************
  294.     *                                                               *
  295.     *   Fix up LASTREAD.BBS (MAXIMUS) if it exists                  *
  296.     *                                                               *
  297.     ****************************************************************/
  298.  
  299.     for (;;) {
  300.  
  301.         sprintf(buffer,"%s\\LASTREAD.BBS",dirptr);
  302.         if (DosOpen(buffer,&hf,&action,0L,FILE_NORMAL,FILE_OPEN,
  303.                     OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYWRITE,0L)) {
  304.             break;
  305.         }
  306.         printf("Fixing %s\r",buffer);
  307.         if (DosChgFilePtr(hf,0L,FILE_END,&filesize)) {
  308.             printf("Can't seek to end of %s\n",buffer);
  309.             DosClose(hf);
  310.             break;
  311.         }
  312.         for (i=0; i<(unsigned)filesize; i+=2) {
  313.             if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
  314.                 (newloc != (unsigned long)i)) {
  315.                 printf("Can't seek in %s\n",buffer);
  316.                 break;
  317.             }
  318.             if (DosRead(hf,&msgnum,sizeof(msgnum),&count) ||
  319.                 (count != sizeof(msgnum))) {
  320.                 printf("Can't read %s\n",buffer);
  321.                 break;
  322.             }
  323.             if (relink(&msgnum)) {
  324.                 if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
  325.                     (newloc != (unsigned long)i)) {
  326.                     printf("Can't re-seek in %s\n",buffer);
  327.                     break;
  328.                 }
  329.                 if (DosWrite(hf,&msgnum,sizeof(msgnum),&count) ||
  330.                     (count != sizeof(msgnum))) {
  331.                     printf("Can't write to %s\n",buffer);
  332.                     break;
  333.                 }
  334.             }
  335.         }
  336.         if (DosClose(hf)) {
  337.             printf("Can't close %s\n",buffer);
  338.             break;
  339.         }
  340.         printf("\n");
  341.         break;
  342.     }
  343.  
  344.     /****************************************************************
  345.     *                                                               *
  346.     *   Fix up LREAD.DAT (OPUS) if it exists                        *
  347.     *                                                               *
  348.     ****************************************************************/
  349.  
  350.     for (;;) {
  351.  
  352.         sprintf(buffer,"%s\\LREAD.DAT",dirptr);
  353.         if (DosOpen(buffer,&hf,&action,0L,FILE_NORMAL,FILE_OPEN,
  354.                     OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYWRITE,0L)) {
  355.             break;
  356.         }
  357.         printf("Fixing %s\r",buffer);
  358.         if (DosChgFilePtr(hf,0L,FILE_END,&filesize)) {
  359.             printf("Can't seek to end of %s\n",buffer);
  360.             DosClose(hf);
  361.             break;
  362.         }
  363.         for (i=4; i<(unsigned)filesize; i+=8) {
  364.             if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
  365.                 (newloc != (unsigned long)i)) {
  366.                 printf("Can't seek in %s\n",buffer);
  367.                 break;
  368.             }
  369.             if (DosRead(hf,&opus,sizeof(opus),&count) ||
  370.                 (count != sizeof(opus))) {
  371.                 printf("Can't read %s\n",buffer);
  372.                 break;
  373.             }
  374.             if (relink(&opus.himsg) | relink(&opus.lastmsg)) {
  375.                 if (DosChgFilePtr(hf,(unsigned long)i,FILE_BEGIN,&newloc) ||
  376.                     (newloc != (unsigned long)i)) {
  377.                     printf("Can't re-seek in %s\n",buffer);
  378.                     break;
  379.                 }
  380.                 if (DosWrite(hf,&opus,sizeof(opus),&count) ||
  381.                     (count != sizeof(opus))) {
  382.                     printf("Can't write to %s\n",buffer);
  383.                     break;
  384.                 }
  385.             }
  386.         }
  387.         if (DosClose(hf)) {
  388.             printf("Can't close %s\n",buffer);
  389.             break;
  390.         }
  391.         printf("\n");
  392.         break;
  393.     }
  394.  
  395. }   /* renum() */
  396.  
  397. /************************************************************************
  398. *                                                                       *
  399. *       main function                                                   *
  400. *                                                                       *
  401. ************************************************************************/
  402.  
  403. main (int argc, char *argv[]) {
  404.  
  405.     unsigned savelow = 1;
  406.     unsigned savemax = (unsigned)-1;
  407.     unsigned i;
  408.     static unsigned char line[300];
  409.     static unsigned char dir[80];
  410.     FILE *fptr;
  411.  
  412.     /* check arguments */
  413.     if (argc < 2) {
  414.         printf("\nRENUM %s Copyright 1991 by Ron Bemis\n",version);
  415.         printf("From Nibbles & Bytes, Node 1:124/1113, 214-231-3841\n");
  416.         printf("Created %s at %s\n\n",__DATE__,__TIME__);
  417.         printf("Usage: RENUM [-N save1 save2] [directory...] [+AREAS.BBS]\n");
  418.         return(1);
  419.     }
  420.  
  421.     for (argv++, argc--; argc; argv++, argc--) {
  422.  
  423.         if ((argv[0][0] == '-') || (argv[0][0] == '/')) {
  424.  
  425.             switch (toupper(argv[0][1])) {
  426.  
  427.                 case 'N':
  428.                     if (argc >= 3) {
  429.                         savelow = atoi(argv[1]);
  430.                         savemax = atoi(argv[2]);
  431.                         if (!savelow) {
  432.                             printf("You must save at least 1 low message\n");
  433.                             return(1);
  434.                         }
  435.                         if (!savemax) {
  436.                             printf("Invalid maximum message number\n");
  437.                             return(1);
  438.                         }
  439.                         if (savelow > savemax) {
  440.                             savemax = savelow;
  441.                         }
  442.                         argv += 2;
  443.                         argc -= 2;
  444.                     }
  445.                     break;
  446.  
  447.                 default:
  448.                     printf("Unknown option '%s'\n",argv[0]);
  449.                     return(1);
  450.             }
  451.  
  452.         } else if (argv[0][0] == '+') {
  453.  
  454.             printf("\nReading %s\n",argv[0]+1);
  455.  
  456.             fptr = fopen(argv[0]+1,"rt");
  457.             if (!fptr) {
  458.                 printf("Can't find %s\n",argv[0]+1);
  459.                 return(1);
  460.             }
  461.  
  462.             if (!fgets(line,sizeof(line),fptr)) {
  463.                 printf("Can't read %s\n",argv[0]+1);
  464.                 fclose(fptr);
  465.                 return(1);
  466.             }
  467.  
  468.             while (fgets(line,sizeof(line),fptr)) {
  469.  
  470.                 i = line[0];
  471.  
  472.                 /* ignore comments, blank lines, and control info */
  473.                 if ((i == ';') || (i == '\n') || (i == '-')) {
  474.                     continue;
  475.                 }
  476.  
  477.                 i = sscanf(line,"%s",dir);
  478.                 if (i != 1) {
  479.                     printf("Invalid line in %s:\n%s",argv[0]+1,line);
  480.                     continue;
  481.                 }
  482.  
  483.                 /* strip flags from front of directory */
  484.                 while (*dir && !isalpha(*dir)) {
  485.                     strcpy(dir,dir+1);
  486.                 }
  487.  
  488.                 /* make sure there's something left */
  489.                 if (!*dir) {
  490.                     printf("Invalid directory in %s:\n%s\n",argv[0]+1,line);
  491.                     continue;
  492.                 }
  493.  
  494.                 renum(dir,savelow,savemax);
  495.  
  496.             }
  497.             fclose(fptr);
  498.  
  499.  
  500.         } else {
  501.  
  502.             renum(argv[0],savelow,savemax);
  503.  
  504.         }
  505.  
  506.     }
  507.  
  508. }   /* main() */
  509.