+ sq(sk, 0, L"200", L"down", L"%ll", bytesdownload, L"up", L"%ll", bytesupload, NULL);
+}
+
+static void cmd_register(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
+{
+ struct uidata *d2;
+
+ haveargs(2);
+ if(data->userinfo == NULL) {
+ sq(sk, 0, L"502", L"Must be logged in", NULL);
+ return;
+ }
+ if(argv[1][0] == L'#') {
+ sq(sk, 0, L"509", L"Name must not begin with a hash sign", NULL);
+ return;
+ }
+ for(d2 = actives; d2 != NULL; d2 = d2->next) {
+ if((d2 != data) && (d2->userinfo == data->userinfo) && d2->regname && !wcscmp(d2->regname, argv[1])) {
+ sq(sk, 0, L"516", L"Name already in use", NULL);
+ return;
+ }
+ }
+ if(data->regname != NULL)
+ free(data->regname);
+ data->regname = swcsdup(argv[1]);
+ sq(sk, 0, L"200", L"Registered", NULL);
+}
+
+static void cmd_sendmsg(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
+{
+ int i, rcptid;
+ struct uidata *rcpt;
+ wchar_t *myname;
+ struct notif *notif;
+
+ haveargs(2);
+ if(data->userinfo == NULL) {
+ sq(sk, 0, L"502", L"Must be logged in", NULL);
+ return;
+ }
+ if(argv[1][0] == L'#') {
+ rcptid = wcstol(argv[1] + 1, NULL, 0);
+ for(rcpt = actives; rcpt != NULL; rcpt = rcpt->next) {
+ if((rcpt->userinfo == data->userinfo) && (rcpt->id == rcptid))
+ break;
+ }
+ } else {
+ for(rcpt = actives; rcpt != NULL; rcpt = rcpt->next) {
+ if((rcpt->userinfo == data->userinfo) && rcpt->regname && !wcscmp(rcpt->regname, argv[1]))
+ break;
+ }
+ }
+ if(rcpt == NULL) {
+ sq(sk, 0, L"517", L"No such recipient", NULL);
+ return;
+ }
+ if(!rcpt->notify.b.msg) {
+ sq(sk, 0, L"518", L"Recipient not listening for messages", NULL);
+ return;
+ }
+ if(data->regname != NULL)
+ myname = swcsdup(data->regname);
+ else
+ myname = swprintf2(L"#%i", data->id);
+ notif = newnotif(rcpt, 640, NOTIF_STR, myname, NOTIF_END);
+ for(i = 2; i < argc; i++)
+ notifappend(notif, NOTIF_STR, argv[i], NOTIF_END);
+ sq(sk, 0, L"200", L"Message sent", NULL);
+}
+
+static void cmd_uptime(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
+{
+ sq(sk, 0, L"200", L"%i", time(NULL) - starttime, NULL);
+}
+
+static void cmd_hup(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
+{
+ extern volatile int reinit;
+
+ havepriv(PERM_ADMIN);
+ flog(LOG_NOTICE, "UI HUP request from %ls", data->username);
+ reinit = 1;
+ sq(sk, 0, L"200", L"Will reinit", NULL);