#include <sys/ioctl.h>
#include <signal.h>
#include <pwd.h>
-#include <setjmp.h>
#include <stdarg.h>
+#include <errno.h>
#include "citadel.h"
+#include "citadel_ipc.h"
#include "axdefs.h"
-#include "serv_info.h"
#include "routines.h"
#include "routines2.h"
#include "rooms.h"
#include "messages.h"
#include "commands.h"
-#include "ipc.h"
#include "client_chat.h"
#include "client_passwords.h"
#include "citadel_decls.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#endif
+#include "screen.h"
+#include "citadel_dirs.h"
#include "md5.h"
-struct march {
- struct march *next;
- char march_name[ROOMNAMELEN];
- char march_floor;
- char march_order;
- };
-
#define IFEXPERT if (userflags&US_EXPERT)
#define IFNEXPERT if ((userflags&US_EXPERT)==0)
#define IFAIDE if (axlevel>=6)
struct march *march = NULL;
/* globals associated with the client program */
-char temp[PATH_MAX]; /* Name of general temp file */
-char temp2[PATH_MAX]; /* Name of general temp file */
-char tempdir[PATH_MAX]; /* Name of general temp dir */
-char editor_path[SIZ]; /* path to external editor */
+char temp[PATH_MAX]; /* Name of general-purpose temp file */
+char temp2[PATH_MAX]; /* Name of general-purpose temp file */
+char tempdir[PATH_MAX]; /* Name of general-purpose temp directory */
+char editor_paths[MAX_EDITORS][SIZ]; /* paths to external editors */
char printcmd[SIZ]; /* print command */
int editor_pid = (-1);
-char fullname[32];
-jmp_buf nextbuf;
-struct CtdlServInfo serv_info; /* Info on the server connected */
+char fullname[USERNAME_SIZE];
int screenwidth;
int screenheight;
unsigned room_flags;
char room_name[ROOMNAMELEN];
-char ugname[ROOMNAMELEN];
-long uglsn; /* holds <u>ngoto info */
+char *uglist[UGLISTLEN]; /* size of the ungoto list */
+long uglistlsn[UGLISTLEN]; /* current read position for all the ungoto's. Not going to make any friends with this one. */
+int uglistsize = 0;
char is_mail = 0; /* nonzero when we're in a mail room */
char axlevel = 0; /* access level */
char is_room_aide = 0; /* boolean flag, 1 if room aide */
long maxmsgnum; /* used for <G>oto */
char sigcaught = 0;
char have_xterm = 0; /* are we running on an xterm? */
-char rc_username[32];
+char rc_username[USERNAME_SIZE];
char rc_password[32];
char hostbuf[SIZ];
char portbuf[SIZ];
char floor_mode;
char curr_floor = 0; /* number of current floor */
char floorlist[128][SIZ]; /* names of floors */
-char express_msgs = 0; /* express messages waiting! */
int termn8 = 0; /* Set to nonzero to cause a logoff */
+int secure; /* Set to nonzero when wire is encrypted */
+int can_do_msg4 = 0; /* Set to nonzero if the server can handle MSG4 commands */
+extern char instant_msgs; /* instant messages waiting! */
extern int rc_ansi_color; /* ansi color value from citadel.rc */
+extern int next_lazy_cmd;
+
+CtdlIPC *ipc_for_signal_handlers; /* KLUDGE cover your eyes */
/*
* here is our 'clean up gracefully and exit' routine
*/
-void logoff(int code)
+void ctdl_logoff(char *file, int line, CtdlIPC *ipc, int code)
{
+ int lp;
+
if (editor_pid > 0) { /* kill the editor if it's running */
kill(editor_pid, SIGHUP);
}
-/* shut down the server... but not if the logoff code is 3, because
- * that means we're exiting because we already lost the server
+
+ /* Free the ungoto list */
+ for (lp = 0; lp < uglistsize; lp++) {
+ free(uglist[lp]);
+ }
+
+/* Shut down the server connection ... but not if the logoff code is 3,
+ * because that means we're exiting because we already lost the server.
*/
- if (code != 3)
- serv_puts("QUIT");
+ if (code != 3) {
+ CtdlIPCQuit(ipc);
+ }
/*
* now clean up various things
*/
+ screen_delete();
unlink(temp);
unlink(temp2);
sleep(1);
kill(0 - getpgrp(), SIGKILL);
}
- sttybbs(SB_RESTORE); /* return the old terminal settings */
+ color(ORIGINAL_PAIR); /* Restore the old color settings */
+ stty_ctdl(SB_RESTORE); /* return the old terminal settings */
+ /*
+ * uncomment the following if you need to know why Citadel exited
+ printf("*** Exit code %d at %s:%d\n", code, file, line);
+ sleep(2);
+ */
exit(code); /* exit with the proper exit code */
}
*/
void dropcarr(int signum)
{
- logoff(SIGHUP);
+ logoff(NULL, 3); /* No IPC when server's already gone! */
}
*/
void catch_sigcont(int signum)
{
- sttybbs(SB_LAST);
+ stty_ctdl(SB_LAST);
signal(SIGCONT, catch_sigcont);
}
-
/* general purpose routines */
-void formout(char *name)
-{ /* display a file */
- char cmd[SIZ];
- snprintf(cmd, sizeof cmd, "MESG %s", name);
- serv_puts(cmd);
- serv_gets(cmd);
- if (cmd[0] != '1') {
- printf("%s\n", &cmd[4]);
+/* display a file */
+void formout(CtdlIPC *ipc, char *name)
+{
+ int r; /* IPC return code */
+ char buf[SIZ];
+ char *text = NULL;
+
+ r = CtdlIPCSystemMessage(ipc, name, &text, buf);
+ if (r / 100 != 1) {
+ scr_printf("%s\n", buf);
return;
}
- fmout(screenwidth, NULL,
- ((userflags & US_PAGINATOR) ? 1 : 0),
- screenheight, 1, 1);
+ if (text) {
+ fmout(screenwidth, NULL, text, NULL,
+ ((userflags & US_PAGINATOR) ? 1 : 0),
+ screenheight, 1, 1);
+ free(text);
+ }
}
-void userlist(char *patn)
+void userlist(CtdlIPC *ipc, char *patn)
{
char buf[SIZ];
char fl[SIZ];
- struct tm *tmbuf;
+ struct tm tmbuf;
time_t lc;
+ int r; /* IPC response code */
+ char *listing = NULL;
- serv_puts("LIST");
- serv_gets(buf);
- if (buf[0] != '1') {
- pprintf("%s\n", &buf[4]);
+ r = CtdlIPCUserListing(ipc, patn, &listing, buf);
+ if (r / 100 != 1) {
+ pprintf("%s\n", buf);
return;
}
+
pprintf(" User Name Num L LastCall Calls Posts\n");
pprintf("------------------------- ----- - ---------- ----- -----\n");
- while (serv_gets(buf), strcmp(buf, "000")) {
+ if (listing != NULL) while (strlen(listing) > 0) {
+ extract_token(buf, listing, 0, '\n', sizeof buf);
+ remove_token(listing, 0, '\n');
+
if (sigcaught == 0) {
- extract(fl, buf, 0);
+ extract_token(fl, buf, 0, '|', sizeof fl);
if (pattern(fl, patn) >= 0) {
pprintf("%-25s ", fl);
pprintf("%5ld %d ", extract_long(buf, 2),
extract_int(buf, 1));
lc = extract_long(buf, 3);
- tmbuf = (struct tm *) localtime(&lc);
+ localtime_r(&lc, &tmbuf);
pprintf("%02d/%02d/%04d ",
- (tmbuf->tm_mon + 1),
- tmbuf->tm_mday,
- (tmbuf->tm_year + 1900));
+ (tmbuf.tm_mon + 1),
+ tmbuf.tm_mday,
+ (tmbuf.tm_year + 1900));
pprintf("%5ld %5ld\n", extract_long(buf, 4), extract_long(buf, 5));
}
}
}
+ free(listing);
pprintf("\n");
}
*/
void load_user_info(char *params)
{
- extract(fullname, params, 0);
+ extract_token(fullname, params, 0, '|', sizeof fullname);
axlevel = extract_int(params, 1);
timescalled = extract_int(params, 2);
posted = extract_int(params, 3);
/*
* jump directly to a room
*/
-void dotgoto(char *towhere, int display_name)
+void dotgoto(CtdlIPC *ipc, char *towhere, int display_name, int fromungoto)
{
- char aaa[SIZ], bbb[SIZ], psearch[SIZ];
+ char aaa[SIZ], bbb[SIZ];
static long ls = 0L;
- int newmailcount;
- static int oldmailcount = (-1);
+ int newmailcount = 0;
int partial_match, best_match;
char from_floor;
+ int ugpos = uglistsize;
+ int r; /* IPC result code */
+ struct ctdlipcroom *room = NULL;
/* store ungoto information */
- strcpy(ugname, room_name);
- uglsn = ls;
-
+ if (fromungoto == 0) {
+ /* sloppy slide them all down, hey it's the client, who cares. :-) */
+ if (uglistsize >= (UGLISTLEN-1)) {
+ int lp;
+ free (uglist[0]);
+ for (lp = 0; lp < (UGLISTLEN-1); lp++) {
+ uglist[lp] = uglist[lp+1];
+ uglistlsn[lp] = uglistlsn[lp+1];
+ }
+ ugpos--;
+ } else {
+ uglistsize++;
+ }
+
+ uglist[ugpos] = malloc(strlen(room_name)+1);
+ strcpy(uglist[ugpos], room_name);
+ uglistlsn[ugpos] = ls;
+ }
+
/* first try an exact match */
- snprintf(aaa, sizeof aaa, "GOTO %s", towhere);
- serv_puts(aaa);
- serv_gets(aaa);
- if (aaa[3] == '*')
- express_msgs = 1;
- if (!strncmp(aaa, "54", 2)) {
+ r = CtdlIPCGotoRoom(ipc, towhere, "", &room, aaa);
+ if (r / 10 == 54) {
newprompt("Enter room password: ", bbb, 9);
- snprintf(aaa, sizeof aaa, "GOTO %s|%s", towhere, bbb);
- serv_puts(aaa);
- serv_gets(aaa);
- if (aaa[3] == '*')
- express_msgs = 1;
- }
- if (!strncmp(aaa, "54", 2)) {
- printf("Wrong password.\n");
- return;
- }
+ r = CtdlIPCGotoRoom(ipc, towhere, bbb, &room, aaa);
+ if (r / 10 == 54) {
+ scr_printf("Wrong password.\n");
+ return;
+ }
+ }
+
/*
* If a match is not found, try a partial match.
* Partial matches anywhere in the string carry a weight of 1,
* left-aligned matches carry a weight of 2. Pick the room that
- * has the highest-weighted match.
+ * has the highest-weighted match. Do not match on forgotten
+ * rooms.
*/
- if (aaa[0] != '2') {
+ if (r / 100 != 2) {
+ struct march *march = NULL;
+
best_match = 0;
strcpy(bbb, "");
- serv_puts("LKRA");
- serv_gets(aaa);
- if (aaa[0] == '1')
- while (serv_gets(aaa), strcmp(aaa, "000")) {
- extract(psearch, aaa, 0);
+
+ r = CtdlIPCKnownRooms(ipc, SubscribedRooms, AllFloors, &march, aaa);
+ if (r / 100 == 1) {
+ /* Run the roomlist; free the data as we go */
+ struct march *mp = march; /* Current */
+
+ while (mp) {
partial_match = 0;
- if (pattern(psearch, towhere) >= 0) {
+ if (pattern(mp->march_name, towhere) >= 0) {
partial_match = 1;
}
- if (!strncasecmp(towhere, psearch, strlen(towhere))) {
+ if (!strncasecmp(mp->march_name, towhere, strlen(towhere))) {
partial_match = 2;
}
if (partial_match > best_match) {
- strcpy(bbb, psearch);
+ strcpy(bbb, mp->march_name);
best_match = partial_match;
}
+ /* Both pointers are NULL at end of list */
+ march = mp->next;
+ free(mp);
+ mp = march;
}
+ }
+
if (strlen(bbb) == 0) {
- printf("No room '%s'.\n", towhere);
+ scr_printf("No room '%s'.\n", towhere);
return;
}
- snprintf(aaa, sizeof aaa, "GOTO %s", bbb);
- serv_puts(aaa);
- serv_gets(aaa);
- if (aaa[3] == '*')
- express_msgs = 1;
+ room = NULL;
+ r = CtdlIPCGotoRoom(ipc, bbb, "", &room, aaa);
}
- if (aaa[0] != '2') {
- printf("%s\n", aaa);
+ if (r / 100 != 1 && r / 100 != 2) {
+ scr_printf("%s\n", aaa);
return;
}
- extract(room_name, &aaa[4], 0);
- room_flags = extract_int(&aaa[4], 4);
+ safestrncpy(room_name, room->RRname, ROOMNAMELEN);
+ room_flags = room->RRflags;
from_floor = curr_floor;
- curr_floor = extract_int(&aaa[4], 10);
+ curr_floor = room->RRfloor;
remove_march(room_name, 0);
if (!strcasecmp(towhere, "_BASEROOM_"))
remove_march(towhere, 0);
+ if (!room->RRunread)
+ next_lazy_cmd = 5; /* Don't read new if no new msgs */
if ((from_floor != curr_floor) && (display_name > 0) && (floor_mode == 1)) {
if (floorlist[(int) curr_floor][0] == 0)
- load_floorlist();
- printf("(Entering floor: %s)\n", &floorlist[(int) curr_floor][0]);
+ load_floorlist(ipc);
+ scr_printf("(Entering floor: %s)\n", &floorlist[(int) curr_floor][0]);
}
if (display_name == 1) {
color(BRIGHT_WHITE);
- printf("%s ", room_name);
+ scr_printf("%s ", room_name);
color(DIM_WHITE);
- printf("- ");
+ scr_printf("- ");
}
if (display_name != 2) {
color(BRIGHT_YELLOW);
- printf("%d ", extract_int(&aaa[4], 1));
+ scr_printf("%d ", room->RRunread);
color(DIM_WHITE);
- printf("new of ");
+ scr_printf("new of ");
color(BRIGHT_YELLOW);
- printf("%d ", extract_int(&aaa[4], 2));
+ scr_printf("%d ", room->RRtotal);
color(DIM_WHITE);
- printf("messages.\n");
+ scr_printf("messages.\n");
}
- highest_msg_read = extract_int(&aaa[4], 6);
- maxmsgnum = extract_int(&aaa[4], 5);
- is_mail = (char) extract_int(&aaa[4], 7);
- is_room_aide = (char) extract_int(&aaa[4], 8);
- ls = extract_long(&aaa[4], 6);
+ highest_msg_read = room->RRlastread;
+ maxmsgnum = room->RRhighest;
+ is_mail = room->RRismailbox;
+ is_room_aide = room->RRaide;
+ ls = room->RRlastread;
/* read info file if necessary */
- if (extract_int(&aaa[4], 3) > 0)
- readinfo();
+ if (room->RRinfoupdated > 0)
+ readinfo(ipc);
/* check for newly arrived mail if we can */
- if (num_parms(&aaa[4]) >= 10) {
- newmailcount = extract_int(&aaa[4], 9);
- if ((oldmailcount >= 0) && (newmailcount > oldmailcount)) {
- color(BRIGHT_RED);
- printf("*** You have new mail\n");
- color(DIM_WHITE);
+ newmailcount = room->RRnewmail;
+ if (newmailcount > 0) {
+ color(BRIGHT_RED);
+ if (newmailcount == 1) {
+ scr_printf("*** A new mail message has arrived.\n");
+ }
+ else {
+ scr_printf("*** %d new mail messages have arrived.\n",
+ newmailcount);
+ }
+ color(DIM_WHITE);
+ if (strlen(rc_gotmail_cmd) > 0) {
+ system(rc_gotmail_cmd);
}
- oldmailcount = newmailcount;
}
+ status_line(ipc->ServInfo.humannode, ipc->ServInfo.site_location,
+ room_name, secure, newmailcount);
}
/* Goto next room having unread messages.
* user back to the lobby when done. The room we end up in is placed in
* newroom - which is set to 0 (the lobby) initially.
*/
-void gotonext(void)
+void gotonext(CtdlIPC *ipc)
{
char buf[SIZ];
struct march *mptr, *mptr2;
char next_room[ROOMNAMELEN];
+ int r; /* IPC response code */
/* Check to see if the march-mode list is already allocated.
* If it is, pop the first room off the list and go there.
*/
if (march == NULL) {
- serv_puts("LKRN");
- serv_gets(buf);
- if (buf[0] == '1')
- while (serv_gets(buf), strcmp(buf, "000")) {
- mptr = (struct march *) malloc(sizeof(struct march));
- mptr->next = NULL;
- extract(mptr->march_name, buf, 0);
- mptr->march_floor = (char) (extract_int(buf, 2) & 0x7F);
- mptr->march_order = (char) (extract_int(buf, 3) & 0x7F);
- if (march == NULL) {
- march = mptr;
- } else {
- mptr2 = march;
- while (mptr2->next != NULL)
- mptr2 = mptr2->next;
- mptr2->next = mptr;
- }
- }
+ r = CtdlIPCKnownRooms(ipc, SubscribedRoomsWithNewMessages,
+ AllFloors, &march, buf);
+
/* add _BASEROOM_ to the end of the march list, so the user will end up
* in the system base room (usually the Lobby>) at the end of the loop
*/
strcpy(next_room, "_BASEROOM_");
}
remove_march(next_room, 0);
- dotgoto(next_room, 1);
+ dotgoto(ipc, next_room, 1, 0);
}
/*
* forget all rooms on a given floor
*/
-void forget_all_rooms_on(int ffloor)
+void forget_all_rooms_on(CtdlIPC *ipc, int ffloor)
{
char buf[SIZ];
- struct march *flist, *fptr;
-
- printf("Forgetting all rooms on %s...\r", &floorlist[ffloor][0]);
- fflush(stdout);
- snprintf(buf, sizeof buf, "LKRA %d", ffloor);
- serv_puts(buf);
- serv_gets(buf);
- if (buf[0] != '1') {
- printf("%-72s\n", &buf[4]);
+ struct march *flist = NULL;
+ struct march *fptr = NULL;
+ struct ctdlipcroom *room = NULL;
+ int r; /* IPC response code */
+
+ scr_printf("Forgetting all rooms on %s...\n", &floorlist[ffloor][0]);
+ scr_flush();
+ remove_march("_FLOOR_", ffloor);
+ r = CtdlIPCKnownRooms(ipc, AllAccessibleRooms, ffloor, &flist, buf);
+ if (r / 100 != 1) {
+ scr_printf("Error %d: %s\n", r, buf);
return;
}
- flist = NULL;
- while (serv_gets(buf), strcmp(buf, "000")) {
- fptr = (struct march *) malloc(sizeof(struct march));
- fptr->next = flist;
- flist = fptr;
- extract(fptr->march_name, buf, 0);
- }
- while (flist != NULL) {
- snprintf(buf, sizeof buf, "GOTO %s", flist->march_name);
- serv_puts(buf);
- serv_gets(buf);
- if (buf[0] == '2') {
- serv_puts("FORG");
- serv_gets(buf);
+ while (flist) {
+ r = CtdlIPCGotoRoom(ipc, flist->march_name, "", &room, buf);
+ if (r / 100 == 2) {
+ r = CtdlIPCForgetRoom(ipc, buf);
+ if (r / 100 != 2) {
+ scr_printf("Error %d: %s\n", r, buf);
+ }
+
}
fptr = flist;
flist = flist->next;
free(fptr);
}
- printf("%-72s\r", "");
}
/*
* routine called by gotofloor() to move to a new room on a new floor
*/
-void gf_toroom(char *towhere, int mode)
+void gf_toroom(CtdlIPC *ipc, char *towhere, int mode)
{
int floor_being_left;
floor_being_left = curr_floor;
- if (mode == GF_GOTO) { /* <;G>oto mode */
- updatels();
- dotgoto(towhere, 1);
+ if (mode == GF_GOTO) { /* <;G>oto mode */
+ updatels(ipc);
+ dotgoto(ipc, towhere, 1, 0);
}
- if (mode == GF_SKIP) { /* <;S>kip mode */
- dotgoto(towhere, 1);
+ else if (mode == GF_SKIP) { /* <;S>kip mode */
+ dotgoto(ipc, towhere, 1, 0);
remove_march("_FLOOR_", floor_being_left);
}
- if (mode == GF_ZAP) { /* <;Z>ap mode */
- dotgoto(towhere, 1);
+ else if (mode == GF_ZAP) { /* <;Z>ap mode */
+ dotgoto(ipc, towhere, 1, 0);
remove_march("_FLOOR_", floor_being_left);
- forget_all_rooms_on(floor_being_left);
+ forget_all_rooms_on(ipc, floor_being_left);
}
}
/*
* go to a new floor
*/
-void gotofloor(char *towhere, int mode)
+void gotofloor(CtdlIPC *ipc, char *towhere, int mode)
{
int a, tofloor;
+ int r; /* IPC response code */
struct march *mptr;
char buf[SIZ], targ[SIZ];
if (floorlist[0][0] == 0)
- load_floorlist();
+ load_floorlist(ipc);
tofloor = (-1);
for (a = 0; a < 128; ++a)
if (!strcasecmp(&floorlist[a][0], towhere))
tofloor = a;
}
if (tofloor < 0) {
- printf("No floor '%s'.\n", towhere);
+ scr_printf("No floor '%s'.\n", towhere);
return;
}
for (mptr = march; mptr != NULL; mptr = mptr->next) {
- if ((mptr->march_floor) == tofloor)
- gf_toroom(mptr->march_name, mode);
+ if ((mptr->march_floor) == tofloor) {
+ gf_toroom(ipc, mptr->march_name, mode);
+ return;
+ }
+ }
+
+ /* Find first known room on the floor */
+
+ strcpy(targ, "");
+ mptr = NULL;
+ r = CtdlIPCKnownRooms(ipc, SubscribedRooms, tofloor, &mptr, buf);
+ if (r / 100 == 1) {
+ struct march *tmp = mptr;
+
+ /* TODO: room order is being ignored? */
+ if (mptr)
+ strncpy(targ, mptr->march_name, ROOMNAMELEN);
+ while (mptr) {
+ tmp = mptr->next;
+ free(mptr);
+ mptr = tmp;
+ }
+ }
+ if (strlen(targ) > 0) {
+ gf_toroom(ipc, targ, mode);
return;
}
+ /* No known rooms on the floor; unzap the first one then */
+
strcpy(targ, "");
- snprintf(buf, sizeof buf, "LKRA %d", tofloor);
- serv_puts(buf);
- serv_gets(buf);
- if (buf[0] == '1')
- while (serv_gets(buf), strcmp(buf, "000")) {
- if ((extract_int(buf, 2) == tofloor) && (strlen(targ) == 0))
- extract(targ, buf, 0);
+ mptr = NULL;
+ r = CtdlIPCKnownRooms(ipc, AllAccessibleRooms, tofloor, &mptr, buf);
+ if (r / 100 == 1) {
+ struct march *tmp = mptr;
+
+ /* TODO: room order is being ignored? */
+ if (mptr)
+ strncpy(targ, mptr->march_name, ROOMNAMELEN);
+ while (mptr) {
+ tmp = mptr->next;
+ free(mptr);
+ mptr = tmp;
}
+ }
if (strlen(targ) > 0) {
- gf_toroom(targ, mode);
+ gf_toroom(ipc, targ, mode);
} else {
- printf("There are no rooms on '%s'.\n", &floorlist[tofloor][0]);
+ scr_printf("There are no rooms on '%s'.\n", &floorlist[tofloor][0]);
}
}
/*
* forget all rooms on current floor
*/
-void forget_this_floor(void)
+void forget_this_floor(CtdlIPC *ipc)
{
-
if (curr_floor == 0) {
- printf("Can't forget this floor.\n");
+ scr_printf("Can't forget this floor.\n");
return;
}
- if (floorlist[0][0] == 0)
- load_floorlist();
- printf("Are you sure you want to forget all rooms on %s? ",
+ if (floorlist[0][0] == 0) {
+ load_floorlist(ipc);
+ }
+ scr_printf("Are you sure you want to forget all rooms on %s? ",
&floorlist[(int) curr_floor][0]);
- if (yesno() == 0)
+ if (yesno() == 0) {
return;
+ }
- gf_toroom("_BASEROOM_", GF_ZAP);
+ gf_toroom(ipc, "_BASEROOM_", GF_ZAP);
}
/*
* Figure out the physical screen dimensions, if we can
+ * WARNING: this is now called from a signal handler!
*/
void check_screen_dims(void)
{
if (have_xterm) { /* dynamically size screen if on an xterm */
if (ioctl(0, TIOCGWINSZ, &xwinsz) == 0) {
if (xwinsz.height)
- screenheight = (int) xwinsz.height;
+ screenheight = is_curses_enabled() ? (int)xwinsz.height - 1 : (int) xwinsz.height;
if (xwinsz.width)
screenwidth = (int) xwinsz.width;
}
/*
* set floor mode depending on client, server, and user settings
*/
-void set_floor_mode(void)
+void set_floor_mode(CtdlIPC* ipc)
{
- if (serv_info.serv_ok_floors == 0) {
+ if (ipc->ServInfo.ok_floors == 0) {
floor_mode = 0; /* Don't use floors if the server */
}
/* doesn't support them! */
/*
* Set or change the user's password
*/
-int set_password(void)
+int set_password(CtdlIPC *ipc)
{
char pass1[20];
char pass2[20];
strcpy(pass1, rc_password);
strcpy(pass2, rc_password);
} else {
- IFNEXPERT formout("changepw");
+ IFNEXPERT formout(ipc, "changepw");
newprompt("Enter a new password: ", pass1, -19);
newprompt("Enter it again to confirm: ", pass2, -19);
}
strproc(pass1);
strproc(pass2);
if (!strcasecmp(pass1, pass2)) {
- snprintf(buf, sizeof buf, "SETP %s", pass1);
- serv_puts(buf);
- serv_gets(buf);
- printf("%s\n", &buf[4]);
- offer_to_remember_password(hostbuf, portbuf, fullname, pass1);
+ CtdlIPCChangePassword(ipc, pass1, buf);
+ scr_printf("%s\n", buf);
+ offer_to_remember_password(ipc, hostbuf, portbuf, fullname, pass1);
return (0);
} else {
- printf("*** They don't match... try again.\n");
+ scr_printf("*** They don't match... try again.\n");
return (1);
}
}
/*
* get info about the server we've connected to
*/
-void get_serv_info(char *supplied_hostname)
+void get_serv_info(CtdlIPC *ipc, char *supplied_hostname)
{
- char buf[512];
+ char buf[SIZ];
- CtdlInternalGetServInfo(&serv_info);
+ CtdlIPCServerInfo(ipc, buf);
/* be nice and identify ourself to the server */
- snprintf(buf, sizeof buf, "IDEN %d|%d|%d|%s|",
- SERVER_TYPE, 0, REV_LEVEL,
- (server_is_local ? "local" : CITADEL));
-
- /* Append a hostname */
- if (supplied_hostname != NULL) {
- strcat(buf, supplied_hostname);
- }
- else {
- locate_host(&buf[strlen(buf)]); /* append to the end */
+ CtdlIPCIdentifySoftware(ipc, SERVER_TYPE, 0, REV_LEVEL,
+ (ipc->isLocal ? "local" : CITADEL),
+ (supplied_hostname) ? supplied_hostname :
+ /* Look up the , in the bible if you're confused */
+ (locate_host(ipc, buf), buf), buf);
+
+ /* Tell the server what our preferred content formats are */
+ if ((CtdlIPCSpecifyPreferredFormats(ipc, buf, "text/html|text/plain") / 100 )== 2) {
+ can_do_msg4 = 1;
}
+}
- serv_puts(buf);
- serv_gets(buf); /* we don't care about the result code */
+
+
+/*
+ * Record compare function for SortOnlineUsers()
+ */
+int idlecmp(const void *rec1, const void *rec2) {
+ time_t i1, i2;
+
+ i1 = extract_long(rec1, 5);
+ i2 = extract_long(rec2, 5);
+
+ if (i1 < i2) return(1);
+ if (i1 > i2) return(-1);
+ return(0);
}
+/*
+ * Sort the list of online users by idle time.
+ * This function frees the supplied buffer, and returns a new one
+ * to the caller. The caller is responsible for freeing the returned buffer.
+ */
+char *SortOnlineUsers(char *listing) {
+ int rows;
+ char *sortbuf;
+ char *retbuf;
+ char buf[SIZ];
+ int i;
+
+ rows = num_tokens(listing, '\n');
+ sortbuf = malloc(rows * SIZ);
+ if (sortbuf == NULL) return(listing);
+ retbuf = malloc(rows * SIZ);
+ if (retbuf == NULL) {
+ free(sortbuf);
+ return(listing);
+ }
+
+ /* Copy the list into a fixed-record-size array for sorting */
+ for (i=0; i<rows; ++i) {
+ memset(buf, 0, SIZ);
+ extract_token(buf, listing, i, '\n', sizeof buf);
+ memcpy(&sortbuf[i*SIZ], buf, (size_t)SIZ);
+ }
+
+ /* Do the sort */
+ qsort(sortbuf, rows, SIZ, idlecmp);
+
+ /* Copy back to a \n delimited list */
+ strcpy(retbuf, "");
+ for (i=0; i<rows; ++i) {
+ strcat(retbuf, &sortbuf[i*SIZ]);
+ if (i<(rows-1)) strcat(retbuf, "\n");
+ }
+ return(retbuf);
+}
/*
* Display list of users currently logged on to the server
*/
-void who_is_online(int longlist)
+void who_is_online(CtdlIPC *ipc, int longlist)
{
char buf[SIZ], username[SIZ], roomname[SIZ], fromhost[SIZ];
char flags[SIZ];
char actual_user[SIZ], actual_room[SIZ], actual_host[SIZ];
- char tbuf[SIZ], clientsoft[SIZ];
+ char clientsoft[SIZ];
time_t timenow = 0;
time_t idletime, idlehours, idlemins, idlesecs;
int last_session = (-1);
-
- serv_puts("TIME");
- serv_gets(tbuf);
- if (tbuf[0] == '2') {
- timenow = extract_long(&tbuf[4], 0);
- }
- else {
- time(&timenow);
+ int skipidle = 0;
+ char *listing = NULL;
+ int r; /* IPC response code */
+
+ if (longlist == 2) {
+ longlist = 0;
+ skipidle = 1;
}
if (!longlist) {
color(BRIGHT_WHITE);
- pprintf("FLG ### User Name Room From host\n");
+ pprintf(" User Name Room Idle From host\n");
color(DIM_WHITE);
- pprintf("--- --- ------------------------- -------------------- ------------------------\n");
- }
- serv_puts("RWHO");
- serv_gets(buf);
- if (buf[0] == '1') {
- while (serv_gets(buf), strcmp(buf, "000")) {
- extract(username, buf, 1);
- extract(roomname, buf, 2);
- extract(fromhost, buf, 3);
- extract(clientsoft, buf, 4);
- extract(flags, buf, 7);
+ pprintf(" ------------------------- -------------------- ---- ------------------------\n");
+ }
+ r = CtdlIPCOnlineUsers(ipc, &listing, &timenow, buf);
+ listing = SortOnlineUsers(listing);
+ if (r / 100 == 1) {
+ while (strlen(listing) > 0) {
+ int isidle = 0;
+
+ /* Get another line */
+ extract_token(buf, listing, 0, '\n', sizeof buf);
+ remove_token(listing, 0, '\n');
+
+ extract_token(username, buf, 1, '|', sizeof username);
+ extract_token(roomname, buf, 2, '|', sizeof roomname);
+ extract_token(fromhost, buf, 3, '|', sizeof fromhost);
+ extract_token(clientsoft, buf, 4, '|', sizeof clientsoft);
+ extract_token(flags, buf, 7, '|', sizeof flags);
idletime = timenow - extract_long(buf, 5);
idlehours = idletime / 3600;
idlemins = (idletime - (idlehours * 3600)) / 60;
idlesecs = (idletime - (idlehours * 3600) - (idlemins * 60));
- if (idletime > 900) {
+ if (idletime > rc_idle_threshold) {
+ /*
while (strlen(roomname) < 20) {
strcat(roomname, " ");
}
strcpy(&roomname[14], "[idle]");
+ */
+ if (skipidle)
+ isidle = 1;
}
if (longlist) {
-
- extract(actual_user, buf, 8);
- extract(actual_room, buf, 9);
- extract(actual_host, buf, 10);
+ extract_token(actual_user, buf, 8, '|', sizeof actual_user);
+ extract_token(actual_room, buf, 9, '|', sizeof actual_room);
+ extract_token(actual_host, buf, 10, '|', sizeof actual_host);
pprintf(" Flags: %s\n", flags);
pprintf("Session: %d\n", extract_int(buf, 0));
pprintf("\n");
} else {
- if (extract_int(buf, 0) == last_session) {
- pprintf(" ");
- } else {
- color(BRIGHT_MAGENTA);
- pprintf("%-3s ", flags);
- color(DIM_WHITE);
- pprintf("%-3d ", extract_int(buf, 0));
+ if (isidle == 0) {
+ if (extract_int(buf, 0) == last_session) {
+ pprintf(" ");
+ } else {
+ color(BRIGHT_MAGENTA);
+ pprintf("%-3s", flags);
+ }
+ last_session = extract_int(buf, 0);
+ color(BRIGHT_CYAN);
+ pprintf("%-25s ", username);
+ color(BRIGHT_MAGENTA);
+ roomname[20] = 0;
+ pprintf("%-20s ", roomname);
+ if (idletime > rc_idle_threshold) {
+ /* over 1000d, must be gone fishing */
+ if (idlehours > 23999) {
+ pprintf("fish");
+ /* over 10 days */
+ } else if (idlehours > 239) {
+ pprintf("%3ldd",
+ idlehours / 24);
+ /* over 10 hours */
+ } else if (idlehours > 9) {
+ pprintf("%1ldd%02ld",
+ idlehours / 24,
+ idlehours % 24);
+ /* less than 10 hours */
+ } else {
+ pprintf("%1ld:%02ld",
+ idlehours, idlemins);
+ }
}
- last_session = extract_int(buf, 0);
- color(BRIGHT_CYAN);
- pprintf("%-25s ", username);
- color(BRIGHT_MAGENTA);
- roomname[20] = 0;
- pprintf("%-20s ", roomname);
- color(BRIGHT_CYAN);
- fromhost[24] = '\0';
- pprintf("%-24s\n", fromhost);
- color(DIM_WHITE);
+ else {
+ pprintf(" ");
+ }
+ pprintf(" ");
+ color(BRIGHT_CYAN);
+ fromhost[24] = '\0';
+ pprintf("%-24s\n", fromhost);
+ color(DIM_WHITE);
+ }
}
}
}
+ free(listing);
}
-void enternew(char *desc, char *buf, int maxlen)
+void enternew(CtdlIPC *ipc, char *desc, char *buf, int maxlen)
{
char bbb[128];
snprintf(bbb, sizeof bbb, "Enter in your new %s: ", desc);
return argc;
}
+static void statusHook(char *s) {
+ sln_printf(s);
+ sln_flush();
+}
+
/*
* main
*/
char hexstring[MD5_HEXSTRING_SIZE];
int stored_password = 0;
char password[SIZ];
-
+ struct ctdlipcmisc chek;
+ struct ctdluser *myself = NULL;
+ CtdlIPC* ipc; /* Our server connection */
+ int r; /* IPC result code */
+
+ setIPCDeathHook(screen_delete);
+ setIPCErrorPrintf(err_printf);
+ setCryptoStatusHook(statusHook);
+
/* Permissions sanity check - don't run citadel setuid/setgid */
if (getuid() != geteuid()) {
- fprintf(stderr, "Please do not run citadel setuid!\n");
- logoff(3);
+ err_printf("Please do not run citadel setuid!\n");
+ logoff(NULL, 3);
} else if (getgid() != getegid()) {
- fprintf(stderr, "Please do not run citadel setgid!\n");
- logoff(3);
+ err_printf("Please do not run citadel setgid!\n");
+ logoff(NULL, 3);
}
- sttybbs(SB_SAVE); /* Store the old terminal parameters */
+ stty_ctdl(SB_SAVE); /* Store the old terminal parameters */
load_command_set(); /* parse the citadel.rc file */
- sttybbs(SB_NO_INTR); /* Install the new ones */
- signal(SIGHUP, dropcarr); /* Cleanup gracefully if carrier is dropped */
+ stty_ctdl(SB_NO_INTR); /* Install the new ones */
+ /* signal(SIGHUP, dropcarr);FIXME */ /* Cleanup gracefully if carrier is dropped */
+ signal(SIGPIPE, dropcarr); /* Cleanup gracefully if local conn. dropped */
signal(SIGTERM, dropcarr); /* Cleanup gracefully if terminated */
- signal(SIGCONT, catch_sigcont); /* Catch SIGCONT so we can reset terminal */
+ signal(SIGCONT, catch_sigcont); /* Catch SIGCONT so we can reset terminal */
+#ifdef SIGWINCH
+ signal(SIGWINCH, scr_winch); /* Window resize signal */
+#endif
+
+#ifdef HAVE_OPENSSL
+ arg_encrypt = RC_DEFAULT;
+#endif
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ arg_screen = RC_DEFAULT;
+#endif
/*
* Handle command line options as if we were called like /bin/login
telnet_client_host = argv[a+1];
argc = shift(argc, argv, a, 2);
}
+ if (!strcmp(argv[a], "-x")) {
+#ifdef HAVE_OPENSSL
+ arg_encrypt = RC_NO;
+#endif
+ argc = shift(argc, argv, a, 1);
+ }
+ if (!strcmp(argv[a], "-X")) {
+#ifdef HAVE_OPENSSL
+ arg_encrypt = RC_YES;
+ argc = shift(argc, argv, a, 1);
+#else
+ fprintf(stderr, "Not compiled with encryption support");
+ return 1;
+#endif
+ }
+ if (!strcmp(argv[a], "-s")) {
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ arg_screen = RC_NO;
+#endif
+ argc = shift(argc, argv, a, 1);
+ }
+ if (!strcmp(argv[a], "-S")) {
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ arg_screen = RC_YES;
+#endif
+ argc = shift(argc, argv, a, 1);
+ }
if (!strcmp(argv[a], "-p")) {
struct stat st;
- if (chdir(BBSDIR) < 0) {
- perror("can't change to " BBSDIR);
- logoff(3);
+ if (chdir(CTDLDIR) < 0) {
+ perror("can't change to " CTDLDIR);
+ logoff(NULL, 3);
}
/*
* guaranteed to have the uid/gid we want.
*/
if (!getuid() || !getgid()) {
- if (stat(BBSDIR "/citadel.config", &st) < 0) {
+ if (stat(file_citadel_config, &st) < 0) {
perror("couldn't stat citadel.config");
- logoff(3);
+ logoff(NULL, 3);
}
if (!getgid() && (setgid(st.st_gid) < 0)) {
perror("couldn't change gid");
- logoff(3);
+ logoff(NULL, 3);
}
if (!getuid() && (setuid(st.st_uid) < 0)) {
perror("couldn't change uid");
- logoff(3);
+ logoff(NULL, 3);
}
/*
- printf("Privileges changed to uid %d gid %d\n",
- getuid(), getgid());
+ scr_printf("Privileges changed to uid %d gid %d\n",
+ getuid(), getgid());
*/
}
argc = shift(argc, argv, a, 1);
}
}
- printf("Attaching to server... \r");
- fflush(stdout);
- attach_to_server(argc, argv, hostbuf, portbuf);
+ screen_new();
- send_ansi_detect();
+#ifdef __CYGWIN__
+ newprompt("Connect to (return for local server): ", hostbuf, 64);
+#endif
- serv_gets(aaa);
+ sln_printf("Attaching to server... \r");
+ sln_flush();
+ ipc = CtdlIPC_new(argc, argv, hostbuf, portbuf);
+ if (!ipc) {
+ screen_delete();
+ error_printf("Can't connect: %s\n", strerror(errno));
+ logoff(NULL, 3);
+ }
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ CtdlIPC_SetNetworkStatusCallback(ipc, wait_indicator);
+#endif
+ ipc_for_signal_handlers = ipc; /* KLUDGE cover your eyes */
+
+ CtdlIPC_chat_recv(ipc, aaa);
if (aaa[0] != '2') {
- printf("%s\n", &aaa[4]);
- logoff(atoi(aaa));
+ scr_printf("%s\n", &aaa[4]);
+ logoff(ipc, atoi(aaa));
}
-/* If there is a [nonce] at the end, put the nonce in <nonce>, else nonce
- * is zeroized.
- */
+ /* If there is a [nonce] at the end, put the nonce in <nonce>, else nonce
+ * is zeroized.
+ */
if ((sptr = strchr(aaa, '<')) == NULL)
- {
- nonce[0] = '\0';
- }
+ {
+ nonce[0] = '\0';
+ }
else
- {
- if ((sptr2 = strchr(sptr, '>')) == NULL)
- {
- nonce[0] = '\0';
- }
- else
- {
- sptr2++;
- *sptr2 = '\0';
- strncpy(nonce, sptr, NONCE_SIZE);
- }
+ {
+ if ((sptr2 = strchr(sptr, '>')) == NULL)
+ {
+ nonce[0] = '\0';
+ }
+ else
+ {
+ sptr2++;
+ *sptr2 = '\0';
+ strncpy(nonce, sptr, (size_t)NONCE_SIZE);
+ }
+ }
+
+#ifdef HAVE_OPENSSL
+ /* Evaluate encryption preferences */
+ if (arg_encrypt != RC_NO && rc_encrypt != RC_NO) {
+ if (!ipc->isLocal || arg_encrypt == RC_YES || rc_encrypt == RC_YES) {
+ secure = (CtdlIPCStartEncryption(ipc, aaa) / 100 == 2) ? 1 : 0;
+ if (!secure)
+ error_printf("Can't encrypt: %s\n", aaa);
+ }
}
-
- get_serv_info(telnet_client_host);
+#endif
- look_for_ansi();
- cls(0);
- color(7);
+ get_serv_info(ipc, telnet_client_host);
+ scr_printf("%-24s\n%s\n%s\n", ipc->ServInfo.software, ipc->ServInfo.humannode,
+ ipc->ServInfo.site_location);
+ scr_flush();
+
+ status_line(ipc->ServInfo.humannode, ipc->ServInfo.site_location, NULL,
+ secure, -1);
- printf("%-23s\n%s\n%s\n", serv_info.serv_software, serv_info.serv_humannode,
- serv_info.serv_bbs_city);
screenwidth = 80; /* default screen dimensions */
screenheight = 24;
+
+ scr_printf(" pause next stop\n");
+ scr_printf(" ctrl-s ctrl-o ctrl-c\n\n");
+ formout(ipc, "hello"); /* print the opening greeting */
+ scr_printf("\n");
- printf(" pause next stop\n");
- printf(" ctrl-s ctrl-o ctrl-c\n\n");
- formout("hello"); /* print the opening greeting */
- printf("\n");
-
-GSTA: /* See if we have a username and password on disk */
+ GSTA: /* See if we have a username and password on disk */
if (rc_remember_passwords) {
get_stored_password(hostbuf, portbuf, fullname, password);
if (strlen(fullname) > 0) {
- snprintf(aaa, sizeof(aaa)-1, "USER %s", fullname);
- serv_puts(aaa);
- serv_gets(aaa);
- if (nonce[0])
- {
- sprintf(aaa, "PAS2 %s", make_apop_string(password, nonce, hexstring));
+ r = CtdlIPCTryLogin(ipc, fullname, aaa);
+ if (r / 100 == 3) {
+ if (*nonce) {
+ r = CtdlIPCTryApopPassword(ipc, make_apop_string(password, nonce, hexstring, sizeof hexstring), aaa);
+ } else {
+ r = CtdlIPCTryPassword(ipc, password, aaa);
+ }
}
- else /* Else no APOP */
- {
- snprintf(aaa, sizeof(aaa)-1, "PASS %s", password);
- }
-
- serv_puts(aaa);
- serv_gets(aaa);
- if (aaa[0] == '2') {
- load_user_info(&aaa[4]);
+
+ if (r / 100 == 2) {
+ load_user_info(aaa);
stored_password = 1;
goto PWOK;
- }
- else {
+ } else {
set_stored_password(hostbuf, portbuf, "", "");
}
}
}
strproc(fullname);
if (!strcasecmp(fullname, "new")) { /* just in case */
- printf("Please enter the name you wish to log in with.\n");
+ scr_printf("Please enter the name you wish to log in with.\n");
}
} while (
- (!strcasecmp(fullname, "bbs"))
- || (!strcasecmp(fullname, "new"))
- || (strlen(fullname) == 0));
+ (!strcasecmp(fullname, "bbs"))
+ || (!strcasecmp(fullname, "new"))
+ || (strlen(fullname) == 0));
if (!strcasecmp(fullname, "off")) {
mcmd = 29;
goto TERMN8;
}
/* sign on to the server */
- snprintf(aaa, sizeof aaa, "USER %s", fullname);
- serv_puts(aaa);
- serv_gets(aaa);
- if (aaa[0] != '3')
+ r = CtdlIPCTryLogin(ipc, fullname, aaa);
+ if (r / 100 != 3)
goto NEWUSR;
/* password authentication */
}
strproc(password);
- if (nonce[0])
- {
- sprintf(aaa, "PAS2 %s", make_apop_string(password, nonce, hexstring));
- }
- else /* Else no APOP */
- {
- snprintf(aaa, sizeof(aaa)-1, "PASS %s", password);
+ if (*nonce) {
+ r = CtdlIPCTryApopPassword(ipc, make_apop_string(password, nonce, hexstring, sizeof hexstring), aaa);
+ } else {
+ r = CtdlIPCTryPassword(ipc, password, aaa);
}
- serv_puts(aaa);
- serv_gets(aaa);
- if (aaa[0] == '2') {
- load_user_info(&aaa[4]);
- offer_to_remember_password(hostbuf, portbuf,
- fullname, password);
+ if (r / 100 == 2) {
+ load_user_info(aaa);
+ offer_to_remember_password(ipc, hostbuf, portbuf,
+ fullname, password);
goto PWOK;
}
- printf("<< wrong password >>\n");
+ scr_printf("<< wrong password >>\n");
if (strlen(rc_password) > 0)
- logoff(0);
+ logoff(ipc, 2);
goto GSTA;
NEWUSR: if (strlen(rc_password) == 0) {
- printf("No record. Enter as new user? ");
+ scr_printf("'%s' not found.\n"
+ "Do you want to create a new account with this name? ",
+ fullname);
if (yesno() == 0)
goto GSTA;
}
- snprintf(aaa, sizeof aaa, "NEWU %s", fullname);
- serv_puts(aaa);
- serv_gets(aaa);
- if (aaa[0] != '2') {
- printf("%s\n", aaa);
+
+ r = CtdlIPCCreateUser(ipc, fullname, 1, aaa);
+ if (r / 100 != 2) {
+ scr_printf("%s\n", aaa);
goto GSTA;
}
- load_user_info(&aaa[4]);
+ load_user_info(aaa);
- while (set_password() != 0);;
+ while (set_password(ipc) != 0);
newnow = 1;
- enter_config(1);
+ enter_config(ipc, 1);
-PWOK:
+ PWOK:
/* Switch color support on or off if we're in user mode */
if (rc_ansi_color == 3) {
if (userflags & US_COLOR)
enable_color = 0;
}
- printf("%s\nAccess level: %d (%s)\n"
- "User #%ld / Login #%d",
- fullname, axlevel, axdefs[(int) axlevel],
- usernum, timescalled);
+ color(BRIGHT_WHITE);
+ scr_printf("\n%s\nAccess level: %d (%s)\n"
+ "User #%ld / Login #%d",
+ fullname, axlevel, axdefs[(int) axlevel],
+ usernum, timescalled);
if (lastcall > 0L) {
- printf(" / Last login: %s\n",
- asctime(localtime(&lastcall)) );
+ scr_printf(" / Last login: %s",
+ asctime(localtime(&lastcall)));
}
- printf("\n");
+ scr_printf("\n");
- serv_puts("CHEK");
- serv_gets(aaa);
- if (aaa[0] == '2') {
- b = extract_int(&aaa[4], 0);
+ r = CtdlIPCMiscCheck(ipc, &chek, aaa);
+ if (r / 100 == 2) {
+ b = chek.newmail;
if (b > 0) {
color(BRIGHT_RED);
if (b == 1)
- printf("*** You have a new private message in Mail>\n");
+ scr_printf("*** You have a new private message in Mail>\n");
if (b > 1)
- printf("*** You have %d new private messages in Mail>\n", b);
+ scr_printf("*** You have %d new private messages in Mail>\n", b);
color(DIM_WHITE);
+ if (strlen(rc_gotmail_cmd) > 0) {
+ system(rc_gotmail_cmd);
+ }
}
- if ((axlevel >= 6) && (extract_int(&aaa[4], 2) > 0)) {
- printf("*** Users need validation\n");
+ if ((axlevel >= 6) && (chek.needvalid > 0)) {
+ scr_printf("*** Users need validation\n");
}
- if (extract_int(&aaa[4], 1) > 0) {
- printf("*** Please register.\n");
- formout("register");
- entregis();
+ if (chek.needregis > 0) {
+ scr_printf("*** Please register.\n");
+ formout(ipc, "register");
+ entregis(ipc);
}
}
/* Make up some temporary filenames for use in various parts of the
* program. Don't mess with these once they've been set, because we
* will be unlinking them later on in the program and we don't
* want to delete something that we didn't create. */
- snprintf(temp, sizeof temp, tmpnam(NULL));
- snprintf(temp2, sizeof temp2, tmpnam(NULL));
- snprintf(tempdir, sizeof tempdir, tmpnam(NULL));
+ CtdlMakeTempFileName(temp, sizeof temp);
+ CtdlMakeTempFileName(temp2, sizeof temp2);
+ CtdlMakeTempFileName(tempdir, sizeof tempdir);
/* Get screen dimensions. First we go to a default of 80x24. Then
* we try to get the user's actual screen dimensions off the server.
*/
screenwidth = 80;
screenheight = 24;
- serv_puts("GETU");
- serv_gets(aaa);
- if (aaa[0] == '2') {
- screenwidth = extract_int(&aaa[4], 0);
- screenheight = extract_int(&aaa[4], 1);
+ r = CtdlIPCGetConfig(ipc, &myself, aaa);
+ if (r == 2) {
+ screenwidth = myself->USscreenwidth;
+ screenheight = myself->USscreenheight;
}
if (getenv("TERM") != NULL)
if (!strcmp(getenv("TERM"), "xterm")) {
check_screen_dims();
#endif
- set_floor_mode();
-
+ set_floor_mode(ipc);
/* Enter the lobby */
- dotgoto("_BASEROOM_", 1);
+ dotgoto(ipc, "_BASEROOM_", 1, 0);
-/* Main loop for the system... user is logged in. */
- strcpy(ugname, "");
- uglsn = 0L;
+ /* Main loop for the system... user is logged in. */
+ uglistsize = 0;
if (newnow == 1)
- readmsgs(3, 1, 5);
+ readmsgs(ipc, LastMessages, ReadForward, 5);
else
- readmsgs(1, 1, 0);
+ readmsgs(ipc, NewMessages, ReadForward, 0);
/* MAIN COMMAND LOOP */
do {
- mcmd = getcmd(argbuf); /* Get keyboard command */
+ mcmd = getcmd(ipc, argbuf); /* Get keyboard command */
#ifdef TIOCGWINSZ
check_screen_dims(); /* if xterm, get screen size */
if (termn8 == 0)
switch (mcmd) {
case 1:
- formout("help");
+ formout(ipc, "help");
break;
case 4:
- entmsg(0, 0);
+ entmsg(ipc, 0, ((userflags & US_EXTEDIT) ? 2 : 0));
break;
case 36:
- entmsg(0, 1);
+ entmsg(ipc, 0, 1);
break;
case 46:
- entmsg(0, 2);
+ entmsg(ipc, 0, 2);
break;
case 78:
- newprompt("What do you want your username to be? ", aaa, 32);
- snprintf(bbb, sizeof bbb, "ENT0 2|0|0|0|%s", aaa);
- serv_puts(bbb);
- serv_gets(aaa);
- if (strncmp("200", aaa, 3))
- printf("\n%s\n", aaa);
- else
- entmsg(0, 0);
- break;
- case 5:
- updatels();
- gotonext();
- break;
- case 47:
- updatelsa();
- gotonext();
- break;
- case 58:
- updatelsa();
- dotgoto("_MAIL_", 1);
+ {
+ /* Only m.author is used */
+ struct ctdlipcmessage m;
+ newprompt("What do you want your username to be? ",
+ m.author, USERNAME_SIZE - 1);
+ m.text = "";
+ r = CtdlIPCPostMessage(ipc, 2, &m, aaa);
+ if (r / 100 != 2)
+ scr_printf("%s\n", aaa);
+ else
+ entmsg(ipc, 0, 0);
+ }
+ break;
+ case 5: /* <G>oto */
+ updatels(ipc);
+ gotonext(ipc);
+ break;
+ case 47: /* <A>bandon */
+ if (!rc_alt_semantics) {
+ updatelsa(ipc);
+ }
+ gotonext(ipc);
+ break;
+ case 90: /* <.A>bandon */
+ if (!rc_alt_semantics)
+ updatelsa(ipc);
+ dotgoto(ipc, argbuf, 0, 0);
+ break;
+ case 58: /* <M>ail */
+ updatelsa(ipc);
+ dotgoto(ipc, "_MAIL_", 1, 0);
break;
case 20:
- updatels();
+ if (strlen(argbuf) > 0) {
+ updatels(ipc);
+ dotgoto(ipc, argbuf, 0, 0);
+ }
+ break;
case 52:
- dotgoto(argbuf, 0);
+ if (strlen(argbuf) > 0) {
+ if (rc_alt_semantics) {
+ updatelsa(ipc);
+ }
+ dotgoto(ipc, argbuf, 0, 0);
+ }
+ break;
+ case 95: /* what exactly is the numbering scheme supposed to be anyway? --Ford, there isn't one. -IO */
+ dotungoto(ipc, argbuf);
break;
case 10:
- readmsgs(0, 1, 0);
+ readmsgs(ipc, AllMessages, ReadForward, 0);
break;
case 9:
- readmsgs(3, 1, 5);
+ readmsgs(ipc, LastMessages, ReadForward, 5);
break;
case 13:
- readmsgs(1, 1, 0);
+ readmsgs(ipc, NewMessages, ReadForward, 0);
break;
case 11:
- readmsgs(0, (-1), 0);
+ readmsgs(ipc, AllMessages, ReadReverse, 0);
break;
case 12:
- readmsgs(2, (-1), 0);
+ readmsgs(ipc, OldMessages, ReadReverse, 0);
break;
case 71:
- readmsgs(3, 1, atoi(argbuf));
+ readmsgs(ipc, LastMessages, ReadForward,
+ atoi(argbuf));
break;
case 7:
- forget();
+ forget(ipc);
break;
case 18:
subshell();
break;
case 38:
- updatels();
- entroom();
+ updatels(ipc);
+ entroom(ipc);
break;
case 22:
- killroom();
+ killroom(ipc);
break;
case 32:
- userlist(argbuf);
+ userlist(ipc, argbuf);
break;
case 27:
- invite();
+ invite(ipc);
break;
case 28:
- kickout();
+ kickout(ipc);
break;
case 23:
- editthisroom();
+ editthisroom(ipc);
break;
case 14:
- roomdir();
+ roomdir(ipc);
break;
case 33:
- download(0);
+ download(ipc, 0);
break;
case 34:
- download(1);
+ download(ipc, 1);
break;
case 31:
- download(2);
+ download(ipc, 2);
break;
case 43:
- download(3);
+ download(ipc, 3);
break;
case 45:
- download(4);
+ download(ipc, 4);
break;
case 55:
- download(5);
+ download(ipc, 5);
break;
case 39:
- upload(0);
+ upload(ipc, 0);
break;
case 40:
- upload(1);
+ upload(ipc, 1);
break;
case 42:
- upload(2);
+ upload(ipc, 2);
break;
case 44:
- upload(3);
+ upload(ipc, 3);
break;
case 57:
- cli_upload();
+ cli_upload(ipc);
break;
case 16:
- ungoto();
+ ungoto(ipc);
break;
case 24:
- whoknows();
+ whoknows(ipc);
break;
case 26:
- validate();
+ validate(ipc);
break;
case 29:
- updatels();
- termn8 = 1;
- break;
case 30:
- updatels();
+ if (!rc_alt_semantics) {
+ updatels(ipc);
+ }
termn8 = 1;
break;
case 48:
- enterinfo();
+ enterinfo(ipc);
break;
case 49:
- readinfo();
+ readinfo(ipc);
break;
case 72:
- cli_image_upload("_userpic_");
+ cli_image_upload(ipc, "_userpic_");
break;
case 73:
- cli_image_upload("_roompic_");
+ cli_image_upload(ipc, "_roompic_");
break;
case 74:
snprintf(aaa, sizeof aaa, "_floorpic_|%d", curr_floor);
- cli_image_upload(aaa);
+ cli_image_upload(ipc, aaa);
break;
case 75:
- enternew("roomname", aaa, 20);
- snprintf(bbb, sizeof bbb, "RCHG %s", aaa);
- serv_puts(bbb);
- serv_gets(aaa);
- if (strncmp("200", aaa, 3))
- printf("\n%s\n", aaa);
+ enternew(ipc, "roomname", aaa, 20);
+ r = CtdlIPCChangeRoomname(ipc, aaa, bbb);
+ if (r / 100 != 2)
+ scr_printf("\n%s\n", bbb);
break;
case 76:
- enternew("hostname", aaa, 25);
- snprintf(bbb, sizeof bbb, "HCHG %s", aaa);
- serv_puts(bbb);
- serv_gets(aaa);
- if (strncmp("200", aaa, 3))
- printf("\n%s\n", aaa);
+ enternew(ipc, "hostname", aaa, 25);
+ r = CtdlIPCChangeHostname(ipc, aaa, bbb);
+ if (r / 100 != 2)
+ scr_printf("\n%s\n", bbb);
break;
case 77:
- enternew("username", aaa, 32);
- snprintf(bbb, sizeof bbb, "UCHG %s", aaa);
- serv_puts(bbb);
- serv_gets(aaa);
- if (strncmp("200", aaa, 3))
- printf("\n%s\n", aaa);
+ enternew(ipc, "username", aaa, 32);
+ r = CtdlIPCChangeUsername(ipc, aaa, bbb);
+ if (r / 100 != 2)
+ scr_printf("\n%s\n", bbb);
break;
case 35:
- set_password();
+ set_password(ipc);
break;
case 21:
if (argbuf[0] == 0)
strcpy(aaa, "?");
- display_help(argbuf);
+ display_help(ipc, argbuf);
break;
case 41:
- formout("register");
- entregis();
+ formout(ipc, "register");
+ entregis(ipc);
break;
case 15:
- printf("Are you sure (y/n)? ");
+ scr_printf("Are you sure (y/n)? ");
if (yesno() == 1) {
- updatels();
+ if (!rc_alt_semantics)
+ updatels(ipc);
a = 0;
termn8 = 1;
}
break;
case 85:
- printf("All users will be disconnected! "
- "Really terminate the server? ");
+ scr_printf("All users will be disconnected! "
+ "Really terminate the server? ");
if (yesno() == 1) {
- serv_puts("DOWN");
- serv_gets(aaa);
- printf("%s\n", &aaa[4]);
- if (aaa[0]=='2') {
- updatels();
+ if (!rc_alt_semantics)
+ updatels(ipc);
+ r = CtdlIPCTerminateServerNow(ipc, aaa);
+ scr_printf("%s\n", aaa);
+ if (r / 100 == 2) {
a = 0;
termn8 = 1;
}
break;
case 86:
- printf("Do you really want to schedule a "
- "server shutdown? ");
+ scr_printf("Do you really want to schedule a "
+ "server shutdown? ");
if (yesno() == 1) {
- serv_puts("SCDN 1");
- serv_gets(aaa);
- if (aaa[0]=='2') {
- if (atoi(&aaa[4])) {
- printf(
-"The Citadel server will terminate when all users are logged off.\n"
- );
- }
- else {
- printf(
-"The Citadel server will not terminate.\n"
- );
+ r = CtdlIPCTerminateServerScheduled(ipc, 1, aaa);
+ if (r / 100 == 2) {
+ if (atoi(aaa)) {
+ scr_printf(
+ "The Citadel server will terminate when all users are logged off.\n"
+ );
+ } else {
+ scr_printf(
+ "The Citadel server will not terminate.\n"
+ );
}
}
}
break;
case 87:
- network_config_management("listrecp",
- "Mailing list recipients");
+ network_config_management(ipc, "listrecp",
+ "Message-by-message mailing list recipients");
+ break;
+
+ case 94:
+ network_config_management(ipc, "digestrecp",
+ "Digest mailing list recipients");
break;
case 89:
- network_config_management("ignet_push_share",
- "Nodes with which we share this room");
+ network_config_management(ipc, "ignet_push_share",
+ "Nodes with which we share this room");
break;
case 88:
- do_ignet_configuration();
+ do_ignet_configuration(ipc);
+ break;
+
+ case 92:
+ do_filterlist_configuration(ipc);
break;
case 6:
- gotonext();
+ if (rc_alt_semantics) {
+ updatelsa(ipc);
+ }
+ gotonext(ipc);
break;
case 3:
- chatmode();
+ chatmode(ipc);
break;
case 2:
- if (server_is_local) {
- sttybbs(SB_RESTORE);
+ if (ipc->isLocal) {
+ screen_reset();
+ stty_ctdl(SB_RESTORE);
snprintf(aaa, sizeof aaa, "USERNAME=\042%s\042; export USERNAME;"
"exec ./subsystem %ld %d %d", fullname,
- usernum, screenwidth, axlevel);
+ usernum, screenwidth, axlevel);
ka_system(aaa);
- sttybbs(SB_NO_INTR);
+ stty_ctdl(SB_NO_INTR);
+ screen_set();
} else {
- printf("*** Can't run doors when server is not local.\n");
+ scr_printf("*** Can't run doors when server is not local.\n");
}
break;
case 17:
- who_is_online(0);
+ who_is_online(ipc, 0);
break;
case 79:
- who_is_online(1);
+ who_is_online(ipc, 1);
break;
+ case 91:
+ who_is_online(ipc, 2);
+ break;
+
case 80:
- do_system_configuration();
+ do_system_configuration(ipc);
break;
case 82:
- do_internet_configuration();
+ do_internet_configuration(ipc);
break;
case 83:
- check_message_base();
+ check_message_base(ipc);
break;
case 84:
- quiet_mode();
+ quiet_mode(ipc);
+ break;
+
+ case 93:
+ stealth_mode(ipc);
break;
case 50:
- enter_config(2);
+ enter_config(ipc, 2);
break;
case 37:
- enter_config(0);
- set_floor_mode();
+ enter_config(ipc, 0);
+ set_floor_mode(ipc);
break;
case 59:
- enter_config(3);
- set_floor_mode();
+ enter_config(ipc, 3);
+ set_floor_mode(ipc);
break;
case 60:
- gotofloor(argbuf, GF_GOTO);
+ gotofloor(ipc, argbuf, GF_GOTO);
break;
case 61:
- gotofloor(argbuf, GF_SKIP);
+ gotofloor(ipc, argbuf, GF_SKIP);
break;
case 62:
- forget_this_floor();
+ forget_this_floor(ipc);
break;
case 63:
- create_floor();
+ create_floor(ipc);
break;
case 64:
- edit_floor();
+ edit_floor(ipc);
break;
case 65:
- kill_floor();
+ kill_floor(ipc);
break;
case 66:
- enter_bio();
+ enter_bio(ipc);
break;
case 67:
- read_bio();
+ read_bio(ipc);
break;
case 25:
- edituser();
+ edituser(ipc, 25);
+ break;
+
+ case 96:
+ edituser(ipc, 96);
break;
case 8:
- knrooms(floor_mode);
- printf("\n");
+ knrooms(ipc, floor_mode);
+ scr_printf("\n");
break;
case 68:
- knrooms(2);
- printf("\n");
+ knrooms(ipc, 2);
+ scr_printf("\n");
break;
case 69:
- misc_server_cmd(argbuf);
+ misc_server_cmd(ipc, argbuf);
break;
case 70:
- edit_system_message(argbuf);
+ edit_system_message(ipc, argbuf);
break;
case 19:
- listzrooms();
- printf("\n");
+ listzrooms(ipc);
+ scr_printf("\n");
break;
case 51:
- deletefile();
+ deletefile(ipc);
break;
case 53:
- netsendfile();
+ netsendfile(ipc);
break;
case 54:
- movefile();
+ movefile(ipc);
break;
case 56:
- page_user();
- break;
-
+ page_user(ipc);
+ break;
+
+ default: /* allow some math on the command */
+ /* commands 100... to 100+MAX_EDITORS-1 will
+ call the appropriate editor... in other
+ words, command numbers 100+ will match
+ the citadel.rc keys editor0, editor1, etc.*/
+ if (mcmd >= 100 && mcmd < (100+MAX_EDITORS))
+ {
+ /* entmsg mode >=2 select editor */
+ entmsg(ipc, 0, mcmd - 100 + 2);
+ break;
+ }
} /* end switch */
} while (termn8 == 0);
-TERMN8: printf("%s logged out.\n", fullname);
+TERMN8: scr_printf("%s logged out.", fullname);
+ termn8 = 0;
+ color(ORIGINAL_PAIR);
+ scr_printf("\n");
while (march != NULL) {
remove_march(march->march_name, 0);
}
if (mcmd == 30) {
- printf("\n\nType 'off' to disconnect, or next user...\n");
+ sln_printf("\n\nType 'off' to disconnect, or next user...\n");
}
- snprintf(aaa, sizeof aaa, "LOUT");
- serv_puts(aaa);
- serv_gets(aaa);
+ CtdlIPCLogout(ipc);
if ((mcmd == 29) || (mcmd == 15)) {
- formout("goodbye");
- logoff(0);
+ screen_delete();
+ stty_ctdl(SB_RESTORE);
+ formout(ipc, "goodbye");
+ logoff(ipc, 0);
}
goto GSTA;