]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - lib/ZRetSubs.c
1da1a579ce49ddca70386928caf30749250bca5c
[1ts-debian.git] / lib / ZRetSubs.c
1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It contains source for the ZRetrieveSubscriptions and
3  * ZRetrieveDefaultSubscriptions functions.
4  *
5  *      Created by:     Robert French
6  *
7  *      $Id: ZRetSubs.c,v 1.26 1999/01/22 23:19:23 ghudson Exp $
8  *
9  *      Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
10  *      For copying and distribution information, see the file
11  *      "mit-copyright.h". 
12  */
13
14 #include <internal.h>
15
16 #ifndef lint
17 static const char rcsid_ZRetrieveSubscriptions_c[] =
18     "$Id: ZRetSubs.c,v 1.26 1999/01/22 23:19:23 ghudson Exp $";
19 #endif
20
21 static Code_t Z_RetSubs ();
22
23 /* Need STDC definition when possible for unsigned short argument. */
24 #ifdef __STDC__
25 Code_t ZRetrieveSubscriptions(char *galaxy,
26                               unsigned short port, int *nsubs)
27 #else
28 Code_t ZRetrieveSubscriptions(galaxy,port,nsubs)
29         ZCONST char *galaxy;
30         unsigned short port;
31         int *nsubs;
32 #endif
33 {
34         int retval;
35         ZNotice_t notice;
36         char asciiport[50];
37         
38         if (!port)                      /* use default port */
39             port = __Zephyr_port;
40
41         retval = ZMakeAscii16(asciiport, sizeof(asciiport), ntohs(port));
42         if (retval != ZERR_NONE)
43                 return (retval);
44
45         (void) memset((char *)&notice, 0, sizeof(notice));
46         notice.z_message = asciiport;
47         notice.z_message_len = strlen(asciiport)+1;
48         notice.z_opcode = CLIENT_GIMMESUBS;
49         notice.z_dest_galaxy = galaxy;
50
51         return(Z_RetSubs(&notice, nsubs, ZAUTH));
52 }
53
54 Code_t ZRetrieveDefaultSubscriptions(galaxy, nsubs)
55         char *galaxy;
56         int *nsubs;
57 {
58         ZNotice_t notice;
59
60         (void) memset((char *)&notice, 0, sizeof(notice));
61         notice.z_message = (char *) 0;
62         notice.z_message_len = 0;
63         notice.z_opcode = CLIENT_GIMMEDEFS;
64         notice.z_dest_galaxy = galaxy;
65
66         return(Z_RetSubs(&notice, nsubs, ZNOAUTH));
67
68 }
69
70 static Code_t Z_RetSubs(notice, nsubs, auth_routine)
71         register ZNotice_t *notice;
72         int *nsubs;
73         Z_AuthProc auth_routine;
74 {
75         register int i;
76         int retval,nrecv,gimmeack;
77         ZNotice_t retnotice;
78         char *ptr,*end,*ptr2;
79         ZSubscription_t *list = __subscriptions_list;
80
81         retval = ZFlushSubscriptions();
82
83         if (retval != ZERR_NONE && retval != ZERR_NOSUBSCRIPTIONS)
84                 return (retval);
85
86         if (ZGetFD() < 0)
87                 if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
88                         return (retval);
89
90         notice->z_kind = ACKED;
91         notice->z_port = __Zephyr_port;
92         notice->z_class = ZEPHYR_CTL_CLASS;
93         notice->z_class_inst = ZEPHYR_CTL_CLIENT;
94         notice->z_sender = 0;
95         notice->z_recipient = "";
96         notice->z_default_format = "";
97
98         if ((retval = ZSendNotice(notice,auth_routine)) != ZERR_NONE)
99                 return (retval);
100
101         nrecv = 0;
102         gimmeack = 0;
103         list = (ZSubscription_t *) 0;
104
105         while (!nrecv || !gimmeack) {
106                 retval = Z_WaitForNotice (&retnotice, ZCompareMultiUIDPred,
107                                           &notice->z_multiuid, SRV_TIMEOUT);
108                 if (retval == ZERR_NONOTICE)
109                   return ETIMEDOUT;
110                 else if (retval != ZERR_NONE)
111                   return retval;
112
113                 if (retnotice.z_kind == SERVNAK) {
114                         ZFreeNotice(&retnotice);
115                         return (ZERR_SERVNAK);
116                 }       
117                 /* non-matching protocol version numbers means the
118                    server is probably an older version--must punt */
119                 if (strcmp(notice->z_version,retnotice.z_version)) {
120                         ZFreeNotice(&retnotice);
121                         return(ZERR_VERS);
122                 }
123                 if (retnotice.z_kind == SERVACK &&
124                     !strcmp(retnotice.z_opcode,notice->z_opcode)) {
125                         ZFreeNotice(&retnotice);
126                         gimmeack = 1;
127                         continue;
128                 } 
129
130                 if (retnotice.z_kind != ACKED) {
131                         ZFreeNotice(&retnotice);
132                         return (ZERR_INTERNAL);
133                 }
134
135                 nrecv++;
136
137                 end = retnotice.z_message+retnotice.z_message_len;
138
139                 __subscriptions_num = 0;
140                 for (ptr=retnotice.z_message;ptr<end;ptr++)
141                         if (!*ptr)
142                                 __subscriptions_num++;
143
144                 __subscriptions_num = __subscriptions_num / 3;
145
146                 list = (ZSubscription_t *)
147                     malloc(__subscriptions_num * sizeof(ZSubscription_t));
148                 if (__subscriptions_num && !list) {
149                         ZFreeNotice(&retnotice);
150                         return (ENOMEM);
151                 }
152
153                 ptr = retnotice.z_message;
154                 for (i = 0; i < __subscriptions_num; i++) {
155                         list[i].zsub_class = (char *)
156                             malloc(strlen(ptr) + 1);
157                         if (!list[i].zsub_class) {
158                                 ZFreeNotice(&retnotice);
159                                 return (ENOMEM);
160                         }
161                         strcpy(list[i].zsub_class, ptr);
162                         ptr += strlen(ptr)+1;
163                         list[i].zsub_classinst = (char *)
164                             malloc(strlen(ptr) + 1);
165                         if (!list[i].zsub_classinst) {
166                                 ZFreeNotice(&retnotice);
167                                 return (ENOMEM);
168                         }
169                         strcpy(list[i].zsub_classinst, ptr);
170                         ptr += strlen(ptr)+1;
171                         ptr2 = ptr;
172                         list[i].zsub_recipient = (char *)
173                             malloc(strlen(ptr2) + 2);
174                         if (!list[i].zsub_recipient) {
175                                 ZFreeNotice(&retnotice);
176                                 return (ENOMEM);
177                         }
178                         if (*ptr2 == '@' || *ptr2 == 0) {
179                                 *list[i].zsub_recipient = '*';
180                                 strcpy(list[i].zsub_recipient + 1, ptr2);
181                         } else {
182                                 strcpy(list[i].zsub_recipient, ptr2);
183                         }
184                         ptr += strlen(ptr)+1;
185                 }
186                 ZFreeNotice(&retnotice);
187         }
188
189         __subscriptions_list = list;
190         __subscriptions_next = 0;
191         *nsubs = __subscriptions_num;
192
193         return (ZERR_NONE);
194 }