]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/lib/ZRetSubs.c
r4254@bucket (orig r244): kcr | 2008-01-20 14:40:42 -0500
[1ts-debian.git] / zephyr / 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$
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$";
19 #endif
20
21 static Code_t Z_RetSubs (register ZNotice_t *, int *, Z_AuthProc);
22
23 /* Need STDC definition when possible for unsigned short argument. */
24 Code_t
25 ZRetrieveSubscriptions(unsigned short port,
26                        int *nsubs)
27 {
28         int retval;
29         ZNotice_t notice;
30         char asciiport[50];
31         
32         if (!port)                      /* use default port */
33             port = __Zephyr_port;
34
35         retval = ZMakeAscii16(asciiport, sizeof(asciiport), ntohs(port));
36         if (retval != ZERR_NONE)
37                 return (retval);
38
39         (void) memset((char *)&notice, 0, sizeof(notice));
40         notice.z_message = asciiport;
41         notice.z_message_len = strlen(asciiport)+1;
42         notice.z_opcode = CLIENT_GIMMESUBS;
43
44         return(Z_RetSubs(&notice, nsubs, ZAUTH));
45 }
46
47 Code_t
48 ZRetrieveDefaultSubscriptions(int *nsubs)
49 {
50         ZNotice_t notice;
51
52         (void) memset((char *)&notice, 0, sizeof(notice));
53         notice.z_message = (char *) 0;
54         notice.z_message_len = 0;
55         notice.z_opcode = CLIENT_GIMMEDEFS;
56
57         return(Z_RetSubs(&notice, nsubs, ZNOAUTH));
58
59 }
60
61 static Code_t
62 Z_RetSubs(register ZNotice_t *notice,
63           int *nsubs,
64           Z_AuthProc auth_routine)
65 {
66         register int i;
67         int retval,nrecv,gimmeack;
68         ZNotice_t retnotice;
69         char *ptr,*end,*ptr2;
70         ZSubscription_t *list = __subscriptions_list;
71
72         retval = ZFlushSubscriptions();
73
74         if (retval != ZERR_NONE && retval != ZERR_NOSUBSCRIPTIONS)
75                 return (retval);
76
77         if (ZGetFD() < 0)
78                 if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
79                         return (retval);
80
81         notice->z_kind = ACKED;
82         notice->z_port = __Zephyr_port;
83         notice->z_class = ZEPHYR_CTL_CLASS;
84         notice->z_class_inst = ZEPHYR_CTL_CLIENT;
85         notice->z_sender = 0;
86         notice->z_recipient = "";
87         notice->z_default_format = "";
88
89         if ((retval = ZSendNotice(notice,auth_routine)) != ZERR_NONE)
90                 return (retval);
91
92         nrecv = 0;
93         gimmeack = 0;
94         list = (ZSubscription_t *) 0;
95
96         while (!nrecv || !gimmeack) {
97                 retval = Z_WaitForNotice (&retnotice, ZCompareMultiUIDPred,
98                                           &notice->z_multiuid, SRV_TIMEOUT);
99                 if (retval == ZERR_NONOTICE)
100                   return ETIMEDOUT;
101                 else if (retval != ZERR_NONE)
102                   return retval;
103
104                 if (retnotice.z_kind == SERVNAK) {
105                         ZFreeNotice(&retnotice);
106                         return (ZERR_SERVNAK);
107                 }       
108                 /* non-matching protocol version numbers means the
109                    server is probably an older version--must punt */
110                 if (strcmp(notice->z_version,retnotice.z_version)) {
111                         ZFreeNotice(&retnotice);
112                         return(ZERR_VERS);
113                 }
114                 if (retnotice.z_kind == SERVACK &&
115                     !strcmp(retnotice.z_opcode,notice->z_opcode)) {
116                         ZFreeNotice(&retnotice);
117                         gimmeack = 1;
118                         continue;
119                 } 
120
121                 if (retnotice.z_kind != ACKED) {
122                         ZFreeNotice(&retnotice);
123                         return (ZERR_INTERNAL);
124                 }
125
126                 nrecv++;
127
128                 end = retnotice.z_message+retnotice.z_message_len;
129
130                 __subscriptions_num = 0;
131                 for (ptr=retnotice.z_message;ptr<end;ptr++)
132                         if (!*ptr)
133                                 __subscriptions_num++;
134
135                 __subscriptions_num = __subscriptions_num / 3;
136
137                 list = (ZSubscription_t *)
138                     malloc(__subscriptions_num * sizeof(ZSubscription_t));
139                 if (__subscriptions_num && !list) {
140                         ZFreeNotice(&retnotice);
141                         return (ENOMEM);
142                 }
143
144                 ptr = retnotice.z_message;
145                 for (i = 0; i < __subscriptions_num; i++) {
146                         list[i].zsub_class = (char *)
147                             malloc(strlen(ptr) + 1);
148                         if (!list[i].zsub_class) {
149                                 ZFreeNotice(&retnotice);
150                                 return (ENOMEM);
151                         }
152                         strcpy(list[i].zsub_class, ptr);
153                         ptr += strlen(ptr)+1;
154                         list[i].zsub_classinst = (char *)
155                             malloc(strlen(ptr) + 1);
156                         if (!list[i].zsub_classinst) {
157                                 ZFreeNotice(&retnotice);
158                                 return (ENOMEM);
159                         }
160                         strcpy(list[i].zsub_classinst, ptr);
161                         ptr += strlen(ptr)+1;
162                         ptr2 = ptr;
163                         list[i].zsub_recipient = (char *)
164                             malloc(strlen(ptr2) + 2);
165                         if (!list[i].zsub_recipient) {
166                                 ZFreeNotice(&retnotice);
167                                 return (ENOMEM);
168                         }
169                         if (*ptr2 == '@' || *ptr2 == 0) {
170                                 *list[i].zsub_recipient = '*';
171                                 strcpy(list[i].zsub_recipient + 1, ptr2);
172                         } else {
173                                 strcpy(list[i].zsub_recipient, ptr2);
174                         }
175                         ptr += strlen(ptr)+1;
176                 }
177                 ZFreeNotice(&retnotice);
178         }
179
180         __subscriptions_list = list;
181         __subscriptions_next = 0;
182         *nsubs = __subscriptions_num;
183
184         return (ZERR_NONE);
185 }