#include #include #include "xzwrite.h" /* * The following code extracts keypressed from an X event: * * keyevent = event->xkey; * XLookupString(&keyevent, buffer, 1, NULL, NULL); */ /* * This entire file could easily be changes so that multiple destination * lists could be used. But I don't know that that's necessary for this * program. */ /* Globals */ DestRec current_dest; static DynObject dests; extern Defaults defs; static void get_dest_from_file(), _get_default_dest(); static int sort_dest_func(const void *, const void *); /* A function for debugging */ void dest_print() { char **d; int i; d = (char **) DynGet(dests, 0); for (i=0; izclass) + strlen(dest->zinst) + strlen(dest->zrecip) + 5, "while adding destination ", NULL); sprintf(buf, "%s,%s,%s", dest->zclass, *dest->zinst ? dest->zinst : "*", *dest->zrecip ? dest->zrecip : "*"); if (DynAdd(dests, (DynPtr) &buf) == DYN_NOMEM) { Warning("Out of memory adding destination ", buf, ". Skipping.", NULL); free(buf); } sort_destinations(); return ((char **) DynGet(dests, 0)); } /* XXX The return/output semantics of this function are not good */ char **dest_add_string(s) char *s; { DestRec dest; if (! parse_into_dest(&dest, s)) return NULL; if (DynAdd(dests, (DynPtr) &s) == DYN_NOMEM) Warning("Out of memory adding destination ", s, ". Skipping.", NULL); sort_destinations(); return ((char **) DynGet(dests, 0)); } char **dest_delete_string(s) char *s; { int i; char **d; d = (char **) DynGet(dests, 0); for (i=0; i 0) { low = mid + 1; } else { return (mid); } } return -1; } char **sort_destinations() { register char **d; register int idx, idx2; int dsiz = DynSize(dests); d = (char **) DynGet(dests, 0); qsort(d, dsiz, sizeof(char *), sort_dest_func); for (idx = 0; idx < DynSize(dests);) { if (d[idx][0] == '!') { /* unsubscription */ char *next = d[idx]; next++; while ((idx2 = binary_find_dest(next)) >= 0) { /* found one to nuke */ DynDelete(dests, idx2); if (idx2 <= idx) { /* indexes shifted, so restart this pass. */ idx--; if (idx <= 0) idx = 0; continue; } } /* ok, no more to nuke from this one, so delete it and move on. */ DynDelete(dests, idx); continue; } /* nope, continue on to next unsub */ idx++; } return d; } /* Fills in dest from s */ int parse_into_dest(dest, s) Dest dest; char *s; { char *a, *b; int x, y; /* Check for just recipient */ if ((a=strchr(s, ','))==0) { if (strlen(s) > ZLEN) return 0; strcpy(dest->zclass, DEFAULT_CLASS); strcpy(dest->zinst, DEFAULT_INST); strcpy(dest->zrecip, s); } /* Check for just class,instance or instace,recipient */ else if ((b=strchr((++a), ','))==0) { if (defs.class_inst) { x = a - 1 - s; if (x >= ZLEN) return 0; strncpy(dest->zclass, s, x); dest->zclass[x] = '\0'; strcpy(dest->zinst, a); strcpy(dest->zrecip, "*"); } else { x = a - 1 - s; if (x >= ZLEN) return 0; strcpy(dest->zclass, DEFAULT_CLASS); strncpy(dest->zinst, s, x); dest->zinst[x] = '\0'; strcpy(dest->zrecip, a); } } /* Otherwise, deal with class,instance,recipent */ else { ++b; x = a - 1 - s; y = b - 1 - a; if (x >= ZLEN || y >= ZLEN) return 0; strncpy(dest->zclass, s, x); dest->zclass[x] = '\0'; strncpy(dest->zinst, a, y); dest->zinst[y] = '\0'; strcpy(dest->zrecip, b); } if (!strcmp(dest->zrecip,"*")) *(dest->zrecip) = '\0'; if (!strcmp(dest->zinst,"*")) *(dest->zinst) = '\0'; return 1; } /* * notice is from . If inst is "PERSONAL", add * destination string "" if * 1) MESSAGE,PERSONAL, is not in list, and * 2) is not in list. * If inst is not "PERSONAL", add destination string * ",>" if it is not in the list. */ void dest_add_reply(notice) ZNotice_t *notice; { char **list, *newdest, buf[ZLEN*3+2]; int i, num; list = dest_text(); num = dest_num(); /* A hack so local-realm is less annoying */ { char *r; r = strchr(notice->z_sender, '@'); if (r && ! strcmp(r+1, ZGetRealm())) *r = '\0'; } if (! strcasecmp(notice->z_class_inst, DEFAULT_INST)) { sprintf(buf, "message,personal,%s", notice->z_sender); for (i=0; i < num; i++) { if (! strcasecmp(list[i], buf) || ! strcasecmp(list[i], notice->z_sender)) return; } newdest = (char *) Malloc(strlen(notice->z_sender) + 1, "while adding reply destination", NULL); sprintf(newdest, "%s", notice->z_sender); } else { sprintf(buf, "message,%s,%s", notice->z_class_inst, notice->z_sender); for (i=0; i < num; i++) { if (! strcasecmp(list[i], buf)) return; } newdest = (char *) Malloc(strlen(notice->z_class) + strlen(notice->z_class_inst) + strlen(notice->z_sender) + 3, "while adding reply destintion", NULL); sprintf(newdest, "%s,%s,%s", notice->z_class, notice->z_class_inst, notice->z_sender); } dest_add_string(newdest); display_dest(); if (defs.track_logins) zeph_subto_logins(¬ice->z_sender, 1); }