Merged pidgin/main into default
[pidgin-git.git] / libpurple / protocols / zephyr / ZAsyncLocate.c
blobbdaf5fc26e72ea356849f2fd0c31b82a802dd2d8
1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains source for asynchronous location functions.
4 * Created by: Marc Horowitz
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 */
11 #include "internal.h"
12 #include "util.h"
14 Code_t ZRequestLocations(user, zald, kind, auth)
15 const char *user;
16 ZAsyncLocateData_t *zald;
17 ZNotice_Kind_t kind; /* UNSAFE, UNACKED, or ACKED */
18 Z_AuthProc auth;
20 int retval;
21 ZNotice_t notice;
22 size_t userlen, versionlen;
24 if (ZGetFD() < 0)
25 if ((retval = ZOpenPort((unsigned short *)0)) != ZERR_NONE)
26 return (retval);
28 (void) memset((char *)&notice, 0, sizeof(notice));
29 notice.z_kind = kind;
30 notice.z_port = __Zephyr_port;
31 notice.z_class = LOCATE_CLASS;
32 notice.z_class_inst = user;
33 notice.z_opcode = LOCATE_LOCATE;
34 notice.z_sender = 0;
35 notice.z_recipient = "";
36 notice.z_default_format = "";
37 notice.z_message_len = 0;
39 if ((retval = ZSendNotice(&notice, auth)) != ZERR_NONE)
40 return(retval);
42 userlen = strlen(user) + 1;
43 versionlen = strlen(notice.z_version) + 1;
44 if ((zald->user = (char *) malloc(userlen)) == NULL) {
45 return(ENOMEM);
47 if ((zald->version = (char *) malloc(versionlen)) == NULL) {
48 free(zald->user);
49 return(ENOMEM);
51 zald->uid = notice.z_multiuid;
52 g_strlcpy(zald->user,user,userlen);
53 g_strlcpy(zald->version,notice.z_version,versionlen);
55 return(ZERR_NONE);
58 Code_t ZParseLocations(notice,zald,nlocs,user)
59 ZNotice_t *notice;
60 ZAsyncLocateData_t *zald;
61 int *nlocs;
62 char **user;
64 char *ptr, *end;
65 int i;
67 ZFlushLocations(); /* This never fails (this function is part of the
68 library, so it is allowed to know this). */
70 /* non-matching protocol version numbers means the
71 server is probably an older version--must punt */
73 if (zald && !purple_strequal(notice->z_version, zald->version))
74 return(ZERR_VERS);
76 if (notice->z_kind == SERVNAK)
77 return (ZERR_SERVNAK);
79 /* flag ACKs as special */
80 if (notice->z_kind == SERVACK &&
81 purple_strequal(notice->z_opcode, LOCATE_LOCATE)) {
82 *nlocs = -1;
83 return(ZERR_NONE);
86 if (notice->z_kind != ACKED)
87 return (ZERR_INTERNAL);
89 end = notice->z_message+notice->z_message_len;
91 __locate_num = 0;
93 for (ptr=notice->z_message;ptr<end;ptr++)
94 if (!*ptr)
95 __locate_num++;
97 __locate_num /= 3;
99 if (__locate_num)
101 __locate_list = (ZLocations_t *)malloc((unsigned)__locate_num*
102 sizeof(ZLocations_t));
103 if (!__locate_list)
104 return (ENOMEM);
105 } else {
106 __locate_list = NULL;
109 for (ptr=notice->z_message, i=0; i<__locate_num; i++) {
110 unsigned int len;
112 len = strlen (ptr) + 1;
113 __locate_list[i].host = (char *) malloc(len);
114 if (!__locate_list[i].host)
115 return (ENOMEM);
116 g_strlcpy(__locate_list[i].host, ptr,len);
117 ptr += len;
119 len = strlen (ptr) + 1;
120 __locate_list[i].time = (char *) malloc(len);
121 if (!__locate_list[i].time)
122 return (ENOMEM);
123 g_strlcpy(__locate_list[i].time, ptr,len);
124 ptr += len;
126 len = strlen (ptr) + 1;
127 __locate_list[i].tty = (char *) malloc(len);
128 if (!__locate_list[i].tty)
129 return (ENOMEM);
130 g_strlcpy(__locate_list[i].tty, ptr,len);
131 ptr += len;
134 __locate_next = 0;
135 *nlocs = __locate_num;
136 if (user) {
137 size_t len;
138 if (zald) {
139 len = strlen(zald->user) + 1;
140 if ((*user = (char *) malloc(len)) == NULL)
141 return(ENOMEM);
142 g_strlcpy(*user,zald->user,len);
143 } else {
144 len = strlen(notice->z_class_inst) + 1;
145 if ((*user = (char *) malloc(len)) == NULL)
146 return(ENOMEM);
147 g_strlcpy(*user,notice->z_class_inst,len);
150 return (ZERR_NONE);
153 int ZCompareALDPred(notice, zald)
154 ZNotice_t *notice;
155 void *zald;
157 return(ZCompareUID(&(notice->z_multiuid),
158 &(((ZAsyncLocateData_t *) zald)->uid)));
161 void ZFreeALD(zald)
162 ZAsyncLocateData_t *zald;
164 if (!zald) return;
166 free(zald->user);
167 free(zald->version);
168 (void) memset(zald, 0, sizeof(*zald));