home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / gnu / emacs / sources / 546 < prev    next >
Encoding:
Text File  |  1992-07-21  |  7.9 KB  |  328 lines

  1. Newsgroups: gnu.emacs.sources
  2. Path: sparky!uunet!europa.asd.contel.com!darwin.sura.net!udel!rochester!cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!spot
  3. From: spot@CS.CMU.EDU (Scott Draves)
  4. Subject: new tzc.c
  5. Message-ID: <1992Jul22.013541.265731@cs.cmu.edu>
  6. Date: Wed, 22 Jul 92 01:35:41 GMT
  7. Organization: School of Computer Science, Carnegie Mellon University
  8. Nntp-Posting-Host: cobol.fox.cs.cmu.edu
  9. Distribution: gnu
  10. Originator: spot@COBOL.FOX.CS.CMU.EDU
  11. Lines: 315
  12.  
  13. /*
  14.    tzc.c  trivial zephyr client
  15.    Copyright (C) 1992 Scott Draves (spot@cs.cmu.edu)
  16.  
  17.    This program is free software; you can redistribute it and/or modify
  18.    it under the terms of the GNU General Public License as published by
  19.    the Free Software Foundation; either version 2 of the License, or
  20.    (at your option) any later version.
  21.  
  22.    This program is distributed in the hope that it will be useful,
  23.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  24.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25.    GNU General Public License for more details.
  26.  
  27.    You should have received a copy of the GNU General Public License
  28.    along with this program; if not, write to the Free Software
  29.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  30.  
  31.    a replacement for zwgc that writes its output formatted so elisp can
  32.    read it in.
  33.   */
  34.  
  35. #include <stdio.h>
  36. #include <strings.h>
  37. #include <ctype.h>
  38. #include <zephyr/zephyr.h>
  39. #include <netdb.h>
  40. #include <sys/socket.h>
  41. #include <netinet/in.h>
  42. #include <arpa/inet.h>
  43.  
  44. #define ZCTL_BINARY "/usr/misc/.zephyr/bin/zctl"
  45.  
  46. struct Globals {
  47.    char        *program;
  48.    u_short    port;
  49. };
  50.  
  51. struct Globals global_storage, *globals;
  52.  
  53. void usage() {
  54.    fprintf(stderr, "usage: %s [-s] [-e exposure]\n", globals->program);
  55. }
  56.  
  57. Code_t check(Code_t e, char *s) {
  58.    if (e) {
  59.       com_err(__FILE__, e, s);
  60.       exit(1);
  61.    }
  62.    return e;
  63. }
  64.  
  65. Code_t warn(Code_t e, char *s) {
  66.    if (e)
  67.       com_err(__FILE__, e, s);
  68.    return e;
  69. }
  70.  
  71. #if 0
  72. /* useful for debugging */
  73. void list_subs() {
  74.    int i, n, one = 1;
  75.    ZSubscription_t sub;
  76.    ZRetrieveSubscriptions(0, &n);
  77.    for (i = 0; i < n; i++) {
  78.       ZGetSubscriptions(&sub, &one);
  79.       printf("recip(%s) class(%s) inst(%s)\n",
  80.          sub.recipient, sub.class, sub.classinst);
  81.    }
  82. }
  83. #endif
  84.  
  85. void subscribe() {
  86.    static ZSubscription_t sub[] =
  87.    {{"%me%", "MESSAGE", "*"},
  88.     {"*", "MESSAGE", "*"},
  89.     {"*", "*", "*"}};
  90.    int n = sizeof(sub) / sizeof(ZSubscription_t);
  91.    sub[0].recipient = ZGetSender();
  92.    check(ZSubscribeTo(sub, n, 0), "ZSubscribeTo");
  93. }
  94.  
  95.  
  96. void subscribe_with_zctl() {
  97.   int pid;
  98.   FILE *fd;
  99.   char st[1024];
  100.   char *portfile;
  101.   extern char *getenv();
  102.  
  103.   portfile = getenv("WGFILE");
  104.  
  105.   if(!portfile) {
  106.     sprintf(st,"/tmp/wg.%d",getuid());
  107.     portfile = st;
  108.   }
  109.  
  110.   fd = fopen(portfile,"w");
  111.   if(!fd) {
  112.     perror(portfile);
  113.     exit(1);
  114.   }
  115.   fprintf(fd, "%d\n", globals->port);
  116.   fclose(fd);
  117.  
  118.   if(!(pid = vfork())) {
  119.       char fn[1024];
  120.       sprintf(fn,"%s/.zephyr.subs.tzc",getenv("HOME"));
  121.       execl(ZCTL_BINARY,"zctl","load",fn,0);
  122.       perror("zwgc exec");
  123.       fprintf(stderr,"Unable to load subscriptions.\n");
  124.       exit(0);
  125.     }
  126.   if(pid == -1) {
  127.       perror("zwgc exec");
  128.       fprintf(stderr,"Unable to fork and load subscriptions.\n");
  129.     }
  130. }
  131.  
  132.  
  133. /*
  134.   like fputs, but quotes the string as necc for 
  135.   reading as a string by gnu-emacs
  136.   */
  137. void fputqs(char *s, FILE *o) {
  138.    char c;
  139.    putc('\"', o);
  140.    while (c = *s++) {
  141.       if (c == '\1') {
  142.      putc('\\', o);
  143.      putc('1', o);
  144.       } else {
  145.      if (c == '\"' || c == '\\')
  146.         putc('\\', o);
  147.      putc(c, o);
  148.       }
  149.    }
  150.    putc('\"', o);
  151. }
  152.  
  153. /* like fputs, but quotes for reading as a symbol by gnu-emacs */
  154. void fputqqs(char *s, FILE *o) {
  155.    char c;
  156.    if ('\0' == *s)
  157.       fputs("nil", o);
  158.    else
  159.       while (c = *s++) {
  160.      if (!(isalnum(c) || strchr("-+*/_~!@$%^&=:<>{}", c)))
  161.         putc('\\', o);
  162.      putc(c, o);
  163.       }
  164. }
  165.  
  166. char *auth_string(int n) {
  167.    switch (n) {
  168.     case ZAUTH_YES    : return "yes";
  169.     case ZAUTH_FAILED : return "failed";
  170.     case ZAUTH_NO     : return "no";
  171.     default           : return "bad-auth-value";
  172.    }
  173. }
  174.  
  175. char *kind_string(int n) {
  176.    switch (n) {
  177.     case UNSAFE:    return "unsafe";
  178.     case UNACKED:   return "unacked";
  179.     case ACKED:     return "acked";
  180.     case HMACK:     return "hmack";
  181.     case HMCTL:     return "hmctl";
  182.     case SERVACK:   return "servack";
  183.     case SERVNAK:   return "servnak";
  184.     case CLIENTACK: return "clientack";
  185.     case STAT:      return "stat";
  186.     default:        return "bad-kind-value";
  187.    }
  188. }
  189.  
  190. void say_hi() {
  191.    printf("; tzc is free software and you are welcome to distribute copies\n");
  192.    printf("; of it under certain conditions; see the source code for details.\n");
  193.    printf("; Copyright (C) 1992 Scott Draves\n\n");
  194. }
  195.  
  196.    
  197.  
  198. int main(int argc, char **argv) {
  199.    char *program;
  200.    int use_zctl = 0, sw;
  201.    extern char *optarg;
  202.    globals = &global_storage;
  203.    program = strrchr(argv[0], '/');
  204.    if (program == NULL)
  205.       program = argv[0];
  206.    else
  207.       program++;
  208.    globals->program = program;
  209.  
  210.    fclose(stdin);
  211.    say_hi();
  212.  
  213.    /* if there were an easy way to block-buffer stdout
  214.       i'd do it here */
  215.  
  216.    check(ZInitialize(), "ZInitialize");
  217.    globals->port = 0;
  218.    check(ZOpenPort(&globals->port), "ZOpenPort");
  219.  
  220.    while ((sw = getopt(argc, argv, "se:")) != EOF)
  221.       switch (sw) {
  222.        case 's':
  223.      use_zctl = 1;
  224.      break;
  225.        case 'e':
  226.      check(ZSetLocation(optarg), "ZSetLocation");
  227.      break;
  228.        case '?':
  229.        default:
  230.      usage();
  231.      exit(1);
  232.       }
  233.  
  234.    if (use_zctl)
  235.       subscribe_with_zctl();
  236.    else
  237.       subscribe();
  238.  
  239.    while (1) {
  240.       ZNotice_t notice;
  241.       struct sockaddr_in from;
  242.       int auth, i, len, forced_termination;
  243.       char *from_host, *p;
  244.       struct hostent *hst;
  245.       time_t now;
  246.       char *now_name;
  247.       
  248.       warn(ZReceiveNotice(¬ice, &from), "ZReceiveNotice");
  249.       auth = ZCheckAuthentication(¬ice, &from);
  250.  
  251.       now = time(0);
  252.       now_name = ctime(&now);
  253.       now_name[24] = '\0';      /* dump newline at end */
  254.  
  255.       /* convert IP# of sender into ascii name */
  256.       hst = gethostbyaddr((char *)¬ice.z_sender_addr,
  257.               sizeof(notice.z_sender_addr), AF_INET);
  258.       from_host = hst ? hst->h_name : inet_ntoa(notice.z_sender_addr);
  259.  
  260.       /* abbreviate sender by throwing away realm if it's local */
  261.       p = strchr(notice.z_sender, '@');
  262.       if (p && !strcmp(p+1, ZGetRealm()))
  263.      *p = '\0';
  264.  
  265.       /* ditto for recipient */
  266.       p = strchr(notice.z_recipient, '@');
  267.       if (p && !strcmp(p+1, ZGetRealm()))
  268.      *p = '\0';
  269.  
  270.  
  271.       putc('\1', stdout);
  272.       fputs("((kind . ", stdout);
  273.       fputs(kind_string(notice.z_kind), stdout);
  274.       fputs(") (class . ", stdout);
  275.       fputqqs(notice.z_class, stdout);
  276.       fputs(") (instance . ", stdout);
  277.       fputqs(notice.z_class_inst, stdout);
  278.       fputs(") (opcode . ", stdout);
  279.       fputqqs(notice.z_opcode, stdout);
  280.       fputs(") (sender . ", stdout);
  281.       fputqs(notice.z_sender, stdout);
  282.       fputs(") (recipient . ", stdout);
  283.       if (notice.z_recipient[0])
  284.      fputqs(notice.z_recipient, stdout);
  285.       else
  286.      fputs("nil", stdout);
  287.       fprintf(stdout,
  288.           ") (port . %d) (auth . %s) (time . \"%s\") (fromhost . ",
  289.           notice.z_port, auth_string(auth), now_name);
  290.       fputqs(from_host, stdout);
  291.       fputs(") (message . (", stdout);
  292.  
  293.       p = notice.z_message;
  294.       len = notice.z_message_len;
  295.       forced_termination = 0;
  296.       if (p[len-1]) {
  297.      /* force null termination */
  298.      /* this code has not been tested */
  299.      p = (char *) malloc(len+1);
  300.      bcopy(notice.z_message, p, len);
  301.      p[len] = '\0';
  302.      len += 1;
  303.      forced_termination = 1;
  304.       }
  305.       for (i = 0; i < len; i++) {
  306.      fputqs(p+i, stdout);
  307.      putc(' ', stdout);
  308.      i += strlen(p+i);
  309.       }
  310.       fputs("))", stdout);
  311.       if (forced_termination) {
  312.      fputs(" (forced-termination . t)", stdout);
  313.      free(p);
  314.       }
  315.       putc(')', stdout);
  316.       putc('\0', stdout);
  317.       putc('\n', stdout);
  318.  
  319.       fflush(stdout);
  320.       
  321.       (void) ZFreeNotice(¬ice);
  322.    }
  323. }
  324. -- 
  325.             l2o
  326. Scott Draves        gso
  327. spot@cs.cmu.edu        ddn
  328.