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);
}