home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume30 / log_tcp / part02 / rfc931.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-20  |  2.6 KB  |  107 lines

  1.  /*
  2.   * rfc931_user() consults the RFC 931 daemon on the client host to look up
  3.   * the remote user name.
  4.   * 
  5.   * Diagnostics are reported through syslog(3).
  6.   * 
  7.   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  8.   * 
  9.   * Inspired by the authutil package (comp.sources.unix volume 22) by Dan
  10.   * Bernstein (brnstnd@kramden.acf.nyu.edu).
  11.   */
  12.  
  13. #ifndef lint
  14. static char sccsid[] = "@(#) rfc931.c 1.1 92/06/11 22:21:41";
  15. #endif
  16.  
  17. #include <stdio.h>
  18. #include <syslog.h>
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <netinet/in.h>
  22. #include <setjmp.h>
  23. #include <signal.h>
  24.  
  25. #include "log_tcp.h"
  26.  
  27. #define    RFC931_PORT    113        /* Semi-well-known port */
  28. #define    TIMEOUT        10        /* wait for at most 10 seconds */
  29.  
  30. extern char *strchr();
  31.  
  32. static jmp_buf timebuf;
  33.  
  34. /* timeout - handle timeouts */
  35.  
  36. static void timeout(sig)
  37. int     sig;
  38. {
  39.     longjmp(timebuf, sig);
  40. }
  41.  
  42. /* rfc931_name - return remote user name */
  43.  
  44. char   *rfc931_name(there)
  45. struct sockaddr_in *there;        /* remote link information */
  46. {
  47.     struct sockaddr_in here;        /* local link information */
  48.     struct sockaddr_in sin;        /* for talking to RFC931 daemon */
  49.     int     length;
  50.     int     s;
  51.     unsigned remote;
  52.     unsigned local;
  53.     static char user[256];        /* XXX */
  54.     FILE   *fp;
  55.     char   *cp;
  56.     char   *result = FROM_UNKNOWN;
  57.  
  58.     /* Find out local port number of our stdin. */
  59.  
  60.     length = sizeof(here);
  61.     if (getsockname(0, (struct sockaddr *) & here, &length) == -1) {
  62.     syslog(LOG_ERR, "getsockname: %m");
  63.     return (result);
  64.     }
  65.     /* Set up timer so we won't get stuck. */
  66.  
  67.     if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  68.     return (result);
  69.     signal(SIGALRM, timeout);
  70.     if (setjmp(timebuf)) {
  71.     close(s);                /* not: fclose(fp) */
  72.     return (result);
  73.     }
  74.     alarm(TIMEOUT);
  75.  
  76.     /* Connect to the RFC931 daemon. */
  77.  
  78.     sin = *there;
  79.     sin.sin_port = htons(RFC931_PORT);
  80.     if (connect(s, (struct sockaddr *) & sin, sizeof(sin)) == -1
  81.     || (fp = fdopen(s, "w+")) == 0) {
  82.     close(s);
  83.     return (result);
  84.     }
  85.     /* Query the RFC 931 server. Would 13-byte writes ever be broken up? */
  86.  
  87.     fprintf(fp, "%u,%u\r\n", ntohs(there->sin_port), ntohs(here.sin_port));
  88.     fflush(fp);
  89.  
  90.     /* Read response. Kill stdio buffer or we may read back our own query. */
  91.  
  92.     setbuf(fp, (char *) 0);
  93.     if (fscanf(fp, "%u , %u : USERID :%*[^:]:%255s", &remote, &local, user) == 3
  94.     && ferror(fp) == 0 && feof(fp) == 0
  95.     && ntohs(there->sin_port) == remote
  96.     && ntohs(here.sin_port) == local) {
  97.     /* Strip trailing carriage return. */
  98.  
  99.     if (cp = strchr(user, '\r'))
  100.         *cp = 0;
  101.     result = user;
  102.     }
  103.     alarm(0);
  104.     fclose(fp);
  105.     return (result);
  106. }
  107.