home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / com / bbs / downsrt / source / downpar.c < prev    next >
C/C++ Source or Header  |  1991-06-06  |  20KB  |  498 lines

  1. /* ============================================================= */
  2. /*  Rob Hamerling's MAXIMUS download file scan and sort utility. */
  3. /*  -> Parameter processing routines for DOWNSORT.               */
  4. /* ============================================================= */
  5.  
  6. // #define DEBUG_MODE
  7.  
  8. #define INCL_BASE
  9. #include <os2.h>
  10.  
  11. #include <ctype.h>
  12. #include <memory.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <time.h>
  17.  
  18. #include "downsort.h"
  19.  
  20. /*  Symbolic names of keyword parameters */
  21. #define    K_CMT      0
  22. #define    K_TIT      1
  23. #define    K_FNT      2
  24. #define    K_DAT      3
  25. #define    K_ALL      4
  26. #define    K_NEW      5
  27. #define    K_GBL      6
  28. #define    K_BBS      7
  29. #define    K_FIL      8
  30. #define    K_ORP      9
  31. #define    K_NNN     10
  32. #define    K_PRE     11
  33. #define    K_SUB     12
  34. #define    K_BOT     13
  35. #define    K_NDS     14
  36. #define    K_ODS     15
  37. #define    K_IPF     16
  38. #define    K_END    255
  39.  
  40. /* ----------------------------------------- */
  41. /* Process commandline and system parameters */
  42. /* ----------------------------------------- */
  43. void get_parm(k,p)
  44. int  k;                                 // parm count
  45. char *p[];                              // pointer array
  46. {
  47.   USHORT i,j,n;                         // counters
  48.   char   c;                             // option letter
  49.  
  50.   DosGetCtryInfo(sizeof(struct _COUNTRYINFO),&c_code,&c_info,&i);
  51.                                         // for date format, etc
  52.   sys_date(today);                      // start timestamp
  53.  
  54.   for (i=1; i<k; ++i) {                 // pre-scan
  55.     if (p[i][0]=='@')                   // config filespec
  56.       strncpy(cfg_path,strupr(&p[i][1]),127); // copy filespec
  57.     else if (p[i][0] == '/' || p[i][0] == '-') { // options
  58.       switch(c = toupper(p[i][1])) {
  59.         case VERBOSE   : oper_mode = VERBOSE;   break;
  60.         case QUIET     : oper_mode = QUIET;     break;
  61.         case HELP      : oper_mode = HELP;      break;
  62.         case QMARK     : oper_mode = HELP;      break;
  63.         }
  64.       }
  65.     }
  66.  
  67.   if (oper_mode == HELP)
  68.     show_help();                        // help explicitly requested
  69.   else if (oper_mode != QUIET)
  70.     show_welcome();                     // good-morning msg
  71.   else
  72.     printf("%s %d.%d%c by %s . . . ",   // simple opening
  73.            PROGNAME,VERSION,SUBVERS,SUFFIX,AUTHOR);
  74.  
  75.   read_cfg(cfg_path);                   // process configuration file
  76.  
  77.   for (i=1; i<k; i++) {                 // all commandline parms
  78.     strupr(p[i]);                       // make string upper case
  79.  
  80.     if (strcmp(p[i],"ORP") == 0)        // ORP-list requested
  81.       lp[P_ORP].priv[0] = SYSOP;        // first/only default: SYSOP
  82.  
  83.     else if (strcmp(p[i],"BBS") == 0 ||
  84.         strncmp(p[i],"BBS:",4) == 0) {  // BBS-list requested
  85.       lp[P_BBS].priv[0] = SYSOP;        // default: HIDDEN
  86.       if (p[i][3] == ':')
  87.         if (conv_priv(&p[i][4],lp[P_BBS].priv,1) <= 0)   // convert
  88.           oper_mode = HELP;
  89.       }
  90.  
  91.     else if (strcmp(p[i],"NEW") == 0 ||
  92.              strncmp(p[i],"NEW:",4) == 0) { // NEW-list requested
  93.       lp[P_NEW].priv[0] = SYSOP;        // first/only default: SYSOP
  94.       if (p[i][3] == ':')
  95.         if (conv_priv(&p[i][4],lp[P_NEW].priv,10) <= 0)   // convert to int
  96.           oper_mode = HELP;
  97.       }
  98.  
  99.     else if (strcmp(p[i],"ALL") == 0 ||
  100.              strncmp(p[i],"ALL:",4) == 0) { // ALL-list requested
  101.       lp[P_ALL].priv[0] = SYSOP;        // first/only default: SYSOP
  102.       if (p[i][3] == ':')
  103.         if (conv_priv(&p[i][4],lp[P_ALL].priv,10) <= 0)   // convert to int
  104.           oper_mode = HELP;
  105.       }
  106.  
  107.     else if (strcmp(p[i],"IPF") == 0 ||
  108.              strncmp(p[i],"IPF:",4) == 0) { // IPF-list requested
  109.       lp[P_IPF].priv[0] = SYSOP;        // first/only default: SYSOP
  110.       if (p[i][3] == ':')
  111.         if (conv_priv(&p[i][4],lp[P_IPF].priv,10) <= 0)   // convert to int
  112.           oper_mode = HELP;
  113.       }
  114.  
  115.     else if (strcmp(p[i],"GBL") == 0 ||
  116.              strncmp(p[i],"GBL:",4) == 0) { // GBL-list requested
  117.       lp[P_GBL].priv[0] = SYSOP;        // first/only default: SYSOP
  118.       if (p[i][3] == ':')
  119.         if (conv_priv(&p[i][4],lp[3].priv,10) <= 0)   // convert to int
  120.           oper_mode = HELP;
  121.       }
  122.  
  123.     else if (strcmp(p[i],"FIL") == 0 ||
  124.              strncmp(p[i],"FIL:",4) == 0) { // FILES.BBS to be generated
  125.       lp[P_FIL].priv[0] = SYSOP;              //
  126.       if (p[i][3] == ':') {             // path specified?
  127.         strncpy(filesbbs_path,&p[i][4],79);
  128.         j = strlen(filesbbs_path);
  129.         if (j>0 && filesbbs_path[j-1] != '\\')
  130.           filesbbs_path[j] = '\\';      // add backslash if needed
  131.         }
  132.       }
  133.  
  134.     else if (p[i][0] == '/' || p[i][0] == '-') { // option flag
  135.       switch(c = toupper(p[i][1])) {
  136.         case TRUNC     : for (j=0; j<P_MAX; ++j)
  137.                            lp[j].wrapflag = TRUNC;
  138.                          break;
  139.         case WRAP      : for (j=0; j<P_MAX; ++j)
  140.                            lp[j].wrapflag = WRAP;
  141.                          break;
  142.         case ALPHA     : for (j=0; j<P_MAX; ++j)
  143.                            lp[j].sortflag = ALPHA;
  144.                          break;
  145.         case TIMESTAMP : for (j=0; j<P_MAX; ++j)
  146.                            lp[j].sortflag = TIMESTAMP;
  147.                          break;
  148.         case KEEPSEQ   : for (j=0; j<P_MAX; ++j)
  149.                            lp[j].sortflag = KEEPSEQ;
  150.                          break;
  151.         case EXCLPRIV  : for (j=0; j<P_MAX; ++j)
  152.                            lp[j].exclflag = EXCLPRIV;
  153.                          break;
  154.         case QUIET     : oper_mode = QUIET;     break;
  155.         case VERBOSE   : oper_mode = VERBOSE;   break;
  156.         case HELP      : oper_mode = HELP;      break;
  157.         case QMARK     : oper_mode = HELP;      break;
  158.         default        : oper_mode = HELP;      break;
  159.         }
  160.       }
  161.  
  162.     else if (0 < (n = atoi(p[i])))      // numeric: NEW-list length
  163.       for (j=0; j<P_MAX; ++j)
  164.         lp[j].max_fil = n;              // new value for all
  165.  
  166.     else if (p[i][0] == '@')            // config filespec
  167.       ;                                 // skip
  168.  
  169.     else
  170.       printf("\nUnknown Parameter: %-50.50s",p[i]);
  171.     }
  172.  
  173.   for (i=0; i<P_MAX; i++)               // all report entries
  174.     for (j=0; j<10; j++)                // all privilege entries
  175.       if (ABS_MAX_priv < lp[i].priv[j] &&  // higher than before
  176.               HIDDEN+1 > lp[i].priv[j])  // but only requested reports
  177.         ABS_MAX_priv = lp[i].priv[j];    // revise if needed
  178.   }
  179.  
  180. /* --------------------------------- */
  181. /* Process privilege parameterstring */
  182. /* --------------------------------- */
  183. int conv_priv(c,p,n)
  184. char   *c;                              // parameter string (uppercase)
  185. int    p[];                             // pointer to privilege array
  186. USHORT n;                               // maximum number of privileges
  187. {
  188.   USHORT i,j,k;                         // counters
  189.  
  190.   for (i=j=0; i<n && c[i]!='\0' && c[i]!=' '; ++i) {
  191.     if (c[i] == '*')                    // asterisk specified?
  192.       p[j] = SYSOP;                     // system default
  193.     else {
  194.       for (k=0; k<HIDDEN-TWIT+1 &&      // search table
  195.                 priv_name[k][0]!=toupper(c[i]); k++);
  196.       p[j] = k + TWIT;                  // store real privilege
  197.       }                                 // endif
  198.     if (p[j]<=HIDDEN)                   // hidden or below?
  199.       ++j;                              // count only valid privs
  200.     }                                   // endfor
  201.   for (i=j; i<n; ++i)                   // remaining priv-values
  202.     p[i] = HIDDEN + 1;                  // undo any previous settings
  203.   return(j);                            // number of valid privs
  204.   }
  205.  
  206. /* ------------------ */
  207. /* Produce time stamp */
  208. /* ------------------ */
  209. char *sys_date(t)
  210. char t[];                               // output buffer
  211. {
  212.   long  secs_now;                       // relative time value
  213.   char *buf;                            // pointer to time string
  214.  
  215.   time(&secs_now);                      // get current time
  216.   buf = ctime(&secs_now);               // convert to char string
  217.   strcpy(t,buf);                        // copy string
  218.   t[16] = '\0';                         // undo secs, year and newline
  219.   return(t);                            // pointer to buffer
  220.   }
  221.  
  222. /* =================================== */
  223. /* Process DOWNSORT Configuration File */
  224. /* =================================== */
  225. void read_cfg(ds_cfg)
  226. char ds_cfg[];
  227. {
  228.   FILE *prm;
  229.   char buf[255];
  230.   char *value;                          // ptr to parameter value
  231.   int  i,j,t;
  232.  
  233.   if ((prm = fopen(ds_cfg,"r")) == NULL )
  234.     printf(OPEN_FAIL,ds_cfg);
  235.  
  236.   else {
  237.     printf("\nReading configuration file: %s",cfg_path);
  238.  
  239.     while (fgets(buf,255,prm)) {        // process 1 line at a time
  240.  
  241.       switch(parse_keyword(buf,&value)) {
  242.  
  243.         case K_CMT:                     // Comment and empty lines
  244.           break;
  245.  
  246.         case K_TIT:                     // list title (ALL, NEW, GBL)
  247.           for (j=0; j<20 && value[j]!='\0'; j++)
  248.             if (value[j] == '~')        // replace tilde by blank
  249.               value[j] = ' ';
  250.           strncpy(list_title,value,20);
  251.           break;
  252.  
  253.         case K_PRE:                     // pre-title
  254.           title_line(value,pre_title);
  255.           break;
  256.  
  257.         case K_SUB:                     // sub-title
  258.           title_line(value,sub_title);
  259.           break;
  260.  
  261.         case K_BOT:                     // bottom line
  262.           title_line(value,bot_lines);
  263.           break;
  264.  
  265.         case K_ODS:                     // Orphan Description
  266.           strncpy(ORPHAN,value,45);     // copy file text
  267.           break;
  268.  
  269.         case K_NDS:                     // Orphan Description
  270.           strncpy(NDS,value,45);        // copy file text
  271.           break;
  272.  
  273.         case K_FNT:                     // Font for all lists
  274.           t = atoi(value);              // convert to integer
  275.           if (t < FONT0 || t > FONT4)   // range check
  276.             printf("\n!Error: TitleFont out of range");
  277.           else
  278.             for (i=0; i<P_MAX; i++)
  279.               lp[i].tfont = t;           // to all parmlist entries
  280.           break;
  281.  
  282.         case K_DAT:                     // Area.Dat
  283.           strncpy(areadat_path,strupr(value),80);  // copy file specification
  284.           break;
  285.  
  286.         case K_NNN:
  287.           if (0 < (t = atoi(value)))    // NEW/BBS-list length
  288.             for (i=0; i<P_MAX; ++i)
  289.               lp[i].max_fil = t;        // new value for all lists
  290.           break;
  291.  
  292.         case K_ALL:                     // create ALL-list(s)
  293.           list_parm(P_ALL,value,10);
  294.           break;
  295.  
  296.         case K_IPF:                     // create ALL-list(s)
  297.           list_parm(P_IPF,value,10);
  298.           break;
  299.  
  300.         case K_BBS:                     // create BBS-list
  301.           list_parm(P_BBS,value,1);
  302.           break;
  303.  
  304.         case K_GBL:                     // create GBL-list
  305.           list_parm(P_GBL,value,10);
  306.           break;
  307.  
  308.         case K_NEW:                     // create NEW-list(s)
  309.           list_parm(P_NEW,value,10);
  310.           break;
  311.  
  312.         case K_ORP:                     // naming of ORP-list
  313.           list_parm(P_ORP,value,1);
  314.           break;
  315.  
  316.         case K_FIL:                     // create FILES.bbs files
  317.           strupr(value);                // all upper case
  318.           conv_priv(value,lp[P_FIL].priv,1);
  319.           if ((value = next_word(value)) != NULL &&
  320.                strcmp(value,"*") != 0) {
  321.             strncpy(filesbbs_path,asciiz(value),80); // spec'd PATH
  322.             j = strlen(filesbbs_path);
  323.             if (j>0 && filesbbs_path[j-1] != '\\')
  324.               filesbbs_path[j] = '\\';    // add backslash if needed
  325.  
  326.             while ((value = next_word(value)) != NULL) {  // remaining parm(s)
  327.               if (value[0] == '/' || value[0] == '-') {  // option flag
  328.                 switch(value[1]) {
  329.                   case ALPHA     : lp[P_FIL].sortflag = ALPHA;     break;
  330.                   case TIMESTAMP : lp[P_FIL].sortflag = TIMESTAMP; break;
  331.                   case KEEPSEQ   : lp[P_FIL].sortflag = KEEPSEQ;   break;
  332.                   case EXCLPRIV  : lp[P_FIL].exclflag = EXCLPRIV;  break;
  333.                   case INCLUDE   : lp[P_FIL].incl_fspec =
  334.                                       (char *)malloc(strlen(asciiz(value+2))+1);
  335.                                    if (lp[P_FIL].incl_fspec == NULL) {
  336.                                      printf(MSG_MEM,PROGNAME);
  337.                                      exit(14);
  338.                                      }
  339.                                    else
  340.                                      strcpy(lp[P_FIL].incl_fspec,
  341.                                                    asciiz(value+2));
  342.                                    break;
  343.                   default        : break;
  344.                   }
  345.                 }
  346.               }
  347.             }
  348.           break;
  349.  
  350.         case K_END:                     // Keyword not found
  351.         default:                        // undefined
  352.           printf("\nUnknown Config Parameter: %-50.50s",buf);
  353.           break;
  354.         }
  355.       }
  356.     }
  357.   }
  358.  
  359. /* =============================== */
  360. /* Process xxxFileList parameters. */
  361. /* =============================== */
  362. void list_parm(k,v,n)
  363. int  k;                                 // appropriate list-parm index
  364. char *v;                                // parameter string pointer
  365. int  n;                                 // max number of privileges
  366. {
  367.   char *nv;                             // moving string pointer
  368.   int  t;                               // intermediate int value
  369.  
  370.   strupr(v);                            // whole string uppercase
  371.   conv_priv(v,lp[k].priv,n);            // privilege string
  372.   if ((nv = next_word(v)) != NULL  &&   // 1st expected: filename
  373.        strcmp(nv,"*") != 0)             // not asterisk
  374.     strncpy(lp[k].name,asciiz(nv),8);   // customised filename
  375.   while ((nv = next_word(nv)) != NULL) { // remaining parm(s)
  376.     if (nv[0] == '/' || nv[0] == '-') { // option flag
  377.       switch(nv[1]) {
  378.         case TRUNC     : lp[k].wrapflag = TRUNC;     break;
  379.         case WRAP      : lp[k].wrapflag = WRAP;      break;
  380.         case ALPHA     : lp[k].sortflag = ALPHA;     break;
  381.         case TIMESTAMP : lp[k].sortflag = TIMESTAMP; break;
  382.         case KEEPSEQ   : lp[k].sortflag = KEEPSEQ;   break;
  383.         case FONT      : t = atoi(nv+2);
  384.                          if (t >= FONT0 && t <= FONT4) // range check
  385.                            lp[k].tfont = t;
  386.                          break;
  387.         case EXCLPRIV  : lp[k].exclflag = EXCLPRIV;  break;
  388.         case INCLUDE   : lp[k].incl_fspec =
  389.                                   (char *)malloc(strlen(asciiz(nv+2))+1);
  390.                          if (lp[k].incl_fspec == NULL) {
  391.                            printf(MSG_MEM,PROGNAME);  // not enough memory
  392.                            exit(14);
  393.                            }
  394.                          else
  395.                            strcpy(lp[k].incl_fspec, asciiz(nv+2));
  396. //           printf("\nInclude '%s' / '%s', strlen=%d",
  397. //               asciiz(nv+2), lp[k].incl_fspec, strlen(asciiz(nv+2)));
  398.                          break;
  399.         default        : break;
  400.         }
  401.       }
  402.     else if (0 < atoi(nv))              // numeric: NEW-list length
  403.       lp[k].max_fil = atoi(nv);
  404.     }
  405.   }
  406.  
  407. /* ============================ */
  408. /* Process xxxTitle parameters. */
  409. /* ============================ */
  410. void  title_line(v,t)
  411. char *v;                                // parameter string pointer
  412. char *t[];                              // pointer to title ptr array
  413. {
  414.   int i,j;                              // counters
  415.  
  416.   for (i=0; i<MAXTIT && t[i]!=NULL; ++i);  // search 1st free place
  417.   if (i<MAXTIT) {                       // not too many subtitles?
  418.     t[i] = (char *)malloc(strlen(v)+1);   // obtain memory
  419.     if (t[i] == NULL) {
  420.       printf(MSG_MEM,PROGNAME);         // not enough memory
  421.       exit(14);
  422.       }
  423.     else {
  424.       for (j=0; v[j]; j++)              // copy whole line
  425.         if (v[j] == '~')                // tilde
  426.           t[i][j] = ' ';                // translate into blank
  427.         else
  428.           t[i][j] = v[j];               // copy
  429.       t[i][j] = '\0';                   // end of string
  430.       }
  431.     }
  432.   }
  433.  
  434. /* ===================================== */
  435. /* Find the number of the config options */
  436. /* Returns the keyword symbolic number,  */
  437. /* and pointer to the keyword value.     */
  438. /* ===================================== */
  439. int  parse_keyword(line,value)
  440. char line[];                            // input line config file
  441. char **value;                           // return: ptr to value string
  442.                                         // (NULL) if not found
  443. {
  444.   int i,p;                              // counters
  445.  
  446.   static struct parse_config {          // Keyword Parameter Spec
  447.        unsigned char id;                // parameter identifier
  448.        unsigned char len;               // keyword length
  449.        char *key;                       // keyword
  450.        } cfg[] = {                      // table of keyword parameters
  451.                                         // NOTE: most significant first!
  452.            {K_ALL, 11, "AllFileList"},
  453.            {K_IPF, 11, "IpfFileList"},
  454.            {K_DAT,  7, "AreaDat"},
  455.            {K_BBS, 11, "BbsFileList"},
  456.            {K_BOT, 10, "BottomLine"},
  457.            {K_FIL, 11, "FilFilePath"},
  458.            {K_GBL, 11, "GblFileList"},
  459.            {K_NNN, 11, "MaxNewFiles"},
  460.            {K_NEW, 11, "NewFileList"},
  461.            {K_NDS, 12, "NotFoundDesc"},
  462.            {K_ORP, 11, "OrpFileList"},
  463.            {K_ODS, 10, "OrphanDesc"},
  464.            {K_PRE,  8, "PreTitle"},
  465.            {K_SUB,  8, "SubTitle"},
  466.            {K_FNT,  9, "TitleFont"},
  467.            {K_TIT,  5, "Title"},
  468.            {K_END,  0, ""},             // end of table: keyw. not found
  469.              };
  470.  
  471.   *value = NULL;                        // init: default return
  472.  
  473.   for (i=0; line[i]==' '; ++i);         // skip leading blanks
  474.   line = line+i;                        // new local pointer
  475.  
  476.   if (line[0] == '%'  ||                // comment
  477.       line[0] == ';'  ||                // comment
  478.       line[0] == '*'  ||                // comment
  479.       line[0] == '\n' ||                // end of line
  480.       line[0] == '\0')                  // end of string
  481.     return(K_CMT);                      // return as comment line
  482.  
  483.   for (i=0; cfg[i].id < K_END &&         // not end of table
  484.            strnicmp(line,cfg[i].key,cfg[i].len) != 0 ; i++);
  485.   p = cfg[i].id;                        // return identification value
  486.  
  487.   *value = next_word(line);             // search value string
  488.   if (*value == NULL)                   // no keyword value
  489.     return(K_CMT);                      // treat as comment
  490.  
  491.   i = strlen(*value);                   // length of value string
  492.   if ((*value)[i-1] == '\n')            // replace end of line
  493.     (*value)[i-1] = '\0';               // by end of string
  494.  
  495.   return(p);                            // return the keyword number
  496.   }
  497.  
  498.