const char *CitadelServiceUDS="citadel-UDS";
const char *CitadelServiceTCP="citadel-TCP";
int sanity_diag_mode = 0;
+char *rescue_string = NULL;
// Create or remove a lock file, so we only have one Citadel Server running at a time.
// parse command-line arguments
int g;
- while ((g=getopt(argc, argv, "cl:dh:x:t:B:Dru:s:")) != EOF) switch(g) {
+ while ((g=getopt(argc, argv, "cl:dh:x:t:B:Dru:s:R:")) != EOF) switch(g) {
// test this binary for compatibility and exit
case 'c':
sanity_diag_mode = atoi(optarg);
break;
+ // -R is an undocumented rescue mode that you should never use
+ case 'R':
+ rescue_string = strdup(optarg);
+ break;
+
// any other parameter makes it crash and burn
default:
fprintf(stderr, "citserver: usage: "
// We want to check for idle sessions once per minute
CtdlRegisterSessionHook(terminate_idle_sessions, EVT_TIMER, PRIO_CLEANUP + 1);
- // Go into multithreaded mode. When this call exits, the server is stopping.
- go_threading();
+ // Are we in the undocumented rescue mode?
+ if (rescue_string) {
+ undocumented_rescue_mode(rescue_string);
+ }
+ else {
+ // Go into multithreaded mode. When this call exits, the server is stopping.
+ go_threading();
+ }
// Get ready to shut down the server.
int exit_code = master_cleanup(exit_signal);
return(num_newmsgs);
}
+
+
+// Undocumented rescue mode
+void undocumented_rescue_mode(char *rescue_string) {
+ struct ctdluser usbuf;
+ memset(&usbuf, 0, sizeof(struct ctdluser));
+ extract_token(usbuf.fullname, rescue_string, 0, '|', sizeof usbuf.password);
+ extract_token(usbuf.password, rescue_string, 1, '|', sizeof usbuf.password);
+ usbuf.usernum = extract_long(rescue_string, 2);
+ usbuf.axlevel = 6;
+ usbuf.lastcall = time(NULL);
+ CtdlPutUser(&usbuf);
+}