home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / comms / network / grn1asrc.lha / grnrc.c < prev    next >
C/C++ Source or Header  |  1992-05-20  |  13KB  |  510 lines

  1. #include    "defs.h"
  2. #include    <stdarg.h>
  3.  
  4. ULONG        grnrcVersion = '1.20';
  5.  
  6. char        userName[256], grnrcName[256];
  7. char        newsEditor[256], mailEditor[256];
  8. char        postNews[256], sendMail[256];
  9. char        uunews[256] = "UUNEWS:";
  10. char        uulib[256] = "UULIB:";
  11. char        uuspool[256] = "UUSPOOL:";
  12. char        logfile[256] = "uuspool:logfile";
  13.  
  14. LOCK        lock = 0;
  15. FIB        *fib = 0;
  16.  
  17. LIST        groupList;
  18.  
  19. BOOL        treeDirty = 0;
  20. BOOL        debug = 0;
  21.  
  22. /************************************************************************/
  23.  
  24. /*
  25.  * void    Abort(void);
  26.  *
  27.  * Synopsis:
  28.  *    Cleanup and exit.  Can be called anywhere, anytime, including from
  29.  *    the debugger by setting PC = Abort.
  30.  */
  31. long    abort_code = 0;
  32. void    Abort(void) {
  33.     exit(abort_code);
  34. }
  35.  
  36. /*
  37.  * void    panic0(v, s, ...);
  38.  * ULONG    v;
  39.  * char        *s;
  40.  * ULONG    a1,a2,a3,a4;
  41.  *
  42.  * Synopsis:
  43.  *    Anywhere you use:
  44.  *        v = (some function);
  45.  *        if (!v) {
  46.  *            printf("some string");
  47.  *            Abort();
  48.  *        }
  49.  *    You can use:
  50.  *        v = (some function);
  51.  *        panic0(v, "some string");
  52.  *    The string and args (a1,a2,a3,a4) are passed to printf...
  53.  */
  54. void    panic0(APTR v, char *s, ...) {
  55.     FILE    *outfp;
  56.     va_list    va;
  57.  
  58.     va_start(va, s);
  59.     if (v) return;
  60.     printf("Panic: ");
  61.     printf(s, va);
  62.     printf("\n");
  63.     outfp = fopen(logfile, "a");
  64.     if (outfp) {
  65.         fprintf(outfp, "GRn panic: ");
  66.         fprintf(outfp, s, va);
  67.         fprintf(outfp, "\n");
  68.         fclose(outfp);
  69.     }
  70.     abort_code = 999;
  71.     va_end(va);
  72.     Abort();
  73. }
  74.  
  75. void    panic(char *s,...) {
  76.     FILE    *outfp;
  77.     va_list    va;
  78.  
  79.     va_start(va, s);
  80.     printf("Panic: ");
  81.     printf(s, va);
  82.     printf("\n");
  83.     outfp = fopen(logfile, "a");
  84.     if (outfp) {
  85.         fprintf(outfp, "GRn panic: ");
  86.         fprintf(outfp, s, va);
  87.         fprintf(outfp, "\n");
  88.         fclose(outfp);
  89.     }
  90.     abort_code = 999;
  91.     va_end(va);
  92.     Abort();
  93. }
  94.  
  95. /************************************************************************/
  96.  
  97. BOOL    EmptyList(list)
  98. LIST    *list;
  99. {
  100.     if (list->lh_TailPred == (NODE *)list) return !0;
  101.     return 0;
  102. }
  103.  
  104. /************************************************************************/
  105.  
  106. UBYTE    *mbuf = 0, *mbufp, *mbufe;
  107.  
  108. void    mclose(void) { if (mbuf) { free(mbuf); mbuf = 0; } }
  109. BOOL    mopen(char *fn) {
  110.     int    fd;
  111.     ULONG    size;
  112.  
  113.     mclose();
  114.     fd = open(fn, O_READ);
  115.     if (fd == -1) return 0;
  116.     size = lseek(fd, 0, 2); lseek(fd, 0, 0);
  117.     mbuf = (UBYTE *)malloc(size);
  118.     if (!mbuf) { close(fd); return 0; }
  119.     read(fd, mbuf, size);
  120.     close(fd);
  121.     mbufp = mbuf;
  122.     mbufe = &mbufp[size];
  123.     return !0;
  124. }
  125.  
  126. BOOL    mread(buf, size)
  127. UBYTE    *buf;
  128. ULONG    size;
  129. {
  130.     ULONG    i;
  131.  
  132.     if (!mbuf || mbufp == mbufe) return 0;
  133.     for (i=0; i<size; i++) *buf++ = (mbufp == mbufe) ? 0 : *mbufp++;
  134.     return !0;
  135. }
  136.  
  137. BOOL    mgets(buf)
  138. UBYTE    *buf;
  139. {
  140.     if (mbufp == mbufe) return 0;
  141.     while (mbufp != mbufe && (*buf++ = *mbufp++));
  142.     *buf++ = '\0';
  143.     return !0;
  144. }
  145.  
  146. /************************************************************************/
  147.  
  148. void    FixName(dst, src)
  149. char    *dst, *src;
  150. {
  151.     short    i, j;
  152.     BOOL    ltFlag = 0;
  153.     char    *d = dst;
  154.  
  155.     for (i=0; src[i]; i++) if (src[i] == '<') ltFlag = !0;
  156.  
  157.     if (*src == '"') {
  158.         for (j=1; src[j] && src[j] != '"'; j++) *dst++ = src[j];
  159.         *dst++ = '\0';
  160.         if (dst-d > 512) printf("FixName1 string to big: %d bytes '%s'\n", dst-d, d);
  161.         return;
  162.     }
  163.     if (*src == '<') {
  164.         for (j=1; src[j] && src[j] != '@' && src[j] != '>'; j++) {
  165.             if (src[j] == '.') 
  166.                 *dst++ = ' ';
  167.             else
  168.                 *dst++ = src[j];
  169.         }
  170.         *dst++ = '\0';
  171.         if (dst-d > 512) printf("FixName2 string to big: %d bytes '%s'\n", dst-d, d);
  172.         return;
  173.     }
  174.     for (j=0; src[j]; j++) {
  175.         if (src[j] == '<') {
  176.             if (!j) {
  177.                 if (strlen(src) > 511) printf("FixName3 string to big: %d bytes '%s'\n", dst-d, src);
  178.                 strncpy(dst, src, 512);
  179.                 return;
  180.             }
  181.             else {
  182.                 for (i=0; i<j; i++) *dst++ = *src++;
  183.                 *dst++ = '\0';
  184.                 if (dst-d > 512) printf("FixName4 string to big: %d bytes '%s'\n", dst-d, d);
  185.                 return;
  186.             }
  187.         }
  188.         if (src[j] == '(' && !ltFlag) {
  189.             j++;
  190.             while (src[j] && src[j] != ')') *dst++ = src[j++];
  191.             *dst++ = '\0';
  192.             if (dst-d > 512) printf("FixName5 string to big: %d bytes '%s'\n", dst-d, d);
  193.             return;
  194.         }
  195.     }
  196.     j=-1;
  197.     for (i=0; src[i]; i++) if (src[i] == '!') j = i;
  198.     if (j != -1) {
  199.         j++;
  200.         while (src[j] && src[j] != ',' && src[j] != '@') *dst++ = src[j++];
  201.         *dst++ = '\0';
  202.     }
  203.     else {
  204.         while (*src && *src != '%' && *src != '@') *dst++ = *src++;
  205.         *dst++ = '\0';
  206.     }
  207.     if (dst-d > 512) printf("FixName6 string to big: %d bytes '%s'\n", dst-d, d);
  208. }
  209.  
  210. /************************************************************************/
  211.  
  212. void    WriteNewsTree() {
  213.     int    fd;
  214.     ART    *ap;
  215.     GLIST    *gp;
  216.     UWORD    end = END;
  217.  
  218.     if (!treeDirty) return;
  219. if (debug) printf("Writing news tree\n");
  220.     fd = open(grnrcName, O_WRITE);
  221.     if (fd == -1) panic("Can't open %s for output", grnrcName);
  222.     write(fd, &grnrcVersion, 4);
  223.  
  224.     for (gp = (GLIST *)groupList.lh_Head; gp->node.ln_Succ; gp=(GLIST *)gp->node.ln_Succ) {
  225.         write(fd, gp->groupName, strlen(gp->groupName)+1);
  226.         write(fd, &gp->hideHeaders, 1);
  227.         write(fd, &gp->hideRead, 1);
  228.         write(fd, &gp->nextReceived, 4);
  229.         write(fd, &gp->sortActive, 2);
  230.         // sort the articles in this group by number
  231.         SortArticlesByNumber(&gp->artList);
  232.         for (ap=(ART *)gp->artList.lh_Head; ap->node.ln_Succ; ap=(ART *)ap->node.ln_Succ) {
  233.             write(fd, &ap->state, 2);
  234.             write(fd, &ap->filenum, 4);
  235.             write(fd, ap->from, strlen(ap->from)+1);
  236.             write(fd, ap->subject, strlen(ap->subject)+1);
  237.         }
  238.         write(fd, &end, 2);
  239.     }
  240.     close(fd);
  241.     treeDirty = 0;
  242. }
  243.  
  244. void    ReadNewsTree() {
  245.     ART    *ap;
  246.     GLIST    *gp;
  247.     char    groupName[256], temp[256];
  248.     UWORD    endTest;
  249.     ULONG    pct;
  250.  
  251. if (debug) printf("GRn - Reading News Tree...\n");
  252.     while (1) {
  253.         if (!mgets(&groupName[0])) break;
  254.         gp = (GLIST *)malloc(sizeof(GLIST));
  255.         panic0(gp, "Can't malloc GLIST %d bytes", sizeof(GLIST));
  256.         gp->node.ln_Name = &gp->header[0];
  257.         AddTail(&groupList, (NODE *)gp);
  258.         NewList(&gp->artList);
  259.         gp->articles = gp->unread = 0;
  260.         mread(&gp->hideHeaders, 1);
  261.         mread(&gp->hideRead, 1);
  262.         mread(&gp->nextReceived, 4);
  263.         mread(&gp->sortActive, 2);
  264.         pct = (100*(ULONG)(mbufp-mbuf))/(ULONG)(mbufe-mbuf);
  265.         while (1) {
  266.             mread(&endTest, 2);
  267.             if (endTest == END) break;
  268.             ap = (ART *)malloc(sizeof(ART));
  269.             panic0(ap, "Can't malloc ART %d bytes", sizeof(ART));
  270.             ap->node.ln_Name = &ap->header[0];
  271.             ap->state = endTest;
  272.             mread(&ap->filenum, 4);
  273.             mgets(temp);
  274.             ap->from = (char *)malloc(strlen(temp)+1);
  275.             panic0(ap->from, "Can't allocate memory for From: field");
  276.             strcpy(ap->from, temp);
  277.  
  278.             mgets(temp);
  279.             ap->subject = (char *)malloc(strlen(temp)+1);
  280.             panic0(ap->subject, "Can't allocate memory for Subject: field");
  281.             strcpy(ap->subject, temp);
  282.  
  283.             AddTail(&gp->artList, (NODE *)ap);
  284.             gp->articles++;
  285.             if (ap->state == UNREAD || ap->state == NEW) gp->unread++;
  286.         }
  287.         strcpy(gp->groupName, groupName);
  288.         sprintf(gp->header, "%-40.40s %6d articles %6d UnRead", gp->groupName, gp->articles, gp->unread);
  289.     }
  290.     mclose();
  291. }
  292.  
  293. void    UpdateNewsTree() {
  294.     GLIST    *gp;
  295.     ART    *ap;
  296.     long    num, last;        // article number
  297.     char    fname[256], work[512], from[512], subject[512];
  298.     FILE    *fp;
  299.     BOOL    flag;
  300.  
  301.     // for each group
  302.     for (gp=(GLIST *)groupList.lh_Head; gp->node.ln_Succ; gp = (GLIST *)gp->node.ln_Succ) {
  303. if (debug) printf("GRn - Pruning %s\n", gp->groupName);
  304.         // scan through list and check to see if the files are still there!
  305.         flag = 0;
  306.         for (ap=(ART *)gp->artList.lh_Head; ap->node.ln_Succ; ap = (ART *)ap->node.ln_Succ) {
  307.             strcpy(fname, uunews);
  308.             AddPart(fname, gp->groupName, 256);
  309.             sprintf(work, "%d", ap->filenum);
  310.             AddPart(fname, work, 256);
  311.             if (!flag) {
  312.                 lock = Lock(fname, SHARED_LOCK);
  313.                 if (lock) {
  314.                     UnLock(lock); lock = 0;
  315.                     flag = !0;
  316.                 }
  317.                 else {
  318.                     if (ap->state == UNREAD) gp->unread--;
  319.                     gp->articles--;
  320.                     Remove((NODE *)ap);
  321.                     if (ap->subject) free(ap->subject);
  322.                     if (ap->from) free(ap->from);
  323.                     free(ap);
  324.                     treeDirty = !0;
  325.                 }
  326.             }
  327.         }
  328.         // Find new articles, mark as unread!
  329. if (debug) printf("GRn - Getting new articles for %s\n", gp->groupName);
  330.         strcpy(fname, uunews);
  331.         AddPart(fname, gp->groupName, 256);
  332.         AddPart(fname, ".next", 256);
  333.         fp = fopen(fname, "r");
  334.         if (fp) {
  335.             fgets(work, 512, fp);
  336.             fclose(fp);
  337.             last = atoi(work);
  338.         }
  339.         else {
  340.             last = 1000000;
  341.         }
  342.         for (num = gp->nextReceived; num<last; num++) {
  343.             strcpy(fname, uunews);
  344.             AddPart(fname, gp->groupName, 256);
  345.             sprintf(work, "%d", num);
  346.             AddPart(fname, work, 256);
  347.             fp = fopen(fname, "r");
  348.             if (!fp) {
  349.                 if (last == 1000000) break;
  350. if (debug) printf("skipping %s\n", fname);
  351.                 continue;
  352.             }
  353.             ap = (ART *)malloc(sizeof(ART));
  354.             panic0(ap, "Can't malloc ART %d bytes", sizeof(ART));
  355.             ap->node.ln_Name = &ap->header[0];
  356.             ap->state = UNREAD;
  357.             ap->filenum = num;
  358.  
  359.             strcpy(from, "UNKNOWN");
  360.             strcpy(subject, "NO SUBJECT");
  361.             while (fgets(work, 512, fp)) {
  362.                 work[strlen(work)-1] = '\0';
  363.                 if (!work[0]) break;
  364.                 if (!strncmp(work, "From: ", 6)) strcpy(from, &work[6]);
  365.                 else if (!strncmp(work, "Subject: ", 9)) strcpy(subject, &work[9]);
  366.             }
  367.             fclose(fp);
  368.             FixName(work, from);
  369.             ap->from = (char *)malloc(strlen(work)+1);
  370.             panic0(ap->from, "Can't allocate memory for From:\n");
  371.             strcpy(ap->from, work);
  372.             ap->subject = (char *)malloc(strlen(subject)+1);
  373.             panic0(ap->subject, "Can't allocate memory for subject:\n");
  374.             strcpy(ap->subject, subject);
  375.             AddTail(&gp->artList, (NODE *)ap);
  376.             gp->articles++;
  377.             gp->unread++;
  378.             treeDirty = !0;
  379.         }
  380.         sprintf(gp->header, "%-40.40s %6d articles %6d UnRead", gp->groupName, gp->articles, gp->unread);
  381.         if (gp->nextReceived != last) {
  382.             gp->nextReceived = last;
  383.             treeDirty = !0;
  384.         }
  385.     }
  386. }
  387.  
  388. /************************************************************************/
  389.  
  390. void    ParseConfig(void) {
  391.     char    buf[512], *ps;
  392.     FILE    *fp;
  393.     BOOL    uulibFlag = 0;
  394.  
  395.     userName[0] = mailEditor[0] = newsEditor[0] = '\0';
  396.     GetVar("USERNAME", &userName[0], 256, GVF_GLOBAL_ONLY);
  397.     GetVar("NEWSEDITOR", &newsEditor[0], 256, GVF_GLOBAL_ONLY);
  398.     GetVar("MAILEDITOR", &newsEditor[0], 256, GVF_GLOBAL_ONLY);
  399.     GetVar("SENDMAIL", &sendMail[0], 256, GVF_GLOBAL_ONLY);
  400.     GetVar("POSTNEWS", &postNews[0], 256, GVF_GLOBAL_ONLY);
  401.     if (userName[0] && newsEditor[0] && mailEditor[0] && sendMail[0] && postNews[0]) return;
  402.  
  403.     fp = fopen("s:uuconfig", "r");
  404.     if (!fp) {
  405.         fp = fopen("uulib:config", "r");
  406.         panic0(fp, "Can't open uulib:config");
  407.         uulibFlag = !0;
  408.     }
  409.     while (fgets(buf, 512, fp) && (!userName[0] || !newsEditor[0] || !mailEditor[0] || !sendMail[0] || !postNews[0])) {
  410.         buf[strlen(buf)-1] = '\0';
  411.         if (userName[0] == '\0' && !strnicmp(buf, "UserName", 8)) {
  412.             ps = &buf[8];
  413.             while (*ps == ' ' || *ps == '\t') ps++;
  414.             if (*ps == '\0') panic("s:uuconfig or uulib:config UserName is NULL");
  415.             strcpy(userName, ps);
  416.         }
  417.         else if (newsEditor[0] == '\0' && !strnicmp(buf, "NewsEditor", 10)) {
  418.             ps = &buf[10];
  419.             while (*ps == ' ' || *ps == '\t') ps++;
  420.             if (*ps == '\0') panic("s:uuconfig or uulib:config NewsEditor is NULL");
  421.             strcpy(newsEditor, ps);
  422.         }
  423.         else if (mailEditor[0] == '\0' && !strnicmp(buf, "MailEditor", 10)) {
  424.             ps = &buf[10];
  425.             while (*ps == ' ' || *ps == '\t') ps++;
  426.             if (*ps == '\0') panic("s:uuconfig or uulib:config MailEditor is NULL");
  427.             strcpy(mailEditor, ps);
  428.         }
  429.         else if (sendMail[0] == '\0' && !strnicmp(buf, "SendMail", 8)) {
  430.             ps = &buf[8];
  431.             while (*ps == ' ' || *ps == '\t') ps++;
  432.             if (*ps == '\0') panic("s:uuconfig or uulib:config Sendmail is NULL");
  433.             strcpy(sendMail, ps);
  434.         }
  435.         else if (postNews[0] == '\0' && !strnicmp(buf, "PostNews", 8)) {
  436.             ps = &buf[8];
  437.             while (*ps == ' ' || *ps == '\t') ps++;
  438.             if (*ps == '\0') panic("s:uuconfig or uulib:config Postnews is NULL");
  439.             strcpy(postNews, ps);
  440.         }
  441.         else if (!strnicmp(buf, "UUNews", 6)) {
  442.             ps = &buf[6];
  443.             while (*ps == ' ' || *ps == '\t') ps++;
  444.             if (*ps) strcpy(uunews, ps);
  445.         }
  446.         else if (!uulibFlag && !strnicmp(buf, "UUlib", 5)) {
  447.             ps = &buf[5];
  448.             while (*ps == ' ' || *ps == '\t') ps++;
  449.             if (*ps) strcpy(uulib, ps);
  450.         }
  451.         else if (!strnicmp(buf, "UUSpool", 7)) {
  452.             ps = &buf[7];
  453.             while (*ps == ' ' || *ps == '\t') ps++;
  454.             if (*ps) strcpy(uuspool, ps);
  455.         }
  456.     }
  457.     fclose(fp);
  458.     if (userName[0]) {
  459.         strcpy(grnrcName, uulib);
  460.         sprintf(buf, "%s.grnrc", userName);
  461.         AddPart(grnrcName, buf, 256);
  462.     }
  463.     else
  464.         panic("s:uuconfig or uulib:config must contain UserName!");
  465.     if (newsEditor[0] && !mailEditor[0])
  466.         strcpy(mailEditor, newsEditor);
  467.     else if (!newsEditor[0] && mailEditor[0])
  468.         strcpy(newsEditor, mailEditor);
  469.     panic0((APTR)newsEditor[0], "s:uuconfig or uulib:config must contain NewsEditor");
  470.     panic0((APTR)mailEditor[0], "s:uuconfig or uulib:config must contain MailEditor");
  471.     if (!sendMail[0]) strcpy(sendMail, "SendMail");
  472.     if (!postNews[0]) strcpy(postNews, "PostNews");
  473.     strcpy(logfile, uuspool);
  474.     AddPart(logfile, "logfile", 256);
  475. }
  476.  
  477. /************************************************************************/
  478.  
  479. void    main(int ac, char *av[]) {
  480.     ULONG    testver = 0x0a0a5050;
  481.     char    buf[256];
  482.  
  483.     if (ac < 2) {
  484.         printf("Usage: GRnrc username\n");
  485.         printf("\tUpdates user .grnrc file!\n");
  486.         exit(999);
  487.     }
  488.     if (ac > 2) debug = !0;
  489.  
  490.     fib = (FIB *)AllocDosObject(DOS_FIB, TAG_DONE);
  491.     panic0(fib, "Can't AllocDosObject(DOS_FIB)");
  492.  
  493.     NewList(&groupList);
  494.  
  495.     ParseConfig();
  496.  
  497.     strcpy(userName, av[1]);
  498.     strcpy(grnrcName, uulib);
  499.     sprintf(buf, "%s.grnrc", userName);
  500.     AddPart(grnrcName, buf, 256);
  501.  
  502.     if (!mopen(grnrcName)) panic("Can't open %s\n", grnrcName);
  503.     mread(&testver, 4);
  504.     if (testver != grnrcVersion) panic("grnrc is wrong version, delete it and run GRn again");
  505.     ReadNewsTree();
  506.     UpdateNewsTree();
  507.     WriteNewsTree();
  508. }
  509.  
  510.