| |
1 /* This file is part of the Project Athena Zephyr Notification System. |
| |
2 * It contains source for asynchronous location functions. |
| |
3 * |
| |
4 * Created by: Marc Horowitz |
| |
5 * |
| |
6 * Copyright (c) 1990,1991 by the Massachusetts Institute of Technology. |
| |
7 * For copying and distribution information, see the file |
| |
8 * "mit-copyright.h". |
| |
9 */ |
| |
10 |
| |
11 #include "internal.h" |
| |
12 |
| |
13 Code_t ZRequestLocations(user, zald, kind, auth) |
| |
14 const char *user; |
| |
15 ZAsyncLocateData_t *zald; |
| |
16 ZNotice_Kind_t kind; /* UNSAFE, UNACKED, or ACKED */ |
| |
17 Z_AuthProc auth; |
| |
18 { |
| |
19 int retval; |
| |
20 ZNotice_t notice; |
| |
21 |
| |
22 if (ZGetFD() < 0) |
| |
23 if ((retval = ZOpenPort((unsigned short *)0)) != ZERR_NONE) |
| |
24 return (retval); |
| |
25 |
| |
26 (void) memset((char *)¬ice, 0, sizeof(notice)); |
| |
27 notice.z_kind = kind; |
| |
28 notice.z_port = __Zephyr_port; |
| |
29 notice.z_class = LOCATE_CLASS; |
| |
30 notice.z_class_inst = user; |
| |
31 notice.z_opcode = LOCATE_LOCATE; |
| |
32 notice.z_sender = 0; |
| |
33 notice.z_recipient = ""; |
| |
34 notice.z_default_format = ""; |
| |
35 notice.z_message_len = 0; |
| |
36 |
| |
37 if ((retval = ZSendNotice(¬ice, auth)) != ZERR_NONE) |
| |
38 return(retval); |
| |
39 |
| |
40 if ((zald->user = (char *) malloc(strlen(user)+1)) == NULL) { |
| |
41 return(ENOMEM); |
| |
42 } |
| |
43 if ((zald->version = (char *) malloc(strlen(notice.z_version)+1)) == NULL) { |
| |
44 free(zald->user); |
| |
45 return(ENOMEM); |
| |
46 } |
| |
47 zald->uid = notice.z_multiuid; |
| |
48 strcpy(zald->user,user); |
| |
49 strcpy(zald->version,notice.z_version); |
| |
50 |
| |
51 return(ZERR_NONE); |
| |
52 } |
| |
53 |
| |
54 Code_t ZParseLocations(notice,zald,nlocs,user) |
| |
55 ZNotice_t *notice; |
| |
56 ZAsyncLocateData_t *zald; |
| |
57 int *nlocs; |
| |
58 char **user; |
| |
59 { |
| |
60 char *ptr, *end; |
| |
61 int i; |
| |
62 |
| |
63 ZFlushLocations(); /* This never fails (this function is part of the |
| |
64 library, so it is allowed to know this). */ |
| |
65 |
| |
66 /* non-matching protocol version numbers means the |
| |
67 server is probably an older version--must punt */ |
| |
68 |
| |
69 if (zald && strcmp(notice->z_version, zald->version)) |
| |
70 return(ZERR_VERS); |
| |
71 |
| |
72 if (notice->z_kind == SERVNAK) |
| |
73 return (ZERR_SERVNAK); |
| |
74 |
| |
75 /* flag ACKs as special */ |
| |
76 if (notice->z_kind == SERVACK && |
| |
77 !strcmp(notice->z_opcode, LOCATE_LOCATE)) { |
| |
78 *nlocs = -1; |
| |
79 return(ZERR_NONE); |
| |
80 } |
| |
81 |
| |
82 if (notice->z_kind != ACKED) |
| |
83 return (ZERR_INTERNAL); |
| |
84 |
| |
85 end = notice->z_message+notice->z_message_len; |
| |
86 |
| |
87 __locate_num = 0; |
| |
88 |
| |
89 for (ptr=notice->z_message;ptr<end;ptr++) |
| |
90 if (!*ptr) |
| |
91 __locate_num++; |
| |
92 |
| |
93 __locate_num /= 3; |
| |
94 |
| |
95 if (__locate_num) |
| |
96 { |
| |
97 __locate_list = (ZLocations_t *)malloc((unsigned)__locate_num* |
| |
98 sizeof(ZLocations_t)); |
| |
99 if (!__locate_list) |
| |
100 return (ENOMEM); |
| |
101 } else { |
| |
102 __locate_list = 0; |
| |
103 } |
| |
104 |
| |
105 for (ptr=notice->z_message, i=0; i<__locate_num; i++) { |
| |
106 unsigned int len; |
| |
107 |
| |
108 len = strlen (ptr) + 1; |
| |
109 __locate_list[i].host = (char *) malloc(len); |
| |
110 if (!__locate_list[i].host) |
| |
111 return (ENOMEM); |
| |
112 (void) strcpy(__locate_list[i].host, ptr); |
| |
113 ptr += len; |
| |
114 |
| |
115 len = strlen (ptr) + 1; |
| |
116 __locate_list[i].time = (char *) malloc(len); |
| |
117 if (!__locate_list[i].time) |
| |
118 return (ENOMEM); |
| |
119 (void) strcpy(__locate_list[i].time, ptr); |
| |
120 ptr += len; |
| |
121 |
| |
122 len = strlen (ptr) + 1; |
| |
123 __locate_list[i].tty = (char *) malloc(len); |
| |
124 if (!__locate_list[i].tty) |
| |
125 return (ENOMEM); |
| |
126 (void) strcpy(__locate_list[i].tty, ptr); |
| |
127 ptr += len; |
| |
128 } |
| |
129 |
| |
130 __locate_next = 0; |
| |
131 *nlocs = __locate_num; |
| |
132 if (user) { |
| |
133 if (zald) { |
| |
134 if ((*user = (char *) malloc(strlen(zald->user)+1)) == NULL) |
| |
135 return(ENOMEM); |
| |
136 strcpy(*user,zald->user); |
| |
137 } else { |
| |
138 if ((*user = (char *) malloc(strlen(notice->z_class_inst)+1)) == NULL) |
| |
139 return(ENOMEM); |
| |
140 strcpy(*user,notice->z_class_inst); |
| |
141 } |
| |
142 } |
| |
143 return (ZERR_NONE); |
| |
144 } |
| |
145 |
| |
146 int ZCompareALDPred(notice, zald) |
| |
147 ZNotice_t *notice; |
| |
148 void *zald; |
| |
149 { |
| |
150 return(ZCompareUID(&(notice->z_multiuid), |
| |
151 &(((ZAsyncLocateData_t *) zald)->uid))); |
| |
152 } |
| |
153 |
| |
154 void ZFreeALD(zald) |
| |
155 ZAsyncLocateData_t *zald; |
| |
156 { |
| |
157 if (!zald) return; |
| |
158 |
| |
159 if (zald->user) free(zald->user); |
| |
160 if (zald->version) free(zald->version); |
| |
161 (void) memset(zald, 0, sizeof(*zald)); |
| |
162 } |