home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / muprg110.zip / MUPURGE.C < prev    next >
C/C++ Source or Header  |  1995-09-09  |  17KB  |  608 lines

  1. #define RDS_TITLE     "MUPURGE"                 /*  Program Name         */
  2. #ifdef __OS2__
  3.   #undef  RDS_TITLE
  4.   #define RDS_TITLE   "MUPURGEP"                /*  Program Name         */
  5. #endif
  6. #define RDS_DATES     "1995"                    /*  Copyright Date       */
  7. #define RDS_VERSION   "1.10"                    /*  Version Number       */
  8. #define NUM_RULES     20                        /*  Maximum Purge Rules  */
  9. /*
  10.  
  11.                              MUPURGE / MUPURGEP
  12.              Copyright (c) Bob Swift, 1995.  All Rights Reserved.
  13.  
  14.    This program is used to read the Max 3.00 USER.BBS file in the
  15.    current directory and purge users based on a combination of access,
  16.    number of calls, and days since the last call.  Purge criteria are
  17.    determined by the Sysop in a control file.  The first record in
  18.    USER.BBS (usually the sysop) is ignored, as are any records marked as
  19.    "Permanent".  Records marked as "Deleted" are purged.
  20.  
  21.    The format for using this program is as follows:
  22.  
  23.                 MUPURGE  [ctlfile]            (for DOS)
  24.                 MUPURGEP [ctlfile]            (for OS/2)
  25.  
  26.    Where [ctlfile] is the path and name of the control file (default is
  27.                    MUPURGE.CTL in the current directory).
  28.  
  29.    Examples:        MUPURGE  c:\max\misc\usrpurge.cfg
  30.                     MUPURGEP ctlfiles\mupurge.ctl
  31.                     MUPURGEP
  32.  
  33.    The program will display a VERY brief set of instructions if it encounters
  34.    an error.  The following is a list of the error codes returned by the
  35.    program:
  36.  
  37.                   0 - No errors.  Normal termination.
  38.                   1 - Bad / Extra command line argument.
  39.                   2 - Unable to open the control file.
  40.                   3 - No purge criteria specified.
  41.                   4 - Unable to create the backup files.
  42.                   5 - Unable to read the input files.
  43.                   6 - Unable to write the output files.
  44.                   7 - Unable to write the log file.
  45.  
  46.    When an error is encountered, the program will exit immediately and will
  47.    attempt to properly close all files.
  48.  
  49.    Although I have chosen to retain all rights to this program, you are free
  50.    to use it under the following conditions:
  51.  
  52.             - You realize that there is NO Warrantee of any sort.
  53.               It was tested pretty thoroughly here before release
  54.               but who knows what bugs may be lurking within.
  55.  
  56.             - You will not modify the code and release a new version
  57.               of the program.  I welcome suggestions for improvement
  58.               (especially when accompanied by code) but I make no
  59.               guarantee of future releases.
  60.  
  61.             - You drop me a note to let me know that you use the
  62.               program.  That way, I know who to inform if there are
  63.               any future releases.  Please either send netmail to:
  64.  
  65.                         Bob Swift
  66.                         1:342/5 @ fidonet
  67.  
  68.               or a postcard to:
  69.  
  70.                         Bob Swift
  71.                         5708 - 47th Street
  72.                         Stony Plain, Alberta
  73.                         T7Z 1C6, Canada
  74.  
  75.             - If you find the program useful, I ask that you do
  76.               something to brighten somebody else's day.  Just
  77.               exactly what, I will leave up to you.
  78.  
  79.    You may freely distribute this program provided that you distribute only
  80.    the complete archive which includes the files:
  81.  
  82.         MUPURGE.EXE     -   Program File for DOS
  83.         MUPURGEP.EXE    -   Program File for OS/2
  84.         MUPURGE.CTL     -   Sample Control File
  85.         MUPURGE.C       -   'C' Source Code
  86.         MAX_U.H         -   Maximus User Structures
  87.         STAMP.H         -   Maximus Stamp Structures
  88.         TYPEDEFS.H      -   Maximus Type Definitions
  89.         MUPURGE.DOC     -   Program Documentation
  90.         FILE_ID.DIZ     -   Program Description File
  91.  
  92.    If you run across any bugs with this program, please report them to the
  93.    address listed above.  Thanks for giving MUPURGE(P) a try.
  94.  
  95.  
  96.                                                    Bob Swift (1:342/5)
  97.  
  98.  
  99.    Revision History
  100.    ----------------
  101.  
  102.    1.00     95/09/06    First release version.
  103.  
  104.    1.10     95/09/09    Added log style option.  Removed the code to
  105.                         read / write the USER.IDX file because it seems
  106.                         that Maximus rebuilds this file whenever it starts
  107.                         up, so I don't have to worry about keeping it in
  108.                         sync.  Besides, the code would potentially cause
  109.                         other problems if the .IDX file was not synchronized
  110.                         with the .BBS file.
  111.  
  112. */
  113.  
  114.  
  115. #include <stdio.h>
  116. #include <string.h>
  117. #include <time.h>
  118. #ifdef __OS2__
  119.   #include <os2.h>
  120. #endif
  121. #include "max_u.h"
  122.  
  123. #define BASE 1936
  124.  
  125. void helpscrn(int ernum);
  126. word julian (word month, word day, word year);
  127. void gregorian (word jdate, word *month, word *day, word *year);
  128.  
  129. /*******************************************************************/
  130.  
  131. void main(int argc, char *argv[])
  132. {
  133.  
  134. static struct _usr    usr_data;
  135.  
  136. struct tm *tm_now;
  137. time_t secs_now;
  138.  
  139. FILE *bbs_in,*bbs_out,*log_out;
  140.  
  141. char temp[256];
  142. char temp1[256];
  143. char temp2[256];
  144. char temp3[256];
  145. char *p,*p1,*p2,*p3;
  146.  
  147. word i,j,k;
  148. sword tp,tc,td;
  149. word today;
  150. word t_priv[NUM_RULES];
  151. word t_call[NUM_RULES];
  152. word t_days[NUM_RULES];
  153. word num_rules;
  154. word f_first;
  155. word f_purge;
  156. word f_log;
  157. word f_logmax;
  158.  
  159. secs_now = time(NULL);
  160. tm_now = localtime(&secs_now);
  161. i = tm_now->tm_mon+1;
  162. j = tm_now->tm_mday;
  163. k = tm_now->tm_year+1900;
  164. today = julian(i,j,k);
  165.  
  166. printf("\n\n%s (v%s)\n",RDS_TITLE,RDS_VERSION);
  167. printf("Copyright (c) Bob Swift, %s.  All Rights Reserved.\n\n",RDS_DATES);
  168.  
  169. if (argc > 2) helpscrn(1);
  170.  
  171. strcpy(temp1,"MUPURGE.CTL");                              /* Control File  */
  172. if (argc == 2) strcpy(temp1,strupr(argv[1]));             /* Control File  */
  173.  
  174. if ((bbs_in=fopen(temp1,"rt")) == NULL) helpscrn(2);
  175.  
  176. num_rules = 0;
  177. f_first = 0;
  178. f_purge = 0;
  179. f_log = 0;
  180. f_logmax = 0;
  181. temp1[0] = '\0';
  182. temp2[0] = '\0';
  183.  
  184. while (fgets(temp3,256,bbs_in) != NULL)
  185.   {
  186.   strcpy(temp,temp3);
  187.  
  188. /*********************************************************
  189. *                                                        *
  190. *  The following routine is used to pull the tokens out  *
  191. *  of the input string from the control file.  This is   *
  192. *  being used rather than the strtok() function because  *
  193. *  of all the problems I had with the strtok() function  *
  194. *  in the OS/2 version compiled with the Watcom C/C++    *
  195. *  compiler.                                             *
  196. *                                                        *
  197. *********************************************************/
  198.  
  199.   tp = 0;
  200.   p = temp;
  201.   p1 = p;
  202.   p2 = p;
  203.   p3 = p;
  204.   k = 0;
  205.   i = 0;
  206.   j = strlen(temp);
  207.   while (i < j)
  208.     {
  209.     if ((temp[i] == ' ') || (temp[i] == '\t') || (temp[i] == '\n'))
  210.       {
  211.       if (k != 0)
  212.         {
  213.         k = 0;
  214.         temp[i] = '\0';
  215.         if (tp == 1) i = j;
  216.         }
  217.       if (p == p3) p++;
  218.       if (p1 == p3) p1++;
  219.       if (p2 == p3) p2++;
  220.       if (tp == 0) p3++;
  221.       }
  222.     else
  223.       {
  224.       if (k == 0)
  225.         {
  226.         k = 1;
  227.         if (p == p3)
  228.           {p1++; p2++; p3++;}
  229.         else
  230.           {
  231.           if (p1 == p3)
  232.             {p2++; p3++;}
  233.           else
  234.             {
  235.             if (p2 == p3)
  236.               p3++;
  237.             else
  238.               tp = 1;
  239.             }
  240.           }
  241.         }
  242.       else
  243.         {
  244.         if (p == p3) p++;
  245.         if (p1 == p3) p1++;
  246.         if (p2 == p3) p2++;
  247.         if (tp == 0) p3++;
  248.         }
  249.       }
  250.     i++;
  251.     }
  252.  
  253. /************************************
  254. *                                   *
  255. *  End of special parsing routine.  *
  256. *                                   *
  257. ************************************/
  258.  
  259. //  p = strtok(temp," \n");
  260.   if (strcmpi(p,"CHKFIRST") == 0) f_first = 1;
  261.   if (strcmpi(p,"PURGE") == 0) f_purge = 1;
  262.   if (strcmpi(p,"LOGMAX") == 0) f_logmax = 1;
  263.   if (strcmpi(p,"LOGFILE") == 0)
  264.     {
  265. //    p1 = strtok(NULL," \n");
  266. //    if (p1 != NULL)
  267.     if ((p1[0] != '\0') && (p1[0] != ';'))
  268.       {
  269.       strcpy(temp1,p1);
  270.       f_log = 1;
  271.       }
  272.     else
  273.       {
  274.       temp1[0] = '\0';
  275.       f_log = 0;
  276.       }
  277.     }
  278.   if (strcmpi(p,"USERPATH") == 0)
  279.     {
  280. //    p1 = strtok(NULL," \n");
  281. //    if (p1 != NULL)
  282.     if ((p1[0] != '\0') && (p1[0] != ';'))
  283.       {
  284.       strcpy(temp2,p1);
  285.       }
  286.     else
  287.       {
  288.       temp2[0] = '\0';
  289.       }
  290.     }
  291.   if (strcmpi(p,"DELETE") == 0)
  292.     {
  293. //    p1 = strtok(NULL," \n");
  294. //    p2 = strtok(NULL," \n");
  295. //    p3 = strtok(NULL," \n");
  296.     if (num_rules < NUM_RULES)
  297.       {
  298.       tp = -1;
  299.       tc = -1;
  300.       td = -1;
  301.       if (p1[0] == 'a' || p1[0] == 'A') tp = atoi(p1+2);
  302.       if (p2[0] == 'a' || p2[0] == 'A') tp = atoi(p2+2);
  303.       if (p3[0] == 'a' || p3[0] == 'A') tp = atoi(p3+2);
  304.       if (p1[0] == 'c' || p1[0] == 'C') tc = atoi(p1+2);
  305.       if (p2[0] == 'c' || p2[0] == 'C') tc = atoi(p2+2);
  306.       if (p3[0] == 'c' || p3[0] == 'C') tc = atoi(p3+2);
  307.       if (p1[0] == 'd' || p1[0] == 'D') td = atoi(p1+2);
  308.       if (p2[0] == 'd' || p2[0] == 'D') td = atoi(p2+2);
  309.       if (p3[0] == 'd' || p3[0] == 'D') td = atoi(p3+2);
  310.       if ((tp > 0) && (tc >= 0) && (td > 0))
  311.         {
  312.         t_priv[num_rules] = tp;
  313.         t_call[num_rules] = tc;
  314.         t_days[num_rules] = td;
  315.         num_rules++;
  316.         }
  317.       }
  318.     }
  319.   }
  320. fclose(bbs_in);
  321.  
  322. if (num_rules < 1) helpscrn(3);
  323.  
  324. if (f_log == 1)
  325.   {
  326.   if ((log_out=fopen(temp1,"at")) == NULL) helpscrn(7);
  327.   }
  328.  
  329. if (temp2[0] != '\0')
  330.   {
  331.   if (temp2[strlen(temp2)-1] != ':' && temp2[strlen(temp2)-1] != '\\')
  332.     strcat(temp2,"\\");
  333.   }
  334.  
  335. strcpy(temp,temp2);
  336. strcpy(temp1,temp2);
  337. strcat(temp,"USER.BBS");
  338. strcat(temp1,"USER.BB$");
  339.  
  340. if ((bbs_in=fopen(temp,"rb")) == NULL) helpscrn(5);
  341. fclose(bbs_in);
  342.  
  343. unlink(temp1);
  344. rename(temp,temp1);
  345. if ((bbs_in=fopen(temp1,"rb")) == NULL) helpscrn(5);
  346. if ((bbs_out=fopen(temp,"wb")) == NULL) helpscrn(4);
  347.  
  348. if (f_log == 1)
  349.   {
  350.   if (f_logmax == 1)
  351.     {
  352.     secs_now = time(NULL);
  353.     tm_now = localtime(&secs_now);
  354.     strftime(temp,80,"+ %d %b %H:%M:%S MUP  ",tm_now);
  355.     }
  356.   else
  357.     temp[0] = '\0';
  358.   fprintf(log_out,"\n%s%s (v%s)\n",temp,RDS_TITLE,RDS_VERSION);
  359.   fprintf(log_out,"%sCopyright (c) Bob Swift, %s.  All Rights Reserved.\n",temp,RDS_DATES,temp);
  360.   if (f_logmax != 1)
  361.     {
  362.     secs_now = time(NULL);
  363.     tm_now = localtime(&secs_now);
  364.     strftime(temp1,80,"%Y %b %d  %H:%M:%S",tm_now);
  365.     fprintf(log_out,"(Program started:  %s)\n",temp1);
  366.     }
  367.   fprintf(log_out,"%s\n",temp);
  368.   }
  369.  
  370. sprintf(temp,"Purge Rules:");
  371. puts(temp);
  372. if (f_log == 1)
  373.   {
  374.   if (f_logmax == 1)
  375.     {
  376.     secs_now = time(NULL);
  377.     tm_now = localtime(&secs_now);
  378.     strftime(temp3,80,"+ %d %b %H:%M:%S MUP  ",tm_now);
  379.     fputs(temp3,log_out);
  380.     }
  381.   fputs(temp,log_out);
  382.   fputs("\n",log_out);
  383.   }
  384. sprintf(temp,"Access (<=)      Calls (<=)      Days (>=)");
  385. puts(temp);
  386. if (f_log == 1)
  387.   {
  388.   if (f_logmax == 1)
  389.     {
  390.     secs_now = time(NULL);
  391.     tm_now = localtime(&secs_now);
  392.     strftime(temp3,80,"+ %d %b %H:%M:%S MUP  ",tm_now);
  393.     fputs(temp3,log_out);
  394.     }
  395.   fputs(temp,log_out);
  396.   fputs("\n",log_out);
  397.   }
  398.  
  399. i = 0;
  400. while (i < num_rules)
  401.   {
  402.   if (t_call[i] == 0)
  403.     sprintf(temp,"%6u%17s%16u",t_priv[i],"n/a",t_days[i]);
  404.   else
  405.     sprintf(temp,"%6u%17u%16u",t_priv[i],t_call[i],t_days[i]);
  406.   puts(temp);
  407.   if (f_log == 1)
  408.     {
  409.     if (f_logmax == 1)
  410.       {
  411.       secs_now = time(NULL);
  412.       tm_now = localtime(&secs_now);
  413.       strftime(temp3,80,"+ %d %b %H:%M:%S MUP  ",tm_now);
  414.       fputs(temp3,log_out);
  415.       }
  416.     fputs(temp,log_out);
  417.     fputs("\n",log_out);
  418.     }
  419.   i++;
  420.   }
  421. puts("");
  422. if (f_log == 1)
  423.   {
  424.   if (f_logmax == 1)
  425.     {
  426.     secs_now = time(NULL);
  427.     tm_now = localtime(&secs_now);
  428.     strftime(temp3,80,"+ %d %b %H:%M:%S MUP  ",tm_now);
  429.     fputs(temp3,log_out);
  430.     }
  431.   fputs("\n",log_out);
  432.   }
  433.  
  434. i = 0;
  435.  
  436. while (fread(&usr_data,sizeof(struct _usr),1,bbs_in) == 1)
  437. {
  438.   i++;
  439.   fprintf(stderr,"Processing: %-36s\r",usr_data.name);
  440.   tp = 0;
  441.   if ((i > 1 || f_first == 1) && ((usr_data.delflag & UFLAG_PERM) != UFLAG_PERM))
  442.     {
  443.     k = today - julian(usr_data.ludate.msg_st.date.mo,usr_data.ludate.msg_st.date.da,usr_data.ludate.msg_st.date.yr+1980);
  444.     j = 0;
  445.     while (j < num_rules)
  446.       {
  447.       if (k >= t_days[j] && usr_data.priv <= t_priv[j] && (usr_data.times <= t_call[j] || t_call[j] == 0))
  448.         {
  449.         j = num_rules;
  450.         usr_data.delflag = UFLAG_DEL;
  451.         sprintf(temp,"Marking: %-25sA=%-6uC=%-6uD=%u",usr_data.name,usr_data.priv,usr_data.times,k);
  452.         if (f_purge == 1)
  453.           {
  454.           temp[0] = 'P';
  455.           temp[1] = 'u';
  456.           temp[3] = 'g';
  457.           }
  458.         puts(temp);
  459.         if (f_log == 1)
  460.           {
  461.           if (f_logmax == 1)
  462.             {
  463.             secs_now = time(NULL);
  464.             tm_now = localtime(&secs_now);
  465.             strftime(temp3,80,"+ %d %b %H:%M:%S MUP  ",tm_now);
  466.             fputs(temp3,log_out);
  467.             }
  468.           fputs(temp,log_out);
  469.           fputs("\n",log_out);
  470.           }
  471.         }
  472.       j++;
  473.       }
  474.     }
  475.   if (((usr_data.delflag & UFLAG_DEL) != UFLAG_DEL) || ((usr_data.delflag & UFLAG_PERM) == UFLAG_PERM) || f_purge == 0)
  476.     {
  477.     if (fwrite(&usr_data,sizeof(struct _usr),1,bbs_out) != 1) helpscrn(6);
  478.     }
  479. }
  480.  
  481. fclose(bbs_in);
  482. fclose(bbs_out);
  483.  
  484. /*  Thank the user and exit gracefully  */
  485. printf("%60s\r"," ");
  486. sprintf(temp,"Operation complete.  Thank-you for using %s.\n",RDS_TITLE);
  487. puts("\n");
  488. puts(temp);
  489. if (f_log == 1)
  490.   {
  491.   if (f_logmax == 1)
  492.     {
  493.     secs_now = time(NULL);
  494.     tm_now = localtime(&secs_now);
  495.     strftime(temp3,80,"+ %d %b %H:%M:%S MUP  ",tm_now);
  496.     fputs(temp3,log_out);
  497.     fputs("\n",log_out);
  498.     fputs(temp3,log_out);
  499.     }
  500.   else
  501.     fputs("\n",log_out);
  502.   fputs(temp,log_out);
  503.   fputs("\n",log_out);
  504.   }
  505. fclose(log_out);
  506. exit(0);
  507. }
  508.  
  509. /*******************************************************************/
  510.  
  511. /* julian -- calculate julian date from gregorian date */
  512.  
  513. word julian (word month, word day, word year)
  514. {
  515.     if (month > 2)
  516.         {
  517.         month -= 3;
  518.         year -= BASE;
  519.         }
  520.     else
  521.         {
  522.         month += 9;
  523.         year -= BASE + 1;
  524.         }
  525.     year = ((long) year * 1461) / 4;
  526.     month = (month * 153 + 2) / 5;
  527.     day += year + month -1;
  528.     return day;
  529. }
  530.  
  531.  
  532.  
  533. /* gregorian -- calculate gregorian date from julian */
  534.  
  535. void gregorian (word jdate, word *month, word *day, word *year)
  536. {
  537.     dword temp;
  538.  
  539.     temp = (long) jdate * 4 + 3;
  540.     *year = temp / 1461;
  541.     *day = (unsigned) (temp % 1461) / 4;
  542.     *month = (*day * 5 + 2);
  543.     *day = (*month % 153) / 5 + 1;
  544.     *month /= 153;
  545.  
  546.     if (*month > 9)
  547.         {
  548.         *year += BASE + 1;
  549.         *month -= 9;
  550.         }
  551.     else
  552.         {
  553.         *year += BASE;
  554.         *month += 3;
  555.         }
  556. }
  557.  
  558. /*******************************************************************/
  559.  
  560. void helpscrn(int ernum)
  561. /*  Here are the error messages and VERY brief instructions  */
  562. {
  563. printf("\n\n");
  564. switch (ernum) {
  565.  
  566. case  1 : printf("Bad / Extra command line argument.\n\n");
  567.           break;
  568.  
  569. case  2 : printf("Unable to open the control file.\n\n");
  570.           break;
  571.  
  572. case  3 : printf("No purge criteria specified.\n\n");
  573.           break;
  574.  
  575. case  4 : printf("Unable to create the backup files.\n\n");
  576.           break;
  577.  
  578. case  5 : printf("Unable to read the input files.\n\n");
  579.           break;
  580.  
  581. case  6 : printf("Unable to write the output files.\n\n");
  582.           break;
  583.  
  584. case  7 : printf("Unable to write the log file.\n\n");
  585.           break;
  586.  
  587.     }
  588.  
  589. printf("This program is used to read the Max 3.00 USER.BBS file in the\n");
  590. printf("current directory and purge users based on a combination of access,\n");
  591. printf("number of calls, and days since the last call.  Purge criteria are\n");
  592. printf("determined by the Sysop in a control file.  The first record in\n");
  593. printf("USER.BBS (usually the sysop) is ignored, as are any records marked as\n");
  594. printf("'Permanent'.  Records marked as 'Deleted' are purged.\n\n");
  595. printf("The format for using this program is as follows:\n\n");
  596. printf("             %s [ctlfile]\n\n",RDS_TITLE);
  597. printf("Where [ctlfile] is the path and name of the control file (default is\n");
  598. printf("                MUPURGE.CTL in the current directory).\n\n");
  599. printf("Examples:        %s c:\\max\\misc\\usrpurge.cfg\n",RDS_TITLE);
  600. printf("                 %s ctlfiles\\mupurge.ctl\n",RDS_TITLE);
  601. printf("                 %s\n\n",RDS_TITLE);
  602.  
  603. exit(ernum);
  604. }
  605.  
  606. /*******************************************************************/
  607.  
  608.