ref: ed2752fe715680692023bbcaf85ddf03c2444c2c
dir: /targ.c/
#include <u.h> #include <libc.h> #include "xml.h" #include "xmpp.h" Target **targets; int curr, numtargets; int targmatches(Target *t, char *s, int n) { return (t->name != nil && strncmp(t->name, s, n) == 0) || (t->jid != nil && strncmp(t->jid, s, n) == 0); } static int cmptarg(void *a, void *b) { Target *ta, *tb; int r; ta = *(void**)a; tb = *(void**)b; if(ta->name != nil && tb->name != nil) r = strcmp(ta->name, tb->name); else r = strcmp(ta->jid, tb->jid); if(r == 0 && ta->type == Erost && tb->type == Erost) return (ta->rost.flags & Fonline) ? -1 : 1; return r; } static void sorttargets(void) { Target *t; t = (curr >= 0) ? targets[curr] : nil; qsort(targets, numtargets, sizeof(t), cmptarg); if(t != nil){ for(curr = 0; curr < numtargets; curr++) if(targets[curr] == t) break; } } Target* addtarget(int type, char *name) { Target *t; numtargets++; if(numtargets == 1 || (numtargets & (numtargets-1)) == 0) targets = realloc(targets, sizeof(t)*numtargets*2); if(targets == nil) sysfatal("%r"); t = targets[numtargets-1] = mallocz(sizeof(*t), 1); if(t == nil) sysfatal("%r"); t->type = type; t->name = strdup(name); sorttargets(); return t; } void rmtarget(Target *t) { int i; if(curr >= 0 && targets[curr] == t){ setlabel("", nil); curr = -1; } free(t->name); free(t->jid); if(t->type == Erost) free(t->rost.show); else if(t->type == Emucent){ free(t->mucent.jid); free(t->mucent.show); }else if(t->type == Emuc) free(t->muc.subj); free(t); for(i = 0; i < numtargets; i++){ if(targets[i] == t){ numtargets--; memcpy(&targets[i], &targets[i+1], sizeof(t)*(numtargets-i)); if(curr > i) curr--; t = nil; break; } } if(t != nil) sysfatal("rmtarget: not found"); } int cmdtarget(int, int argc, char **argv) { Target *t; char *a, *b; int i, cycle, alen, blen; if(argc < 2){ curr = -1; setlabel("", nil); return 0; } a = argv[1]; b = strchr(a, '/'); if(b == nil){ blen = 0; alen = strlen(a); }else{ b++; blen = strlen(b); alen = b-1 - a; } for(cycle = 0, i = curr+1; cycle < 2; cycle++){ for(; i < numtargets; i++){ char *s; t = targets[i]; if(b == nil && t->type == Emuc && targmatches(t, a, alen)){ setlabel(t->jid, nil); curr = i; return 0; } if(t->type == Erost && targmatches(t, a, alen) && (b == nil || strncmp(t->jid, b, blen) == 0)){ s = smprint("%t", t); setlabel(s, (t->rost.flags & Fonline) ? t->rost.show : "offline"); free(s); curr = i; return 0; } if(t->type == Emucent && b != nil && targmatches(t->mucent.room, a, alen) && strncmp(t->name, b, blen) == 0){ s = smprint("%t", t); setlabel(s, nil); free(s); curr = i; return 0; } } i = 0; } print("no such target: %q\n", a); return 0; } int targetfmt(Fmt *f) { Target *t; t = va_arg(f->args, Target*); if(t->type == Erost && curr >= 0 && targets[curr] == t) return fmtprint(f, "%s", t->name); if(t->type == Emucent) return fmtprint(f, "%s/%s", t->mucent.room->name, t->name); if(t->jid == nil) return fmtprint(f, "%s", t->name); return fmtprint(f, "%s/%s", t->name, t->jid); }