From: Michael Hampton Date: Mon, 16 Feb 2004 15:06:45 +0000 (+0000) Subject: * Add specific error codes for every command on the wire protocol, so that X-Git-Tag: v7.86~5613 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=6ca67305d6d449ad5d8ced6e38e80d7e4dc955ab * Add specific error codes for every command on the wire protocol, so that clients can more easily determine what went wrong. Partially updated session.txt (will finish it later). This lets clients more easily determine what, if anything, went wrong with a particular command. --- diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 63f518f2d..9677f66dd 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,10 @@ $Log$ + Revision 614.31 2004/02/16 15:06:44 error + * Add specific error codes for every command on the wire protocol, so that + clients can more easily determine what went wrong. Partially updated + session.txt (will finish it later). This lets clients more easily + determine what, if anything, went wrong with a particular command. + Revision 614.30 2004/02/15 06:06:49 ajc * More work on IMAP TLS. Still not working correctly. :( Added in support for server-side certificates. Now instead of failing it hangs. @@ -5328,4 +5334,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import - diff --git a/citadel/citserver.c b/citadel/citserver.c index 887b4ae39..327659b77 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -473,7 +473,7 @@ void cmd_iden(char *argbuf) int do_lookup = 0; if (num_parms(argbuf)<4) { - cprintf("%d usage error\n",ERROR); + cprintf("%d usage error\n", ERROR + ILLEGAL_VALUE); return; } @@ -552,14 +552,14 @@ void cmd_mesg(char *mname) phree(dirs[1]); if (strlen(targ)==0) { - cprintf("%d '%s' not found.\n",ERROR,mname); + cprintf("%d '%s' not found.\n",ERROR + FILE_NOT_FOUND, mname); return; } mfp = fopen(targ,"r"); if (mfp==NULL) { cprintf("%d Cannot open '%s': %s\n", - ERROR,targ,strerror(errno)); + ERROR + INTERNAL_ERROR, targ, strerror(errno)); return; } cprintf("%d %s\n",LISTING_FOLLOWS,buf); @@ -608,7 +608,7 @@ void cmd_emsg(char *mname) mfp = fopen(targ,"w"); if (mfp==NULL) { cprintf("%d Cannot open '%s': %s\n", - ERROR,targ,strerror(errno)); + ERROR + INTERNAL_ERROR, targ, strerror(errno)); return; } cprintf("%d %s\n", SEND_LISTING, targ); @@ -656,14 +656,14 @@ int CtdlAccessCheck(int required_level) { if (CC->internal_pgm) return(0); if (required_level >= ac_internal) { cprintf("%d This is not a user-level command.\n", - ERROR+HIGHER_ACCESS_REQUIRED); + ERROR + HIGHER_ACCESS_REQUIRED); return(-1); } if (CC->user.axlevel >= 6) return(0); if (required_level >= ac_aide) { cprintf("%d This command requires Aide access.\n", - ERROR+HIGHER_ACCESS_REQUIRED); + ERROR + HIGHER_ACCESS_REQUIRED); return(-1); } @@ -676,7 +676,7 @@ int CtdlAccessCheck(int required_level) { if (CC->logged_in) return(0); if (required_level >= ac_logged_in) { - cprintf("%d Not logged in.\n", ERROR+NOT_LOGGED_IN); + cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN); return(-1); } @@ -698,7 +698,7 @@ void cmd_term(char *cmdbuf) session_num = extract_int(cmdbuf, 0); if (session_num == CC->cs_pid) { - cprintf("%d You can't kill your own session.\n", ERROR); + cprintf("%d You can't kill your own session.\n", ERROR + ILLEGAL_VALUE); return; } @@ -729,7 +729,7 @@ void cmd_term(char *cmdbuf) } } else { - cprintf("%d No such session.\n", ERROR); + cprintf("%d No such session.\n", ERROR + ILLEGAL_VALUE); } } @@ -768,7 +768,7 @@ void cmd_ipgm(char *argbuf) */ if (!CC->is_local_socket) { sleep(5); - cprintf("%d Authentication failed.\n",ERROR); + cprintf("%d Authentication failed.\n", ERROR + PASSWORD_REQUIRED); } else if (secret == config.c_ipgm_secret) { CC->internal_pgm = 1; @@ -778,7 +778,7 @@ void cmd_ipgm(char *argbuf) } else { sleep(5); - cprintf("%d Authentication failed.\n",ERROR); + cprintf("%d Authentication failed.\n", ERROR + PASSWORD_REQUIRED); lprintf(3, "Warning: ipgm authentication failed.\n"); CC->kill_me = 1; } @@ -914,7 +914,7 @@ void citproto_begin_session() { if (CC->nologin==1) { cprintf("%d %s: Too many users are already online " "(maximum is %d)\n", - ERROR+MAX_SESSIONS_EXCEEDED, + ERROR + MAX_SESSIONS_EXCEEDED, config.c_nodename, config.c_maxsessions); } else { @@ -1311,7 +1311,7 @@ void do_command_loop(void) { #endif else if (!DLoader_Exec_Cmd(cmdbuf)) { - cprintf("%d Unrecognized or unsupported command.\n", ERROR); + cprintf("%d Unrecognized or unsupported command.\n", ERROR + CMD_NOT_SUPPORTED); } /* Run any after-each-command outines registered by modules */ diff --git a/citadel/file_ops.c b/citadel/file_ops.c index 7a6a771cd..9942479c3 100644 --- a/citadel/file_ops.c +++ b/citadel/file_ops.c @@ -195,7 +195,7 @@ void cmd_movf(char *cmdbuf) } if (getroom(&qrbuf, newroom) != 0) { - cprintf("%d '%s' does not exist.\n", ERROR, newroom); + cprintf("%d '%s' does not exist.\n", ERROR + ROOM_NOT_FOUND, newroom); return; } if ((qrbuf.QRflags & QR_DIRECTORY) == 0) { @@ -206,7 +206,7 @@ void cmd_movf(char *cmdbuf) snprintf(newpath, sizeof newpath, "./files/%s/%s", qrbuf.QRdirname, filename); if (link(pathname, newpath) != 0) { - cprintf("%d Couldn't move file: %s\n", ERROR, + cprintf("%d Couldn't move file: %s\n", ERROR + INTERNAL_ERROR, strerror(errno)); return; } @@ -274,7 +274,7 @@ void cmd_netf(char *cmdbuf) BBSDIR, (long)getpid(), ++seq); ofp = fopen(outfile, "a"); if (ofp == NULL) { - cprintf("%d internal error\n", ERROR); + cprintf("%d internal error\n", ERROR + INTERNAL_ERROR); return; } @@ -363,7 +363,7 @@ void cmd_open(char *cmdbuf) if (CC->download_fp != NULL) { cprintf("%d You already have a download file open.\n", - ERROR); + ERROR + RESOURCE_BUSY); return; } @@ -379,7 +379,7 @@ void cmd_open(char *cmdbuf) if (CC->download_fp == NULL) { cprintf("%d cannot open %s: %s\n", - ERROR, pathname, strerror(errno)); + ERROR + INTERNAL_ERROR, pathname, strerror(errno)); return; } @@ -408,7 +408,7 @@ void cmd_oimg(char *cmdbuf) if (CC->download_fp != NULL) { cprintf("%d You already have a download file open.\n", - ERROR); + ERROR + RESOURCE_BUSY); return; } @@ -474,7 +474,7 @@ void cmd_uopn(char *cmdbuf) if (CC->upload_fp != NULL) { cprintf("%d You already have a upload file open.\n", - ERROR); + ERROR + RESOURCE_BUSY); return; } @@ -500,7 +500,7 @@ void cmd_uopn(char *cmdbuf) CC->upload_fp = fopen(CC->upl_path, "wb"); if (CC->upload_fp == NULL) { cprintf("%d Cannot open %s: %s\n", - ERROR, CC->upl_path, strerror(errno)); + ERROR + INTERNAL_ERROR, CC->upl_path, strerror(errno)); return; } cprintf("%d Ok\n", CIT_OK); @@ -519,7 +519,7 @@ void cmd_uimg(char *cmdbuf) int a; if (num_parms(cmdbuf) < 2) { - cprintf("%d Usage error.\n", ERROR); + cprintf("%d Usage error.\n", ERROR + ILLEGAL_VALUE); return; } @@ -527,7 +527,7 @@ void cmd_uimg(char *cmdbuf) extract(basenm, cmdbuf, 1); if (CC->upload_fp != NULL) { cprintf("%d You already have an upload file open.\n", - ERROR); + ERROR + RESOURCE_BUSY); return; } @@ -575,7 +575,7 @@ void cmd_uimg(char *cmdbuf) CC->upload_fp = fopen(CC->upl_path, "wb"); if (CC->upload_fp == NULL) { cprintf("%d Cannot open %s: %s\n", - ERROR, CC->upl_path, strerror(errno)); + ERROR + INTERNAL_ERROR, CC->upl_path, strerror(errno)); return; } cprintf("%d Ok\n", CIT_OK); @@ -592,7 +592,7 @@ void cmd_clos(void) if (CC->download_fp == NULL) { cprintf("%d You don't have a download file open.\n", - ERROR); + ERROR + RESOURCE_NOT_OPEN); return; } @@ -633,7 +633,7 @@ void cmd_ucls(char *cmd) char upload_notice[512]; if (CC->upload_fp == NULL) { - cprintf("%d You don't have an upload file open.\n", ERROR); + cprintf("%d You don't have an upload file open.\n", ERROR + RESOURCE_NOT_OPEN); return; } @@ -690,7 +690,7 @@ void cmd_read(char *cmdbuf) if (CC->download_fp == NULL) { cprintf("%d You don't have a download file open.\n", - ERROR); + ERROR + RESOURCE_NOT_OPEN); return; } @@ -715,13 +715,13 @@ void cmd_writ(char *cmdbuf) bytes = extract_int(cmdbuf, 0); if (CC->upload_fp == NULL) { - cprintf("%d You don't have an upload file open.\n", ERROR); + cprintf("%d You don't have an upload file open.\n", ERROR + RESOURCE_NOT_OPEN); return; } if (bytes > 4096) { cprintf("%d You may not write more than 4096 bytes.\n", - ERROR); + ERROR + TOO_BIG); return; } @@ -749,7 +749,7 @@ void cmd_ndop(char *cmdbuf) if (CC->download_fp != NULL) { cprintf("%d You already have a download file open.\n", - ERROR); + ERROR + RESOURCE_BUSY); return; } @@ -767,7 +767,7 @@ void cmd_ndop(char *cmdbuf) CC->download_fp = fopen(pathname, "r"); if (CC->download_fp == NULL) { cprintf("%d cannot open %s: %s\n", - ERROR, pathname, strerror(errno)); + ERROR + INTERNAL_ERROR, pathname, strerror(errno)); return; } @@ -796,7 +796,7 @@ void cmd_nuop(char *cmdbuf) if (CC->upload_fp != NULL) { cprintf("%d You already have an upload file open.\n", - ERROR); + ERROR + RESOURCE_BUSY); return; } @@ -816,7 +816,7 @@ void cmd_nuop(char *cmdbuf) CC->upload_fp = fopen(CC->upl_path, "w"); if (CC->upload_fp == NULL) { cprintf("%d Cannot open %s: %s\n", - ERROR, CC->upl_path, strerror(errno)); + ERROR + INTERNAL_ERROR, CC->upl_path, strerror(errno)); return; } diff --git a/citadel/ipcdef.h b/citadel/ipcdef.h index 36b82633a..94b781203 100644 --- a/citadel/ipcdef.h +++ b/citadel/ipcdef.h @@ -19,8 +19,12 @@ extern "C" { #define NOT_LOGGED_IN 20 #define CMD_NOT_SUPPORTED 30 #define PASSWORD_REQUIRED 40 +#define ALREADY_LOGGED_IN 41 +#define USERNAME_REQUIRED 42 #define HIGHER_ACCESS_REQUIRED 50 #define MAX_SESSIONS_EXCEEDED 51 +#define RESOURCE_BUSY 52 +#define RESOURCE_NOT_OPEN 53 #define NOT_HERE 60 #define INVALID_FLOOR_OPERATION 61 #define NO_SUCH_USER 70 @@ -28,6 +32,7 @@ extern "C" { #define ROOM_NOT_FOUND 72 #define NO_SUCH_SYSTEM 73 #define ALREADY_EXISTS 74 +#define MESSAGE_NOT_FOUND 75 #define ASYNC_MSG 900 #define ASYNC_GEXP 01 diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 527bd2efe..2091f0e33 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1066,7 +1066,7 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ * if (!msg_ok) { if (do_proto) cprintf("%d Message %ld is not in this room.\n", - ERROR, msg_num); + ERROR + MESSAGE_NOT_FOUND, msg_num); return(om_no_such_msg); } */ @@ -1078,7 +1078,7 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ if (TheMessage == NULL) { if (do_proto) cprintf("%d Can't locate msg %ld on disk\n", - ERROR, msg_num); + ERROR + MESSAGE_NOT_FOUND, msg_num); return(om_no_such_msg); } @@ -1136,11 +1136,11 @@ int CtdlOutputPreLoadedMsg(struct CtdlMessage *TheMessage, if (TheMessage->cm_format_type != FMT_RFC822) { if (do_proto) cprintf("%d This is not a MIME message.\n", - ERROR); + ERROR + ILLEGAL_VALUE); } else if (CC->download_fp != NULL) { if (do_proto) cprintf( "%d You already have a download open.\n", - ERROR); + ERROR + RESOURCE_BUSY); } else { /* Parse the message text component */ mptr = TheMessage->cm_fields['M']; @@ -1519,7 +1519,7 @@ void cmd_msg3(char *cmdbuf) if (CC->internal_pgm == 0) { cprintf("%d This command is for internal programs only.\n", - ERROR); + ERROR + HIGHER_ACCESS_REQUIRED); return; } @@ -1527,7 +1527,7 @@ void cmd_msg3(char *cmdbuf) msg = CtdlFetchMessage(msgnum); if (msg == NULL) { cprintf("%d Message %ld not found.\n", - ERROR, msgnum); + ERROR + MESSAGE_NOT_FOUND, msgnum); return; } @@ -1536,7 +1536,7 @@ void cmd_msg3(char *cmdbuf) if (smr.len == 0) { cprintf("%d Unable to serialize message\n", - ERROR+INTERNAL_ERROR); + ERROR + INTERNAL_ERROR); return; } @@ -1738,7 +1738,7 @@ long send_message(struct CtdlMessage *msg, /* pointer to buffer */ if (smr.len == 0) { cprintf("%d Unable to serialize message\n", - ERROR+INTERNAL_ERROR); + ERROR + INTERNAL_ERROR); return (-1L); } @@ -2899,7 +2899,7 @@ void cmd_dele(char *delstr) cprintf("%d %d message%s deleted.\n", CIT_OK, num_deleted, ((num_deleted != 1) ? "s" : "")); } else { - cprintf("%d Message %ld not found.\n", ERROR, delnum); + cprintf("%d Message %ld not found.\n", ERROR + MESSAGE_NOT_FOUND, delnum); } } @@ -2936,7 +2936,7 @@ void cmd_move(char *args) is_copy = extract_int(args, 2); if (getroom(&qtemp, targ) != 0) { - cprintf("%d '%s' does not exist.\n", ERROR, targ); + cprintf("%d '%s' does not exist.\n", ERROR + ROOM_NOT_FOUND, targ); return; } @@ -3292,7 +3292,7 @@ void cmd_isme(char *argbuf) { cprintf("%d %s\n", CIT_OK, addr); } else { - cprintf("%d Not you.\n", ERROR); + cprintf("%d Not you.\n", ERROR + ILLEGAL_VALUE); } } diff --git a/citadel/policy.c b/citadel/policy.c index d267ac80b..409ffe66a 100644 --- a/citadel/policy.c +++ b/citadel/policy.c @@ -103,7 +103,7 @@ void cmd_gpex(char *argbuf) { memcpy(&exp, &config.c_ep, sizeof(struct ExpirePolicy)); } else { - cprintf("%d Invalid keyword \"%s\"\n", ERROR, which); + cprintf("%d Invalid keyword \"%s\"\n", ERROR + ILLEGAL_VALUE, which); return; } @@ -125,14 +125,14 @@ void cmd_spex(char *argbuf) { exp.expire_value = extract_int(argbuf, 2); if ((exp.expire_mode < 0) || (exp.expire_mode > 3)) { - cprintf("%d Invalid policy.\n", ERROR); + cprintf("%d Invalid policy.\n", ERROR + ILLEGAL_VALUE); return; } if (!strcasecmp(which, "room")) { if (!is_room_aide()) { cprintf("%d Higher access required.\n", - ERROR+HIGHER_ACCESS_REQUIRED); + ERROR + HIGHER_ACCESS_REQUIRED); return; } lgetroom(&CC->room, CC->room.QRname); @@ -144,7 +144,7 @@ void cmd_spex(char *argbuf) { if (CC->user.axlevel < 6) { cprintf("%d Higher access required.\n", - ERROR+HIGHER_ACCESS_REQUIRED); + ERROR + HIGHER_ACCESS_REQUIRED); return; } @@ -167,7 +167,7 @@ void cmd_spex(char *argbuf) { else if (!strcasecmp(which, "site")) { if (exp.expire_mode == EXPIRE_NEXTLEVEL) { cprintf("%d Invalid policy (no higher level)\n", - ERROR); + ERROR + ILLEGAL_VALUE); return; } memcpy(&config.c_ep, &exp, sizeof(struct ExpirePolicy)); @@ -177,7 +177,7 @@ void cmd_spex(char *argbuf) { } else { - cprintf("%d Invalid keyword \"%s\"\n", ERROR, which); + cprintf("%d Invalid keyword \"%s\"\n", ERROR + ILLEGAL_VALUE, which); return; } diff --git a/citadel/room_ops.c b/citadel/room_ops.c index 69b8a77c9..e4a66b7e9 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -935,7 +935,6 @@ void cmd_goto(char *gargs) (CC->user.axlevel < 6) ) { lprintf(9, "Failed to acquire private room\n"); - goto NOPE; } else { memcpy(&CC->room, &QRscratch, sizeof(struct ctdlroom)); @@ -945,7 +944,7 @@ void cmd_goto(char *gargs) } } -NOPE: cprintf("%d room '%s' not found\n", ERROR + ROOM_NOT_FOUND, towhere); + cprintf("%d room '%s' not found\n", ERROR + ROOM_NOT_FOUND, towhere); } @@ -1237,12 +1236,12 @@ void cmd_setr(char *args) r = CtdlRenameRoom(CC->room.QRname, new_name, new_floor); if (r == crr_room_not_found) { - cprintf("%d Internal error - room not found?\n", ERROR); + cprintf("%d Internal error - room not found?\n", ERROR + INTERNAL_ERROR); } else if (r == crr_already_exists) { cprintf("%d '%s' already exists.\n", ERROR + ALREADY_EXISTS, new_name); } else if (r == crr_noneditable) { - cprintf("%d Cannot edit this room.\n", ERROR); + cprintf("%d Cannot edit this room.\n", ERROR + NOT_HERE); } else if (r == crr_invalid_floor) { cprintf("%d Target floor does not exist.\n", ERROR + INVALID_FLOOR_OPERATION); @@ -1252,7 +1251,7 @@ void cmd_setr(char *args) CC->room.QRname); } else if (r != crr_ok) { cprintf("%d Error: CtdlRenameRoom() returned %d\n", - ERROR, r); + ERROR + INTERNAL_ERROR, r); } if (r != crr_ok) { @@ -1430,7 +1429,7 @@ void cmd_rinf(void) info_fp = fopen(filename, "r"); if (info_fp == NULL) { - cprintf("%d No info file.\n", ERROR); + cprintf("%d No info file.\n", ERROR + FILE_NOT_FOUND); return; } cprintf("%d Info:\n", LISTING_FOLLOWS); @@ -1681,7 +1680,7 @@ void cmd_cre8(char *args) new_room_floor = 0; if ((strlen(new_room_name) == 0) && (cre8_ok == 1)) { - cprintf("%d Invalid room name.\n", ERROR); + cprintf("%d Invalid room name.\n", ERROR + ILLEGAL_VALUE); return; } @@ -1716,7 +1715,7 @@ void cmd_cre8(char *args) } if ((new_room_type < 0) || (new_room_type > 5)) { - cprintf("%d Invalid room type.\n", ERROR); + cprintf("%d Invalid room type.\n", ERROR + ILLEGAL_VALUE); return; } @@ -1724,7 +1723,7 @@ void cmd_cre8(char *args) if ((config.c_aide_mailboxes == 0) || (CC->user.axlevel < 6)) { cprintf("%d Higher access required\n", - ERROR+HIGHER_ACCESS_REQUIRED); + ERROR + HIGHER_ACCESS_REQUIRED); return; } } @@ -1852,7 +1851,7 @@ void cmd_cflr(char *argbuf) if (strlen(new_floor_name) == 0) { cprintf("%d Blank floor name not allowed.\n", - ERROR+ILLEGAL_VALUE); + ERROR + ILLEGAL_VALUE); return; } @@ -1948,7 +1947,7 @@ void cmd_eflr(char *argbuf) np = num_parms(argbuf); if (np < 1) { - cprintf("%d Usage error.\n", ERROR); + cprintf("%d Usage error.\n", ERROR + ILLEGAL_VALUE); return; } diff --git a/citadel/serv_bio.c b/citadel/serv_bio.c index a8313a62e..926fb3be6 100644 --- a/citadel/serv_bio.c +++ b/citadel/serv_bio.c @@ -56,14 +56,15 @@ void cmd_ebio(char *cmdbuf) { FILE *fp; if (!(CC->logged_in)) { - cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN); + cprintf("%d Not logged in.\n",ERROR + NOT_LOGGED_IN); return; } snprintf(buf, sizeof buf, "./bio/%ld",CC->user.usernum); fp = fopen(buf,"w"); if (fp == NULL) { - cprintf("%d Cannot create file\n",ERROR); + cprintf("%d Cannot create file: %s\n", ERROR + INTERNAL_ERROR, + strerror(errno)); return; } cprintf("%d \n",SEND_LISTING); @@ -86,7 +87,7 @@ void cmd_rbio(char *cmdbuf) extract(buf,cmdbuf,0); if (getuser(&ruser,buf)!=0) { - cprintf("%d No such user.\n",ERROR+NO_SUCH_USER); + cprintf("%d No such user.\n",ERROR + NO_SUCH_USER); return; } snprintf(buf, sizeof buf, "./bio/%ld",ruser.usernum); @@ -114,7 +115,7 @@ void cmd_lbio(char *cmdbuf) { ls=popen("cd ./bio; ls","r"); if (ls==NULL) { - cprintf("%d Cannot open listing.\n",ERROR+FILE_NOT_FOUND); + cprintf("%d Cannot open listing.\n",ERROR + FILE_NOT_FOUND); return; } diff --git a/citadel/serv_calendar.c b/citadel/serv_calendar.c index a92138ec8..6de73bff4 100644 --- a/citadel/serv_calendar.c +++ b/citadel/serv_calendar.c @@ -388,7 +388,7 @@ void ical_respond(long msgnum, char *partnum, char *action) { msg = CtdlFetchMessage(msgnum); if (msg == NULL) { cprintf("%d Message %ld not found.\n", - ERROR+ILLEGAL_VALUE, + ERROR + ILLEGAL_VALUE, (long)msgnum ); return; @@ -435,7 +435,7 @@ void ical_respond(long msgnum, char *partnum, char *action) { return; } else { - cprintf("%d No calendar object found\n", ERROR); + cprintf("%d No calendar object found\n", ERROR + ROOM_NOT_FOUND); return; } @@ -734,7 +734,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) { msg = CtdlFetchMessage(msgnum); if (msg == NULL) { cprintf("%d Message %ld not found.\n", - ERROR+ILLEGAL_VALUE, + ERROR + ILLEGAL_VALUE, (long)msgnum ); return; @@ -790,7 +790,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) { return; } else { - cprintf("%d No calendar object found\n", ERROR); + cprintf("%d No calendar object found\n", ERROR + ROOM_NOT_FOUND); return; } @@ -975,7 +975,7 @@ void ical_hunt_for_conflicts(icalcomponent *cal) { if (getroom(&CC->room, USERCALENDARROOM) != 0) { getroom(&CC->room, hold_rm); - cprintf("%d You do not have a calendar.\n", ERROR); + cprintf("%d You do not have a calendar.\n", ERROR + ROOM_NOT_FOUND); return; } @@ -1004,7 +1004,7 @@ void ical_conflicts(long msgnum, char *partnum) { msg = CtdlFetchMessage(msgnum); if (msg == NULL) { cprintf("%d Message %ld not found.\n", - ERROR+ILLEGAL_VALUE, + ERROR + ILLEGAL_VALUE, (long)msgnum ); return; @@ -1028,7 +1028,7 @@ void ical_conflicts(long msgnum, char *partnum) { return; } else { - cprintf("%d No calendar object found\n", ERROR); + cprintf("%d No calendar object found\n", ERROR + ROOM_NOT_FOUND); return; } @@ -1152,7 +1152,7 @@ void ical_freebusy(char *who) { strcpy(hold_rm, CC->room.QRname); /* save current room */ if (getroom(&CC->room, calendar_room_name) != 0) { - cprintf("%d Cannot open calendar\n", ERROR+ROOM_NOT_FOUND); + cprintf("%d Cannot open calendar\n", ERROR + ROOM_NOT_FOUND); getroom(&CC->room, hold_rm); return; } @@ -1162,7 +1162,7 @@ void ical_freebusy(char *who) { fb = icalcomponent_new_vfreebusy(); if (fb == NULL) { cprintf("%d Internal error: cannot allocate memory.\n", - ERROR+INTERNAL_ERROR); + ERROR + INTERNAL_ERROR); icalcomponent_free(encaps); getroom(&CC->room, hold_rm); return; @@ -1189,7 +1189,7 @@ void ical_freebusy(char *who) { if (encaps == NULL) { icalcomponent_free(fb); cprintf("%d Internal error: cannot allocate memory.\n", - ERROR+INTERNAL_ERROR); + ERROR + INTERNAL_ERROR); getroom(&CC->room, hold_rm); return; } @@ -1268,7 +1268,7 @@ void cmd_ical(char *argbuf) return; } - cprintf("%d Invalid subcommand\n", ERROR+CMD_NOT_SUPPORTED); + cprintf("%d Invalid subcommand\n", ERROR + CMD_NOT_SUPPORTED); } diff --git a/citadel/serv_chat.c b/citadel/serv_chat.c index d7d85b735..a91dd162f 100644 --- a/citadel/serv_chat.c +++ b/citadel/serv_chat.c @@ -397,7 +397,7 @@ void cmd_pexp(char *argbuf) struct ExpressMessage *ptr, *holdptr; if (CC->FirstExpressMessage == NULL) { - cprintf("%d No express messages waiting.\n", ERROR); + cprintf("%d No express messages waiting.\n", ERROR + MESSAGE_NOT_FOUND); return; } begin_critical_section(S_SESSION_TABLE); @@ -435,7 +435,7 @@ void cmd_gexp(char *argbuf) { struct ExpressMessage *ptr; if (CC->FirstExpressMessage == NULL) { - cprintf("%d No express messages waiting.\n", ERROR); + cprintf("%d No express messages waiting.\n", ERROR + MESSAGE_NOT_FOUND); return; } @@ -638,7 +638,7 @@ void cmd_sexp(char *argbuf) extract(x_msg, argbuf, 1); if (!x_user[0]) { - cprintf("%d You were not previously paged.\n", ERROR); + cprintf("%d You were not previously paged.\n", ERROR + NO_SUCH_USER); return; } if ((!strcasecmp(x_user, "broadcast")) && (CC->user.axlevel < 6)) { @@ -652,7 +652,7 @@ void cmd_sexp(char *argbuf) if (message_sent == 0) { cprintf("%d '%s' is not logged in " "or is not accepting pages.\n", - ERROR, x_user); + ERROR + NO_SUCH_USER, x_user); return; } cprintf("%d Transmit message (will deliver to %d users)\n", @@ -685,7 +685,7 @@ void cmd_sexp(char *argbuf) } else { cprintf("%d '%s' is not logged in " "or is not accepting pages.\n", - ERROR, x_user); + ERROR + NO_SUCH_USER, x_user); } diff --git a/citadel/serv_crypto.c b/citadel/serv_crypto.c index f21a045df..3d614e1c2 100644 --- a/citadel/serv_crypto.c +++ b/citadel/serv_crypto.c @@ -288,14 +288,14 @@ void cmd_stls(char *params) int retval, bits, alg_bits; if (!ssl_ctx) { - cprintf("%d No SSL_CTX available\n", ERROR); + cprintf("%d No SSL_CTX available\n", ERROR + CMD_NOT_SUPPORTED); return; } if (!(CC->ssl = SSL_new(ssl_ctx))) { lprintf(2, "SSL_new failed: %s\n", - ERR_reason_error_string(ERR_peek_error())); - cprintf("%d SSL_new: %s\n", ERROR, - ERR_reason_error_string(ERR_get_error())); + ERR_reason_error_string(ERR_peek_error())); + cprintf("%d SSL_new: %s\n", ERROR + INTERNAL_ERROR, + ERR_reason_error_string(ERR_get_error())); return; } if (!(SSL_set_fd(CC->ssl, CC->client_socket))) { @@ -303,8 +303,8 @@ void cmd_stls(char *params) ERR_reason_error_string(ERR_peek_error())); SSL_free(CC->ssl); CC->ssl = NULL; - cprintf("%d SSL_set_fd: %s\n", ERROR, - ERR_reason_error_string(ERR_get_error())); + cprintf("%d SSL_set_fd: %s\n", ERROR + INTERNAL_ERROR, + ERR_reason_error_string(ERR_get_error())); return; } cprintf("%d \n", CIT_OK); diff --git a/citadel/serv_expire.c b/citadel/serv_expire.c index d29220bf3..f3de34e25 100644 --- a/citadel/serv_expire.c +++ b/citadel/serv_expire.c @@ -663,7 +663,7 @@ void cmd_fsck(char *argbuf) { /* Lame way of checking whether anyone else is doing this now */ if (rr != NULL) { - cprintf("%d Another FSCK is already running.\n", ERROR); + cprintf("%d Another FSCK is already running.\n", ERROR + RESOURCE_BUSY); return; } diff --git a/citadel/serv_listsub.c b/citadel/serv_listsub.c index 33b9b3645..2138fda19 100644 --- a/citadel/serv_listsub.c +++ b/citadel/serv_listsub.c @@ -93,14 +93,14 @@ void do_subscribe(char *room, char *email, char *subtype, char *webpage) { int found_sub = 0; if (getroom(&qrbuf, room) != 0) { - cprintf("%d There is no list called '%s'\n", ERROR, room); + cprintf("%d There is no list called '%s'\n", ERROR + ROOM_NOT_FOUND, room); return; } if ((qrbuf.QRflags2 & QR2_SELFLIST) == 0) { cprintf("%d '%s' " "does not accept subscribe/unsubscribe requests.\n", - ERROR+HIGHER_ACCESS_REQUIRED, qrbuf.QRname); + ERROR + HIGHER_ACCESS_REQUIRED, qrbuf.QRname); return; } @@ -131,7 +131,7 @@ void do_subscribe(char *room, char *email, char *subtype, char *webpage) { if (found_sub != 0) { cprintf("%d '%s' is already subscribed to '%s'.\n", - ERROR, + ERROR + ALREADY_EXISTS, email, qrbuf.QRname); return; } @@ -206,14 +206,14 @@ void do_unsubscribe(char *room, char *email, char *webpage) { if (getroom(&qrbuf, room) != 0) { cprintf("%d There is no list called '%s'\n", - ERROR+ROOM_NOT_FOUND, room); + ERROR + ROOM_NOT_FOUND, room); return; } if ((qrbuf.QRflags2 & QR2_SELFLIST) == 0) { cprintf("%d '%s' " "does not accept subscribe/unsubscribe requests.\n", - ERROR+HIGHER_ACCESS_REQUIRED, qrbuf.QRname); + ERROR + HIGHER_ACCESS_REQUIRED, qrbuf.QRname); return; } @@ -244,7 +244,7 @@ void do_unsubscribe(char *room, char *email, char *webpage) { if (found_sub == 0) { cprintf("%d '%s' is not subscribed to '%s'.\n", - ERROR+NO_SUCH_USER, + ERROR + NO_SUCH_USER, email, qrbuf.QRname); return; } @@ -329,14 +329,14 @@ void do_confirm(char *room, char *token) { if (getroom(&qrbuf, room) != 0) { cprintf("%d There is no list called '%s'\n", - ERROR+ROOM_NOT_FOUND, room); + ERROR + ROOM_NOT_FOUND, room); return; } if ((qrbuf.QRflags2 & QR2_SELFLIST) == 0) { cprintf("%d '%s' " "does not accept subscribe/unsubscribe requests.\n", - ERROR+HIGHER_ACCESS_REQUIRED, qrbuf.QRname); + ERROR + HIGHER_ACCESS_REQUIRED, qrbuf.QRname); return; } @@ -452,7 +452,7 @@ void do_confirm(char *room, char *token) { cprintf("%d %d operation(s) confirmed.\n", CIT_OK, success); } else { - cprintf("%d Invalid token.\n", ERROR); + cprintf("%d Invalid token.\n", ERROR + ILLEGAL_VALUE); } } @@ -477,7 +477,7 @@ void cmd_subs(char *cmdbuf) { if ( (strcasecmp(subtype, "list")) && (strcasecmp(subtype, "digest")) ) { cprintf("%d Invalid subscription type '%s'\n", - ERROR+ILLEGAL_VALUE, subtype); + ERROR + ILLEGAL_VALUE, subtype); } else { extract(room, cmdbuf, 1); @@ -498,7 +498,7 @@ void cmd_subs(char *cmdbuf) { do_confirm(room, token); } else { - cprintf("%d Invalid command\n", ERROR); + cprintf("%d Invalid command\n", ERROR + ILLEGAL_VALUE); } } diff --git a/citadel/serv_mrtg.c b/citadel/serv_mrtg.c index a616a88ed..1783e5865 100644 --- a/citadel/serv_mrtg.c +++ b/citadel/serv_mrtg.c @@ -122,7 +122,7 @@ void cmd_mrtg(char *argbuf) { } else { cprintf("%d Unrecognized keyword '%s'\n", - ERROR+ILLEGAL_VALUE, which); + ERROR + ILLEGAL_VALUE, which); } } diff --git a/citadel/serv_network.c b/citadel/serv_network.c index 878be3451..163499caa 100644 --- a/citadel/serv_network.c +++ b/citadel/serv_network.c @@ -364,7 +364,7 @@ void cmd_snet(char *argbuf) { fp = fopen(tempfilename, "w"); if (fp == NULL) { cprintf("%d Cannot open %s: %s\n", - ERROR+INTERNAL_ERROR, + ERROR + INTERNAL_ERROR, tempfilename, strerror(errno)); } @@ -1641,7 +1641,7 @@ void cmd_netp(char *cmdbuf) char nexthop[SIZ]; if (doing_queue) { - cprintf("%d spooling - try again in a few minutes\n", ERROR); + cprintf("%d spooling - try again in a few minutes\n", ERROR + RESOURCE_BUSY); return; } @@ -1649,17 +1649,17 @@ void cmd_netp(char *cmdbuf) extract(pass, cmdbuf, 1); if (is_valid_node(nexthop, secret, node) != 0) { - cprintf("%d authentication failed\n", ERROR); + cprintf("%d authentication failed\n", ERROR + PASSWORD_REQUIRED); return; } if (strcasecmp(pass, secret)) { - cprintf("%d authentication failed\n", ERROR); + cprintf("%d authentication failed\n", ERROR + PASSWORD_REQUIRED); return; } if (network_talking_to(node, NTT_CHECK)) { - cprintf("%d Already talking to %s right now\n", ERROR, node); + cprintf("%d Already talking to %s right now\n", ERROR + RESOURCE_BUSY, node); return; } diff --git a/citadel/serv_pas2.c b/citadel/serv_pas2.c index 94c6ff483..c3f31cea3 100644 --- a/citadel/serv_pas2.c +++ b/citadel/serv_pas2.c @@ -40,13 +40,13 @@ void cmd_pas2(char *argbuf) if (!strcmp(CC->curr_user, NLI)) { - cprintf("%d You must enter a user with the USER command first.\n", ERROR); + cprintf("%d You must enter a user with the USER command first.\n", ERROR + USERNAME_REQUIRED); return; } if (CC->logged_in) { - cprintf("%d Already logged in.\n", ERROR); + cprintf("%d Already logged in.\n", ERROR + ALREADY_LOGGED_IN); return; } @@ -54,7 +54,7 @@ void cmd_pas2(char *argbuf) if (getuser(&CC->user, CC->curr_user)) { - cprintf("%d Unable to find user record for %s.\n", ERROR, CC->curr_user); + cprintf("%d Unable to find user record for %s.\n", ERROR + NO_SUCH_USER, CC->curr_user); return; } @@ -63,7 +63,7 @@ void cmd_pas2(char *argbuf) if (strlen(pw) != (MD5_HEXSTRING_SIZE-1)) { - cprintf("%d Auth string of length %ld is the wrong length (should be %d).\n", ERROR, (long)strlen(pw), MD5_HEXSTRING_SIZE-1); + cprintf("%d Auth string of length %ld is the wrong length (should be %d).\n", ERROR + ILLEGAL_VALUE, (long)strlen(pw), MD5_HEXSTRING_SIZE-1); return; } @@ -76,7 +76,7 @@ void cmd_pas2(char *argbuf) } else { - cprintf("%d Wrong password.\n", ERROR); + cprintf("%d Wrong password.\n", ERROR + PASSWORD_REQUIRED); return; } } diff --git a/citadel/serv_smtp.c b/citadel/serv_smtp.c index 73739f488..56408ca6e 100644 --- a/citadel/serv_smtp.c +++ b/citadel/serv_smtp.c @@ -1482,7 +1482,7 @@ void cmd_smtp(char *argbuf) { } else { - cprintf("%d Invalid command.\n", ERROR+ILLEGAL_VALUE); + cprintf("%d Invalid command.\n", ERROR + ILLEGAL_VALUE); } } diff --git a/citadel/serv_vandelay.c b/citadel/serv_vandelay.c index 1e1addde8..252a4f122 100644 --- a/citadel/serv_vandelay.c +++ b/citadel/serv_vandelay.c @@ -562,7 +562,7 @@ void cmd_artv(char *cmdbuf) { if (CtdlAccessCheck(ac_internal)) return; if (is_running) { cprintf("%d The importer/exporter is already running.\n", - ERROR); + ERROR + RESOURCE_BUSY); return; } is_running = 1; @@ -572,7 +572,7 @@ void cmd_artv(char *cmdbuf) { extract(cmd, cmdbuf, 0); if (!strcasecmp(cmd, "export")) artv_do_export(); else if (!strcasecmp(cmd, "import")) artv_do_import(); - else cprintf("%d illegal command\n", ERROR); + else cprintf("%d illegal command\n", ERROR + ILLEGAL_VALUE); unlink(artv_tempfilename1); unlink(artv_tempfilename2); diff --git a/citadel/serv_vcard.c b/citadel/serv_vcard.c index 5ea0d4068..c1c30c670 100644 --- a/citadel/serv_vcard.c +++ b/citadel/serv_vcard.c @@ -193,7 +193,7 @@ void cmd_igab(char *argbuf) { if (getroom(&CC->room, ADDRESS_BOOK_ROOM) != 0) { getroom(&CC->room, hold_rm); - cprintf("%d cannot get address book room\n", ERROR); + cprintf("%d cannot get address book room\n", ERROR + ROOM_NOT_FOUND); return; } @@ -517,7 +517,7 @@ void cmd_regi(char *argbuf) { char tmpcountry[SIZ]; if (!(CC->logged_in)) { - cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN); + cprintf("%d Not logged in.\n",ERROR + NOT_LOGGED_IN); return; } @@ -573,7 +573,7 @@ void cmd_greg(char *argbuf) extract(who, argbuf, 0); if (!(CC->logged_in)) { - cprintf("%d Not logged in.\n", ERROR+NOT_LOGGED_IN); + cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN); return; } @@ -581,12 +581,12 @@ void cmd_greg(char *argbuf) if ((CC->user.axlevel < 6) && (strcasecmp(who,CC->curr_user))) { cprintf("%d Higher access required.\n", - ERROR+HIGHER_ACCESS_REQUIRED); + ERROR + HIGHER_ACCESS_REQUIRED); return; } if (getuser(&usbuf, who) != 0) { - cprintf("%d '%s' not found.\n", ERROR+NO_SUCH_USER, who); + cprintf("%d '%s' not found.\n", ERROR + NO_SUCH_USER, who); return; } @@ -757,7 +757,7 @@ void cmd_qdir(char *argbuf) { if (CtdlDirectoryLookup(citadel_addr, internet_addr) != 0) { cprintf("%d %s was not found.\n", - ERROR+NO_SUCH_USER, internet_addr); + ERROR + NO_SUCH_USER, internet_addr); return; } diff --git a/citadel/techdoc/session.txt b/citadel/techdoc/session.txt index eb95a92f2..431bd4e21 100644 --- a/citadel/techdoc/session.txt +++ b/citadel/techdoc/session.txt @@ -158,7 +158,7 @@ OK even if no user is logged in. The first step in logging in a user. This command takes one argument: the name of the user to be logged in. If the user exists, a MORE_DATA return code will be sent, which means the client should execute PASS as the next -command. If the user does not exist, ERROR is returned. +command. If the user does not exist, ERROR + NO_SUCH_USER is returned. PASS (send PASSword) @@ -166,10 +166,12 @@ command. If the user does not exist, ERROR is returned. The second step in logging in a user. This command takes one argument: the password for the user we are attempting to log in. If the password doesn't match the correct password for the user we specified for the USER command, -or if a USER command has not been executed yet, ERROR is returned. If the -password is correct, OK is returned and the user is now logged in... and -most of the other server commands can now be executed. Along with OK, the -following parameters are returned: +ERROR + PASSWORD_REQUIRED is returned. If a USER command has not been +executed yet, ERROR + USERNAME_REQUIRED is returned. If a user is already +logged in, ERROR + ALREADY_LOGGED_IN is returned. If the password is +correct, OK is returned and the user is now logged in... and most of the +other server commands can now be executed. Along with OK, the following +parameters are returned: 0 - The user's name (in case the client wants the right upper/lower casing) 1 - The user's current access level @@ -188,11 +190,16 @@ on the name. Note that the new account is installed with a default configuration, and no password, so the client should immediately prompt the user for a password and install it with the SETP command as soon as this command completes. This command returns OK if the account was created and -logged in, or ERROR if another user already exists with this name. If OK, -it will also return the same parameters that PASS returns. +logged in, ERROR + ALREADY_EXISTS if another user already exists with this +name, ERROR + NOT_HERE if self-service account creation is disabled, +ERROR + MAX_SESSIONS_EXCEEDED if too many users are logged in, ERROR + +USERNAME_REQUIRED if a username was not provided, or ERROR + ILELGAL_VALUE +if the username provided is invalid. If OK, it will also return the same +parameters that PASS returns. - Please note that the NEWU command should only be used for self-service user account -creation. For administratively creating user accounts, please use the CREU command. + Please note that the NEWU command should only be used for self-service +user account creation. For administratively creating user accounts, please +use the CREU command. SETP (SET new Password) @@ -200,7 +207,8 @@ creation. For administratively creating user accounts, please use the CREU comm This command sets a new password for the currently logged in user. The argument to this command will be the new password. The command always returns OK, unless the client is not logged in, in which case it will return -ERROR. +ERROR + NOT_LOGGED_IN, or if the user is an auto-login user, in which case +it will return ERROR + NOT_HERE. CREU (CREate new User account) @@ -210,20 +218,22 @@ argument to this command will be the name of the account. No case conversion is done on the name. Note that the new account is installed with a default configuration, and no password. The second argument is optional, and will be an initial password for the user. This command returns OK if the account was -created, or ERROR if another user already exists with this name. +created, ERROR + HIGHER_ACCESS_REQUIRED if the user is not an Aide, ERROR + +USERNAME_REQUIRED if no username was specified, or ERROR + ALREADY_EXISTS if +another user already exists with this name. - Please note that CREU is intended to be used for activities in which a system -administrator is creating user accounts. For self-service user account -creation, use the NEWU command. + Please note that CREU is intended to be used for activities in which a +system administrator is creating user accounts. For self-service user +account creation, use the NEWU command. LKRN (List Known Rooms with New messages) - List known rooms with new messages. If the client is not logged in, ERROR -is returned. Otherwise, LISTING_FOLLOWS is returned, followed by the room -listing. Each line in the listing contains the full name of a room, followed -by the '|' symbol, and then a number that may contain the following bits: - + List known rooms with new messages. If the client is not logged in, ERROR + +NOT_LOGGED_IN is returned. Otherwise, LISTING_FOLLOWS is returned, followed +by the room listing. Each line in the listing contains the full name of a +room, followed by the '|' symbol, and then a number that may contain the +following bits: #define QR_PERMANENT 1 /* Room does not purge */ #define QR_PRIVATE 4 /* Set for any type of private room */ @@ -241,6 +251,7 @@ by the '|' symbol, and then a number that may contain the following bits: Then it returns another '|' symbol, followed by a second set of bits comprised of the following: + #define QR2_SYSTEM 1 /* System room; hide by default */ #define QR2_SELFLIST 2 /* Self-service mailing list mgmt */ @@ -303,11 +314,11 @@ in. GETU (GET User configuration) This command retrieves the screen dimensions and user options for the -currently logged in account. ERROR will be returned if no user is logged -in, of course. Otherwise, OK will be returned, followed by four parameters. -The first parameter is the user's screen width, the second parameter is the -user's screen height, and the third parameter is a bag of bits with the -following meanings: +currently logged in account. ERROR + NOT_LOGGED_IN will be returned if no +user is logged in, of course. Otherwise, OK will be returned, followed by +four parameters. The first parameter is the user's screen width, the second +parameter is the user's screen height, and the third parameter is a bag of +bits with the following meanings: #define US_LASTOLD 16 /* Print last old message with new */ #define US_EXPERT 32 /* Experienced user */ @@ -325,7 +336,8 @@ following meanings: user options (which were probably obtained with a GETU command, and perhaps modified by the user) and writes them to the user account. This command should be passed three parameters: the screen width, the screen height, and -the option bits (see above). +the option bits (see above). It returns ERROR + NOT_LOGGED_IN if no user is +logged in, and ERROR + ILLEGAL_VALUE if the parameters are incorrect. Note that there exist bits here which are not listed in this document. Some are flags that can only be set by Aides or the system administrator. SETU @@ -394,16 +406,16 @@ third positions of the result code to find out what happened: NOT_LOGGED_IN - Of course you can't go there. You didn't log in. PASSWORD_REQUIRED - Either a password was not supplied, or the supplied password was incorrect. - NO_SUCH_ROOM - The requested room does not exist. + ROOM_NOT_FOUND - The requested room does not exist. The typical procedure for entering a passworded room would be: 1. Execute a GOTO command without supplying any password. - 2. ERROR+PASSWORD_REQUIRED will be returned. The client now knows that + 2. ERROR + PASSWORD_REQUIRED will be returned. The client now knows that the room is passworded, and prompts the user for a password. 3. Execute a GOTO command, supplying both the room name and the password. 4. If OK is returned, the command is complete. If, however, -ERROR+PASSWORD_REQUIRED is still returned, tell the user that the supplied +ERROR + PASSWORD_REQUIRED is still returned, tell the user that the supplied password was incorrect. The user remains in the room he/she was previously in. @@ -450,14 +462,14 @@ the one specified. returned, the client must transmit a list of fields to search for. The field headers are listed below in the writeup for the "MSG0" command. - This command can return three possible results. An ERROR code may be returned -if no user is currently logged in or if something else went wrong. Otherwise, -LISTING_FOLLOWS will be returned, and the listing will consist of zero or -more message numbers, one per line. The listing ends, as always, with the -string "000" alone on a line by itself. The listed message numbers can be used -to request messages from the system. If "search mode" is being used, the -server will return START_CHAT_MODE, and the client is expected to transmit -the search criteria, and then read the message list. + This command can return three possible results. ERROR + NOT_LOGGED_IN will +be returned if no user is currently logged in. Otherwise, LISTING_FOLLOWS +will be returned, and the listing will consist of zero or more message +numbers, one per line. The listing ends, as always, with the string "000" +alone on a line by itself. The listed message numbers can be used to request +messages from the system. If "search mode" is being used, the server will +return START_CHAT_MODE, and the client is expected to transmit the search +criteria, and then read the message list. Since this is somewhat complex, here are some examples: @@ -503,7 +515,6 @@ the search criteria, and then read the message list. criteria. These criteria are applied with an AND logic. - MSG0 (read MeSsaGe, mode 0) This is a command used to read the text of a message. "Mode 0" implies that @@ -515,9 +526,9 @@ argument specifies whether the client wants headers and/or message body: 1 = Headers only 2 = Body only - If the request is denied, an ERROR code will be returned. Otherwise, the -LISTING_FOLLOWS code will be returned, followed by the contents of the message. -The following fields may be sent: + If the request is denied, ERROR + NOT_LOGGED_IN or ERROR + MESSAGE_NOT_FOUND +will be returned. Otherwise, LISTING_FOLLOWS will be returned, followed by +the contents of the message. The following fields may be sent: type= Formatting type. The currently defined types are: 0 = "traditional" Citadel formatting. This means that newlines should be @@ -558,8 +569,8 @@ signifies that the message text begins on the next line. WHOK (WHO Knows room) - This command is available only to Aides. ERROR+HIGHER_ACCESS_REQUIRED will -be returned if the user is not an Aide. Otherwise, it returns + This command is available only to Aides. ERROR + HIGHER_ACCESS_REQUIRED +will be returned if the user is not an Aide. Otherwise, it returns LISTING_FOLLOWS and then lists, one user per line, every user who has access to the current room. @@ -621,32 +632,33 @@ to determine ahead of time what commands may be utilized. RDIR (Read room DIRectory) - Use this command to read the directory of a directory room. ERROR+NOT_HERE -will be returned if the room has no directory, or some other error; ERROR + -HIGHER_ACCESS_REQUIRED will be returned if the room's directory is not -visible and the user does not have Aide or Room Aide privileges; otherwise -LISTING_FOLLOWS will be returned, followed by the room's directory. Each -line of the directory listing will contain three fields: a filename, the -length of the file, and a description. + Use this command to read the directory of a directory room. ERROR + NOT_HERE +will be returned if the room has no directory, ERROR + HIGHER_ACCESS_REQUIRED +will be returned if the room's directory is not visible and the user does not +have Aide or Room Aide privileges, ERROR + NOT_LOGGED_IN will be returned if +the user is not logged in; otherwise LISTING_FOLLOWS will be returned, +followed by the room's directory. Each line of the directory listing will +contain three fields: a filename, the length of the file, and a description. The server message contained on the same line with LISTING_FOLLOWS will contain the name of the system and the name of the directory, such as: + uncensored.citadel.org|/usr/bbs/files/my_room_directory SLRP (Set Last-message-Read Pointer) This command marks all messages in the current room as read (seen) up to and -including the specified number. Its sole parameter -is the number of the last message that has been read. This allows the pointer -to be set at any arbitrary point in the room. Optionally, the parameter -"highest" may be used instead of a message number, to set the pointer to the -number of the highest message in the room, effectively marking all messages -in the room as having been read (ala the Citadel oto command). +including the specified number. Its sole parameter is the number of the last +message that has been read. This allows the pointer to be set at any +arbitrary point in the room. Optionally, the parameter "highest" may be used +instead of a message number, to set the pointer to the number of the highest +message in the room, effectively marking all messages in the room as having +been read (ala the Citadel oto command). - The command will return OK if the pointer was set, or ERROR if something -went wrong. If OK is returned, it will be followed by a single argument -containing the message number the last-read-pointer was set to. + The command will return OK if the pointer was set, or ERROR + NOT_LOGGED_IN +if the user is not logged in. If OK is returned, it will be followed by a +single argument containing the message number the last-read-pointer was set to. INVT (INViTe a user to a room) @@ -656,10 +668,11 @@ current room. It is used primarily to add users to invitation-only rooms, but it may also be used in other types of private rooms as well. Its sole parameter is the name of the user to invite. - The command will return OK if the operation succeeded, or ERROR if it did -not. ERROR+HIGHER_ACCESS_REQUIRED may also be returned if the operation -would have been possible if the user had higher access, and ERROR+NOT_HERE -may be returned if the room is not a private room. + The command will return OK if the operation succeeded. ERROR + NO_SUCH_USER +will be returned if the user does not exist, ERROR + HIGHER_ACCESS_REQUIRED +will be returned if the operation would have been possible if the user had +higher access, and ERROR + NOT_HERE may be returned if the room is not a +private room. KICK (KICK a user out of a room) @@ -687,7 +700,6 @@ editing. Possible return codes are: ERROR+NOT_LOGGED_IN - No user is logged in. ERROR+HIGHER_ACCESS_REQUIRED - Not enough access. Typically, only aides and the room aide associated with the current room, can access this command. - ERROR+NOT_HERE - Lobby>, Mail>, and Aide> cannot be edited. OK - Command succeeded. Parameters are returned. If OK is returned, the following parameters will be returned as well: @@ -715,7 +727,7 @@ should be passed the following arguments: 5. The floor number on which the room should reside 6. The room listing order 7. The default view for the room (see views.txt) - 8. A second set of flags (buts) associated with the room + 8. A second set of flags (bits) associated with the room *Important: You should always use GETR to retrieve the current attributes of the room, then change what you want to change, and then use SETR to write it @@ -724,6 +736,9 @@ particular bit is set, and you don't know what it means, LEAVE IT ALONE and only toggle the bits you want to toggle. This will allow for upward compatibility. + The _BASEROOM_, user's Mail> and Aide> rooms can only be partially edited. +Any changes which cannot be made will be silently ignored. + If the room is a private room, you have the option of causing all users who currently have access, to forget the room. If you want to do this, set the "bump" flag to 1, otherwise set it to 0. @@ -732,9 +747,10 @@ currently have access, to forget the room. If you want to do this, set the GETA This command is used to get the name of the Room Aide for the current room. -It will return ERROR+NOT_LOGGED_IN if no user is logged in, ERROR if there -is no current room, or OK if the command succeeded. Along with OK there will -be returned one parameter: the name of the Room Aide. +It will return ERROR + NOT_LOGGED_IN if no user is logged in, or OK if the +command succeeded. Along with OK there will be returned one parameter: the +name of the Room Aide. A conforming server must guarantee that the user is +always in some room. SETA @@ -743,10 +759,9 @@ be returned one parameter: the name of the Room Aide. parameter should be passed, which is the name of the user who is to be the new Room Aide. Under Citadel/UX, this command may only be executed by Aides and by the *current* Room Aide for the room. Return codes possible are: - ERROR+NOT_LOGGED_IN (Not logged in.) - ERROR+HIGHER_ACCESS_REQUIRED (Higher access required.) - ERROR+NOT_HERE (No current room, or room cannot be edited. -Under Citadel/UX, the Lobby> Mail> and Aide> rooms are non-editable.) + ERROR + NOT_LOGGED_IN (Not logged in.) + ERROR + HIGHER_ACCESS_REQUIRED (Higher access required.) + ERROR + NOT_HERE (Room cannot be edited.) OK (Command succeeded.) @@ -786,7 +801,6 @@ correct upper and lower case characters. In addition, if the recipient is having his/her mail forwarded, the forwarding address will be returned. SEND_LISTING - The request is valid. The client should now transmit the text of the message (ending with a 000 on a line by itself, as usual). - ERROR - Miscellaneous error. (Explanation probably follows.) ERROR + NOT_LOGGED_IN - Not logged in. ERROR + HIGHER_ACCESS_REQUIRED - Higher access is required. An explanation follows, worded in a form that can be displayed to the user. diff --git a/citadel/user_ops.c b/citadel/user_ops.c index 43deedcef..d512db3c6 100644 --- a/citadel/user_ops.c +++ b/citadel/user_ops.c @@ -407,7 +407,7 @@ void cmd_user(char *cmdbuf) a = CtdlLoginExistingUser(username); switch (a) { case login_already_logged_in: - cprintf("%d Already logged in.\n", ERROR); + cprintf("%d Already logged in.\n", ERROR + ALREADY_LOGGED_IN); return; case login_too_many_users: cprintf("%d %s: " @@ -421,9 +421,9 @@ void cmd_user(char *cmdbuf) MORE_DATA, CC->curr_user); return; case login_not_found: - cprintf("%d %s not found.\n", ERROR, username); + cprintf("%d %s not found.\n", ERROR + NO_SUCH_USER, username); return; - cprintf("%d Internal error\n", ERROR); + cprintf("%d Internal error\n", ERROR + INTERNAL_ERROR); } } @@ -673,14 +673,14 @@ void cmd_pass(char *buf) switch (a) { case pass_already_logged_in: - cprintf("%d Already logged in.\n", ERROR); + cprintf("%d Already logged in.\n", ERROR + ALREADY_LOGGED_IN); return; case pass_no_user: cprintf("%d You must send a name with USER first.\n", - ERROR); + ERROR + USERNAME_REQUIRED); return; case pass_wrong_password: - cprintf("%d Wrong password.\n", ERROR); + cprintf("%d Wrong password.\n", ERROR + PASSWORD_REQUIRED); return; case pass_ok: logged_in_response(); @@ -859,12 +859,12 @@ void cmd_newu(char *cmdbuf) if (config.c_disable_newu) { cprintf("%d Self-service user account creation " - "is disabled on this system.\n", ERROR); + "is disabled on this system.\n", ERROR + NOT_HERE); return; } if (CC->logged_in) { - cprintf("%d Already logged in.\n", ERROR); + cprintf("%d Already logged in.\n", ERROR + ALREADY_LOGGED_IN); return; } if (CC->nologin) { @@ -877,14 +877,14 @@ void cmd_newu(char *cmdbuf) strproc(username); if (strlen(username) == 0) { - cprintf("%d You must supply a user name.\n", ERROR); + cprintf("%d You must supply a user name.\n", ERROR + USERNAME_REQUIRED); return; } if ((!strcasecmp(username, "bbs")) || (!strcasecmp(username, "new")) || (!strcasecmp(username, "."))) { - cprintf("%d '%s' is an invalid login name.\n", ERROR, username); + cprintf("%d '%s' is an invalid login name.\n", ERROR + ILLEGAL_VALUE, username); return; } @@ -902,7 +902,7 @@ void cmd_newu(char *cmdbuf) ERROR + INTERNAL_ERROR); return; } else { - cprintf("%d unknown error\n", ERROR); + cprintf("%d unknown error\n", ERROR + INTERNAL_ERROR); } } @@ -917,7 +917,7 @@ void cmd_setp(char *new_pw) return; } if ( (CC->user.uid != BBSUID) && (CC->user.uid != (-1)) ) { - cprintf("%d Not allowed. Use the 'passwd' command.\n", ERROR); + cprintf("%d Not allowed. Use the 'passwd' command.\n", ERROR + NOT_HERE); return; } strproc(new_pw); @@ -956,7 +956,7 @@ void cmd_creu(char *cmdbuf) strproc(password); if (strlen(username) == 0) { - cprintf("%d You must supply a user name.\n", ERROR); + cprintf("%d You must supply a user name.\n", ERROR + USERNAME_REQUIRED); return; } @@ -977,7 +977,7 @@ void cmd_creu(char *cmdbuf) ERROR + ALREADY_EXISTS, username); return; } else { - cprintf("%d An error occured creating the user account.\n", ERROR); + cprintf("%d An error occured creating the user account.\n", ERROR + INTERNAL_ERROR); } } @@ -1010,7 +1010,7 @@ void cmd_setu(char *new_parms) return; if (num_parms(new_parms) < 3) { - cprintf("%d Usage error.\n", ERROR); + cprintf("%d Usage error.\n", ERROR + ILLEGAL_VALUE); return; } lgetuser(&CC->user, CC->curr_user); @@ -1070,7 +1070,7 @@ void cmd_seen(char *argbuf) { } if (num_parms(argbuf) != 2) { - cprintf("%d Invalid parameters\n", ERROR); + cprintf("%d Invalid parameters\n", ERROR + ILLEGAL_VALUE); return; } @@ -1127,7 +1127,7 @@ void cmd_invt_kick(char *iuser, int op) } if (lgetuser(&USscratch, iuser) != 0) { - cprintf("%d No such user.\n", ERROR); + cprintf("%d No such user.\n", ERROR + NO_SUCH_USER); return; } CtdlGetRelationship(&vbuf, &USscratch, &CC->room); @@ -1203,7 +1203,7 @@ void cmd_forg(void) cprintf("%d Ok\n", CIT_OK); } else { - cprintf("%d You may not forget this room.\n", ERROR); + cprintf("%d You may not forget this room.\n", ERROR + NOT_HERE); } }