home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / b / bmh02src.zip / NNTP.C < prev    next >
C/C++ Source or Header  |  1992-08-18  |  7KB  |  282 lines

  1. /*
  2.    nntp.c : Paul Healy, EI9GL.
  3.  
  4.    920816 : Added this header, bmh version.
  5.             Todo:
  6.                . check that the date is ok for nntp
  7.                . generally check file writes for success
  8.  
  9.  * NNTP Server/Client - See RFC977
  10.  * Jeffrey R. Comstock. - NR0D - Bloomington, Minnesota USA
  11.  * Copyright 1990 Jeffrey R. Comstock, All Rights Reserved.
  12.  * Permission granted for non-commercial copying and use, provided
  13.  * this notice is retained.
  14.  *
  15.  * DB3FL 9107xx: heavily rewritten and bug fixing in file-handling
  16.  *
  17.  * ported to NOS by PE1NMB - 920120
  18.  *
  19.  * Mods by PA0GRI and WG7J
  20.  */
  21. #include <stdio.h>
  22. #include <time.h>
  23. #include <ctype.h>
  24. #include <string.h>
  25. #include <io.h>
  26. #include <dir.h>
  27. #include "mailer.h"
  28. #include "current.h"
  29. #include "nntp.h"
  30. #include "send.h"
  31. #include "lock.h"
  32. #include "rc.h"
  33. #include "smtp.h"
  34. #include "misc.h"
  35.  
  36. static int
  37. makedir(char *path)
  38. {
  39.     if (path == NULL)
  40.         return -1;
  41.  
  42.     if (access(path, 0) == -1) {
  43.       fprintf(stderr, "bmh: making directory %s\n", path);
  44.         if (mkdir(path) == -1) {
  45.          perror(path);
  46.             return -1;
  47.            }
  48.       }
  49.  
  50.     return 0;
  51. }
  52.  
  53. /*
  54.  * creating path to a new newsgroup
  55.  */
  56. int
  57. makepath(char *path)
  58. {
  59.    char *cp = path;
  60.  
  61.    if (*cp == '/')
  62.       cp++;
  63.  
  64.     while (1) {
  65.        cp = strchr(cp, '/');
  66.  
  67.       if ( cp == NULL )
  68.            return makedir(path);
  69.         else
  70.             *cp = '\0';
  71.  
  72.         if (makedir(path) == -1)
  73.             return -1;
  74.  
  75.       if (cp != NULL) {
  76.            *cp = '/';
  77.          cp++;
  78.          }
  79.       }
  80. }
  81.  
  82. static int
  83. addpath(char *group)
  84. {
  85.    char path[256], *cp = path;
  86.     FILE *pointerfp = fopenlocked(getrc(newsdir), "pointer", "", "a");
  87.    int ret;
  88.  
  89.    sprintf(path, "%s/%s", getrc(newsdir), group);
  90.    while (*cp) {
  91.       if (*cp == '.')
  92.          *cp = '/';
  93.       cp++;
  94.       }
  95.    ret = makepath(path);
  96.  
  97.     if (pointerfp == NULL) {
  98.       fprintf(stderr, "nntp: can't open pointer file\n");
  99.         return -1;
  100.       }
  101.  
  102.    fprintf(pointerfp, "%s %s\n", group, path);
  103.    fcloselocked(pointerfp, getrc(newsdir), "pointer");
  104.  
  105.    return ret;
  106. }
  107.  
  108. static int
  109. addhistory(char *id, char *group, long num)
  110. {
  111.    FILE *fp = fopenlocked(getrc(newsdir), "history", "", "a");
  112.    struct tm *stm;
  113.    long currtime;
  114.  
  115.    if (fp == NULL) {
  116.       fprintf(stderr, "nntp: error opening %s/history\n", getrc(newsdir));
  117.       return -1;
  118.       }
  119.  
  120.    time(&currtime);
  121.    stm = localtime(&currtime);
  122.  
  123.    fprintf(fp, "%s %2.2d%2.2d%2.2d %2.2d%2.2d%2.2d %s/%d\n",
  124.       id,
  125.       stm->tm_year, stm->tm_mon+1, stm->tm_mday,
  126.       stm->tm_hour, stm->tm_min, stm->tm_sec,
  127.       group, num);
  128.  
  129.    fcloselocked(fp, getrc(newsdir), "history");
  130.  
  131.    return 0;
  132. }
  133.  
  134. static char *
  135. getpath(char *group, char *path, int maxpath)
  136. {
  137.    FILE *fp = fopenlocked(getrc(newsdir), "pointer", "", "r");
  138.    int grplen = strlen(group);
  139.    char *result = path, tmp[256];
  140.  
  141.    sprintf(path, "%s/%s", getrc(newsdir), news2dir(strcpy(tmp, group)));
  142.  
  143.    if (fp == NULL)
  144.       return result;
  145.  
  146.    while (fgets(path, maxpath, fp) != NULL)
  147.       if (strncmp(group, path, grplen) == 0) {
  148.          rip(path);
  149.          result = &path[grplen+1];
  150.          break;
  151.          }
  152.  
  153.    fcloselocked(fp, getrc(newsdir), "pointer");
  154.  
  155.    return result;
  156. }
  157.  
  158. static long
  159. updateactivelist(char *group)
  160. {
  161.    FILE *activefp = fopenlocked(getrc(newsdir), "active", "", "r+"), *tmpfp;
  162.    long number = 0;
  163.    char buf[512], filename[256];
  164.    int grplen = strlen(group);
  165.  
  166.    if ( (activefp == NULL) &&
  167.         ( (activefp = fopenlocked(getrc(newsdir), "active", "", "w+")) == NULL)
  168.       ) {
  169.       fprintf(stderr, "post: can't open active file\n");
  170.       return -1L;
  171.       }
  172.  
  173.    if ((tmpfp = tempfile("post", filename, "w")) == NULL) {
  174.       fcloselocked(activefp, getrc(newsdir), "active");
  175.       fprintf(stderr, "post: can't open temporary file\n");
  176.       return -1;
  177.       }
  178.  
  179.    while (fgets(buf, sizeof(buf), activefp) != NULL)
  180.       if (strncmp(group, buf, grplen) == 0) {
  181.          long low;
  182.          char posting, moderated = ' ';
  183.  
  184.          sscanf(&buf[grplen+1], "%ld %ld %c %c",
  185.             &number, &low, &posting, &moderated);
  186.          fprintf(tmpfp,"%s %5.5ld %5.5ld %c %c\n",
  187.             group, ++number, low, posting, moderated);
  188.          }
  189.       else
  190.          fputs(buf, tmpfp);
  191.  
  192.    if (number == 0) {
  193.       addpath(group);
  194.       number = 1;
  195.       fprintf(tmpfp, "%s 00001 00001 y\n", group);
  196.       }
  197.  
  198.    rewind(tmpfp);
  199.    rewind(activefp);
  200.    dupfile(tmpfp, activefp);
  201.  
  202.    fcloselocked(activefp, getrc(newsdir), "active");
  203.    fclose(tmpfp);
  204.    unlink(filename);
  205.  
  206.    return number;
  207. }
  208.  
  209. static int
  210. xferart(FILE *fpin, char *from, char *group, char *msgid)
  211. {
  212.    long num;
  213.  
  214.    if ((num = updateactivelist(group)) > 0L) {
  215.       char Num[20], pathname[256], *path;
  216.       FILE *fp;
  217.       
  218.       sprintf(Num, "%ld", num);
  219.  
  220.       if ( (fp = fopenlocked(path = getpath(group, pathname, sizeof(pathname)),
  221.                   Num, "", "w")) == NULL) {
  222.          fprintf(stderr, "post: can't open %s/%s\n", path, Num);
  223.          return -1;
  224.          }
  225.       dupfile(fpin, fp);
  226.       fcloselocked(fp, path, Num);
  227.  
  228.       addhistory(msgid, group, num);
  229.       return 0;
  230.    }
  231.    else {
  232.       fprintf(stderr, "post: can't update active list\n");
  233.       return -1;
  234.       }
  235. }
  236.  
  237. int
  238. post(FILE *fpin, char *newsgroup, char *subject)
  239. {
  240.    char msgid[256], filename[256], from[256];
  241.    int ret = -1;
  242.    FILE *fp;
  243.  
  244.    if ( makepath(getrc(newsdir)) == -1 )
  245.       return -1;
  246.  
  247.    sprintf(msgid, "<%ld@%s>", get_msgid(getrc(mqueue)), getrc(hostname));
  248.    sprintf(from, "%s@%s", getrc(username), getrc(hostname));
  249.  
  250.    if ((fp = tempfile("post", filename, "w")) == NULL)
  251.       return -1;
  252.  
  253.    fprintf(fp, "Path: %s\n", getrc(username) );
  254.    fprintf(fp, "Sender: nntp@%s\n", getrc(hostname));
  255.    fprintf(fp, "Newsgroup: %s\n", newsgroup);
  256.  
  257.    fprintf(fp, "Date: %s", ptime(time(NULL)));
  258.    fprintf(fp, "Msgid: %s\n", msgid);
  259.    fprintf(fp, "From: %s", from);
  260.    if (getrc(fullname) != NULL)
  261.       fprintf(fp, " (%s)", getrc(fullname) );
  262.    fputc('\n', fp);
  263.    fprintf(fp, "Subject: %s\n", subject);
  264.  
  265.    if (getrc(replyto) != NULL)
  266.       fprintf(fp, "Reply-To: %s\n", getrc(replyto));
  267.    if (getrc(organ) != NULL)
  268.       fprintf(fp,"Organization: %s\n", getrc(organ));
  269.    fputc('\n', fp);
  270.  
  271.    dupfile(fpin, fp);
  272.    rewind(fp);
  273.    ret = xferart(fp, from, newsgroup, msgid);
  274.  
  275.    fclose(fp);
  276.    unlink(filename);
  277.    if (ret == -1)
  278.       fprintf(stderr, "post: failed to send article\n");
  279.  
  280.    return ret;
  281. }
  282.