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