]> code.citadel.org Git - citadel.git/blobdiff - citadel/citadel_ipc.c
* Allow multiple simultaneous IPC connections. All changes necessary for
[citadel.git] / citadel / citadel_ipc.c
index 6ca729fff5f26909ae90af1be1b1328a0ba77aca..7c7193a96387ec3b13a84523cb17286cd8789a2b 100644 (file)
@@ -39,11 +39,11 @@ static volatile int upload_in_progress = 0; /* upload file open */
 /*
  * Does nothing.  The server should always return 200.
  */
-int CtdlIPCNoop(void)
+int CtdlIPCNoop(CtdlIPC *ipc)
 {
        char aaa[128];
 
-       return CtdlIPCGenericCommand("NOOP", NULL, 0, NULL, NULL, aaa);
+       return CtdlIPCGenericCommand(ipc, "NOOP", NULL, 0, NULL, NULL, aaa);
 }
 
 
@@ -51,7 +51,7 @@ int CtdlIPCNoop(void)
  * Does nothing interesting.  The server should always return 200
  * along with your string.
  */
-int CtdlIPCEcho(const char *arg, char *cret)
+int CtdlIPCEcho(CtdlIPC *ipc, const char *arg, char *cret)
 {
        register int ret;
        char *aaa;
@@ -63,7 +63,7 @@ int CtdlIPCEcho(const char *arg, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "ECHO %s", arg);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
@@ -73,16 +73,16 @@ int CtdlIPCEcho(const char *arg, char *cret)
  * Asks the server to close the connecction.
  * Should always return 200.
  */
-int CtdlIPCQuit(void)
+int CtdlIPCQuit(CtdlIPC *ipc)
 {
        register int ret;
        char aaa[128];
 
-       netio_lock();
-       serv_puts("QUIT");
-       serv_gets(aaa);
+       CtdlIPC_lock(ipc);
+       CtdlIPC_putline(ipc, "QUIT");
+       CtdlIPC_getline(ipc, aaa);
        ret = atoi(aaa);
-       netio_unlock();
+       CtdlIPC_unlock(ipc);
        return ret;
 }
 
@@ -91,16 +91,16 @@ int CtdlIPCQuit(void)
  * Asks the server to logout.  Should always return 200, even if no user
  * was logged in.  The user will not be logged in after this!
  */
-int CtdlIPCLogout(void)
+int CtdlIPCLogout(CtdlIPC *ipc)
 {
        register int ret;
        char aaa[128];
 
-       netio_lock();
-       serv_puts("LOUT");
-       serv_gets(aaa);
+       CtdlIPC_lock(ipc);
+       CtdlIPC_putline(ipc, "LOUT");
+       CtdlIPC_getline(ipc, aaa);
        ret = atoi(aaa);
-       netio_unlock();
+       CtdlIPC_unlock(ipc);
        return ret;
 }
 
@@ -110,7 +110,7 @@ int CtdlIPCLogout(void)
  * username is able to log in, with the username correctly spelled in cret.
  * Returns various 500 error codes if the user doesn't exist, etc.
  */
-int CtdlIPCTryLogin(const char *username, char *cret)
+int CtdlIPCTryLogin(CtdlIPC *ipc, const char *username, char *cret)
 {
        register int ret;
        char *aaa;
@@ -122,7 +122,7 @@ int CtdlIPCTryLogin(const char *username, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "USER %s", username);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
@@ -132,7 +132,7 @@ int CtdlIPCTryLogin(const char *username, char *cret)
  * Second stage of authentication - provide password.  The server returns
  * 200 and several arguments in cret relating to the user's account.
  */
-int CtdlIPCTryPassword(const char *passwd, char *cret)
+int CtdlIPCTryPassword(CtdlIPC *ipc, const char *passwd, char *cret)
 {
        register int ret;
        char *aaa;
@@ -144,7 +144,7 @@ int CtdlIPCTryPassword(const char *passwd, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "PASS %s", passwd);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
@@ -157,7 +157,7 @@ int CtdlIPCTryPassword(const char *passwd, char *cret)
  * user - intended for use by system administrators to create accounts on
  * behalf of other users.
  */
-int CtdlIPCCreateUser(const char *username, int selfservice, char *cret)
+int CtdlIPCCreateUser(CtdlIPC *ipc, const char *username, int selfservice, char *cret)
 {
        register int ret;
        char *aaa;
@@ -169,7 +169,7 @@ int CtdlIPCCreateUser(const char *username, int selfservice, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "%s %s", selfservice ? "NEWU" : "CREU",  username);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
@@ -178,7 +178,7 @@ int CtdlIPCCreateUser(const char *username, int selfservice, char *cret)
 /*
  * Changes the user's password.  Returns 200 if changed, errors otherwise.
  */
-int CtdlIPCChangePassword(const char *passwd, char *cret)
+int CtdlIPCChangePassword(CtdlIPC *ipc, const char *passwd, char *cret)
 {
        register int ret;
        char *aaa;
@@ -190,7 +190,7 @@ int CtdlIPCChangePassword(const char *passwd, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "SETP %s", passwd);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
@@ -200,7 +200,7 @@ int CtdlIPCChangePassword(const char *passwd, char *cret)
 /* Caller must free the march list */
 /* which is 0 = LRMS, 1 = LKRN, 2 = LKRO, 3 = LKRA, 4 = LZRM */
 /* floor is -1 for all, or floornum */
-int CtdlIPCKnownRooms(int which, int floor, struct march **listing, char *cret)
+int CtdlIPCKnownRooms(CtdlIPC *ipc, int which, int floor, struct march **listing, char *cret)
 {
        register int ret;
        struct march *march = NULL;
@@ -216,7 +216,7 @@ int CtdlIPCKnownRooms(int which, int floor, struct march **listing, char *cret)
        if (floor < -1) return -2;      /* Can't validate upper bound, sorry */
 
        sprintf(aaa, "%s %d", proto[which], floor);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, &bbb, &bbbsize, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, &bbb, &bbbsize, cret);
        if (ret / 100 == 1) {
                struct march *mptr;
 
@@ -252,7 +252,7 @@ int CtdlIPCKnownRooms(int which, int floor, struct march **listing, char *cret)
 
 /* GETU */
 /* Caller must free the struct usersupp; caller may pass an existing one */
-int CtdlIPCGetConfig(struct usersupp **uret, char *cret)
+int CtdlIPCGetConfig(CtdlIPC *ipc, struct usersupp **uret, char *cret)
 {
        register int ret;
 
@@ -261,7 +261,7 @@ int CtdlIPCGetConfig(struct usersupp **uret, char *cret)
        if (!*uret) *uret = (struct usersupp *)calloc(1, sizeof (struct usersupp));
        if (!*uret) return -1;
 
-       ret = CtdlIPCGenericCommand("GETU", NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, "GETU", NULL, 0, NULL, NULL, cret);
        if (ret / 100 == 2) {
                uret[0]->USscreenwidth = extract_int(cret, 0);
                uret[0]->USscreenheight = extract_int(cret, 1);
@@ -272,7 +272,7 @@ int CtdlIPCGetConfig(struct usersupp **uret, char *cret)
 
 
 /* SETU */
-int CtdlIPCSetConfig(struct usersupp *uret, char *cret)
+int CtdlIPCSetConfig(CtdlIPC *ipc, struct usersupp *uret, char *cret)
 {
        char aaa[48];
 
@@ -282,12 +282,12 @@ int CtdlIPCSetConfig(struct usersupp *uret, char *cret)
        sprintf(aaa, "SETU %d|%d|%d",
                        uret->USscreenwidth, uret->USscreenheight,
                        uret->flags);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* GOTO */
-int CtdlIPCGotoRoom(const char *room, const char *passwd,
+int CtdlIPCGotoRoom(CtdlIPC *ipc, const char *room, const char *passwd,
                struct ctdlipcroom **rret, char *cret)
 {
        register int ret;
@@ -313,7 +313,7 @@ int CtdlIPCGotoRoom(const char *room, const char *passwd,
                }
                sprintf(aaa, "GOTO %s", room);
        }
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        if (ret / 100 == 2) {
                extract(rret[0]->RRname, cret, 0);
                rret[0]->RRunread = extract_long(cret, 1);
@@ -336,7 +336,7 @@ int CtdlIPCGotoRoom(const char *room, const char *passwd,
 /* MSGS */
 /* which is 0 = all, 1 = old, 2 = new, 3 = last, 4 = first, 5 = gt, 6 = lt */
 /* whicharg is number of messages, applies to last, first, gt, lt */
-int CtdlIPCGetMessages(int which, int whicharg, const char *template,
+int CtdlIPCGetMessages(CtdlIPC *ipc, int which, int whicharg, const char *template,
                long **mret, char *cret)
 {
        register int ret;
@@ -359,7 +359,7 @@ int CtdlIPCGetMessages(int which, int whicharg, const char *template,
                sprintf(aaa, "MSGS %s|%d|%d", proto[which], whicharg,
                                (template) ? 1 : 0);
        if (template) count = strlen(template);
-       ret = CtdlIPCGenericCommand(aaa, template, count, &bbb, &bbbsize, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, template, count, &bbb, &bbbsize, cret);
        count = 0;
        while (strlen(bbb)) {
                int a;
@@ -378,7 +378,7 @@ int CtdlIPCGetMessages(int which, int whicharg, const char *template,
 
 
 /* MSG0, MSG2 */
-int CtdlIPCGetSingleMessage(long msgnum, int headers, int as_mime,
+int CtdlIPCGetSingleMessage(CtdlIPC *ipc, long msgnum, int headers, int as_mime,
                struct ctdlipcmessage **mret, char *cret)
 {
        register int ret;
@@ -396,7 +396,7 @@ int CtdlIPCGetSingleMessage(long msgnum, int headers, int as_mime,
 
        strcpy(mret[0]->content_type, "");
        sprintf(aaa, "MSG%d %ld|%d", as_mime, msgnum, headers);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, &bbb, &bbbsize, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, &bbb, &bbbsize, cret);
        if (ret / 100 == 1) {
                if (as_mime != 2) {
                        strcpy(mret[0]->mime_chosen, "1");      /* Default chosen-part is "1" */
@@ -513,7 +513,7 @@ int CtdlIPCGetSingleMessage(long msgnum, int headers, int as_mime,
 
 
 /* WHOK */
-int CtdlIPCWhoKnowsRoom(char **listing, char *cret)
+int CtdlIPCWhoKnowsRoom(CtdlIPC *ipc, char **listing, char *cret)
 {
        register int ret;
        size_t bytes;
@@ -522,13 +522,13 @@ int CtdlIPCWhoKnowsRoom(char **listing, char *cret)
        if (!listing) return -2;
        if (*listing) return -2;
 
-       ret = CtdlIPCGenericCommand("WHOK", NULL, 0, listing, &bytes, cret);
+       ret = CtdlIPCGenericCommand(ipc, "WHOK", NULL, 0, listing, &bytes, cret);
        return ret;
 }
 
 
 /* INFO */
-int CtdlIPCServerInfo(struct CtdlServInfo *ServInfo, char *cret)
+int CtdlIPCServerInfo(CtdlIPC *ipc, struct CtdlServInfo *ServInfo, char *cret)
 {
        register int ret;
        size_t bytes;
@@ -538,7 +538,7 @@ int CtdlIPCServerInfo(struct CtdlServInfo *ServInfo, char *cret)
        if (!cret) return -2;
        if (!ServInfo) return -2;
 
-       ret = CtdlIPCGenericCommand("INFO", NULL, 0, &listing, &bytes, cret);
+       ret = CtdlIPCGenericCommand(ipc, "INFO", NULL, 0, &listing, &bytes, cret);
        if (ret / 100 == 1) {
                int line = 0;
 
@@ -579,7 +579,7 @@ int CtdlIPCServerInfo(struct CtdlServInfo *ServInfo, char *cret)
 
 
 /* RDIR */
-int CtdlIPCReadDirectory(char **listing, char *cret)
+int CtdlIPCReadDirectory(CtdlIPC *ipc, char **listing, char *cret)
 {
        register int ret;
        size_t bytes;
@@ -588,7 +588,7 @@ int CtdlIPCReadDirectory(char **listing, char *cret)
        if (!listing) return -2;
        if (*listing) return -2;
 
-       ret = CtdlIPCGenericCommand("RDIR", NULL, 0, listing, &bytes, cret);
+       ret = CtdlIPCGenericCommand(ipc, "RDIR", NULL, 0, listing, &bytes, cret);
        return ret;
 }
 
@@ -596,7 +596,7 @@ int CtdlIPCReadDirectory(char **listing, char *cret)
 /*
  * Set last-read pointer in this room to msgnum, or 0 for HIGHEST.
  */
-int CtdlIPCSetLastRead(long msgnum, char *cret)
+int CtdlIPCSetLastRead(CtdlIPC *ipc, long msgnum, char *cret)
 {
        register int ret;
        char aaa[16];
@@ -607,13 +607,13 @@ int CtdlIPCSetLastRead(long msgnum, char *cret)
                sprintf(aaa, "SLRP %ld", msgnum);
        else
                sprintf(aaa, "SLRP HIGHEST");
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        return ret;
 }
 
 
 /* INVT */
-int CtdlIPCInviteUserToRoom(const char *username, char *cret)
+int CtdlIPCInviteUserToRoom(CtdlIPC *ipc, const char *username, char *cret)
 {
        register int ret;
        char *aaa;
@@ -625,14 +625,14 @@ int CtdlIPCInviteUserToRoom(const char *username, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "INVT %s", username);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* KICK */
-int CtdlIPCKickoutUserFromRoom(const char *username, char *cret)
+int CtdlIPCKickoutUserFromRoom(CtdlIPC *ipc, const char *username, char *cret)
 {
        register int ret;
        char *aaa;
@@ -643,14 +643,14 @@ int CtdlIPCKickoutUserFromRoom(const char *username, char *cret)
        aaa = (char *)malloc(strlen(username) + 6);
 
        sprintf(aaa, "KICK %s", username);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* GETR */
-int CtdlIPCGetRoomAttributes(struct quickroom **qret, char *cret)
+int CtdlIPCGetRoomAttributes(CtdlIPC *ipc, struct quickroom **qret, char *cret)
 {
        register int ret;
 
@@ -659,7 +659,7 @@ int CtdlIPCGetRoomAttributes(struct quickroom **qret, char *cret)
        if (!*qret) *qret = (struct quickroom *)calloc(1, sizeof (struct quickroom));
        if (!*qret) return -1;
 
-       ret = CtdlIPCGenericCommand("GETR", NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, "GETR", NULL, 0, NULL, NULL, cret);
        if (ret / 100 == 2) {
                extract(qret[0]->QRname, cret, 0);
                extract(qret[0]->QRpasswd, cret, 1);
@@ -674,7 +674,7 @@ int CtdlIPCGetRoomAttributes(struct quickroom **qret, char *cret)
 
 /* SETR */
 /* set forget to kick all users out of room */
-int CtdlIPCSetRoomAttributes(int forget, struct quickroom *qret, char *cret)
+int CtdlIPCSetRoomAttributes(CtdlIPC *ipc, int forget, struct quickroom *qret, char *cret)
 {
        register int ret;
        char *aaa;
@@ -689,23 +689,23 @@ int CtdlIPCSetRoomAttributes(int forget, struct quickroom *qret, char *cret)
        sprintf(aaa, "SETR %s|%s|%s|%d|%d|%d|%d",
                        qret->QRname, qret->QRpasswd, qret->QRdirname,
                        qret->QRflags, forget, qret->QRfloor, qret->QRorder);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* GETA */
-int CtdlIPCGetRoomAide(char *cret)
+int CtdlIPCGetRoomAide(CtdlIPC *ipc, char *cret)
 {
        if (!cret) return -1;
 
-       return CtdlIPCGenericCommand("GETA", NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, "GETA", NULL, 0, NULL, NULL, cret);
 }
 
 
 /* SETA */
-int CtdlIPCSetRoomAide(const char *username, char *cret)
+int CtdlIPCSetRoomAide(CtdlIPC *ipc, const char *username, char *cret)
 {
        register int ret;
        char *aaa;
@@ -717,14 +717,14 @@ int CtdlIPCSetRoomAide(const char *username, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "SETA %s", username);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* ENT0 */
-int CtdlIPCPostMessage(int flag, const struct ctdlipcmessage *mr, char *cret)
+int CtdlIPCPostMessage(CtdlIPC *ipc, int flag, const struct ctdlipcmessage *mr, char *cret)
 {
        register int ret;
        char *aaa;
@@ -737,7 +737,7 @@ int CtdlIPCPostMessage(int flag, const struct ctdlipcmessage *mr, char *cret)
 
        sprintf(aaa, "ENT0 %d|%s|%d|%d|%s", flag, mr->recipient, mr->anonymous,
                        mr->type, mr->author);
-       ret = CtdlIPCGenericCommand(aaa, mr->text, strlen(mr->text), NULL,
+       ret = CtdlIPCGenericCommand(ipc, aaa, mr->text, strlen(mr->text), NULL,
                        NULL, cret);
        free(aaa);
        return ret;
@@ -745,7 +745,7 @@ int CtdlIPCPostMessage(int flag, const struct ctdlipcmessage *mr, char *cret)
 
 
 /* RINF */
-int CtdlIPCRoomInfo(char **iret, char *cret)
+int CtdlIPCRoomInfo(CtdlIPC *ipc, char **iret, char *cret)
 {
        size_t bytes;
 
@@ -753,12 +753,12 @@ int CtdlIPCRoomInfo(char **iret, char *cret)
        if (!iret) return -2;
        if (*iret) return -2;
 
-       return CtdlIPCGenericCommand("RINF", NULL, 0, iret, &bytes, cret);
+       return CtdlIPCGenericCommand(ipc, "RINF", NULL, 0, iret, &bytes, cret);
 }
 
 
 /* DELE */
-int CtdlIPCDeleteMessage(long msgnum, char *cret)
+int CtdlIPCDeleteMessage(CtdlIPC *ipc, long msgnum, char *cret)
 {
        char aaa[16];
 
@@ -766,12 +766,12 @@ int CtdlIPCDeleteMessage(long msgnum, char *cret)
        if (!msgnum) return -2;
 
        sprintf(aaa, "DELE %ld", msgnum);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* MOVE */
-int CtdlIPCMoveMessage(int copy, long msgnum, const char *destroom, char *cret)
+int CtdlIPCMoveMessage(CtdlIPC *ipc, int copy, long msgnum, const char *destroom, char *cret)
 {
        register int ret;
        char *aaa;
@@ -784,26 +784,26 @@ int CtdlIPCMoveMessage(int copy, long msgnum, const char *destroom, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "MOVE %ld|%s|%d", msgnum, destroom, copy);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* KILL */
-int CtdlIPCDeleteRoom(int for_real, char *cret)
+int CtdlIPCDeleteRoom(CtdlIPC *ipc, int for_real, char *cret)
 {
        char aaa[16];
 
        if (!cret) return -2;
 
        sprintf(aaa, "KILL %d", for_real);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* CRE8 */
-int CtdlIPCCreateRoom(int for_real, const char *roomname, int type,
+int CtdlIPCCreateRoom(CtdlIPC *ipc, int for_real, const char *roomname, int type,
                const char *password, int floor, char *cret)
 {
        register int ret;
@@ -823,23 +823,23 @@ int CtdlIPCCreateRoom(int for_real, const char *roomname, int type,
                sprintf(aaa, "CRE8 %d|%s|%d||%d", for_real, roomname, type,
                                floor);
        }
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* FORG */
-int CtdlIPCForgetRoom(char *cret)
+int CtdlIPCForgetRoom(CtdlIPC *ipc, char *cret)
 {
        if (!cret) return -2;
 
-       return CtdlIPCGenericCommand("FORG", NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, "FORG", NULL, 0, NULL, NULL, cret);
 }
 
 
 /* MESG */
-int CtdlIPCSystemMessage(const char *message, char **mret, char *cret)
+int CtdlIPCSystemMessage(CtdlIPC *ipc, const char *message, char **mret, char *cret)
 {
        register int ret;
        char *aaa;
@@ -854,23 +854,23 @@ int CtdlIPCSystemMessage(const char *message, char **mret, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "MESG %s", message);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, mret, &bytes, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, mret, &bytes, cret);
        free(aaa);
        return ret;
 }
 
 
 /* GNUR */
-int CtdlIPCNextUnvalidatedUser(char *cret)
+int CtdlIPCNextUnvalidatedUser(CtdlIPC *ipc, char *cret)
 {
        if (!cret) return -2;
 
-       return CtdlIPCGenericCommand("GNUR", NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, "GNUR", NULL, 0, NULL, NULL, cret);
 }
 
 
 /* GREG */
-int CtdlIPCGetUserRegistration(const char *username, char **rret, char *cret)
+int CtdlIPCGetUserRegistration(CtdlIPC *ipc, const char *username, char **rret, char *cret)
 {
        register int ret;
        char *aaa;
@@ -890,14 +890,14 @@ int CtdlIPCGetUserRegistration(const char *username, char **rret, char *cret)
                sprintf(aaa, "GREG %s", username);
        else
                sprintf(aaa, "GREG _SELF_");
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, rret, &bytes, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, rret, &bytes, cret);
        free(aaa);
        return ret;
 }
 
 
 /* VALI */
-int CtdlIPCValidateUser(const char *username, int axlevel, char *cret)
+int CtdlIPCValidateUser(CtdlIPC *ipc, const char *username, int axlevel, char *cret)
 {
        register int ret;
        char *aaa;
@@ -910,14 +910,14 @@ int CtdlIPCValidateUser(const char *username, int axlevel, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "VALI %s|%d", username, axlevel);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* EINF */
-int CtdlIPCSetRoomInfo(int for_real, const char *info, char *cret)
+int CtdlIPCSetRoomInfo(CtdlIPC *ipc, int for_real, const char *info, char *cret)
 {
        char aaa[16];
 
@@ -925,12 +925,12 @@ int CtdlIPCSetRoomInfo(int for_real, const char *info, char *cret)
        if (!info) return -1;
 
        sprintf(aaa, "EINF %d", for_real);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* LIST */
-int CtdlIPCUserListing(char **listing, char *cret)
+int CtdlIPCUserListing(CtdlIPC *ipc, char **listing, char *cret)
 {
        size_t bytes;
 
@@ -938,30 +938,30 @@ int CtdlIPCUserListing(char **listing, char *cret)
        if (!listing) return -1;
        if (*listing) return -1;
 
-       return CtdlIPCGenericCommand("LIST", NULL, 0, listing, &bytes, cret);
+       return CtdlIPCGenericCommand(ipc, "LIST", NULL, 0, listing, &bytes, cret);
 }
 
 
 /* REGI */
-int CtdlIPCSetRegistration(const char *info, char *cret)
+int CtdlIPCSetRegistration(CtdlIPC *ipc, const char *info, char *cret)
 {
        if (!cret) return -1;
        if (!info) return -1;
 
-       return CtdlIPCGenericCommand("REGI", info, strlen(info),
+       return CtdlIPCGenericCommand(ipc, "REGI", info, strlen(info),
                        NULL, NULL, cret);
 }
 
 
 /* CHEK */
-int CtdlIPCMiscCheck(struct ctdlipcmisc *chek, char *cret)
+int CtdlIPCMiscCheck(CtdlIPC *ipc, struct ctdlipcmisc *chek, char *cret)
 {
        register int ret;
 
        if (!cret) return -1;
        if (!chek) return -1;
 
-       ret = CtdlIPCGenericCommand("CHEK", NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, "CHEK", NULL, 0, NULL, NULL, cret);
        if (ret / 100 == 2) {
                chek->newmail = extract_long(cret, 0);
                chek->needregis = extract_int(cret, 1);
@@ -972,7 +972,7 @@ int CtdlIPCMiscCheck(struct ctdlipcmisc *chek, char *cret)
 
 
 /* DELF */
-int CtdlIPCDeleteFile(const char *filename, char *cret)
+int CtdlIPCDeleteFile(CtdlIPC *ipc, const char *filename, char *cret)
 {
        register int ret;
        char *aaa;
@@ -984,14 +984,14 @@ int CtdlIPCDeleteFile(const char *filename, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "DELF %s", filename);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* MOVF */
-int CtdlIPCMoveFile(const char *filename, const char *destroom, char *cret)
+int CtdlIPCMoveFile(CtdlIPC *ipc, const char *filename, const char *destroom, char *cret)
 {
        register int ret;
        char *aaa;
@@ -1004,14 +1004,14 @@ int CtdlIPCMoveFile(const char *filename, const char *destroom, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "MOVF %s|%s", filename, destroom);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* NETF */
-int CtdlIPCNetSendFile(const char *filename, const char *destnode, char *cret)
+int CtdlIPCNetSendFile(CtdlIPC *ipc, const char *filename, const char *destnode, char *cret)
 {
        register int ret;
        char *aaa;
@@ -1024,14 +1024,14 @@ int CtdlIPCNetSendFile(const char *filename, const char *destnode, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "NETF %s|%s", filename, destnode);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* RWHO */
-int CtdlIPCOnlineUsers(char **listing, time_t *stamp, char *cret)
+int CtdlIPCOnlineUsers(CtdlIPC *ipc, char **listing, time_t *stamp, char *cret)
 {
        register int ret;
        size_t bytes;
@@ -1040,16 +1040,16 @@ int CtdlIPCOnlineUsers(char **listing, time_t *stamp, char *cret)
        if (!listing) return -1;
        if (*listing) return -1;
 
-       *stamp = CtdlIPCServerTime(cret);
+       *stamp = CtdlIPCServerTime(ipc, cret);
        if (!*stamp)
                *stamp = time(NULL);
-       ret = CtdlIPCGenericCommand("RWHO", NULL, 0, listing, &bytes, cret);
+       ret = CtdlIPCGenericCommand(ipc, "RWHO", NULL, 0, listing, &bytes, cret);
        return ret;
 }
 
 
 /* OPEN */
-int CtdlIPCFileDownload(const char *filename, void **buf, char *cret)
+int CtdlIPCFileDownload(CtdlIPC *ipc, const char *filename, void **buf, char *cret)
 {
        register int ret;
        size_t bytes;
@@ -1067,7 +1067,7 @@ int CtdlIPCFileDownload(const char *filename, void **buf, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "OPEN %s", filename);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        /* FIXME: Possible race condition */
        if (ret / 100 == 2) {
@@ -1075,8 +1075,8 @@ int CtdlIPCFileDownload(const char *filename, void **buf, char *cret)
                bytes = extract_long(cret, 0);
                last_mod = extract_int(cret, 1);
                extract(mimetype, cret, 2);
-               ret = CtdlIPCReadDownload(buf, bytes, cret);
-               ret = CtdlIPCEndDownload(cret);
+               ret = CtdlIPCReadDownload(ipc, buf, bytes, cret);
+               ret = CtdlIPCEndDownload(ipc, cret);
                if (ret / 100 == 2)
                        sprintf(cret, "%d|%ld|%s|%s", bytes, last_mod,
                                        filename, mimetype);
@@ -1086,7 +1086,7 @@ int CtdlIPCFileDownload(const char *filename, void **buf, char *cret)
 
 
 /* OPNA */
-int CtdlIPCAttachmentDownload(long msgnum, const char *part, void **buf,
+int CtdlIPCAttachmentDownload(CtdlIPC *ipc, long msgnum, const char *part, void **buf,
                char *cret)
 {
        register int ret;
@@ -1107,7 +1107,7 @@ int CtdlIPCAttachmentDownload(long msgnum, const char *part, void **buf,
        if (!aaa) return -1;
 
        sprintf(aaa, "OPNA %ld|%s", msgnum, part);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        /* FIXME: Possible race condition */
        if (ret / 100 == 2) {
@@ -1115,8 +1115,8 @@ int CtdlIPCAttachmentDownload(long msgnum, const char *part, void **buf,
                bytes = extract_long(cret, 0);
                last_mod = extract_int(cret, 1);
                extract(mimetype, cret, 2);
-               ret = CtdlIPCReadDownload(buf, bytes, cret);
-               ret = CtdlIPCEndDownload(cret);
+               ret = CtdlIPCReadDownload(ipc, buf, bytes, cret);
+               ret = CtdlIPCEndDownload(ipc, cret);
                if (ret / 100 == 2)
                        sprintf(cret, "%d|%ld|%s|%s", bytes, last_mod,
                                        filename, mimetype);
@@ -1126,7 +1126,7 @@ int CtdlIPCAttachmentDownload(long msgnum, const char *part, void **buf,
 
 
 /* OIMG */
-int CtdlIPCImageDownload(const char *filename, void **buf, char *cret)
+int CtdlIPCImageDownload(CtdlIPC *ipc, const char *filename, void **buf, char *cret)
 {
        register int ret;
        size_t bytes;
@@ -1144,7 +1144,7 @@ int CtdlIPCImageDownload(const char *filename, void **buf, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "OIMG %s", filename);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        /* FIXME: Possible race condition */
        if (ret / 100 == 2) {
@@ -1152,8 +1152,8 @@ int CtdlIPCImageDownload(const char *filename, void **buf, char *cret)
                bytes = extract_long(cret, 0);
                last_mod = extract_int(cret, 1);
                extract(mimetype, cret, 2);
-               ret = CtdlIPCReadDownload(buf, bytes, cret);
-               ret = CtdlIPCEndDownload(cret);
+               ret = CtdlIPCReadDownload(ipc, buf, bytes, cret);
+               ret = CtdlIPCEndDownload(ipc, cret);
                if (ret / 100 == 2)
                        sprintf(cret, "%d|%ld|%s|%s", bytes, last_mod,
                                        filename, mimetype);
@@ -1163,7 +1163,7 @@ int CtdlIPCImageDownload(const char *filename, void **buf, char *cret)
 
 
 /* UOPN */
-int CtdlIPCFileUpload(const char *filename, const char *comment, void *buf,
+int CtdlIPCFileUpload(CtdlIPC *ipc, const char *filename, const char *comment, void *buf,
                size_t bytes, char *cret)
 {
        register int ret;
@@ -1178,19 +1178,19 @@ int CtdlIPCFileUpload(const char *filename, const char *comment, void *buf,
        if (!aaa) return -1;
 
        sprintf(aaa, "UOPN %s|%s", filename, comment);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        /* FIXME: Possible race condition */
        if (ret / 100 == 2)
                upload_in_progress = 1;
-       ret = CtdlIPCWriteUpload(buf, bytes, cret);
-       ret = CtdlIPCEndUpload(cret);
+       ret = CtdlIPCWriteUpload(ipc, buf, bytes, cret);
+       ret = CtdlIPCEndUpload(ipc, cret);
        return ret;
 }
 
 
 /* UIMG */
-int CtdlIPCImageUpload(int for_real, const char *filename, size_t bytes,
+int CtdlIPCImageUpload(CtdlIPC *ipc, int for_real, const char *filename, size_t bytes,
                char *cret)
 {
        register int ret;
@@ -1204,7 +1204,7 @@ int CtdlIPCImageUpload(int for_real, const char *filename, size_t bytes,
        if (!aaa) return -1;
 
        sprintf(aaa, "UIMG %d|%s", for_real, filename);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        /* FIXME: Possible race condition */
        if (ret / 100 == 2)
@@ -1214,7 +1214,7 @@ int CtdlIPCImageUpload(int for_real, const char *filename, size_t bytes,
 
 
 /* QUSR */
-int CtdlIPCQueryUsername(const char *username, char *cret)
+int CtdlIPCQueryUsername(CtdlIPC *ipc, const char *username, char *cret)
 {
        register int ret;
        char *aaa;
@@ -1226,14 +1226,14 @@ int CtdlIPCQueryUsername(const char *username, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "QUSR %s", username);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* LFLR */
-int CtdlIPCFloorListing(char **listing, char *cret)
+int CtdlIPCFloorListing(CtdlIPC *ipc, char **listing, char *cret)
 {
        size_t bytes;
 
@@ -1241,12 +1241,12 @@ int CtdlIPCFloorListing(char **listing, char *cret)
        if (!listing) return -2;
        if (*listing) return -2;
 
-       return CtdlIPCGenericCommand("LFLR", NULL, 0, listing, &bytes, cret);
+       return CtdlIPCGenericCommand(ipc, "LFLR", NULL, 0, listing, &bytes, cret);
 }
 
 
 /* CFLR */
-int CtdlIPCCreateFloor(int for_real, const char *name, char *cret)
+int CtdlIPCCreateFloor(CtdlIPC *ipc, int for_real, const char *name, char *cret)
 {
        register int ret;
        char *aaa;
@@ -1258,14 +1258,14 @@ int CtdlIPCCreateFloor(int for_real, const char *name, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "CFLR %s|%d", name, for_real);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* KFLR */
-int CtdlIPCDeleteFloor(int for_real, int floornum, char *cret)
+int CtdlIPCDeleteFloor(CtdlIPC *ipc, int for_real, int floornum, char *cret)
 {
        char aaa[27];
 
@@ -1273,12 +1273,12 @@ int CtdlIPCDeleteFloor(int for_real, int floornum, char *cret)
        if (floornum < 0) return -1;
 
        sprintf(aaa, "KFLR %d|%d", floornum, for_real);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* EFLR */
-int CtdlIPCEditFloor(int floornum, const char *floorname, char *cret)
+int CtdlIPCEditFloor(CtdlIPC *ipc, int floornum, const char *floorname, char *cret)
 {
        register int ret;
        char *aaa;
@@ -1291,14 +1291,14 @@ int CtdlIPCEditFloor(int floornum, const char *floorname, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "EFLR %d|%s", floornum, floorname);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* IDEN */
-int CtdlIPCIdentifySoftware(int developerid, int clientid, int revision,
+int CtdlIPCIdentifySoftware(CtdlIPC *ipc, int developerid, int clientid, int revision,
                const char *software_name, const char *hostname, char *cret)
 {
        register int ret;
@@ -1315,14 +1315,14 @@ int CtdlIPCIdentifySoftware(int developerid, int clientid, int revision,
 
        sprintf(aaa, "IDEN %d|%d|%d|%s|%s", developerid, clientid,
                        revision, software_name, hostname);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* SEXP */
-int CtdlIPCSendInstantMessage(const char *username, const char *text,
+int CtdlIPCSendInstantMessage(CtdlIPC *ipc, const char *username, const char *text,
                char *cret)
 {
        register int ret;
@@ -1336,11 +1336,11 @@ int CtdlIPCSendInstantMessage(const char *username, const char *text,
 
        if (text) {
                sprintf(aaa, "SEXP %s|-", username);
-               ret = CtdlIPCGenericCommand(aaa, text, strlen(text),
+               ret = CtdlIPCGenericCommand(ipc, aaa, text, strlen(text),
                                NULL, NULL, cret);
        } else {
                sprintf(aaa, "SEXP %s||", username);
-               ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+               ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        }
        free(aaa);
        return ret;
@@ -1348,7 +1348,7 @@ int CtdlIPCSendInstantMessage(const char *username, const char *text,
 
 
 /* GEXP */
-int CtdlIPCGetInstantMessage(char **listing, char *cret)
+int CtdlIPCGetInstantMessage(CtdlIPC *ipc, char **listing, char *cret)
 {
        size_t bytes;
 
@@ -1356,36 +1356,36 @@ int CtdlIPCGetInstantMessage(char **listing, char *cret)
        if (!listing) return -2;
        if (*listing) return -2;
 
-       return CtdlIPCGenericCommand("GEXP", NULL, 0, listing, &bytes, cret);
+       return CtdlIPCGenericCommand(ipc, "GEXP", NULL, 0, listing, &bytes, cret);
 }
 
 
 /* DEXP */
 /* mode is 0 = enable, 1 = disable, 2 = status */
-int CtdlIPCEnableInstantMessageReceipt(int mode, char *cret)
+int CtdlIPCEnableInstantMessageReceipt(CtdlIPC *ipc, int mode, char *cret)
 {
        char aaa[16];
 
        if (!cret) return -2;
 
        sprintf(aaa, "DEXP %d", mode);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* EBIO */
-int CtdlIPCSetBio(char *bio, char *cret)
+int CtdlIPCSetBio(CtdlIPC *ipc, char *bio, char *cret)
 {
        if (!cret) return -2;
        if (!bio) return -2;
 
-       return CtdlIPCGenericCommand("EBIO", bio, strlen(bio),
+       return CtdlIPCGenericCommand(ipc, "EBIO", bio, strlen(bio),
                        NULL, NULL, cret);
 }
 
 
 /* RBIO */
-int CtdlIPCGetBio(const char *username, char **listing, char *cret)
+int CtdlIPCGetBio(CtdlIPC *ipc, const char *username, char **listing, char *cret)
 {
        register int ret;
        size_t bytes;
@@ -1400,14 +1400,14 @@ int CtdlIPCGetBio(const char *username, char **listing, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "RBIO %s", username);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, listing, &bytes, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, listing, &bytes, cret);
        free(aaa);
        return ret;
 }
 
 
 /* LBIO */
-int CtdlIPCListUsersWithBios(char **listing, char *cret)
+int CtdlIPCListUsersWithBios(CtdlIPC *ipc, char **listing, char *cret)
 {
        size_t bytes;
 
@@ -1415,57 +1415,57 @@ int CtdlIPCListUsersWithBios(char **listing, char *cret)
        if (!listing) return -2;
        if (*listing) return -2;
 
-       return CtdlIPCGenericCommand("LBIO", NULL, 0, listing, &bytes, cret);
+       return CtdlIPCGenericCommand(ipc, "LBIO", NULL, 0, listing, &bytes, cret);
 }
 
 
 /* STEL */
-int CtdlIPCStealthMode(int mode, char *cret)
+int CtdlIPCStealthMode(CtdlIPC *ipc, int mode, char *cret)
 {
        char aaa[16];
 
        if (!cret) return -1;
 
        sprintf(aaa, "STEL %d", mode ? 1 : 0);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* TERM */
-int CtdlIPCTerminateSession(int sid, char *cret)
+int CtdlIPCTerminateSession(CtdlIPC *ipc, int sid, char *cret)
 {
        char aaa[16];
 
        if (!cret) return -1;
 
        sprintf(aaa, "TERM %d", sid);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* DOWN */
-int CtdlIPCTerminateServerNow(char *cret)
+int CtdlIPCTerminateServerNow(CtdlIPC *ipc, char *cret)
 {
        if (!cret) return -1;
 
-       return CtdlIPCGenericCommand("DOWN", NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, "DOWN", NULL, 0, NULL, NULL, cret);
 }
 
 
 /* SCDN */
-int CtdlIPCTerminateServerScheduled(int mode, char *cret)
+int CtdlIPCTerminateServerScheduled(CtdlIPC *ipc, int mode, char *cret)
 {
        char aaa[16];
 
        if (!cret) return -1;
 
        sprintf(aaa, "SCDN %d", mode ? 1 : 0);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* EMSG */
-int CtdlIPCEnterSystemMessage(const char *filename, const char *text,
+int CtdlIPCEnterSystemMessage(CtdlIPC *ipc, const char *filename, const char *text,
                char *cret)
 {
        register int ret;
@@ -1479,14 +1479,14 @@ int CtdlIPCEnterSystemMessage(const char *filename, const char *text,
        if (!aaa) return -1;
 
        sprintf(aaa, "EMSG %s", filename);
-       ret = CtdlIPCGenericCommand(aaa, text, strlen(text), NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, text, strlen(text), NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* HCHG */
-int CtdlIPCChangeHostname(const char *hostname, char *cret)
+int CtdlIPCChangeHostname(CtdlIPC *ipc, const char *hostname, char *cret)
 {
        register int ret;
        char *aaa;
@@ -1498,14 +1498,14 @@ int CtdlIPCChangeHostname(const char *hostname, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "HCHG %s", hostname);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* RCHG */
-int CtdlIPCChangeRoomname(const char *roomname, char *cret)
+int CtdlIPCChangeRoomname(CtdlIPC *ipc, const char *roomname, char *cret)
 {
        register int ret;
        char *aaa;
@@ -1517,14 +1517,14 @@ int CtdlIPCChangeRoomname(const char *roomname, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "RCHG %s", roomname);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
 
 
 /* UCHG */
-int CtdlIPCChangeUsername(const char *username, char *cret)
+int CtdlIPCChangeUsername(CtdlIPC *ipc, const char *username, char *cret)
 {
        register int ret;
        char *aaa;
@@ -1536,7 +1536,7 @@ int CtdlIPCChangeUsername(const char *username, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "UCHG %s", username);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
@@ -1544,12 +1544,12 @@ int CtdlIPCChangeUsername(const char *username, char *cret)
 
 /* TIME */
 /* This function returns the actual server time reported, or 0 if error */
-time_t CtdlIPCServerTime(char *cret)
+time_t CtdlIPCServerTime(CtdlIPC *ipc, char *cret)
 {
        register time_t tret;
        register int ret;
 
-       ret = CtdlIPCGenericCommand("TIME", NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, "TIME", NULL, 0, NULL, NULL, cret);
        if (ret / 100 == 2) {
                tret = extract_long(cret, 0);
        } else {
@@ -1560,7 +1560,7 @@ time_t CtdlIPCServerTime(char *cret)
 
 
 /* AGUP */
-int CtdlIPCAideGetUserParameters(const char *who,
+int CtdlIPCAideGetUserParameters(CtdlIPC *ipc, const char *who,
                                 struct usersupp **uret, char *cret)
 {
        register int ret;
@@ -1572,7 +1572,7 @@ int CtdlIPCAideGetUserParameters(const char *who,
        if (!*uret) return -1;
 
        sprintf(aaa, "AGUP %s", who);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 
        if (ret / 100 == 2) {
                extract(uret[0]->fullname, cret, 0);
@@ -1590,7 +1590,7 @@ int CtdlIPCAideGetUserParameters(const char *who,
 
 
 /* ASUP */
-int CtdlIPCAideSetUserParameters(const struct usersupp *uret, char *cret)
+int CtdlIPCAideSetUserParameters(CtdlIPC *ipc, const struct usersupp *uret, char *cret)
 {
        register int ret;
        char *aaa;
@@ -1605,7 +1605,7 @@ int CtdlIPCAideSetUserParameters(const struct usersupp *uret, char *cret)
                        uret->fullname, uret->password, uret->flags,
                        uret->timescalled, uret->posted, uret->axlevel,
                        uret->usernum, uret->lastcall, uret->USuserpurge);
-       ret = CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
        free(aaa);
        return ret;
 }
@@ -1613,7 +1613,7 @@ int CtdlIPCAideSetUserParameters(const struct usersupp *uret, char *cret)
 
 /* GPEX */
 /* which is 0 = room, 1 = floor, 2 = site */
-int CtdlIPCGetMessageExpirationPolicy(int which, char *cret)
+int CtdlIPCGetMessageExpirationPolicy(CtdlIPC *ipc, int which, char *cret)
 {
        static char *proto[] = {"room", "floor", "site"};
        char aaa[11];
@@ -1622,14 +1622,14 @@ int CtdlIPCGetMessageExpirationPolicy(int which, char *cret)
        if (which < 0 || which > 2) return -2;
        
        sprintf(aaa, "GPEX %s", proto[which]);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* SPEX */
 /* which is 0 = room, 1 = floor, 2 = site */
 /* policy is 0 = inherit, 1 = no purge, 2 = by count, 3 = by age (days) */
-int CtdlIPCSetMessageExpirationPolicy(int which, int policy, int value,
+int CtdlIPCSetMessageExpirationPolicy(CtdlIPC *ipc, int which, int policy, int value,
                char *cret)
 {
        char aaa[38];
@@ -1640,12 +1640,12 @@ int CtdlIPCSetMessageExpirationPolicy(int which, int policy, int value,
        if (policy >= 2 && value < 1) return -2;
 
        sprintf(aaa, "SPEX %d|%d|%d", which, policy, value);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* CONF GET */
-int CtdlGetSystemConfig(char **listing, char *cret)
+int CtdlGetSystemConfig(CtdlIPC *ipc, char **listing, char *cret)
 {
        size_t bytes;
 
@@ -1653,24 +1653,61 @@ int CtdlGetSystemConfig(char **listing, char *cret)
        if (!listing) return -2;
        if (*listing) return -2;
 
-       return CtdlIPCGenericCommand("CONF GET", NULL, 0,
+       return CtdlIPCGenericCommand(ipc, "CONF GET", NULL, 0,
                        listing, &bytes, cret);
 }
 
 
 /* CONF SET */
-int CtdlSetSystemConfig(const char *listing, char *cret)
+int CtdlSetSystemConfig(CtdlIPC *ipc, const char *listing, char *cret)
 {
        if (!cret) return -2;
        if (!listing) return -2;
 
-       return CtdlIPCGenericCommand("CONF SET", listing, strlen(listing),
+       return CtdlIPCGenericCommand(ipc, "CONF SET", listing, strlen(listing),
                        NULL, NULL, cret);
 }
 
 
+/* CONF GETSYS */
+int CtdlGetSystemConfigByType(CtdlIPC *ipc, const char *mimetype,
+               char **listing, char *cret)
+{
+       char *aaa;
+       size_t bytes;
+
+       if (!cret) return -2;
+       if (!mimetype) return -2;
+       if (!listing) return -2;
+       if (*listing) return -2;
+
+       aaa = malloc(strlen(mimetype) + 13);
+       if (!aaa) return -1;
+       sprintf(aaa, "CONF GETSYS|%s", mimetype);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0,
+                       listing, &bytes, cret);
+}
+
+
+/* CONF PUTSYS */
+int CtdlSetSystemConfigByType(CtdlIPC *ipc, const char *mimetype,
+              const char *listing, char *cret)
+{
+       char *aaa;
+
+       if (!cret) return -2;
+       if (!mimetype) return -2;
+       if (!listing) return -2;
+
+       aaa = malloc(strlen(mimetype) + 13);
+       if (!aaa) return -1;
+       sprintf(aaa, "CONF PUTSYS|%s", mimetype);
+       return CtdlIPCGenericCommand(ipc, aaa, listing, strlen(listing),
+                       NULL, NULL, cret);
+}
+
 /* MMOD */
-int CtdlIPCModerateMessage(long msgnum, int level, char *cret)
+int CtdlIPCModerateMessage(CtdlIPC *ipc, long msgnum, int level, char *cret)
 {
        char aaa[27];
 
@@ -1678,12 +1715,12 @@ int CtdlIPCModerateMessage(long msgnum, int level, char *cret)
        if (!msgnum) return -2;
 
        sprintf(aaa, "MMOD %ld|%d", msgnum, level);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* REQT */
-int CtdlIPCRequestClientLogout(int session, char *cret)
+int CtdlIPCRequestClientLogout(CtdlIPC *ipc, int session, char *cret)
 {
        char aaa[16];
 
@@ -1691,12 +1728,12 @@ int CtdlIPCRequestClientLogout(int session, char *cret)
        if (session < 0) return -2;
 
        sprintf(aaa, "REQT %d", session);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* SEEN */
-int CtdlIPCSetMessageSeen(long msgnum, int seen, char *cret)
+int CtdlIPCSetMessageSeen(CtdlIPC *ipc, long msgnum, int seen, char *cret)
 {
        char aaa[27];
 
@@ -1704,19 +1741,19 @@ int CtdlIPCSetMessageSeen(long msgnum, int seen, char *cret)
        if (msgnum < 0) return -2;
 
        sprintf(aaa, "SEEN %ld|%d", msgnum, seen ? 1 : 0);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
 /* STLS */
-int CtdlIPCStartEncryption(char *cret)
+int CtdlIPCStartEncryption(CtdlIPC *ipc, char *cret)
 {
-       return CtdlIPCGenericCommand("STLS", NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, "STLS", NULL, 0, NULL, NULL, cret);
 }
 
 
 /* QDIR */
-int CtdlIPCDirectoryLookup(const char *address, char *cret)
+int CtdlIPCDirectoryLookup(CtdlIPC *ipc, const char *address, char *cret)
 {
        char *aaa;
 
@@ -1727,7 +1764,18 @@ int CtdlIPCDirectoryLookup(const char *address, char *cret)
        if (!aaa) return -1;
 
        sprintf(aaa, "QDIR %s", address);
-       return CtdlIPCGenericCommand(aaa, NULL, 0, NULL, NULL, cret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
+}
+
+
+/* IPGM */
+int CtdlIPCInternalProgram(CtdlIPC *ipc, int secret, char *cret)
+{
+       char aaa[30];
+
+       if (!cret) return -2;
+       sprintf(aaa, "IPGM %d", secret);
+       return CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret);
 }
 
 
@@ -1739,7 +1787,6 @@ int CtdlIPCDirectoryLookup(const char *address, char *cret)
  * EXPI
  * GTLS
  * IGAB
- * IPGM
  * MSG3
  * MSG4
  * NDOP
@@ -1754,24 +1801,24 @@ int CtdlIPCDirectoryLookup(const char *address, char *cret)
 /* ************************************************************************** */
 
 
-inline void netio_lock(void)
+inline void CtdlIPC_lock(CtdlIPC *ipc)
 {
 #ifdef THREADED_CLIENT
-       pthread_mutex_lock(&rwlock);
+       pthread_mutex_lock(&(ipc->mutex));
 #endif
 }
 
 
-inline void netio_unlock(void)
+inline void CtdlIPC_unlock(CtdlIPC *ipc)
 {
 #ifdef THREADED_CLIENT
-       pthread_mutex_unlock(&rwlock);
+       pthread_mutex_unlock(&(ipc->mutex));
 #endif
 }
 
 
 /* Read a listing from the server up to 000.  Append to dest if it exists */
-char *CtdlIPCReadListing(char *dest)
+char *CtdlIPCReadListing(CtdlIPC *ipc, char *dest)
 {
        size_t length = 0;
        size_t linelength;
@@ -1787,7 +1834,7 @@ char *CtdlIPCReadListing(char *dest)
                length = 0;
        }
 
-       while (serv_gets(aaa), strcmp(aaa, "000")) {
+       while (CtdlIPC_getline(ipc, aaa), strcmp(aaa, "000")) {
                linelength = strlen(aaa);
                ret = (char *)realloc(ret, (size_t)(length + linelength + 2));
                if (ret) {
@@ -1802,7 +1849,7 @@ char *CtdlIPCReadListing(char *dest)
 
 
 /* Send a listing to the server; generate the ending 000. */
-int CtdlIPCSendListing(const char *listing)
+int CtdlIPCSendListing(CtdlIPC *ipc, const char *listing)
 {
        char *text;
 
@@ -1812,21 +1859,21 @@ int CtdlIPCSendListing(const char *listing)
                while (text[strlen(text) - 1] == '\n')
                        text[strlen(text) - 1] = '\0';
                strcat(text, "\n000");
-               serv_puts(text);
+               CtdlIPC_putline(ipc, text);
                free(text);
                text = NULL;
        } else {
                /* Malloc failed but we are committed to send */
                /* This may result in extra blanks at the bottom */
-               serv_puts(text);
-               serv_puts("000");
+               CtdlIPC_putline(ipc, text);
+               CtdlIPC_putline(ipc, "000");
        }
        return 0;
 }
 
 
 /* Partial read of file from server */
-size_t CtdlIPCPartialRead(void **buf, size_t offset, size_t bytes, char *cret)
+size_t CtdlIPCPartialRead(CtdlIPC *ipc, void **buf, size_t offset, size_t bytes, char *cret)
 {
        register size_t len = 0;
        char aaa[SIZ];
@@ -1836,10 +1883,10 @@ size_t CtdlIPCPartialRead(void **buf, size_t offset, size_t bytes, char *cret)
        if (bytes < 1) return -1;
        if (offset < 0) return -1;
 
-       netio_lock();
+       CtdlIPC_lock(ipc);
        sprintf(aaa, "READ %d|%d", offset, bytes);
-       serv_puts(aaa);
-       serv_gets(aaa);
+       CtdlIPC_putline(ipc, aaa);
+       CtdlIPC_getline(ipc, aaa);
        if (aaa[0] != '6')
                strcpy(cret, &aaa[4]);
        else {
@@ -1847,27 +1894,27 @@ size_t CtdlIPCPartialRead(void **buf, size_t offset, size_t bytes, char *cret)
                *buf = (void *)realloc(*buf, (size_t)(offset + len));
                if (*buf) {
                        /* I know what I'm doing */
-                       serv_read((char *)&buf[offset], len);
+                       serv_read(ipc, (char *)&buf[offset], len);
                } else {
                        /* We have to read regardless */
-                       serv_read(aaa, len);
+                       serv_read(ipc, aaa, len);
                        len = -1;
                }
        }
-       netio_unlock();
+       CtdlIPC_unlock(ipc);
        return len;
 }
 
 
 /* CLOS */
-int CtdlIPCEndDownload(char *cret)
+int CtdlIPCEndDownload(CtdlIPC *ipc, char *cret)
 {
        register int ret;
 
        if (!cret) return -2;
        if (!download_in_progress) return -2;
 
-       ret = CtdlIPCGenericCommand("CLOS", NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, "CLOS", NULL, 0, NULL, NULL, cret);
        if (ret / 100 == 2)
                download_in_progress = 0;
        return ret;
@@ -1875,19 +1922,19 @@ int CtdlIPCEndDownload(char *cret)
 
 
 /* MSGP */
-int CtdlIPCSpecifyPreferredFormats(char *cret, char *formats) {
+int CtdlIPCSpecifyPreferredFormats(CtdlIPC *ipc, char *cret, char *formats) {
        register int ret;
        char cmd[SIZ];
        
        snprintf(cmd, sizeof cmd, "MSGP %s", formats);
-       ret = CtdlIPCGenericCommand(cmd, NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, cmd, NULL, 0, NULL, NULL, cret);
        return ret;
 }
 
 
 
 /* READ */
-int CtdlIPCReadDownload(void **buf, size_t bytes, char *cret)
+int CtdlIPCReadDownload(CtdlIPC *ipc, void **buf, size_t bytes, char *cret)
 {
        register size_t len;
 
@@ -1898,7 +1945,7 @@ int CtdlIPCReadDownload(void **buf, size_t bytes, char *cret)
 
        len = 0;
        while (len < bytes) {
-               len = CtdlIPCPartialRead(buf, len, 4096, cret);
+               len = CtdlIPCPartialRead(ipc, buf, len, 4096, cret);
                if (len == -1) {
                        free(*buf);
                        return 0;
@@ -1909,14 +1956,14 @@ int CtdlIPCReadDownload(void **buf, size_t bytes, char *cret)
 
 
 /* UCLS */
-int CtdlIPCEndUpload(char *cret)
+int CtdlIPCEndUpload(CtdlIPC *ipc, char *cret)
 {
        register int ret;
 
        if (!cret) return -1;
        if (!upload_in_progress) return -1;
 
-       ret = CtdlIPCGenericCommand("UCLS", NULL, 0, NULL, NULL, cret);
+       ret = CtdlIPCGenericCommand(ipc, "UCLS", NULL, 0, NULL, NULL, cret);
        if (ret / 100 == 2)
                upload_in_progress = 0;
        return ret;
@@ -1924,7 +1971,7 @@ int CtdlIPCEndUpload(char *cret)
 
 
 /* WRIT */
-int CtdlIPCWriteUpload(void *buf, size_t bytes, char *cret)
+int CtdlIPCWriteUpload(CtdlIPC *ipc, void *buf, size_t bytes, char *cret)
 {
        register int ret = -1;
        register size_t offset;
@@ -1937,15 +1984,15 @@ int CtdlIPCWriteUpload(void *buf, size_t bytes, char *cret)
        offset = 0;
        while (offset < bytes) {
                sprintf(aaa, "WRIT %d", bytes - offset);
-               serv_puts(aaa);
-               serv_gets(aaa);
+               CtdlIPC_putline(ipc, aaa);
+               CtdlIPC_getline(ipc, aaa);
                strcpy(cret, &aaa[4]);
                ret = atoi(aaa);
                if (aaa[0] == '7') {
                        register size_t to_write;
 
                        to_write = extract_long(&aaa[4], 0);
-                       serv_write(buf + offset, to_write);
+                       serv_write(ipc, buf + offset, to_write);
                        offset += to_write;
                } else {
                        break;
@@ -1959,6 +2006,7 @@ int CtdlIPCWriteUpload(void *buf, size_t bytes, char *cret)
  * Generic command method.  This method should handle any server command
  * except for CHAT.  It takes the following arguments:
  *
+ * ipc                 The server to speak with
  * command             Preformatted command to send to server
  * to_send             A text or binary file to send to server
  *                     (only sent if server requests it)
@@ -1981,20 +2029,24 @@ int CtdlIPCWriteUpload(void *buf, size_t bytes, char *cret)
  * protocol_response as described above.  Some commands send additional
  * data in this string.
  */
-int CtdlIPCGenericCommand(const char *command, const char *to_send,
+int CtdlIPCGenericCommand(CtdlIPC *ipc,
+               const char *command, const char *to_send,
                size_t bytes_to_send, char **to_receive, 
                size_t *bytes_to_receive, char *proto_response)
 {
        char buf[SIZ];
        register int ret;
+       int watch_ssl = 0;
 
        if (!command) return -2;
        if (!proto_response) return -2;
 
-       netio_lock();
-       serv_puts((char *)command);
+       if (ipc->ssl) watch_ssl = 1;
+
+       CtdlIPC_lock(ipc);
+       CtdlIPC_putline(ipc, command);
        while (1) {
-               serv_gets(proto_response);
+               CtdlIPC_getline(ipc, proto_response);
                if (proto_response[3] == '*')
                        express_msgs = 1;
                ret = atoi(proto_response);
@@ -2008,18 +2060,18 @@ int CtdlIPCGenericCommand(const char *command, const char *to_send,
                        break;
                case 1:                         /* LISTING_FOLLOWS */
                        if (to_receive && !*to_receive && bytes_to_receive) {
-                               *to_receive = CtdlIPCReadListing(NULL);
+                               *to_receive = CtdlIPCReadListing(ipc, NULL);
                        } else { /* Drain */
-                               while (serv_gets(buf), strcmp(buf, "000")) ;
+                               while (CtdlIPC_getline(ipc, buf), strcmp(buf, "000")) ;
                                ret = -ret;
                        }
                        break;
                case 4:                         /* SEND_LISTING */
                        if (to_send) {
-                               CtdlIPCSendListing(to_send);
+                               CtdlIPCSendListing(ipc, to_send);
                        } else {
                                /* No listing given, fake it */
-                               serv_puts("000");
+                               CtdlIPC_putline(ipc, "000");
                                ret = -ret;
                        }
                        break;
@@ -2032,7 +2084,7 @@ int CtdlIPCGenericCommand(const char *command, const char *to_send,
                                if (!*to_receive) {
                                        ret = -1;
                                } else {
-                                       serv_read(*to_receive,
+                                       serv_read(ipc, *to_receive,
                                                        *bytes_to_receive);
                                }
                        } else {
@@ -2041,16 +2093,16 @@ int CtdlIPCGenericCommand(const char *command, const char *to_send,
 
                                drain = extract_long(proto_response, 0);
                                while (drain > SIZ) {
-                                       serv_read(buf, SIZ);
+                                       serv_read(ipc, buf, SIZ);
                                        drain -= SIZ;
                                }
-                               serv_read(buf, drain);
+                               serv_read(ipc, buf, drain);
                                ret = -ret;
                        }
                        break;
                case 7:                         /* SEND_BINARY */
                        if (to_send && bytes_to_send) {
-                               serv_write((char *)to_send, bytes_to_send);
+                               serv_write(ipc, to_send, bytes_to_send);
                        } else if (bytes_to_send) {
                                /* Fake it, send nulls */
                                size_t fake;
@@ -2058,32 +2110,32 @@ int CtdlIPCGenericCommand(const char *command, const char *to_send,
                                fake = bytes_to_send;
                                memset(buf, '\0', SIZ);
                                while (fake > SIZ) {
-                                       serv_write(buf, SIZ);
+                                       serv_write(ipc, buf, SIZ);
                                        fake -= SIZ;
                                }
-                               serv_write(buf, fake);
+                               serv_write(ipc, buf, fake);
                                ret = -ret;
                        } /* else who knows?  DANGER WILL ROBINSON */
                        break;
                case 8:                         /* START_CHAT_MODE */
                        if (!strncasecmp(command, "CHAT", 4)) {
                                /* Don't call chatmode with generic! */
-                               serv_puts("/quit");
+                               CtdlIPC_putline(ipc, "/quit");
                                ret = -ret;
                        } else {
                                /* In this mode we send then receive listing */
                                if (to_send) {
-                                       CtdlIPCSendListing(to_send);
+                                       CtdlIPCSendListing(ipc, to_send);
                                } else {
                                        /* No listing given, fake it */
-                                       serv_puts("000");
+                                       CtdlIPC_putline(ipc, "000");
                                        ret = -ret;
                                }
                                if (to_receive && !*to_receive
                                                && bytes_to_receive) {
-                                       *to_receive = CtdlIPCReadListing(NULL);
+                                       *to_receive = CtdlIPCReadListing(ipc, NULL);
                                } else { /* Drain */
-                                       while (serv_gets(buf),
+                                       while (CtdlIPC_getline(ipc, buf),
                                                        strcmp(buf, "000")) ;
                                        ret = -ret;
                                }
@@ -2091,12 +2143,12 @@ int CtdlIPCGenericCommand(const char *command, const char *to_send,
                        break;
                case 9:                         /* ASYNC_MSG */
                        /* CtdlIPCDoAsync(ret, proto_response); */
-                       free(CtdlIPCReadListing(NULL)); /* STUB FIXME */
+                       free(CtdlIPCReadListing(ipc, NULL));    /* STUB FIXME */
                        break;
                }
                if (ret / 100 != 9)
                        break;
        }
-       netio_unlock();
+       CtdlIPC_unlock(ipc);
        return ret;
 }