/*
- * Citadel/UX
- *
- * citadel.c - Main source file.
* $Id$
+ *
+ * Main source module for the client program.
*/
#include "sysdep.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
-#include <time.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
#include <limits.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "ipc.h"
#include "client_chat.h"
#include "client_passwords.h"
-#include "client_icq.h"
#include "citadel_decls.h"
#include "tools.h"
+#include "acconfig.h"
+#include "client_crypto.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#endif
+#include "screen.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)
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[256]; /* path to external editor */
-char printcmd[256]; /* print command */
+char editor_path[SIZ]; /* path to external editor */
+char printcmd[SIZ]; /* print command */
int editor_pid = (-1);
char fullname[32];
jmp_buf nextbuf;
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 */
int posted;
unsigned userflags;
long usernum = 0L; /* user number */
+time_t lastcall = 0L; /* Date/time of previous login */
char newnow;
long highest_msg_read; /* used for <A>bandon room cmd */
long maxmsgnum; /* used for <G>oto */
char have_xterm = 0; /* are we running on an xterm? */
char rc_username[32];
char rc_password[32];
-char hostbuf[256];
-char portbuf[256];
+char hostbuf[SIZ];
+char portbuf[SIZ];
char rc_floor_mode;
char floor_mode;
char curr_floor = 0; /* number of current floor */
-char floorlist[128][256]; /* names of floors */
+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 */
+
+extern int rc_ansi_color; /* ansi color value from citadel.rc */
/*
* here is our 'clean up gracefully and exit' routine
*/
void logoff(int code)
{
+ int lp;
if (editor_pid > 0) { /* kill the editor if it's running */
kill(editor_pid, SIGHUP);
}
+
+ /* Free the ungoto list */
+ for (lp = 0; lp < uglistsize; lp++)
+ free (uglist[lp]);
+
/* shut down the server... but not if the logoff code is 3, because
* that means we're exiting because we already lost the server
*/
* now clean up various things
*/
+ screen_delete();
+
unlink(temp);
unlink(temp2);
nukedir(tempdir);
-/*
- * We handle "next" and "stop" much differently than in earlier versions.
- * The signal catching routine simply sets a flag and returns.
- */
-void sighandler(int which_sig)
-{
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- sigcaught = which_sig;
- return;
-}
-
-
/*
* signal catching function for hangups...
*/
void formout(char *name)
{ /* display a file */
- char cmd[256];
+ 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]);
+ scr_printf("%s\n", &cmd[4]);
return;
}
- fmout(screenwidth, NULL,
+ fmout(screenwidth, NULL, NULL,
((userflags & US_PAGINATOR) ? 1 : 0),
screenheight, 1, 1);
}
void userlist(char *patn)
{
- char buf[256];
- char fl[256];
+ char buf[SIZ];
+ char fl[SIZ];
struct tm *tmbuf;
time_t lc;
pprintf("%s\n", &buf[4]);
return;
}
- sigcaught = 0;
- sttybbs(SB_YES_INTR);
pprintf(" User Name Num L LastCall Calls Posts\n");
pprintf("------------------------- ----- - ---------- ----- -----\n");
while (serv_gets(buf), strcmp(buf, "000")) {
}
}
- sttybbs(SB_NO_INTR);
pprintf("\n");
}
posted = extract_int(params, 3);
userflags = extract_int(params, 4);
usernum = extract_long(params, 5);
+ lastcall = extract_long(params, 6);
}
/*
* jump directly to a room
*/
-void dotgoto(char *towhere, int display_name)
+void dotgoto(char *towhere, int display_name, int fromungoto)
{
- char aaa[256], bbb[256], psearch[256];
+ char aaa[SIZ], bbb[SIZ], psearch[SIZ];
static long ls = 0L;
- int newmailcount;
+ int newmailcount = 0;
static int oldmailcount = (-1);
int partial_match, best_match;
char from_floor;
+ int ugpos = uglistsize;
/* store ungoto information */
- strcpy(ugname, room_name);
- uglsn = ls;
-
+ if (fromungoto == 0)
+ {
+ if (uglistsize >= (UGLISTLEN-1))
+ { /* sloppy slide them all down, hey it's the client, who cares. :-) */
+ 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);
express_msgs = 1;
}
if (!strncmp(aaa, "54", 2)) {
- printf("Wrong password.\n");
+ scr_printf("Wrong password.\n");
return;
}
/*
}
}
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);
express_msgs = 1;
}
if (aaa[0] != '2') {
- printf("%s\n", aaa);
+ scr_printf("%s\n", aaa);
return;
}
extract(room_name, &aaa[4], 0);
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]);
+ 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 ", extract_int(&aaa[4], 1));
color(DIM_WHITE);
- printf("new of ");
+ scr_printf("new of ");
color(BRIGHT_YELLOW);
- printf("%d ", extract_int(&aaa[4], 2));
+ scr_printf("%d ", extract_int(&aaa[4], 2));
color(DIM_WHITE);
- printf("messages.\n");
+ scr_printf("messages.\n");
}
highest_msg_read = extract_int(&aaa[4], 6);
maxmsgnum = extract_int(&aaa[4], 5);
newmailcount = extract_int(&aaa[4], 9);
if ((oldmailcount >= 0) && (newmailcount > oldmailcount)) {
color(BRIGHT_RED);
- printf("*** You have new mail\n");
+ scr_printf("*** You have new mail\n");
color(DIM_WHITE);
}
oldmailcount = newmailcount;
+ status_line(serv_info.serv_humannode, serv_info.serv_bbs_city,
+ room_name, secure, newmailcount);
+ } else {
+ status_line(serv_info.serv_humannode, serv_info.serv_bbs_city,
+ room_name, secure, -1);
}
}
*/
void gotonext(void)
{
- char buf[256];
+ char buf[SIZ];
struct march *mptr, *mptr2;
char next_room[ROOMNAMELEN];
strcpy(next_room, "_BASEROOM_");
}
remove_march(next_room, 0);
- dotgoto(next_room, 1);
+ dotgoto(next_room, 1, 0);
}
/*
*/
void forget_all_rooms_on(int ffloor)
{
- char buf[256];
+ char buf[SIZ];
struct march *flist, *fptr;
- printf("Forgetting all rooms on %s...\r", &floorlist[ffloor][0]);
- fflush(stdout);
+ scr_printf("Forgetting all rooms on %s...\r", &floorlist[ffloor][0]);
+ scr_flush();
snprintf(buf, sizeof buf, "LKRA %d", ffloor);
serv_puts(buf);
serv_gets(buf);
if (buf[0] != '1') {
- printf("%-72s\n", &buf[4]);
+ scr_printf("%-72s\n", &buf[4]);
return;
}
flist = NULL;
flist = flist->next;
free(fptr);
}
- printf("%-72s\r", "");
+ scr_printf("%-72s\r", "");
}
if (mode == GF_GOTO) { /* <;G>oto mode */
updatels();
- dotgoto(towhere, 1);
+ dotgoto(towhere, 1, 0);
}
if (mode == GF_SKIP) { /* <;S>kip mode */
- dotgoto(towhere, 1);
+ dotgoto(towhere, 1, 0);
remove_march("_FLOOR_", floor_being_left);
}
if (mode == GF_ZAP) { /* <;Z>ap mode */
- dotgoto(towhere, 1);
+ dotgoto(towhere, 1, 0);
remove_march("_FLOOR_", floor_being_left);
forget_all_rooms_on(floor_being_left);
}
{
int a, tofloor;
struct march *mptr;
- char buf[256], targ[256];
+ char buf[SIZ], targ[SIZ];
if (floorlist[0][0] == 0)
load_floorlist();
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 (strlen(targ) > 0) {
gf_toroom(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]);
}
}
{
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? ",
+ scr_printf("Are you sure you want to forget all rooms on %s? ",
&floorlist[(int) curr_floor][0]);
if (yesno() == 0)
return;
/*
* Figure out the physical screen dimensions, if we can
+ * WARNING: this is now called from a signal handler!
*/
void check_screen_dims(void)
{
unsigned short ypixels; /* pixels */
} xwinsz;
+ if (scr_set_windowsize())
+ return;
+
if (have_xterm) { /* dynamically size screen if on an xterm */
if (ioctl(0, TIOCGWINSZ, &xwinsz) == 0) {
if (xwinsz.height)
{
char pass1[20];
char pass2[20];
- char buf[256];
+ char buf[SIZ];
if (strlen(rc_password) > 0) {
strcpy(pass1, rc_password);
snprintf(buf, sizeof buf, "SETP %s", pass1);
serv_puts(buf);
serv_gets(buf);
- printf("%s\n", &buf[4]);
+ scr_printf("%s\n", &buf[4]);
offer_to_remember_password(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(void)
+void get_serv_info(char *supplied_hostname)
{
char buf[512];
snprintf(buf, sizeof buf, "IDEN %d|%d|%d|%s|",
SERVER_TYPE, 0, REV_LEVEL,
(server_is_local ? "local" : CITADEL));
- locate_host(&buf[strlen(buf)]); /* append to the end */
+
+ /* Append a hostname */
+ if (supplied_hostname != NULL) {
+ strcat(buf, supplied_hostname);
+ }
+ else {
+ locate_host(&buf[strlen(buf)]); /* append to the end */
+ }
+
serv_puts(buf);
serv_gets(buf); /* we don't care about the result code */
}
*/
void who_is_online(int longlist)
{
- char buf[128], username[128], roomname[128], fromhost[128],
- flags[128];
- char tbuf[128], clientsoft[128];
+ 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];
time_t timenow = 0;
time_t idletime, idlehours, idlemins, idlesecs;
int last_session = (-1);
+ int skipidle = 0;
+
+ if (longlist == 2)
+ {
+ longlist = 0;
+ skipidle = 1;
+ }
+
+ serv_puts("TIME");
+ serv_gets(tbuf);
+ if (tbuf[0] == '2') {
+ timenow = extract_long(&tbuf[4], 0);
+ }
+ else {
+ time(&timenow);
+ }
- if (longlist) {
- serv_puts("TIME");
- serv_gets(tbuf);
- if (tbuf[0] == '2') {
- timenow = extract_long(&tbuf[4], 0);
- } else {
- time(&timenow);
- }
- } else {
+ if (!longlist) {
color(BRIGHT_WHITE);
pprintf("FLG ### User Name Room From host\n");
color(DIM_WHITE);
serv_gets(buf);
if (buf[0] == '1') {
while (serv_gets(buf), strcmp(buf, "000")) {
+ int isidle = 0;
extract(username, buf, 1);
extract(roomname, buf, 2);
extract(fromhost, buf, 3);
extract(clientsoft, buf, 4);
extract(flags, buf, 7);
+ idletime = timenow - extract_long(buf, 5);
+ idlehours = idletime / 3600;
+ idlemins = (idletime - (idlehours * 3600)) / 60;
+ idlesecs = (idletime - (idlehours * 3600) - (idlemins * 60));
+
+ if (idletime > 900) {
+ while (strlen(roomname) < 20) {
+ strcat(roomname, " ");
+ }
+ strcpy(&roomname[14], "[idle]");
+ if (skipidle)
+ isidle = 1;
+ }
+
if (longlist) {
- idletime = timenow - extract_long(buf, 5);
- idlehours = idletime / 3600;
- idlemins = (idletime - (idlehours * 3600)) / 60;
- idlesecs = (idletime - (idlehours * 3600) - (idlemins * 60));
- pprintf("\nFlags: %-3s Sess# %-3d Name: %-25s Room: %s\n",
- flags, extract_int(buf, 0), username, roomname);
- pprintf("from <%s> using <%s>, idle %ld:%02ld:%02ld\n",
- fromhost, clientsoft,
- (long) idlehours, (long) idlemins, (long) idlesecs);
- } 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));
+ extract(actual_user, buf, 8);
+ extract(actual_room, buf, 9);
+ extract(actual_host, buf, 10);
+
+ pprintf(" Flags: %s\n", flags);
+ pprintf("Session: %d\n", extract_int(buf, 0));
+ pprintf(" Name: %s\n", username);
+ pprintf("In room: %s\n", roomname);
+ pprintf(" Host: %s\n", fromhost);
+ pprintf(" Client: %s\n", clientsoft);
+ pprintf(" Idle: %ld:%02ld:%02ld\n",
+ (long) idlehours,
+ (long) idlemins,
+ (long) idlesecs);
+
+ if ( (strlen(actual_user)+strlen(actual_room)+strlen(actual_host)) > 0) {
+ pprintf("(really ");
+ if (strlen(actual_user)>0) pprintf("<%s> ", actual_user);
+ if (strlen(actual_room)>0) pprintf("in <%s> ", actual_room);
+ if (strlen(actual_host)>0) pprintf("from <%s> ", actual_host);
+ pprintf(")\n");
}
- last_session = extract_int(buf, 0);
- color(BRIGHT_CYAN);
- pprintf("%-25s ", username);
- color(BRIGHT_MAGENTA);
- roomname[20] = 0;
- pprintf("%-20s ", roomname);
- color(BRIGHT_CYAN);
- pprintf("%-24s\n", fromhost);
- color(DIM_WHITE);
+ pprintf("\n");
+
+ } else {
+ if (isidle == 0) {
+ if (extract_int(buf, 0) == last_session) {
+ pprintf(" ");
+ } else {
+ color(BRIGHT_MAGENTA);
+ pprintf("%-3s ", flags);
+ color(DIM_WHITE);
+ pprintf("%-3d ", extract_int(buf, 0));
+ }
+ 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);
+ }
}
}
}
newprompt(bbb, buf, maxlen);
}
+
+
+int shift(int argc, char **argv, int start, int count) {
+ int i;
+
+ for (i=start; i<(argc-count); ++i) {
+ argv[i] = argv[i+count];
+ }
+ argc = argc - count;
+ return argc;
+}
+
/*
* main
*/
int a, b, mcmd;
char aaa[100], bbb[100];/* general purpose variables */
char argbuf[32]; /* command line buf */
- volatile int termn8 = 0;
+ char nonce[NONCE_SIZE];
+ char *telnet_client_host = NULL;
+ char *sptr, *sptr2; /* USed to extract the nonce */
+ char hexstring[MD5_HEXSTRING_SIZE];
int stored_password = 0;
- char password[256];
+ char password[SIZ];
+
+ /* Permissions sanity check - don't run citadel setuid/setgid */
+ if (getuid() != geteuid()) {
+ err_printf("Please do not run citadel setuid!\n");
+ logoff(3);
+ } else if (getgid() != getegid()) {
+ err_printf("Please do not run citadel setgid!\n");
+ logoff(3);
+ }
sttybbs(SB_SAVE); /* Store the old terminal parameters */
load_command_set(); /* parse the citadel.rc file */
sttybbs(SB_NO_INTR); /* Install the new ones */
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
signal(SIGHUP, dropcarr); /* Cleanup gracefully if carrier is dropped */
signal(SIGTERM, dropcarr); /* Cleanup gracefully if terminated */
signal(SIGCONT, catch_sigcont); /* Catch SIGCONT so we can reset terminal */
- printf("Attaching to server... \r");
- fflush(stdout);
- attach_to_server(argc, argv, hostbuf, portbuf);
+#ifdef HAVE_OPENSSL
+ arg_encrypt = RC_DEFAULT;
+#endif
+#ifdef HAVE_CURSES_H
+ arg_screen = RC_DEFAULT;
+#endif
- send_ansi_detect();
+ /*
+ * Handle command line options as if we were called like /bin/login
+ * (i.e. from in.telnetd)
+ */
+ for (a=0; a<argc; ++a) {
+ if ((argc > a+1) && (!strcmp(argv[a], "-h")) ) {
+ 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")) {
+#ifdef HAVE_CURSES_H
+ arg_screen = RC_NO;
+#endif
+ argc = shift(argc, argv, a, 1);
+ }
+ if (!strcmp(argv[a], "-S")) {
+#ifdef HAVE_CURSES_H
+ 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);
+ }
+
+ /*
+ * Drop privileges if necessary. We stat
+ * citadel.config to get the uid/gid since it's
+ * guaranteed to have the uid/gid we want.
+ */
+ if (!getuid() || !getgid()) {
+ if (stat(BBSDIR "/citadel.config", &st) < 0) {
+ perror("couldn't stat citadel.config");
+ logoff(3);
+ }
+ if (!getgid() && (setgid(st.st_gid) < 0)) {
+ perror("couldn't change gid");
+ logoff(3);
+ }
+ if (!getuid() && (setuid(st.st_uid) < 0)) {
+ perror("couldn't change uid");
+ logoff(3);
+ }
+ /*
+ scr_printf("Privileges changed to uid %d gid %d\n",
+ getuid(), getgid());
+ */
+ }
+ argc = shift(argc, argv, a, 1);
+ }
+ }
+
+ screen_new();
+
+ sln_printf("Attaching to server... \r");
+ sln_flush();
+ attach_to_server(argc, argv, hostbuf, portbuf);
serv_gets(aaa);
if (aaa[0] != '2') {
- printf("%s\n", &aaa[4]);
+ scr_printf("%s\n", &aaa[4]);
logoff(atoi(aaa));
}
- get_serv_info();
- look_for_ansi();
- cls(0);
- color(7);
+/* 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';
+ }
+ else
+ {
+ if ((sptr2 = strchr(sptr, '>')) == NULL)
+ {
+ nonce[0] = '\0';
+ }
+ else
+ {
+ sptr2++;
+ *sptr2 = '\0';
+ strncpy(nonce, sptr, NONCE_SIZE);
+ }
+ }
+
+ get_serv_info(telnet_client_host);
+
+ scr_printf("%-24s\n%s\n%s\n", serv_info.serv_software, serv_info.serv_humannode,
+ serv_info.serv_bbs_city);
+ scr_flush();
+
+ secure = starttls();
+ status_line(serv_info.serv_humannode, serv_info.serv_bbs_city, 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;
-
- printf(" pause next stop\n");
- printf(" ctrl-s ctrl-o ctrl-c\n\n");
+
+ scr_printf(" pause next stop\n");
+ scr_printf(" ctrl-s ctrl-o ctrl-c\n\n");
formout("hello"); /* print the opening greeting */
- printf("\n");
+ scr_printf("\n");
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) {
- sprintf(aaa, "USER %s", fullname);
+ snprintf(aaa, sizeof(aaa)-1, "USER %s", fullname);
serv_puts(aaa);
serv_gets(aaa);
- sprintf(aaa, "PASS %s", password);
+ if (nonce[0])
+ {
+ snprintf(aaa, sizeof aaa, "PAS2 %s", make_apop_string(password, nonce, hexstring, sizeof hexstring));
+ }
+ else /* Else no APOP */
+ {
+ snprintf(aaa, sizeof(aaa)-1, "PASS %s", password);
+ }
+
serv_puts(aaa);
serv_gets(aaa);
if (aaa[0] == '2') {
}
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"))
newprompt("\rPlease enter your password: ", password, -19);
}
strproc(password);
- snprintf(aaa, sizeof aaa, "PASS %s", password);
+
+ if (nonce[0])
+ {
+ snprintf(aaa, sizeof aaa, "PAS2 %s", make_apop_string(password, nonce, hexstring, sizeof hexstring));
+ }
+ else /* Else no APOP */
+ {
+ snprintf(aaa, sizeof aaa, "PASS %s", password);
+ }
+
serv_puts(aaa);
serv_gets(aaa);
if (aaa[0] == '2') {
fullname, password);
goto PWOK;
}
- printf("<< wrong password >>\n");
+ scr_printf("<< wrong password >>\n");
if (strlen(rc_password) > 0)
logoff(0);
goto GSTA;
NEWUSR: if (strlen(rc_password) == 0) {
- printf("No record. Enter as new user? ");
+ scr_printf("No record. Enter as new user? ");
if (yesno() == 0)
goto GSTA;
}
serv_puts(aaa);
serv_gets(aaa);
if (aaa[0] != '2') {
- printf("%s\n", aaa);
+ scr_printf("%s\n", aaa);
goto GSTA;
}
load_user_info(&aaa[4]);
enter_config(1);
+PWOK:
+ /* Switch color support on or off if we're in user mode */
+ if (rc_ansi_color == 3) {
+ if (userflags & US_COLOR)
+ enable_color = 1;
+ else
+ enable_color = 0;
+ }
-PWOK: printf("%s\nAccess level: %d (%s)\nUser #%ld / Call #%d\n",
- fullname, axlevel, axdefs[(int) axlevel],
- usernum, timescalled);
+ scr_printf("%s\nAccess level: %d (%s)\n"
+ "User #%ld / Login #%d",
+ fullname, axlevel, axdefs[(int) axlevel],
+ usernum, timescalled);
+ if (lastcall > 0L) {
+ scr_printf(" / Last login: %s\n",
+ asctime(localtime(&lastcall)) );
+ }
+ scr_printf("\n");
serv_puts("CHEK");
serv_gets(aaa);
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 ((axlevel >= 6) && (extract_int(&aaa[4], 2) > 0)) {
- printf("*** Users need validation\n");
+ scr_printf("*** Users need validation\n");
}
if (extract_int(&aaa[4], 1) > 0) {
- printf("*** Please register.\n");
+ scr_printf("*** Please register.\n");
formout("register");
entregis();
}
/* Enter the lobby */
- dotgoto("_BASEROOM_", 1);
+ dotgoto("_BASEROOM_", 1, 0);
/* Main loop for the system... user is logged in. */
- strcpy(ugname, "");
- uglsn = 0L;
+ uglistsize = 0;
if (newnow == 1)
readmsgs(3, 1, 5);
else
readmsgs(1, 1, 0);
- do { /* MAIN LOOP OF PROGRAM */
-
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- mcmd = getcmd(argbuf);
+ /* MAIN COMMAND LOOP */
+ do {
+ mcmd = getcmd(argbuf); /* Get keyboard command */
#ifdef TIOCGWINSZ
- check_screen_dims();
+ check_screen_dims(); /* if xterm, get screen size */
#endif
if (termn8 == 0)
serv_puts(bbb);
serv_gets(aaa);
if (strncmp("200", aaa, 3))
- printf("\n%s\n", aaa);
+ scr_printf("\n%s\n", aaa);
else
entmsg(0, 0);
break;
gotonext();
break;
case 47:
- updatelsa();
+ if (!rc_alt_semantics)
+ updatelsa();
gotonext();
break;
+ case 90:
+ if (!rc_alt_semantics)
+ updatelsa();
+ dotgoto(argbuf, 0, 0);
+ break;
case 58:
updatelsa();
- dotgoto("_MAIL_", 1);
+ dotgoto("_MAIL_", 1, 0);
break;
case 20:
updatels();
+ dotgoto(argbuf, 0, 0);
+ break;
case 52:
- dotgoto(argbuf, 0);
+ if (rc_alt_semantics)
+ updatelsa();
+ dotgoto(argbuf, 0, 0);
break;
case 10:
readmsgs(0, 1, 0);
validate();
break;
case 29:
- updatels();
+ if (!rc_alt_semantics)
+ updatels();
termn8 = 1;
break;
case 30:
- updatels();
+ if (!rc_alt_semantics)
+ updatels();
termn8 = 1;
break;
case 48:
serv_puts(bbb);
serv_gets(aaa);
if (strncmp("200", aaa, 3))
- printf("\n%s\n", aaa);
+ scr_printf("\n%s\n", aaa);
break;
case 76:
enternew("hostname", aaa, 25);
serv_puts(bbb);
serv_gets(aaa);
if (strncmp("200", aaa, 3))
- printf("\n%s\n", aaa);
+ scr_printf("\n%s\n", aaa);
break;
case 77:
enternew("username", aaa, 32);
serv_puts(bbb);
serv_gets(aaa);
if (strncmp("200", aaa, 3))
- printf("\n%s\n", aaa);
+ scr_printf("\n%s\n", aaa);
break;
case 35:
break;
case 15:
- printf("Are you sure (y/n)? ");
+ scr_printf("Are you sure (y/n)? ");
if (yesno() == 1) {
updatels();
a = 0;
}
break;
+ case 85:
+ scr_printf("All users will be disconnected! "
+ "Really terminate the server? ");
+ if (yesno() == 1) {
+ serv_puts("DOWN");
+ serv_gets(aaa);
+ scr_printf("%s\n", &aaa[4]);
+ if (aaa[0]=='2') {
+ updatels();
+ a = 0;
+ termn8 = 1;
+ }
+ }
+ break;
+
+ case 86:
+ 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])) {
+ 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");
+ break;
+
+ case 89:
+ network_config_management("ignet_push_share",
+ "Nodes with which we share this room");
+ break;
+
+ case 88:
+ do_ignet_configuration();
+ break;
+
+ case 92:
+ do_filterlist_configuration();
+ break;
+
case 6:
+ if (rc_alt_semantics)
+ updatelsa();
gotonext();
break;
case 2:
if (server_is_local) {
+ screen_reset();
sttybbs(SB_RESTORE);
snprintf(aaa, sizeof aaa, "USERNAME=\042%s\042; export USERNAME;"
"exec ./subsystem %ld %d %d", fullname,
usernum, screenwidth, axlevel);
ka_system(aaa);
sttybbs(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;
who_is_online(1);
break;
+ case 91:
+ who_is_online(2);
+ break;
+
case 80:
do_system_configuration();
break;
case 8:
knrooms(floor_mode);
- printf("\n");
+ scr_printf("\n");
break;
case 68:
knrooms(2);
- printf("\n");
+ scr_printf("\n");
break;
case 69:
case 19:
listzrooms();
- printf("\n");
+ scr_printf("\n");
break;
case 51:
page_user();
break;
- case 81:
- setup_icq();
- break;
-
} /* end switch */
} while (termn8 == 0);
- TERMN8:printf("%s logged out.\n", fullname);
- while (march != NULL)
+TERMN8: scr_printf("%s logged out.\n", fullname);
+ while (march != NULL) {
remove_march(march->march_name, 0);
- if (mcmd == 30)
- printf("\n\nType 'off' to hang up, or next user...\n");
+ }
+ if (mcmd == 30) {
+ sln_printf("\n\nType 'off' to disconnect, or next user...\n");
+ }
snprintf(aaa, sizeof aaa, "LOUT");
serv_puts(aaa);
serv_gets(aaa);
+ screen_delete();
+ sttybbs(SB_RESTORE);
if ((mcmd == 29) || (mcmd == 15)) {
formout("goodbye");
logoff(0);
}
goto GSTA;
-} /* end main() */
+} /* end main() */