7 * The following code extracts keypressed from an X event:
9 * keyevent = event->xkey;
10 * XLookupString(&keyevent, buffer, 1, NULL, NULL);
14 * This entire file could easily be changes so that multiple destination
15 * lists could be used. But I don't know that that's necessary for this
22 static DynObject dests;
25 static void get_dest_from_file(), _get_default_dest();
26 static int sort_dest_func(const void *, const void *);
28 /* A function for debugging */
34 d = (char **) DynGet(dests, 0);
35 for (i=0; i<DynSize(dests); i++)
36 printf("%d %s\n", i, d[i]);
41 return ((char **) DynGet(dests, 0));
46 return (DynSize(dests));
49 void dest_set_current_dest(dest)
52 (void) memcpy((char *) ¤t_dest, (char *) dest, sizeof(DestRec));
57 dests = DynCreate(sizeof(char *), 0);
59 Error("Out of memory reading destinations", NULL);
61 strcpy(current_dest.zclass, DEFAULT_CLASS);
62 strcpy(current_dest.zinst, DEFAULT_INST);
63 strcpy(current_dest.zrecip, get_username());
66 char **load_default_dest()
70 if (! *get_home_dir())
71 Error("Cannot find your home directory.", NULL);
73 if (defs.read_xzwrite)
74 _get_default_dest(XZWRITE_DEST_FILE);
76 _get_default_dest(ZEPHYR_FILE);
78 _get_default_dest(ANYONE_FILE);
80 if (DynSize(dests) == 0) {
83 Warning("XZwrite: No destinations specified, using default.",
86 def = (char *) Malloc(strlen("...") + 1, "adding default dests",
89 if (DynAdd(dests, (char *) &def) == DYN_NOMEM)
90 Error("Out of memory adding default destinations.", NULL);
94 return ((char **) DynGet(dests, 0));
97 static void _get_default_dest(s)
102 filename = (char *) Malloc(strlen(get_home_dir()) + strlen(s) + 1,
103 "While reading file ", s, NULL);
104 sprintf(filename, "%s%s", get_home_dir(), s);
105 get_dest_from_file(dests, filename);
109 static void get_dest_from_file(dests, f)
114 char *line, buf[BUFSIZ];
117 if ((file = fopen(f, "r")) == NULL) {
118 Warning("Cannot find destinations file ", f, NULL);
122 while (bfgets(buf, 80, file)) {
123 if (buf[0] == '#' || buf[0] == '\0') {
125 printf("xzwrite: skipping comment or blank line\n");
129 if (! parse_into_dest(&dest, buf)) {
130 Warning("Ignoring incorrect destination: ", buf, NULL);
134 line = (char *) Malloc(strlen(buf) + 1, "parsing file ", f, NULL);
136 if (DynAdd(dests, (char *) &line) == DYN_NOMEM)
137 Error("Out of memory parsing file ", f, NULL);
143 char **dest_add(dest)
148 /* Two extra bytes if instance or recipient are "" */
149 buf = (char *) Malloc(strlen(dest->zclass) + strlen(dest->zinst) +
150 strlen(dest->zrecip) + 5,
151 "while adding destination ", NULL);
152 sprintf(buf, "%s,%s,%s", dest->zclass,
153 *dest->zinst ? dest->zinst : "*",
154 *dest->zrecip ? dest->zrecip : "*");
156 if (DynAdd(dests, (DynPtr) &buf) == DYN_NOMEM) {
157 Warning("Out of memory adding destination ", buf, ". Skipping.",
163 return ((char **) DynGet(dests, 0));
166 /* XXX The return/output semantics of this function are not good */
167 char **dest_add_string(s)
172 if (! parse_into_dest(&dest, s))
175 if (DynAdd(dests, (DynPtr) &s) == DYN_NOMEM)
176 Warning("Out of memory adding destination ", s, ". Skipping.",
180 return ((char **) DynGet(dests, 0));
183 char **dest_delete_string(s)
189 d = (char **) DynGet(dests, 0);
190 for (i=0; i<DynSize(dests); i++) {
191 if (! strcmp(s, d[i])) {
197 return ((char **) DynGet(dests, 0));
200 char **delete_dest_index(i)
205 ret = DynDelete(dests, i);
209 return ((char **) DynGet(dests, 0));
213 static int sort_dest_func(a1, a2)
216 char **c1 = (char **) a1, **c2 = (char **) a2;
217 char *s1, *s2, *i1, *i2;
219 /* A string with a , in it is always less than one without */
221 i1 = strchr(s1, ',');
222 i2 = strchr(s2, ',');
223 if (i1 == NULL && i2 != NULL)
225 else if (i1 != NULL && i2 == NULL)
228 return strcmp(s1, s2);
232 binary_find_dest(key)
235 register int low = 0, high = DynHigh(dests), mid;
239 d = (char **) DynGet(dests, 0);
241 /* do binary search */
242 while (low <= high) {
243 mid = (low + high) / 2;
244 val = sort_dest_func(&key, &d[mid]);
247 } else if (val > 0) {
257 char **sort_destinations()
260 register int idx, idx2;
261 int dsiz = DynSize(dests);
263 d = (char **) DynGet(dests, 0);
264 qsort(d, dsiz, sizeof(char *), sort_dest_func);
266 for (idx = 0; idx < DynSize(dests);) {
267 if (d[idx][0] == '!') {
271 while ((idx2 = binary_find_dest(next)) >= 0) {
272 /* found one to nuke */
273 DynDelete(dests, idx2);
275 /* indexes shifted, so restart this pass. */
282 /* ok, no more to nuke from this one, so delete it and
284 DynDelete(dests, idx);
287 /* nope, continue on to next unsub */
293 /* Fills in dest from s */
294 int parse_into_dest(dest, s)
301 /* Check for just recipient */
302 if ((a=strchr(s, ','))==0) {
303 if (strlen(s) > ZLEN)
305 strcpy(dest->zclass, DEFAULT_CLASS);
306 strcpy(dest->zinst, DEFAULT_INST);
307 strcpy(dest->zrecip, s);
310 /* Check for just class,instance or instace,recipient */
311 else if ((b=strchr((++a), ','))==0) {
312 if (defs.class_inst) {
317 strncpy(dest->zclass, s, x);
318 dest->zclass[x] = '\0';
319 strcpy(dest->zinst, a);
320 strcpy(dest->zrecip, "*"); }
326 strcpy(dest->zclass, DEFAULT_CLASS);
327 strncpy(dest->zinst, s, x);
328 dest->zinst[x] = '\0';
329 strcpy(dest->zrecip, a); }
332 /* Otherwise, deal with class,instance,recipent */
337 if (x >= ZLEN || y >= ZLEN)
340 strncpy(dest->zclass, s, x);
341 dest->zclass[x] = '\0';
342 strncpy(dest->zinst, a, y);
343 dest->zinst[y] = '\0';
344 strcpy(dest->zrecip, b);
346 if (!strcmp(dest->zrecip,"*")) *(dest->zrecip) = '\0';
347 if (!strcmp(dest->zinst,"*")) *(dest->zinst) = '\0';
353 * notice is from <MESSAGE,inst,sender>. If inst is "PERSONAL", add
354 * destination string "<sender>" if
355 * 1) MESSAGE,PERSONAL,<sender> is not in list, and
356 * 2) <sender> is not in list.
357 * If inst is not "PERSONAL", add destination string
358 * "<MESSAGE,<inst>,<sender>>" if it is not in the list.
360 void dest_add_reply(notice)
363 char **list, *newdest, buf[ZLEN*3+2];
370 /* A hack so local-realm is less annoying */
374 r = strchr(notice->z_sender, '@');
375 if (r && ! strcmp(r+1, ZGetRealm()))
379 if (! strcasecmp(notice->z_class_inst, DEFAULT_INST)) {
380 sprintf(buf, "message,personal,%s", notice->z_sender);
381 for (i=0; i < num; i++) {
382 if (! strcasecmp(list[i], buf) ||
383 ! strcasecmp(list[i], notice->z_sender))
387 newdest = (char *) Malloc(strlen(notice->z_sender) + 1,
388 "while adding reply destination", NULL);
389 sprintf(newdest, "%s", notice->z_sender);
392 sprintf(buf, "message,%s,%s", notice->z_class_inst,
394 for (i=0; i < num; i++) {
395 if (! strcasecmp(list[i], buf))
399 newdest = (char *) Malloc(strlen(notice->z_class) +
400 strlen(notice->z_class_inst) +
401 strlen(notice->z_sender) + 3,
402 "while adding reply destintion",
404 sprintf(newdest, "%s,%s,%s", notice->z_class,
405 notice->z_class_inst, notice->z_sender);
408 dest_add_string(newdest);
411 if (defs.track_logins)
412 zeph_subto_logins(¬ice->z_sender, 1);