]> andersk Git - zcommit.git/blob - src/zsend-0.0.1/zsend.c
Added source for zsend
[zcommit.git] / src / zsend-0.0.1 / zsend.c
1 /*
2    zsend.c  simple zephyr sender
3    Copyright (C) 1994 Darrell Kindred
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #include <strings.h>
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <ctype.h>
25 #include <zephyr/zephyr.h>
26 #include <zephyr/zephyr_err.h>
27 #include <netdb.h>
28 #include <sys/socket.h>
29 #include <sys/wait.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <sys/file.h>
33 #include <signal.h>
34 #include <string.h>
35 #include <time.h>
36
37 #define DEFAULT_CLASS "MESSAGE"
38 #define DEFAULT_INSTANCE "PERSONAL"
39 #define URGENT_INSTANCE "URGENT"
40 #define DEFAULT_OPCODE ""
41 #define FILSRV_CLASS "FILSRV"
42 #ifdef CMU_INTERREALM
43 #define DEFAULT_REALM "ANDREW.CMU.EDU"
44 #endif
45
46 extern Code_t ZCancelSubscriptions(), ZUnsetLocation(), ZClosePort(),
47   //ZRetrieveSubscriptions(), 
48               ZGetSubscriptions(), ZSubscribeTo(),
49               ZSendNotice(), ZInitialize(), ZOpenPort(), ZPending(),
50               ZCompareUID(), ZReceiveNotice(), ZCheckAuthentication(),
51               ZFreeNotice(), ZSetLocation();
52 #ifdef CMU_INTERREALM
53 extern char *ZExpandRealm();
54 #endif
55
56 typedef struct PendingReply PendingReply;
57 struct PendingReply {
58    char *instance;
59    char *recipient;
60    ZUnique_Id_t uid;
61    PendingReply *next;
62 };
63
64 struct Globals {
65    const char   *program;
66    int          argc;
67    const char   **argv;
68
69    u_short      port;
70    int          zfd;
71
72    int          debug;
73
74    /* linked list of messages sent which are waiting for replies */
75    PendingReply *pending_replies;
76
77 };
78
79 struct Globals global_storage, *globals = &global_storage;
80
81 void usage(const char *progname) {
82    fprintf(stderr, "usage: %s [options] [recipients]\n", progname);
83    fprintf(stderr, "   options:\n");
84    fprintf(stderr, "      -i <inst>      use instance <inst>\n");
85    fprintf(stderr, "      -c <class>     use class <class>\n");
86 #ifdef CMU_INTERREALM
87    fprintf(stderr, "      -r <realm>     use realm <realm>\n");
88 #endif
89    fprintf(stderr, "      -s <sig>       use signature <sig>\n");
90    fprintf(stderr, "      -S <sender>    use sender <sender>\n");
91    fprintf(stderr, "      -O <opcode>    use opcode <opcode>\n");
92    fprintf(stderr, "      -m <msg>       send msg instead of reading stdin (must be last arg)\n");
93    fprintf(stderr, "      -d             print debugging information\n");
94 }
95
96 void exit_tzc() {
97    ZClosePort();
98    exit(0);
99 }                
100
101 Code_t check(Code_t e, char *s) {
102    if (e) {
103       printf(";;; return code %d\n",(int) e);
104       fflush(stdout);
105       com_err(__FILE__, e, s);
106       exit(1);
107    }
108    return e;
109 }
110
111 Code_t warn(Code_t e, char *s) {
112    if (e)
113       com_err(__FILE__, e, s);
114    return e;
115 }
116
117 char *auth_string(int n) {
118    switch (n) {
119     case ZAUTH_YES    : return "yes";
120     case ZAUTH_FAILED : return "failed";
121     case ZAUTH_NO     : return "no";
122     default           : return "bad-auth-value";
123    }
124 }
125  
126 char *kind_string(int n) {
127    switch (n) {
128     case UNSAFE:    return "unsafe";
129     case UNACKED:   return "unacked";
130     case ACKED:     return "acked";
131     case HMACK:     return "hmack";
132     case HMCTL:     return "hmctl";
133     case SERVACK:   return "servack";
134     case SERVNAK:   return "servnak";
135     case CLIENTACK: return "clientack";
136     case STAT:      return "stat";
137     default:        return "bad-kind-value";
138    }
139 }
140
141 /* warning: this uses ctime which returns a pointer to a static buffer
142  * which is overwritten with each call. */
143 char *time_str(time_t time_num)
144 {
145     char *now_name;
146     now_name = ctime(&time_num);
147     now_name[24] = '\0';        /* dump newline at end */
148     return(now_name);
149 }
150
151 /* return time in the format "14:15:03" */
152 /* uses ctime, which returns a ptr to a static buffer */
153 char *debug_time_str(time_t time_num)
154 {
155     char *now_name;
156     now_name = ctime(&time_num);
157     now_name[19] = '\0';        /* strip year */
158     return now_name+11;         /* strip date */
159 }
160
161 void
162 setup()
163 {
164    check(ZInitialize(), "ZInitialize");
165    globals->port = 0;
166    check(ZOpenPort(&globals->port), "ZOpenPort");
167
168    globals->pending_replies = NULL;
169 }
170
171 int get_message(char **msg, char *sig) {
172         /* XXX fix this to be dynamic */
173         static char buf[65535];
174         int c, len;
175         char *p;
176         strcpy(buf, sig);
177         len = strlen(sig)+1;
178         p = &(buf[len]);
179         while ((c=getchar()) != EOF) {
180                 *p++ = c;
181                 len++;
182         }
183         len++;
184         *p = '\0';
185         *msg = buf;
186         return len;
187 }
188
189 int get_message_arg(char **msg, char *msgptr, char *sig) {
190         /* XXX fix this to be dynamic */
191         static char buf[65535];
192         int c, len;
193         int i = 0;
194         char *p;
195         strcpy(buf, sig);
196         len = strlen(sig)+1;
197         strcpy(&buf[len], msgptr);
198         len += strlen(msgptr)+1;
199         *msg = buf;
200         return len;
201 }
202
203 int main(int argc, const char *argv[]) {
204    const char *program;
205    const char **recipient;
206    char *msg;
207    int broadcast, msglen;
208    int n_recips = 0;
209    int (*auth)();
210    int use_zctl = 0, sw;
211    int havemsg = 0;
212    int haverealm = 0;
213    extern char *optarg;
214    extern int optind;
215    char location[BUFSIZ];
216    ZNotice_t notice;
217    int retval;
218    char *sender=NULL, *signature="", *instance=DEFAULT_INSTANCE,
219      *class=DEFAULT_CLASS, *opcode=DEFAULT_OPCODE, *msgptr="";     
220 #ifdef CMU_INTERREALM
221    char *realm=DEFAULT_REALM;
222    char rlmrecip[BUFSIZ];
223    char *cp;
224 #endif
225
226    program = strrchr(argv[0], '/');
227    if (program == NULL)
228       program = argv[0];
229    else
230       program++;
231
232    while ((sw = getopt(argc, argv, "di:s:c:S:m:O:r:")) != EOF)
233       switch (sw) {
234        case 'O':
235          opcode = optarg;
236          break;
237        case 'i':
238          instance = optarg;
239          break;
240        case 'c':
241          class = optarg;
242          break;
243        case 's':
244          signature = optarg;
245          break;
246        case 'S':
247          sender = optarg;
248          break;
249        case 'd':
250          /* debug = 1; */
251          break;
252 #ifdef CMU_INTERREALM
253        case 'r':
254          realm = optarg;
255          haverealm = 1;
256          break;
257 #endif
258        case 'm':
259          msgptr = optarg;
260          havemsg = 1;
261          break;
262        case '?':
263        default:
264          usage(program);
265          exit(1);
266       }
267
268     broadcast = (optind == argc);
269
270     if (broadcast && !(strcmp(class, DEFAULT_CLASS) ||
271                        (strcmp(instance, DEFAULT_INSTANCE) &&
272                         strcmp(instance, URGENT_INSTANCE)))) {
273         /* must specify recipient if using default class and
274            (default instance or urgent instance) */
275         fprintf(stderr, "No recipients specified.\n");
276         usage(program);
277         exit(1);
278     }
279
280     if(havemsg)
281         msglen = get_message_arg(&msg, msgptr, signature);
282     else
283         msglen = get_message(&msg, signature);
284
285     setup();
286
287     for ( ; broadcast || optind < argc; optind++) {
288       bzero((char *) &notice, sizeof(notice));
289
290       notice.z_kind = UNACKED;
291       notice.z_port = 0;
292       notice.z_class = class;
293       notice.z_opcode = opcode;
294       notice.z_sender = sender;
295       notice.z_class_inst = instance;
296 #ifdef CMU_INTERREALM
297       if (!broadcast && (cp = strchr(argv[optind], '@'))) {
298         (void) strcpy(rlmrecip, argv[optind]);
299         cp = strchr(rlmrecip, '@');
300         if (cp) {
301           cp++;
302           (void) strcpy(cp, (char *) ZExpandRealm(cp));
303         }
304         notice.z_recipient = rlmrecip;
305       } else if(haverealm) {
306         rlmrecip[0] = '@';
307         (void) strcpy(&rlmrecip[1], (char *) ZExpandRealm(realm));
308         notice.z_recipient = rlmrecip;
309       } else
310 #endif
311       notice.z_recipient = (char *) (broadcast ? "" : argv[optind]);
312       notice.z_message = msg;
313       notice.z_message_len = msglen;
314       notice.z_default_format = "@bold(UNAUTHENTIC) Class $class, Instance $instance:\n$message";
315       auth = ZNOAUTH;
316       if (auth == ZAUTH) {
317         notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n$message";
318       }
319       if ((retval = ZSendNotice(&notice, auth)) != ZERR_NONE) {
320 #if 1
321         char bfr[BUFSIZ];
322         (void) sprintf(bfr, "while sending notice to %s", 
323                        notice.z_recipient);
324         com_err(__FILE__, retval, bfr);
325 #endif
326         fprintf(stderr, "error %d from ZSendNotice while sending to %s\n", 
327                 retval, notice.z_recipient);
328         exit(1);
329       }
330       if (broadcast)
331         break;
332    }
333    exit(0);
334 }
This page took 0.157954 seconds and 5 git commands to generate.