]> andersk Git - zcommit.git/commitdiff
Added source for zsend
authorGreg Brockman <gdb@mit.edu>
Tue, 23 Mar 2010 21:03:07 +0000 (17:03 -0400)
committerGreg Brockman <gdb@mit.edu>
Tue, 23 Mar 2010 21:03:07 +0000 (17:03 -0400)
12 files changed:
bin/zsend [deleted file]
src/zsend-0.0.1/Makefile [new file with mode: 0644]
src/zsend-0.0.1/ZCkAuth.c [new file with mode: 0644]
src/zsend-0.0.1/debian/changelog [new file with mode: 0644]
src/zsend-0.0.1/debian/control [new file with mode: 0644]
src/zsend-0.0.1/debian/copyright [new file with mode: 0644]
src/zsend-0.0.1/debian/dirs [new file with mode: 0644]
src/zsend-0.0.1/debian/rules [new file with mode: 0755]
src/zsend-0.0.1/debian/zsend.files [new file with mode: 0644]
src/zsend-0.0.1/lread.c [new file with mode: 0644]
src/zsend-0.0.1/lread.h [new file with mode: 0644]
src/zsend-0.0.1/zsend.c [new file with mode: 0644]

diff --git a/bin/zsend b/bin/zsend
deleted file mode 100755 (executable)
index 7dde6b3..0000000
Binary files a/bin/zsend and /dev/null differ
diff --git a/src/zsend-0.0.1/Makefile b/src/zsend-0.0.1/Makefile
new file mode 100644 (file)
index 0000000..e3751b3
--- /dev/null
@@ -0,0 +1,50 @@
+SHELL = /bin/sh
+
+prefix=/usr
+exec_prefix=${prefix}
+datadir=${prefix}/share
+sysconfdir=${prefix}/etc
+sbindir=${exec_prefix}/sbin
+lsbindir=${sbindir}
+mandir=${prefix}/share/man
+
+includedir=${prefix}/include
+libdir=${exec_prefix}/lib
+bindir=${exec_prefix}/bin
+
+srcdir=
+top_srcdir=
+BUILDTOP=
+CC=gcc -m32
+INSTALL=/usr/bin/install -c
+
+IRFLAGS=-DINTERREALM
+CPPFLAGS=-I/usr/athena/include
+CFLAGS=-g -O2
+ALL_CFLAGS=${CFLAGS} ${IRFLAGS} ${CPPFLAGS}
+LDFLAGS=-L${BUILDTOP}/lib 
+#LIBS=-lreadline -L/usr/athena/lib -Wl,-R /usr/athena/lib -lzephyr -lkrb4 -lkrb5 -lcrypto -lcrypt -lresolv -lcom_err -ldl 
+LIBS=-lreadline -L/usr/athena/lib -lzephyr -lkrb4 -lkrb5 -lcrypto -lcrypt -lresolv -lcom_err -ldl 
+
+OBJS= ZCkAuth.o lread.o
+
+all: zsend
+
+zsend.o: zsend.c
+
+zsend: zsend.o lread.o lread.h ZCkAuth.o
+       ${CC} ${LDFLAGS} -o $@ ZCkAuth.o lread.o zsend.o ${LIBS}
+
+.c.o:
+       ${CC} -c ${ALL_CFLAGS} $<
+
+check:
+
+install: zsend
+       ${INSTALL} -m 755 -s zsend ../../bin
+
+clean:
+       rm -f *.o zsend
+
+.PHONY: all check install clean
+
diff --git a/src/zsend-0.0.1/ZCkAuth.c b/src/zsend-0.0.1/ZCkAuth.c
new file mode 100644 (file)
index 0000000..6b65387
--- /dev/null
@@ -0,0 +1,75 @@
+/* Modifications for tzc by Darrell Kindred <dkindred@cmu.edu>, April 1997:
+ *   - cache the kerberos credentials, so we can continue to check auth
+ *     even if the user re-kinits.
+ */
+
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains source for the ZCheckAuthentication function.
+ *
+ *     Created by:     Robert French
+ *
+ *     /mit/zephyr/src/CVS/zephyr/lib/zephyr/ZCkAuth.c,v
+ *     ghudson
+ *
+ *     Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
+ *     For copying and distribution information, see the file
+ *     "mit-copyright.h". 
+ */
+/* /mit/zephyr/src/CVS/zephyr/lib/zephyr/ZCkAuth.c,v 1.21 1995/06/30 22:03:53 ghudson Exp */
+
+
+#if 0
+#include <internal.h>
+#else
+#include <zephyr/zephyr.h>
+#define ZAUTH_UNSET (-3)      /* from internal.h */
+#include <stdio.h>           /* for NULL */
+#endif
+
+/* Check authentication of the notice.
+   If it looks authentic but fails the Kerberos check, return -1.
+   If it looks authentic and passes the Kerberos check, return 1.
+   If it doesn't look authentic, return 0
+
+   When not using Kerberos, return true if the notice claims to be authentic.
+   Only used by clients; the server uses its own routine.
+ */
+Code_t ZCheckAuthentication(notice, from)
+    ZNotice_t *notice;
+    struct sockaddr_in *from;
+{      
+#ifdef ZEPHYR_USES_KERBEROS
+    int result;
+    ZChecksum_t our_checksum;
+    static CREDENTIALS cred;
+    static int got_cred = 0;
+
+    /* If the value is already known, return it. */
+    if (notice->z_checked_auth != ZAUTH_UNSET)
+       return (notice->z_checked_auth);
+
+    if (!notice->z_auth)
+       return (ZAUTH_NO);
+       
+    if (!got_cred &&
+       (result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, 
+                              __Zephyr_realm, &cred)) != 0)
+      return (ZAUTH_NO);
+
+    got_cred = 1;
+
+#ifdef NOENCRYPTION
+    our_checksum = 0;
+#else /* NOENCRYPTION */
+    our_checksum = des_quad_cksum(notice->z_packet, NULL, 
+                                notice->z_default_format+
+                                strlen(notice->z_default_format)+1-
+                                notice->z_packet, 0, cred.session);
+#endif /* NOENCRYPTION */
+    /* if mismatched checksum, then the packet was corrupted */
+    return ((our_checksum == notice->z_checksum) ? ZAUTH_YES : ZAUTH_FAILED);
+
+#else /* ZEPHYR_USES_KERBEROS */
+    return (notice->z_auth ? ZAUTH_YES : ZAUTH_NO);
+#endif
+} 
diff --git a/src/zsend-0.0.1/debian/changelog b/src/zsend-0.0.1/debian/changelog
new file mode 100644 (file)
index 0000000..0e910aa
--- /dev/null
@@ -0,0 +1,6 @@
+zsend (0.0.1-1) stable; urgency=low
+
+  * Initial Release.
+
+ -- Aaron Solochek <aarons@aberrant.org>  Sun, 09 Oct 2005 10:30:00 -0600
+
diff --git a/src/zsend-0.0.1/debian/control b/src/zsend-0.0.1/debian/control
new file mode 100644 (file)
index 0000000..4960cb8
--- /dev/null
@@ -0,0 +1,15 @@
+Source: zsend
+Section: net
+Priority: optional
+Maintainer: Aaron Solochek <aarons@aberrant.org>
+Build-Depends: debhelper, bison, libzephyr-dev, libreadline-dev
+Standards-Version: 3.1.1
+
+Package: zsend
+Section: net
+Architecture: any
+Depends: zephyr-clients, ${shlibs:Depends}
+Description: zsend is a stripped zwrite ideal for use in scripts
+ .
+ This package contains the zsend binary for use in zephyr notification
+ scripts.
diff --git a/src/zsend-0.0.1/debian/copyright b/src/zsend-0.0.1/debian/copyright
new file mode 100644 (file)
index 0000000..bce481d
--- /dev/null
@@ -0,0 +1,29 @@
+This package was debianized by Aaron Solochek <aarons@aberrant.org> on
+Mon,  4 Dec 2000 05:28:22 -0500.
+
+Copyright:
+
+/*
+
+Copyright 1987,1988,1995 by the Massachusetts Institute of Technology
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the Massachusetts
+Institute of Technology (M.I.T.) not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
diff --git a/src/zsend-0.0.1/debian/dirs b/src/zsend-0.0.1/debian/dirs
new file mode 100644 (file)
index 0000000..e772481
--- /dev/null
@@ -0,0 +1 @@
+usr/bin
diff --git a/src/zsend-0.0.1/debian/rules b/src/zsend-0.0.1/debian/rules
new file mode 100755 (executable)
index 0000000..1d06031
--- /dev/null
@@ -0,0 +1,90 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper. 
+# GNU copyright 1997 by Joey Hess.
+#
+# This version is for a hypothetical package that builds an
+# architecture-dependant package, as well as an architecture-independent
+# package.
+
+# Uncomment this to turn on verbose mode. 
+#export DH_VERBOSE=1
+
+# This is the debhelper compatability version to use.
+export DH_COMPAT=3
+
+# This has to be exported to make some magic below work.
+export DH_OPTIONS
+SONAME=3
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+
+       # Add here commands to configure the package.
+       -mkdir build-tree
+       cp *.c build-tree/
+       cp *.h build-tree/
+       cp Makefile build-tree/
+
+build: configure-stamp build-stamp
+build-stamp:
+       dh_testdir
+
+       # Add here commands to compile the package.
+       $(MAKE) -C `pwd`/build-tree 
+       touch build-stamp
+
+clean:
+       dh_testdir
+       dh_testroot
+       -rm -f build-stamp configure-stamp
+
+       # Add here commands to clean up after the build process.
+       -rm -rf build-tree debian/tmp
+
+       dh_clean
+
+install: DH_OPTIONS=
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       -rm -rf debian/tmp
+       dh_installdirs
+       mkdir -p debian/tmp/usr/bin/
+
+       # Add here commands to install the package into debian/tmp.
+       cd build-tree&&$(MAKE)  DESTDIR=`pwd`/../debian/tmp install
+
+
+# Build architecture-independent files here.
+# Pass -i to all debhelper commands in this target to reduce clutter.
+binary-indep: build install
+
+
+# Build architecture-dependent files here.
+# Pass -a to all debhelper commands in this target to reduce clutter.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       set -e; \
+       dh_movefiles -pzsend
+       dh_movefiles --sourcedir=debian/tmp -pzsend 
+       dh_installdebconf 
+       dh_installdocs
+       dh_installchangelogs 
+       dh_strip
+       dh_compress
+       dh_fixperms
+       dh_makeshlibs
+       dh_shlibdeps
+       dh_installdeb
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+
+.PHONY: build clean binary-indep binary-arch binary install configure
+
+
diff --git a/src/zsend-0.0.1/debian/zsend.files b/src/zsend-0.0.1/debian/zsend.files
new file mode 100644 (file)
index 0000000..e772481
--- /dev/null
@@ -0,0 +1 @@
+usr/bin
diff --git a/src/zsend-0.0.1/lread.c b/src/zsend-0.0.1/lread.c
new file mode 100644 (file)
index 0000000..852c82e
--- /dev/null
@@ -0,0 +1,703 @@
+/*
+  lread.c: simple sexp-like data structures in C.
+          useful for communication between emacs and C client programs
+
+   Copyright (C) 1992 Nick Thompson (nix@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.
+
+   TODO
+
+   add tag checking on CAR, CDR, etc?
+ */
+
+#include <setjmp.h>
+
+#include "lread.h"
+#include <stdio.h>
+#include <string.h>    /* for strlen() */
+
+Value *
+vmake_cons(Value *car, Value *cdr)
+{
+   Value *v = ALLOC_VALUE();
+   v->tag = cons;
+   VCAR(v) = car;
+   VCDR(v) = cdr;
+   return v;
+}
+
+Value *
+vmake_symbol(int length, char *data)
+{
+   Value *v = ALLOC_VALUE();
+   v->tag = symbol;
+   VSLENGTH(v) = length;
+   VSDATA(v) = data;
+   return v;
+}
+
+Value *
+vmake_symbol_c(char *s)
+{
+   Value *v = ALLOC_VALUE();
+   v->tag = symbol;
+   VSLENGTH(v) = strlen(s);
+   VSDATA(v) = s;
+   return v;
+}
+
+Value *
+vmake_string(int length, char *data)
+{
+   Value *v = ALLOC_VALUE();
+   v->tag = string;
+   VSLENGTH(v) = length;
+   VSDATA(v) = data;
+   return v;
+}
+
+Value *
+vmake_string_c(char *s)
+{
+   Value *v = ALLOC_VALUE();
+   v->tag = string;
+   VSLENGTH(v) = strlen(s);
+   VSDATA(v) = s;
+   return v;
+}
+
+char *
+vextract_string_c(Value *v)
+{
+   char *s = (char *) malloc(VSLENGTH(v) + 1);
+   memcpy(s, VSDATA(v), VSLENGTH(v));
+   s[VSLENGTH(v)] = '\0';
+   return s;
+}
+
+Value *
+vmake_integer(int n)
+{
+   Value *v = ALLOC_VALUE();
+   v->tag = integer;
+   VINTEGER(v) = n;
+   return v;
+}
+
+Value *
+vmake_var(enum Vtag tag, void **value)
+{
+   Value *v = ALLOC_VALUE();
+   v->tag = var;
+   VVTAG(v) = tag;
+   VVDATA(v) = value;
+   return v;
+}
+
+int
+vlength(Value *l)
+{
+    int i;
+    for (i=0; VTAG(l) == cons; i++, l = VCDR(l))
+       ;
+    return i;
+}
+
+typedef struct {
+   jmp_buf abort;              /* nonlocal exit for abort */
+
+   char *input_string;         /* input string */
+   int buflen;                 /* amount left in input string */
+   char *buf;                  /* pointer into input */
+
+   int strbuflen;              /* length of scratch buffer */
+   char *strbuf;               /* scratch buffer for building strings */
+} Globals;
+
+Value *read_value(Globals *g);
+Value *read_list(Globals *g);
+
+#define PEEK_CHAR(g)   (*(g)->buf)
+#define NEXT_CHAR(g)   ((g)->buflen > 0 ? \
+                        (void) ((g)->buf++,((g)->buflen--)) : \
+                        (void) (ABORT(g, 23)))
+#define ABORT(g, code) longjmp((g)->abort, (code))
+
+/* A pox on languages without coroutines. */
+/* I don't feel like putting the entire state of the parser in data
+ * structures that I can save and restore myself, so if EOF is
+ * encountered while parsing the parser will have to start from
+ * scratch when it gets more data */
+
+void
+expand_strbuf(Globals *g)
+{
+   if (g->strbuflen == 0) {
+      g->strbuflen = 128;
+      g->strbuf = (char *) malloc(g->strbuflen);
+   }
+   else {
+      int newbuflen = 3 * g->strbuflen / 2;
+      char *newbuf = (char *) malloc(newbuflen);
+      memcpy(newbuf, g->strbuf, g->strbuflen);
+      free(g->strbuf);
+      g->strbuf = newbuf;
+      g->strbuflen = newbuflen;
+   }
+}
+
+int parse(int slen, char *s, Value **v)
+{
+   Globals g;
+   int jmpret;
+
+   if (0 == (jmpret = setjmp(g.abort))) {      /* successful parse */
+      g.input_string = s;
+      g.buflen = slen;
+      g.buf = g.input_string;
+      g.strbuflen = 0;
+      g.strbuf = NULL;
+      expand_strbuf(&g);
+      *v = read_value(&g);
+      return g.buf - g.input_string;
+   }
+   else {                      /* return from nonlocal abort */
+      free(g.strbuf);
+      *v = NULL;
+      return 0;
+   }
+}
+
+int
+read_escape(Globals *g, char *c)
+{
+   int valid = 1;
+   int nc = PEEK_CHAR(g);
+
+   switch (nc) {
+    case '\n':
+      valid = 0;
+      NEXT_CHAR(g);
+      break;
+    case 'n':
+      *c = '\n';
+      NEXT_CHAR(g);
+      break;
+    case 't':
+      *c = '\t';
+      NEXT_CHAR(g);
+      break;
+    default:
+      if (nc >= '0' && nc <= '7') {
+       int digits;
+       /* handle octal \nnn notation */
+       *c = 0;
+       for (digits = 0; digits < 3; digits++) {
+         if (nc < '0' || nc > '7')
+           break;
+         *c = (*c * 8) + (nc - '0');
+         NEXT_CHAR(g);
+         nc = PEEK_CHAR(g);
+       }
+      } else {
+       /* backslash followed by some random char, like \q.
+        * (some of these are actually valid, but I don't think prin1 will
+         * produce them, so it's not too critical). */
+       *c = nc;
+       NEXT_CHAR(g);
+      }
+      break;
+   }
+   return valid;
+}
+
+Value *
+read_string(Globals *g)
+{
+   int strpos = 0;
+   Value *v;
+   char c;
+
+#define ADD_CHAR(c)    \
+   if (strpos >= g->strbuflen) \
+      expand_strbuf(g);                \
+   g->strbuf[strpos++] = (c)
+
+   while (1) {
+      switch (PEEK_CHAR(g)) {
+       case '\"':
+        NEXT_CHAR(g);
+        v = ALLOC_VALUE();
+        v->tag = string;
+        v->value.s.length = strpos;
+        v->value.s.string = (char *) malloc(v->value.s.length);
+        memcpy(v->value.s.string, g->strbuf, v->value.s.length);
+        return v;
+        break;
+       case '\\':
+        NEXT_CHAR(g);
+        if (read_escape(g, &c))
+           ADD_CHAR(c);
+        break;
+       default:
+        ADD_CHAR(PEEK_CHAR(g));
+        NEXT_CHAR(g);
+        break;
+      }
+   }
+}
+
+/* characters
+(
+)
+"
+\
+<white>
+<character>
+<number>
+ */
+
+Value *
+read_num_or_symbol(Globals *g)
+{
+   Value *v;
+   int strpos = 0;
+   int i;
+   int is_integer;
+
+#define ADD_CHAR(c)    \
+   if (strpos >= g->strbuflen) \
+      expand_strbuf(g);                \
+   g->strbuf[strpos++] = (c)
+
+   while (g->buflen > 0) {
+      switch (PEEK_CHAR(g)) {
+       case ' ':
+       case '\t':
+       case '\n':
+       case '\0':
+       case '\"':
+       case '(':
+       case ')':
+       case '.':
+        goto done;
+        break;
+       case '\\':
+        NEXT_CHAR(g);
+        ADD_CHAR(PEEK_CHAR(g));
+        NEXT_CHAR(g);
+        break;
+       default:
+        ADD_CHAR(PEEK_CHAR(g));
+        NEXT_CHAR(g);
+        break;
+      }
+   }
+   ABORT(g, 23);
+
+ done:
+   /* is this a number or a symbol? */
+   /* assume integer to start */
+   is_integer = 1;
+
+   /* assume no empty strings? */
+
+   /* if the first character is '+' or '-' and that's not the only */
+   /* character it can still be an integer */
+   i = 0;
+   if (strpos > 0) {
+      if (g->strbuf[0] == '-' || g->strbuf[0] == '+') {
+        if (strpos > 1) {
+           i = 1;
+        } else {
+           is_integer = 0;
+        }
+      }
+   }
+
+   while (is_integer && i < strpos) {
+      if (g->strbuf[i] < '0' || g->strbuf[i] > '9')
+        is_integer = 0;
+      i++;
+   }
+
+   if (is_integer) {
+      /* it's an integer */
+      v = ALLOC_VALUE();
+      v->tag = integer;
+      ADD_CHAR('\0');
+      v->value.integer.i = atoi(g->strbuf);
+   }
+   else {
+      /* it's a symbol */
+      if (3 == strpos &&
+         !memcmp(g->strbuf, "nil", 3)) {
+        v = NULL;
+      } else {
+        v = ALLOC_VALUE();
+        v->tag = symbol;
+        v->value.s.length = strpos;
+        v->value.s.string = (char *) malloc(v->value.s.length);
+        memcpy(v->value.s.string, g->strbuf, v->value.s.length);
+      }
+   }
+   return v;
+}
+
+Value *
+read_value(Globals *g)
+{
+   while (g->buflen > 0) {
+      switch (PEEK_CHAR(g)) {
+       case ' ':
+       case '\t':
+       case '\n':
+       case '\0':
+        NEXT_CHAR(g);
+        break;
+       case '\"':                      /* begin string */
+        NEXT_CHAR(g);
+        return read_string(g);
+        break;
+       case '(':
+        NEXT_CHAR(g);
+        return read_list(g);
+        break;
+       case ')':
+       case '.':
+        return NULL;
+        break;
+       default:
+        return read_num_or_symbol(g);
+        break;
+      }
+   }
+   ABORT(g, 23);
+}
+
+Value *
+read_list(Globals *g)
+{
+   Value *list;
+   Value **tail;
+   Value *v;
+
+   tail = &list;
+   while (g->buflen > 0) {
+      if (NULL == (v = read_value(g))) {
+        switch (PEEK_CHAR(g)) {
+
+         case ')':
+           if (tail != NULL) {         /* if no last cdr yet, use nil */
+              *tail = NULL;
+           }
+           NEXT_CHAR(g);
+           return list;
+           break;
+
+         case '.':                     /* set last cdr explicitly */
+           NEXT_CHAR(g);
+           *tail = read_value(g);
+           if (*tail == NULL) {
+              /* badly formed input ??? */
+              ABORT(g, 13);
+           }
+           tail = NULL;
+           break;
+
+         default:
+           /* badly formed input ??? */
+           ABORT(g, 13);
+           break;
+        }
+      }
+      else {                   /* read a value, add it to the list */
+        if (NULL == tail) {
+           /* two values after a . in a list.  very bad! ??? */
+           ABORT(g, 13);
+        }
+        *tail = ALLOC_VALUE();
+        (*tail)->tag = cons;
+        (*tail)->value.cons.car = v;
+        tail = &(*tail)->value.cons.cdr;
+      }
+   }
+   ABORT(g, 23);       /* added this  -dkindred */
+}
+
+void free_value(Value *v)
+{
+   switch(VTAG(v)) {
+    case cons:
+      free_value(v->value.cons.car);
+      free_value(v->value.cons.cdr);
+      break;
+    case string:
+    case symbol:
+      free(v->value.s.string);
+      break;
+    default:
+      break;
+   }
+   free(v);
+}
+
+void prin(FILE *f, Value *v);
+
+void
+prinlis(FILE *f, Value *v, int first)
+{
+   switch(VTAG(v)) {
+    case cons:                         /* continue printing list */
+      if (! first)
+        putc(' ', f);
+      prin(f, v->value.cons.car);
+      prinlis(f, v->value.cons.cdr, 0);
+      break;
+    case nil:                          /* last elt in list */
+      putc(')', f);
+      break;
+    default:                           /* dotted pair */
+      putc(' ', f);
+      putc('.', f);
+      putc(' ', f);
+      prin(f, v);
+      putc(')', f);
+      break;
+   }
+}
+
+void
+prin(FILE *f, Value *v)
+{
+   switch (VTAG(v)) {
+    case nil:
+      fputs("\'()", f);
+      break;
+    case cons:
+      putc('(', f);
+      prinlis(f, v, 1);
+      break;
+    case string:
+      /* ??? do quoting of '"' ??? */
+      putc('\"', f);
+      fwrite(v->value.s.string, 1, v->value.s.length, f);
+      putc('\"', f);
+      break;
+    case symbol:
+      /* ??? do quoting of all whitespace and special chars ??? */
+      fwrite(v->value.s.string, 1, v->value.s.length, f);
+      break;
+    case integer:
+      fprintf(f, "%ld", v->value.integer.i);
+      break;
+    default:
+      fputs("#<huh?>", f);
+      break;
+   }
+}
+
+#define CHECK_TAG(v, t) if (VTAG(v) != (t)) return 0
+
+int
+eqv(Value *v1, Value *v2)
+{
+
+   switch (v1->tag) {
+/*
+    case any:
+      return 1;
+      break;
+ */
+    case nil:
+      CHECK_TAG(v2, nil);
+      return 1;
+      break;
+    case cons:
+      CHECK_TAG(v2, cons);
+      return (eqv(VCAR(v1), VCAR(v2)) &&
+             eqv(VCDR(v1), VCDR(v2)));
+      break;
+    case string:
+      CHECK_TAG(v2, string);
+      return (VSLENGTH(v1) == VSLENGTH(v2) &&
+             0 == memcmp(VSDATA(v1), VSDATA(v2), VSLENGTH(v1)));
+      break;
+    case symbol:
+      CHECK_TAG(v2, symbol);
+      return (VSLENGTH(v1) == VSLENGTH(v2) &&
+             0 == memcmp(VSDATA(v1), VSDATA(v2), VSLENGTH(v1)));
+      break;
+    case integer:
+      CHECK_TAG(v2, integer);
+      return (VINTEGER(v1) == VINTEGER(v2));
+      break;
+    case var:
+      if (VVTAG(v1) != any)
+        CHECK_TAG(v2, VVTAG(v1));
+      return 1;
+      break;
+    default:
+      fprintf(stderr,"eqv(): bad tag: %d\n",(int)(v1->tag));
+      /* die? */
+      return 0;
+      break;
+   }
+}
+
+Value *
+assqv(Value *key, Value *assoc)
+{
+   Value *pair;
+
+   /* cdr on through */
+   while (VTAG(assoc) == cons) {
+      pair = VCAR(assoc);
+      if (VTAG(pair) == cons && eqv(VCAR(pair), key)) {
+        return pair;
+      }
+      assoc = VCDR(assoc);
+   }
+   return NULL;
+}
+
+int
+destructure(Value *pattern, Value *match)
+{
+   switch (VTAG(pattern)) {
+    case any:
+      return 1;
+      break;
+    case nil:
+      CHECK_TAG(match, nil);
+      return 1;
+      break;
+    case cons:
+      CHECK_TAG(match, cons);
+      return (destructure(VCAR(pattern), VCAR(match)) &&
+             destructure(VCDR(pattern), VCDR(match)));
+      break;
+    case string:
+      CHECK_TAG(match, string);
+      return (VSLENGTH(pattern) == VSLENGTH(match) &&
+             0 == memcmp(VSDATA(pattern), VSDATA(match), VSLENGTH(pattern)));
+      break;
+    case symbol:
+      CHECK_TAG(match, symbol);
+      return (VSLENGTH(pattern) == VSLENGTH(match) &&
+             0 == memcmp(VSDATA(pattern), VSDATA(match), VSLENGTH(pattern)));
+      break;
+    case integer:
+      CHECK_TAG(match, integer);
+      return (VINTEGER(pattern) == VINTEGER(match));
+      break;
+    case var:
+      if (VVTAG(pattern) != any)
+        CHECK_TAG(match, VVTAG(pattern));
+      if (VVDATA(pattern) != NULL)
+        *VVDATA(pattern) = (void *) match;
+      return 1;
+      break;
+    default:
+      fprintf(stderr,"destructure(): bad tag: %d\n",(int)VTAG(pattern));
+      /* die? */
+      return 0;
+      break;
+   }
+}
+
+#ifdef TEST
+
+read_and_parse()
+{
+#define BUFLEN 512
+   char buf[BUFLEN];   /* this will have to be dynamically expanded */
+   int bufpos = 0;
+   int ret;
+   Value *v = NULL;
+   Value *match_data;
+   Value *pattern = vmake_cons(vmake_symbol_c("integer"),
+                              vmake_var(integer, (void **) &match_data));
+
+   while (1) {
+      ret = read(0, buf + bufpos, BUFLEN - bufpos);
+      if (ret < 0) {
+        perror("read");
+        exit(1);
+      }
+      else {
+        bufpos += ret;
+
+        do {
+           if (v != NULL) {
+              free_value(v);
+              v = NULL;
+           }
+           ret = parse(bufpos, buf, &v);
+           if (ret > 0) {
+              memmove(buf, buf + ret, bufpos - ret);
+              bufpos -= ret;
+              printf("parsed: ");
+              prin(stdout, v);
+              fputc('\n', stdout);
+
+              if (destructure(pattern, v)) {
+                 printf("match_data = ");
+                 prin(stdout, match_data);
+                 fputc('\n', stdout);
+              }
+              else {
+                 printf("destructure failed\n");
+              }
+
+              free_value(v);
+           }
+           else
+              printf("EOF\n");
+        } while (ret > 0);
+      }
+   }
+}
+
+main(int argc, char *argv[])
+{
+   read_and_parse();
+#if 0
+      Value *v;
+      v = ALLOC_VALUE();
+
+      v->tag = cons;
+      v->value.cons.car = ALLOC_VALUE();
+      v->value.cons.car->tag = symbol;
+      v->value.cons.car->value.s.length = 6;
+      v->value.cons.car->value.s.string = "symbol";
+
+      v->value.cons.cdr = ALLOC_VALUE();
+      v->value.cons.cdr->tag = cons;
+
+      v->value.cons.cdr->value.cons.car = ALLOC_VALUE();
+      v->value.cons.cdr->value.cons.car->tag = string;
+      v->value.cons.cdr->value.cons.car->value.s.length = 6;
+      v->value.cons.cdr->value.cons.car->value.s.string = "string";
+
+      v->value.cons.cdr->value.cons.cdr = ALLOC_VALUE();
+      v->value.cons.cdr->value.cons.cdr->tag = integer;
+      v->value.cons.cdr->value.cons.cdr->value.integer.i = 23;
+      prin(stdout, v);
+      fputc('\n', stdout);
+#endif
+}
+#endif
diff --git a/src/zsend-0.0.1/lread.h b/src/zsend-0.0.1/lread.h
new file mode 100644 (file)
index 0000000..57daf67
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+   lread.h  Header file for elisp reader and destructurer
+   Copyright (C) 1992 Nick Thompson (nix@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.
+
+   This code is useful for communicating with emacs, particularly in
+   subprocesses which are started by emacs.  It allows you to do structured
+   ipc by passing printed s-expressions between emacs and the subprocess -
+   strings are parsed into a union "Value" by this code and there is also a
+   fairly convenient way to extract data.
+   
+  */
+
+#include <stdlib.h>    /* for malloc() */
+
+enum Vtag { any, nil, cons, string, symbol, integer, var };
+
+typedef struct Value Value;
+struct Value {
+   enum Vtag tag;
+   union {
+      /* tag nil has no data */
+      struct { Value *car, *cdr; } cons;
+      struct { int length; char *string; } s;  /* tag string or symbol */
+      struct { long i; } integer;
+      struct { enum Vtag tag; void **value; } var;
+   } value;
+};
+
+#define ALLOC_VALUE()  ((Value *) malloc(sizeof(Value)))
+
+#define VTAG(v) (v?((v)->tag):nil)
+
+extern Value *vmake_cons(Value *car, Value *cdr);
+#define VCAR(v) ((v)->value.cons.car)
+#define VCDR(v) ((v)->value.cons.cdr)
+
+extern Value *vmake_symbol(int length, char *data);
+extern Value *vmake_symbol_c(char *s);
+extern Value *vmake_string(int length, char *data);
+extern Value *vmake_string_c(char *s);
+extern char *vextract_string_c(Value *v);
+#define VSLENGTH(v) ((v)->value.s.length)
+#define VSDATA(v) ((v)->value.s.string)
+
+extern Value *vmake_integer(int n);
+#define VINTEGER(v) ((v)->value.integer.i)
+
+extern Value *vmake_var(enum Vtag tag, void **value);
+#define VVTAG(v) ((v)->value.var.tag)
+#define VVDATA(v) ((v)->value.var.value)
+
+extern Value *assqv(Value *key, Value *assoc);
+extern int vlength(Value *l);
+
+extern int eqv();
+extern int parse();
+extern void free_value();
diff --git a/src/zsend-0.0.1/zsend.c b/src/zsend-0.0.1/zsend.c
new file mode 100644 (file)
index 0000000..f3149d0
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+   zsend.c  simple zephyr sender
+   Copyright (C) 1994 Darrell Kindred
+
+   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.
+
+*/
+
+#include <strings.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include <zephyr/zephyr.h>
+#include <zephyr/zephyr_err.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/file.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+
+#define DEFAULT_CLASS "MESSAGE"
+#define DEFAULT_INSTANCE "PERSONAL"
+#define URGENT_INSTANCE "URGENT"
+#define DEFAULT_OPCODE ""
+#define FILSRV_CLASS "FILSRV"
+#ifdef CMU_INTERREALM
+#define DEFAULT_REALM "ANDREW.CMU.EDU"
+#endif
+
+extern Code_t ZCancelSubscriptions(), ZUnsetLocation(), ZClosePort(),
+  //ZRetrieveSubscriptions(), 
+              ZGetSubscriptions(), ZSubscribeTo(),
+              ZSendNotice(), ZInitialize(), ZOpenPort(), ZPending(),
+              ZCompareUID(), ZReceiveNotice(), ZCheckAuthentication(),
+              ZFreeNotice(), ZSetLocation();
+#ifdef CMU_INTERREALM
+extern char *ZExpandRealm();
+#endif
+
+typedef struct PendingReply PendingReply;
+struct PendingReply {
+   char *instance;
+   char *recipient;
+   ZUnique_Id_t        uid;
+   PendingReply *next;
+};
+
+struct Globals {
+   const char  *program;
+   int          argc;
+   const char   **argv;
+
+   u_short     port;
+   int         zfd;
+
+   int         debug;
+
+   /* linked list of messages sent which are waiting for replies */
+   PendingReply *pending_replies;
+
+};
+
+struct Globals global_storage, *globals = &global_storage;
+
+void usage(const char *progname) {
+   fprintf(stderr, "usage: %s [options] [recipients]\n", progname);
+   fprintf(stderr, "   options:\n");
+   fprintf(stderr, "      -i <inst>      use instance <inst>\n");
+   fprintf(stderr, "      -c <class>     use class <class>\n");
+#ifdef CMU_INTERREALM
+   fprintf(stderr, "      -r <realm>     use realm <realm>\n");
+#endif
+   fprintf(stderr, "      -s <sig>       use signature <sig>\n");
+   fprintf(stderr, "      -S <sender>    use sender <sender>\n");
+   fprintf(stderr, "      -O <opcode>    use opcode <opcode>\n");
+   fprintf(stderr, "      -m <msg>       send msg instead of reading stdin (must be last arg)\n");
+   fprintf(stderr, "      -d             print debugging information\n");
+}
+
+void exit_tzc() {
+   ZClosePort();
+   exit(0);
+}               
+
+Code_t check(Code_t e, char *s) {
+   if (e) {
+      printf(";;; return code %d\n",(int) e);
+      fflush(stdout);
+      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;
+}
+
+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";
+   }
+}
+
+/* warning: this uses ctime which returns a pointer to a static buffer
+ * which is overwritten with each call. */
+char *time_str(time_t time_num)
+{
+    char *now_name;
+    now_name = ctime(&time_num);
+    now_name[24] = '\0';       /* dump newline at end */
+    return(now_name);
+}
+
+/* return time in the format "14:15:03" */
+/* uses ctime, which returns a ptr to a static buffer */
+char *debug_time_str(time_t time_num)
+{
+    char *now_name;
+    now_name = ctime(&time_num);
+    now_name[19] = '\0';       /* strip year */
+    return now_name+11;                /* strip date */
+}
+
+void
+setup()
+{
+   check(ZInitialize(), "ZInitialize");
+   globals->port = 0;
+   check(ZOpenPort(&globals->port), "ZOpenPort");
+
+   globals->pending_replies = NULL;
+}
+
+int get_message(char **msg, char *sig) {
+       /* XXX fix this to be dynamic */
+       static char buf[65535];
+       int c, len;
+       char *p;
+       strcpy(buf, sig);
+       len = strlen(sig)+1;
+       p = &(buf[len]);
+       while ((c=getchar()) != EOF) {
+               *p++ = c;
+               len++;
+       }
+       len++;
+       *p = '\0';
+       *msg = buf;
+       return len;
+}
+
+int get_message_arg(char **msg, char *msgptr, char *sig) {
+       /* XXX fix this to be dynamic */
+       static char buf[65535];
+       int c, len;
+        int i = 0;
+       char *p;
+       strcpy(buf, sig);
+       len = strlen(sig)+1;
+        strcpy(&buf[len], msgptr);
+        len += strlen(msgptr)+1;
+        *msg = buf;
+       return len;
+}
+
+int main(int argc, const char *argv[]) {
+   const char *program;
+   const char **recipient;
+   char *msg;
+   int broadcast, msglen;
+   int n_recips = 0;
+   int (*auth)();
+   int use_zctl = 0, sw;
+   int havemsg = 0;
+   int haverealm = 0;
+   extern char *optarg;
+   extern int optind;
+   char location[BUFSIZ];
+   ZNotice_t notice;
+   int retval;
+   char *sender=NULL, *signature="", *instance=DEFAULT_INSTANCE,
+     *class=DEFAULT_CLASS, *opcode=DEFAULT_OPCODE, *msgptr="";     
+#ifdef CMU_INTERREALM
+   char *realm=DEFAULT_REALM;
+   char rlmrecip[BUFSIZ];
+   char *cp;
+#endif
+
+   program = strrchr(argv[0], '/');
+   if (program == NULL)
+      program = argv[0];
+   else
+      program++;
+
+   while ((sw = getopt(argc, argv, "di:s:c:S:m:O:r:")) != EOF)
+      switch (sw) {
+       case 'O':
+         opcode = optarg;
+        break;
+       case 'i':
+        instance = optarg;
+        break;
+       case 'c':
+        class = optarg;
+        break;
+       case 's':
+         signature = optarg;
+        break;
+       case 'S':
+         sender = optarg;
+        break;
+       case 'd':
+        /* debug = 1; */
+        break;
+#ifdef CMU_INTERREALM
+       case 'r':
+        realm = optarg;
+        haverealm = 1;
+        break;
+#endif
+       case 'm':
+        msgptr = optarg;
+        havemsg = 1;
+        break;
+       case '?':
+       default:
+        usage(program);
+        exit(1);
+      }
+
+    broadcast = (optind == argc);
+
+    if (broadcast && !(strcmp(class, DEFAULT_CLASS) ||
+                      (strcmp(instance, DEFAULT_INSTANCE) &&
+                       strcmp(instance, URGENT_INSTANCE)))) {
+       /* must specify recipient if using default class and
+          (default instance or urgent instance) */
+       fprintf(stderr, "No recipients specified.\n");
+       usage(program);
+       exit(1);
+    }
+
+    if(havemsg)
+        msglen = get_message_arg(&msg, msgptr, signature);
+    else
+        msglen = get_message(&msg, signature);
+
+    setup();
+
+    for ( ; broadcast || optind < argc; optind++) {
+      bzero((char *) &notice, sizeof(notice));
+
+      notice.z_kind = UNACKED;
+      notice.z_port = 0;
+      notice.z_class = class;
+      notice.z_opcode = opcode;
+      notice.z_sender = sender;
+      notice.z_class_inst = instance;
+#ifdef CMU_INTERREALM
+      if (!broadcast && (cp = strchr(argv[optind], '@'))) {
+       (void) strcpy(rlmrecip, argv[optind]);
+       cp = strchr(rlmrecip, '@');
+       if (cp) {
+         cp++;
+         (void) strcpy(cp, (char *) ZExpandRealm(cp));
+       }
+       notice.z_recipient = rlmrecip;
+      } else if(haverealm) {
+       rlmrecip[0] = '@';
+       (void) strcpy(&rlmrecip[1], (char *) ZExpandRealm(realm));
+       notice.z_recipient = rlmrecip;
+      } else
+#endif
+      notice.z_recipient = (char *) (broadcast ? "" : argv[optind]);
+      notice.z_message = msg;
+      notice.z_message_len = msglen;
+      notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n$message";
+      auth = ZNOAUTH;
+      if (auth == ZAUTH) {
+       notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n$message";
+      }
+      if ((retval = ZSendNotice(&notice, auth)) != ZERR_NONE) {
+#if 1
+       char bfr[BUFSIZ];
+       (void) sprintf(bfr, "while sending notice to %s", 
+                      notice.z_recipient);
+       com_err(__FILE__, retval, bfr);
+#endif
+       fprintf(stderr, "error %d from ZSendNotice while sending to %s\n", 
+               retval, notice.z_recipient);
+       exit(1);
+      }
+      if (broadcast)
+       break;
+   }
+   exit(0);
+}
This page took 0.374844 seconds and 5 git commands to generate.