home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / news / cnews.tar / contrib / snntpd / msgid.c < prev    next >
C/C++ Source or Header  |  1992-10-31  |  3KB  |  149 lines

  1. /*
  2.  * msgid -- message ID client interface
  3.  * vix 13feb91 [negative caching]
  4.  * vix 24may90 [written]
  5.  * with mods ken@sdd.hp.com 01jul90
  6.  * hide 4BSD networking goo, Geoff Collyer, October 1992
  7.  *
  8.  * $Header: msgid.c,v 1.6 91/08/17 12:04:11 vixie Locked $
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include <sys/types.h>
  15. #include <sys/time.h>
  16.  
  17. #ifdef hpux
  18. #include <sys/param.h>
  19. #include <libBSD.h>
  20. #endif
  21. #include <syslog.h>
  22.  
  23. #define NEEDMSGS
  24. #include "msgid.h"
  25. #include "ipc.h"
  26.  
  27. #define SERVERTIMEOUT 30
  28.  
  29. static char hostname[256];
  30. static int s = -1;        /* connection to msgidd */
  31.  
  32. static int read_answer();
  33.  
  34. /*
  35.  * Protocol:
  36.  *    Return value as used here is from the server to us.  Note that this
  37.  *    may not be the same as the return value from msgid().
  38.  *
  39.  *    3 message types:
  40.  *    MCANCEL: Delete an id from the holding queues.  Return value is
  41.  *        non-0 for failure.
  42.  *    MADD: Check for dup and add as needed.  Return value is non-0 for dup.
  43.  *    MHOST: inform the server who is on the other end of this nntpd.
  44.  *        Return value is non-0 for failure.  Used only in msgid_init().
  45.  *    MOLD: produce a log message of type "old"
  46.  */
  47.  
  48. static int
  49. sndmsg(type, msg, fail)        /* send a message and get an answer */
  50. int type;
  51. char *msg;
  52. {
  53.     char buf[300];
  54.  
  55.     (void) strcpy(buf, msgs[type]);
  56.     (void) strcat(buf, msg);
  57.     if (write(s, buf, strlen(buf)) < 0) {
  58.         (void) close(s);
  59.         s = -1;
  60.         syslog(LOG_ERR, "msgid: host message write: %m", SOCKNAME);
  61.         return fail;
  62.     }
  63.     return read_answer();
  64. }
  65.  
  66. /* 
  67.  * returns: 0 for ok, 1 for failure
  68.  */
  69. msgid_init()
  70. {
  71.     static int dead_server_count = 0;
  72.  
  73.     s = ipcopen(ipcpath("localhost", "unix", SOCKNAME), "");
  74.     if (s < 0) {
  75.         /*
  76.          * only syslog every 128 messages, so that dead msgidd
  77.          * doesn't lead to multi-megabyte syslog files (vix,
  78.          * 13feb91)
  79.          */
  80.         if ((dead_server_count++ % 128) == 0)
  81.             syslog(LOG_ERR, "msgid: can't connect to %s: %m",
  82.                 SOCKNAME);
  83.         return 1;
  84.     }
  85.     if (hostname[0] == '\0')
  86.         (void) gethostname(hostname, sizeof hostname);
  87.     return sndmsg(MHOST, hostname, 1);
  88. }
  89.  
  90. /* 
  91.  * returns: nonzero = duplicate, return value doesn't mean much for the
  92.  *          MADD or MOLD messages
  93.  */
  94. int
  95. msgid(id, mtype)
  96. char *id;
  97. int mtype;
  98. {
  99.     register char *cp = id;
  100.  
  101.     if (s == -1 && msgid_init())
  102.         return 0;
  103.  
  104.     /*
  105.      * We need to do this just because gethistent does it
  106.      * "in place" so add vs old gets fried ...
  107.      *
  108.      * If running Bnews, converts "id" to lower case.
  109.      * If running Cnews, converts "id" per rfc822.
  110.      */
  111. #ifndef BNEWS
  112.     cp = strrchr(id, '@');        /* look for @ in message id */
  113. #endif
  114.     if (cp != NULL)
  115.         for (; *cp != '\0'; ++cp)
  116.             if (isupper(*cp))
  117.                 *cp = tolower(*cp);
  118.     return sndmsg(mtype, id, 0);
  119. }
  120.  
  121. static int    
  122. read_answer()
  123. {
  124.     register int i;
  125.     fd_set readfds;
  126.     register fd_set *rfdp = &readfds;
  127.     char c;
  128.     struct timeval to;
  129.  
  130.     FD_ZERO(rfdp);
  131.     FD_SET(s, rfdp);
  132.     to.tv_sec = SERVERTIMEOUT;
  133.     to.tv_usec = 0;
  134.     i = select(s + 1, rfdp, (fd_set *)NULL, (fd_set *)NULL, &to);
  135.     if (i < 0)
  136.         syslog(LOG_ERR, "msgid: select: %m");
  137.     else if (i == 0 || FD_ISSET(s, rfdp) == 0 ||
  138.         (i = read(s, &c, 1)) == 0)
  139.         syslog(LOG_ERR, "msgid: read timeout");
  140.     else if (i < 0)
  141.         syslog(LOG_ERR, "msgid: read: %m");
  142.     else
  143.         return c != 0;
  144.  
  145.     (void) close(s);
  146.     s = -1;
  147.     return 0;
  148. }
  149.