home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.emacs.sources
- Path: sparky!uunet!europa.asd.contel.com!darwin.sura.net!udel!rochester!cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!spot
- From: spot@CS.CMU.EDU (Scott Draves)
- Subject: new tzc.c
- Message-ID: <1992Jul22.013541.265731@cs.cmu.edu>
- Date: Wed, 22 Jul 92 01:35:41 GMT
- Organization: School of Computer Science, Carnegie Mellon University
- Nntp-Posting-Host: cobol.fox.cs.cmu.edu
- Distribution: gnu
- Originator: spot@COBOL.FOX.CS.CMU.EDU
- Lines: 315
-
- /*
- tzc.c trivial zephyr client
- Copyright (C) 1992 Scott Draves (spot@cs.cmu.edu)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- a replacement for zwgc that writes its output formatted so elisp can
- read it in.
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include <ctype.h>
- #include <zephyr/zephyr.h>
- #include <netdb.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-
- #define ZCTL_BINARY "/usr/misc/.zephyr/bin/zctl"
-
- struct Globals {
- char *program;
- u_short port;
- };
-
- struct Globals global_storage, *globals;
-
- void usage() {
- fprintf(stderr, "usage: %s [-s] [-e exposure]\n", globals->program);
- }
-
- Code_t check(Code_t e, char *s) {
- if (e) {
- com_err(__FILE__, e, s);
- exit(1);
- }
- return e;
- }
-
- Code_t warn(Code_t e, char *s) {
- if (e)
- com_err(__FILE__, e, s);
- return e;
- }
-
- #if 0
- /* useful for debugging */
- void list_subs() {
- int i, n, one = 1;
- ZSubscription_t sub;
- ZRetrieveSubscriptions(0, &n);
- for (i = 0; i < n; i++) {
- ZGetSubscriptions(&sub, &one);
- printf("recip(%s) class(%s) inst(%s)\n",
- sub.recipient, sub.class, sub.classinst);
- }
- }
- #endif
-
- void subscribe() {
- static ZSubscription_t sub[] =
- {{"%me%", "MESSAGE", "*"},
- {"*", "MESSAGE", "*"},
- {"*", "*", "*"}};
- int n = sizeof(sub) / sizeof(ZSubscription_t);
- sub[0].recipient = ZGetSender();
- check(ZSubscribeTo(sub, n, 0), "ZSubscribeTo");
- }
-
-
- void subscribe_with_zctl() {
- int pid;
- FILE *fd;
- char st[1024];
- char *portfile;
- extern char *getenv();
-
- portfile = getenv("WGFILE");
-
- if(!portfile) {
- sprintf(st,"/tmp/wg.%d",getuid());
- portfile = st;
- }
-
- fd = fopen(portfile,"w");
- if(!fd) {
- perror(portfile);
- exit(1);
- }
- fprintf(fd, "%d\n", globals->port);
- fclose(fd);
-
- if(!(pid = vfork())) {
- char fn[1024];
- sprintf(fn,"%s/.zephyr.subs.tzc",getenv("HOME"));
- execl(ZCTL_BINARY,"zctl","load",fn,0);
- perror("zwgc exec");
- fprintf(stderr,"Unable to load subscriptions.\n");
- exit(0);
- }
- if(pid == -1) {
- perror("zwgc exec");
- fprintf(stderr,"Unable to fork and load subscriptions.\n");
- }
- }
-
-
- /*
- like fputs, but quotes the string as necc for
- reading as a string by gnu-emacs
- */
- void fputqs(char *s, FILE *o) {
- char c;
- putc('\"', o);
- while (c = *s++) {
- if (c == '\1') {
- putc('\\', o);
- putc('1', o);
- } else {
- if (c == '\"' || c == '\\')
- putc('\\', o);
- putc(c, o);
- }
- }
- putc('\"', o);
- }
-
- /* like fputs, but quotes for reading as a symbol by gnu-emacs */
- void fputqqs(char *s, FILE *o) {
- char c;
- if ('\0' == *s)
- fputs("nil", o);
- else
- while (c = *s++) {
- if (!(isalnum(c) || strchr("-+*/_~!@$%^&=:<>{}", c)))
- putc('\\', o);
- putc(c, o);
- }
- }
-
- char *auth_string(int n) {
- switch (n) {
- case ZAUTH_YES : return "yes";
- case ZAUTH_FAILED : return "failed";
- case ZAUTH_NO : return "no";
- default : return "bad-auth-value";
- }
- }
-
- char *kind_string(int n) {
- switch (n) {
- case UNSAFE: return "unsafe";
- case UNACKED: return "unacked";
- case ACKED: return "acked";
- case HMACK: return "hmack";
- case HMCTL: return "hmctl";
- case SERVACK: return "servack";
- case SERVNAK: return "servnak";
- case CLIENTACK: return "clientack";
- case STAT: return "stat";
- default: return "bad-kind-value";
- }
- }
-
- void say_hi() {
- printf("; tzc is free software and you are welcome to distribute copies\n");
- printf("; of it under certain conditions; see the source code for details.\n");
- printf("; Copyright (C) 1992 Scott Draves\n\n");
- }
-
-
-
- int main(int argc, char **argv) {
- char *program;
- int use_zctl = 0, sw;
- extern char *optarg;
- globals = &global_storage;
- program = strrchr(argv[0], '/');
- if (program == NULL)
- program = argv[0];
- else
- program++;
- globals->program = program;
-
- fclose(stdin);
- say_hi();
-
- /* if there were an easy way to block-buffer stdout
- i'd do it here */
-
- check(ZInitialize(), "ZInitialize");
- globals->port = 0;
- check(ZOpenPort(&globals->port), "ZOpenPort");
-
- while ((sw = getopt(argc, argv, "se:")) != EOF)
- switch (sw) {
- case 's':
- use_zctl = 1;
- break;
- case 'e':
- check(ZSetLocation(optarg), "ZSetLocation");
- break;
- case '?':
- default:
- usage();
- exit(1);
- }
-
- if (use_zctl)
- subscribe_with_zctl();
- else
- subscribe();
-
- while (1) {
- ZNotice_t notice;
- struct sockaddr_in from;
- int auth, i, len, forced_termination;
- char *from_host, *p;
- struct hostent *hst;
- time_t now;
- char *now_name;
-
- warn(ZReceiveNotice(¬ice, &from), "ZReceiveNotice");
- auth = ZCheckAuthentication(¬ice, &from);
-
- now = time(0);
- now_name = ctime(&now);
- now_name[24] = '\0'; /* dump newline at end */
-
- /* convert IP# of sender into ascii name */
- hst = gethostbyaddr((char *)¬ice.z_sender_addr,
- sizeof(notice.z_sender_addr), AF_INET);
- from_host = hst ? hst->h_name : inet_ntoa(notice.z_sender_addr);
-
- /* abbreviate sender by throwing away realm if it's local */
- p = strchr(notice.z_sender, '@');
- if (p && !strcmp(p+1, ZGetRealm()))
- *p = '\0';
-
- /* ditto for recipient */
- p = strchr(notice.z_recipient, '@');
- if (p && !strcmp(p+1, ZGetRealm()))
- *p = '\0';
-
-
- putc('\1', stdout);
- fputs("((kind . ", stdout);
- fputs(kind_string(notice.z_kind), stdout);
- fputs(") (class . ", stdout);
- fputqqs(notice.z_class, stdout);
- fputs(") (instance . ", stdout);
- fputqs(notice.z_class_inst, stdout);
- fputs(") (opcode . ", stdout);
- fputqqs(notice.z_opcode, stdout);
- fputs(") (sender . ", stdout);
- fputqs(notice.z_sender, stdout);
- fputs(") (recipient . ", stdout);
- if (notice.z_recipient[0])
- fputqs(notice.z_recipient, stdout);
- else
- fputs("nil", stdout);
- fprintf(stdout,
- ") (port . %d) (auth . %s) (time . \"%s\") (fromhost . ",
- notice.z_port, auth_string(auth), now_name);
- fputqs(from_host, stdout);
- fputs(") (message . (", stdout);
-
- p = notice.z_message;
- len = notice.z_message_len;
- forced_termination = 0;
- if (p[len-1]) {
- /* force null termination */
- /* this code has not been tested */
- p = (char *) malloc(len+1);
- bcopy(notice.z_message, p, len);
- p[len] = '\0';
- len += 1;
- forced_termination = 1;
- }
- for (i = 0; i < len; i++) {
- fputqs(p+i, stdout);
- putc(' ', stdout);
- i += strlen(p+i);
- }
- fputs("))", stdout);
- if (forced_termination) {
- fputs(" (forced-termination . t)", stdout);
- free(p);
- }
- putc(')', stdout);
- putc('\0', stdout);
- putc('\n', stdout);
-
- fflush(stdout);
-
- (void) ZFreeNotice(¬ice);
- }
- }
- --
- l2o
- Scott Draves gso
- spot@cs.cmu.edu ddn
-