2 zsend.c simple zephyr sender
3 Copyright (C) 1994 Darrell Kindred
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.
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.
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.
23 #include <sys/types.h>
25 #include <zephyr/zephyr.h>
26 #include <zephyr/zephyr_err.h>
28 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
37 #define DEFAULT_CLASS "MESSAGE"
38 #define DEFAULT_INSTANCE "PERSONAL"
39 #define URGENT_INSTANCE "URGENT"
40 #define DEFAULT_OPCODE ""
41 #define FILSRV_CLASS "FILSRV"
43 #define DEFAULT_REALM "ANDREW.CMU.EDU"
46 extern Code_t ZCancelSubscriptions(), ZUnsetLocation(), ZClosePort(),
47 //ZRetrieveSubscriptions(),
48 ZGetSubscriptions(), ZSubscribeTo(),
49 ZSendNotice(), ZInitialize(), ZOpenPort(), ZPending(),
50 ZCompareUID(), ZReceiveNotice(), ZCheckAuthentication(),
51 ZFreeNotice(), ZSetLocation();
53 extern char *ZExpandRealm();
56 typedef struct PendingReply PendingReply;
74 /* linked list of messages sent which are waiting for replies */
75 PendingReply *pending_replies;
79 struct Globals global_storage, *globals = &global_storage;
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");
87 fprintf(stderr, " -r <realm> use realm <realm>\n");
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");
101 Code_t check(Code_t e, char *s) {
103 printf(";;; return code %d\n",(int) e);
105 com_err(__FILE__, e, s);
111 Code_t warn(Code_t e, char *s) {
113 com_err(__FILE__, e, s);
117 char *auth_string(int 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";
126 char *kind_string(int 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";
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)
146 now_name = ctime(&time_num);
147 now_name[24] = '\0'; /* dump newline at end */
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)
156 now_name = ctime(&time_num);
157 now_name[19] = '\0'; /* strip year */
158 return now_name+11; /* strip date */
164 check(ZInitialize(), "ZInitialize");
166 check(ZOpenPort(&globals->port), "ZOpenPort");
168 globals->pending_replies = NULL;
171 int get_message(char **msg, char *sig) {
172 /* XXX fix this to be dynamic */
173 static char buf[65535];
179 while ((c=getchar()) != EOF) {
189 int get_message_arg(char **msg, char *msgptr, char *sig) {
190 /* XXX fix this to be dynamic */
191 static char buf[65535];
197 strcpy(&buf[len], msgptr);
198 len += strlen(msgptr)+1;
203 int main(int argc, const char *argv[]) {
205 const char **recipient;
207 int broadcast, msglen;
210 int use_zctl = 0, sw;
215 char location[BUFSIZ];
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];
226 program = strrchr(argv[0], '/');
232 while ((sw = getopt(argc, argv, "di:s:c:S:m:O:r:")) != EOF)
252 #ifdef CMU_INTERREALM
268 broadcast = (optind == argc);
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");
281 msglen = get_message_arg(&msg, msgptr, signature);
283 msglen = get_message(&msg, signature);
287 for ( ; broadcast || optind < argc; optind++) {
288 bzero((char *) ¬ice, sizeof(notice));
290 notice.z_kind = UNACKED;
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, '@');
302 (void) strcpy(cp, (char *) ZExpandRealm(cp));
304 notice.z_recipient = rlmrecip;
305 } else if(haverealm) {
307 (void) strcpy(&rlmrecip[1], (char *) ZExpandRealm(realm));
308 notice.z_recipient = rlmrecip;
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";
317 notice.z_default_format = "Class $class, Instance $instance:\nTo: @bold($recipient)\n$message";
319 if ((retval = ZSendNotice(¬ice, auth)) != ZERR_NONE) {
322 (void) sprintf(bfr, "while sending notice to %s",
324 com_err(__FILE__, retval, bfr);
326 fprintf(stderr, "error %d from ZSendNotice while sending to %s\n",
327 retval, notice.z_recipient);