home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / pfixp10.lzh / POSTFIX.C < prev    next >
C/C++ Source or Header  |  1993-08-22  |  9KB  |  354 lines

  1. /*
  2.  
  3. POSTFIX -- Restores lastread pointers after SQFIX
  4.  
  5. Version 1.0  (10/12/92)
  6.  
  7. Written by Bob Quinlan of Austin, Texas, USA
  8. Sysop of Red October at 512-834-2593 (1:382/111)
  9.  
  10. Copyright 1992 by Bob Quinlan
  11.  
  12. Compatible with Maximus 2.00 and 2.01
  13.  
  14.  
  15. This program is intended to be run after SQFIX and various other
  16. utilities that reset the lastread pointers.  It reads a pair of files
  17. (areaname.PFH and areaname.PFL) generated by PREFIX to determine what
  18. lastread pointers assignments to restore.
  19.  
  20. It uses arrival datestamps to determine where to restore the lastread
  21. pointers.  This will usually put the lastread pointers back on the exact
  22. messages where they were originally, but it may occasionally be off by a
  23. few messages.
  24.  
  25. See the instruction to PREFIX before using POSTFIX.
  26.  
  27. POSTFIX must be followed by the name of a message area.  It will attempt
  28. to restore the lastread pointers for that area.  When it is finished it
  29. will delete the .PF? files created by PREFIX.
  30.  
  31.  
  32. POSTFIX returns ERRORLEVEL 0 after a successful run.  ERRORLEVEL 1 is
  33. returned to indicate an error.
  34.  
  35. NOTICE:  You may use, copy, and distribute this program freely as long
  36. as you insure that both the executable and the documentation (.DOC)
  37. files are included in the distribution package.  The source code does
  38. not need to be included.  You may modify this program and document, so
  39. long as reasonable credit is given to the original author if a
  40. substantial portion of the original remains intact.  The author is not
  41. responsible for any losses which may occur either directly or indirectly
  42. as a result of using this program.
  43.  
  44. This program uses the Squish MsgAPI and the Maximus structures written
  45. by Scott J. Dudley.  "Squish" is a trademark of Scott J. Dudley.
  46.  
  47. HISTORY:
  48. Version 1.0  (10/12/92) -- Original release.  Written in Borland C.
  49.  
  50. Large memory model
  51.  
  52. OS/2 version (8/22/93) -- Ported using IBM's C SET/2 by Richard Butler
  53.                         - no code changes made to POSTFIX.C
  54. */
  55.  
  56. /* Needed for use with MSGAPI modified for C SET/2 */
  57.  
  58. #define __386__
  59. #define __MSC__
  60. #define _MSC_VER 600
  61. #define OS_2
  62. #define msgapierr _msgapierr
  63.  
  64. /* end */
  65.  
  66. #include <ctype.h>
  67. #include <errno.h>
  68. #include <fcntl.h>
  69. #include <io.h>
  70. /* #include <mem.h>
  71.    #include <dos.h */
  72. #include <share.h>
  73. #include <stdio.h>
  74. #include <stdlib.h>
  75. #include <string.h>
  76. #include <sys\stat.h>
  77. #include <sys\types.h>
  78. #include "prog.h"     /* From MsgAPI by Scott J. Dudley modified for C SET/2 */
  79. #include "alc.h"      /* From MsgAPI by Scott J. Dudley modified for C SET/2 */
  80. #include "msgapi.h"   /* From MsgAPI by Scott J. Dudley modified for C SET/2 */
  81. #include "mstruct.h"  /* Maximus structures by Scott J. Dudley: modified
  82.                          to avoid duplicate definitions of datestamps  */
  83.  
  84. #define MAXLINE     (128)
  85. #define MAXNAME     (36)
  86.  
  87.  
  88. int stampcmp(struct _stamp *ds1, struct _stamp *ds2);
  89.  
  90.  
  91. typedef struct
  92.     {
  93.     struct _stamp stamp;
  94.     UMSGID umsgid;
  95.     } MSG_DATA;
  96.  
  97.  
  98. int main(int argc, char *argv[])
  99. {
  100. struct _area arearef;
  101. XMSG   xmsg;
  102. MSG    *area;
  103. MSGH   *msg;
  104. UMSGID uid;
  105. struct _minf mi;
  106. UMSGID umsgid;
  107. dword  msgn;
  108. dword  match;
  109. int    exact;
  110.  
  111. char   msgpath[MAXLINE];
  112. char   stamppath[MAXLINE];
  113. FILE   *stamp_fp;
  114. char   lastmsgnpath[MAXLINE];
  115. FILE   *lastmsgn_fp;
  116. char   lastumsgidpath[MAXLINE];
  117. FILE   *lastumsgid_fp;
  118.  
  119. long   messages;
  120. MSG_DATA *new;
  121. long   stamps;
  122. struct _stamp *old;
  123. UMSGID *msgindex;
  124.  
  125. char   line[MAXLINE];
  126. char   *ch;
  127. int    i, j;
  128.  
  129.  
  130. /*************/
  131. /*  POSTFIX  */
  132. /*************/
  133.  
  134. printf("POSTFIX/2 1.0 -- Copyright 1992 by Bob Quinlan (10/12/92)\n");
  135.  
  136. if (argc == 2)
  137.     {
  138.     strncpy(msgpath, argv[1], MAXLINE);
  139.     }
  140. else
  141.     {
  142.     fprintf(stderr, "No message area specified!\n");
  143.     exit(1);
  144.     }
  145.  
  146. /*  Open the message API  */
  147. mi.req_version = 0;
  148. mi.def_zone = 1;
  149. if (MsgOpenApi(&mi) != 0)
  150.     {
  151.     fprintf(stderr, "Unable to initialize MsgAPI!\n");
  152.     exit(1);
  153.     }
  154.  
  155. /*  Open the message area  */
  156. if ((area=MsgOpenArea(msgpath, MSGAREA_NORMAL, MSGTYPE_SQUISH)) == NULL)
  157.     {
  158.     fprintf(stderr, "Unable to open area %s (%d)!\n", msgpath, msgapierr);
  159.     exit(1);
  160.     }
  161.  
  162. /*  Allocate space for the message data array  */
  163. messages = MsgGetHighMsg(area);
  164. new = calloc(messages, sizeof(MSG_DATA));
  165.  
  166. /*  Lock the message area for better efficiency  */
  167. MsgLock(area);
  168.  
  169. /*  Read in message datestamps and umsgids  */
  170. for (msgn = 1; msgn <= messages; msgn++)
  171.     {
  172.     /*  Read the message  */
  173.     if ((msg=MsgOpenMsg(area, MOPEN_READ, msgn)) == NULL)
  174.         {
  175.         fprintf(stderr, "Unable to open message %ld for reading (%d)!\n",
  176.               msgn, msgapierr);
  177.         exit(1);
  178.         }
  179.     if (MsgReadMsg(msg, &xmsg, 0L, 0L, NULL, 0L, NULL) == -1)
  180.         {
  181.         fprintf(stderr, "Unable to read message %ld (%d)!\n", msgn, msgapierr);
  182.         exit(1);
  183.         }
  184.     new[msgn-1].stamp = xmsg.date_arrived;
  185.     new[msgn-1].umsgid = MsgMsgnToUid(area, msgn);
  186.     if (MsgCloseMsg(msg) != 0)
  187.         {
  188.         fprintf(stderr, "Unable to close message %ld (%d)!\n", msgn, msgapierr);
  189.         exit(1);
  190.         }
  191.     }
  192.  
  193. /*  Unlock the message area  */
  194. MsgUnlock(area);
  195.  
  196. /*  Close the message area  */
  197. if (MsgCloseArea(area) != 0)
  198.     {
  199.     fprintf(stderr, "Unable to close area %s (%d)!\n", msgpath, msgapierr);
  200.     exit(1);
  201.     }
  202.  
  203. /*  Close the message API  */
  204. if (MsgCloseApi() != 0)
  205.     {
  206.     fprintf(stderr, "Unable to deinitialize MsgAPI!\n");
  207.     exit(1);
  208.     }
  209.  
  210. /*  Open the datestamp file  */
  211. strcpy(stamppath, msgpath);
  212. strcat(stamppath, ".pfh");
  213. if ((stamp_fp = fopen(stamppath, "rb")) == NULL)
  214.     {
  215.     fprintf(stderr, "Unable to open %s\n", stamppath);
  216.     exit(1);
  217.     }
  218.  
  219. /*  Allocate space for the message index array  */
  220. stamps = filelength(fileno(stamp_fp))/sizeof(struct _stamp);
  221. old = calloc(stamps, sizeof(struct _stamp));
  222.  
  223. /*  Read in the datestamps  */
  224. if (fread(old, sizeof(struct _stamp), stamps, stamp_fp) < stamps)
  225.     {
  226.     fprintf(stderr, "Unable to read %s\n", stamppath);
  227.     exit(1);
  228.     }
  229.  
  230. /*  Close the datestamp file  */
  231. fclose(stamp_fp);
  232.  
  233. /*  Delete the datestamp file  */
  234. remove(stamppath);
  235.  
  236. /*  Allocate space for the message index array  */
  237. msgindex = calloc(stamps, sizeof(UMSGID));
  238.  
  239. /*  Correlate datestamps with new messages and store their umsgid values  */
  240. printf("Finding equivalent messages");
  241. for (i = 0; i < stamps; i++)
  242.     {
  243.     match = 0;
  244.     exact = 0;
  245.     for (j = 0; j < messages; j++)
  246.         {
  247.         if (stampcmp(&new[j].stamp, &old[i]) == 0)
  248.             {
  249.             match = j;
  250.             exact = 1;
  251.             break;
  252.             }
  253.         if ((!match) && (j) && (stampcmp(&new[j].stamp, &old[i]) > 0))
  254.             {
  255.             match = j-1;
  256.             }
  257.         }
  258.     msgindex[i] = new[match].umsgid;
  259.     if (exact)
  260.         printf(".");
  261.     else
  262.         printf(":");
  263.     }
  264. printf("\n");
  265.  
  266. /*  Free unneeded arrays  */
  267. free(old);
  268. free(new);
  269.  
  270. /*  Open the lastread msg number file  */
  271. strcpy(lastmsgnpath, msgpath);
  272. strcat(lastmsgnpath, ".pfl");
  273. if ((lastmsgn_fp = fopen(lastmsgnpath, "rb")) == NULL)
  274.     {
  275.     fprintf(stderr, "Unable to open %s\n", lastmsgnpath);
  276.     exit(1);
  277.     }
  278.  
  279. /*  Open the lastread UMSGID file  */
  280. strcpy(lastumsgidpath, msgpath);
  281. strcat(lastumsgidpath, ".SQL");
  282. if ((lastumsgid_fp = fopen(lastumsgidpath, "wb")) == NULL)
  283.     {
  284.     fprintf(stderr, "Unable to open %s\n", lastumsgidpath);
  285.     exit(1);
  286.     }
  287.  
  288. printf("Converting message numbers");
  289. /*  Convert and write lastread message numbers  */
  290. while (fread(&msgn, sizeof(dword), 1, lastmsgn_fp) > 0)
  291.     {
  292.     umsgid = msgindex[msgn-1];
  293.     if (fwrite(&umsgid, sizeof(UMSGID), 1, lastumsgid_fp) < 1)
  294.         {
  295.         fprintf(stderr, "Unable to write lastread pointer.\n");
  296.         exit(1);
  297.         }
  298.     printf(".");
  299.     }
  300. printf("\n");
  301.  
  302. /*  Close the lastread UMSGID file  */
  303. fclose(lastumsgid_fp);
  304.  
  305. /*  Close the lastread msg number file  */
  306. fclose(lastmsgn_fp);
  307.  
  308. /*  Delete the lastread msg number file  */
  309. remove(lastmsgnpath);
  310.  
  311. /*  Free array  */
  312. free(msgindex);
  313.  
  314. return 0;
  315. }
  316.  
  317.  
  318. int stampcmp(struct _stamp *ds1, struct _stamp *ds2)
  319. {
  320. if (ds1->date.yr > ds2->date.yr)
  321.     return 1;
  322. if (ds1->date.yr < ds2->date.yr)
  323.     return -1;
  324.  
  325. if (ds1->date.mo > ds2->date.mo)
  326.     return 1;
  327. if (ds1->date.mo < ds2->date.mo)
  328.     return -1;
  329.  
  330. if (ds1->date.da > ds2->date.da)
  331.     return 1;
  332. if (ds1->date.da < ds2->date.da)
  333.     return -1;
  334.  
  335. if (ds1->time.hh > ds2->time.hh)
  336.     return 1;
  337. if (ds1->time.hh < ds2->time.hh)
  338.     return -1;
  339.  
  340. if (ds1->time.mm > ds2->time.mm)
  341.     return 1;
  342. if (ds1->time.mm < ds2->time.mm)
  343.     return -1;
  344.  
  345. if (ds1->time.ss > ds2->time.ss)
  346.     return 1;
  347. if (ds1->time.ss < ds2->time.ss)
  348.     return -1;
  349.  
  350. return 0;
  351. }
  352.  
  353.  
  354.