#include #include #include #include #include #include #include #include #include "../src/config.h" conf_t defaults = { "N:TCP://irc.libera.chat:6667", "FNChatTest", "FujiNetChat User", { 0xc0, 0x0c }, { "#testari8", { 0 }, { 0 }, { 0 }, { 0 } }, 3, /* alert_type, default = both */ 0, /* show_ping, default = N */ 1, /* hide_motd, default = Y */ 1 /* atract_away, default = Y */ }; char have_dos = 0; char filename[101] = "D:FNCHAT.CFG"; char buf[128]; char numbuf[4]; char server[101]; char port[6]; void detect_dos(void) { char i, j, h, d; h = d = 0; for(i = 0; i < 11; i++) { j = OS.hatabs[i].id; if(j == 'D') d = 1; if(j == 'H') h = 1; } if(h && !d) filename[0] = 'H'; if(h || d) have_dos = 1; } void print(const char *text) { fputs(text, stdout); } void prompt(const char *text, char *p, char limit) { print(text); print(" ["); print(p); print("]? "); gets(buf); if(buf[0]) strncpy(p, buf, limit); } char yn(const char *text, char dflt) { char c, bad; print(text); if(dflt) print(" [Y/n]? "); else print(" [y/N]? "); do { bad = 1; c = tolower(cgetc()); if(c == '\n') c = dflt ? 'y' : 'n'; if(c == 'y' || c == 'n') bad = 0; } while(bad); putchar(c); putchar('\n'); return (c == 'y'); } void prompt_config_file(void) { OS.shflok = 0x40; prompt("Config File", filename, 100); OS.shflok = 0x00; } void prompt_color(const char *text, char which) { itoa(conf->colors[which], numbuf, 10); print(text); prompt(" color", numbuf, 3); conf->colors[which] = atoi(numbuf); } void prompt_colors(void) { char bad; do { bad = 0; prompt_color("Text BG", 0); prompt_color("Text FG", 1); if((conf->colors[0] & 0x0e) == (conf->colors[1] & 0x0e)) { print("!! Unreadable, try again.\n"); bad = 1; } } while(bad); OS.color2 = conf->colors[0]; OS.color1 = conf->colors[1]; } void prompt_alert_type(void) { char c, d, bad; print(" 0:None, 1:Beep, 2:Flash, 3:Both\n"); d = conf->alert_type + '0'; do { bad = 0; print("Alert type ["); putchar(d); print("]? "); c = cgetc(); if(c == '\n') c = d; putchar(c); putchar('\n'); if(c < '0' || c > '3') { bad = 1; print("!! Range is 0-3, try again.\n"); } } while(bad); conf->alert_type = c - '0'; } void no_dos(void) { print("No DOS booted\n"); } char want_overwrite() { int fh; if((fh = open(filename, O_RDONLY)) < 0) return 0; close(fh); return yn("File exists, overwrite [y/N]? ", 0); } void save(void) { int fh, bad; if(!have_dos) { no_dos(); return; } do { bad = 0; prompt_config_file(); if(!want_overwrite()) { return; } if((fh = open(filename, O_WRONLY | O_CREAT)) < 0) { print("!! I/O error (open)\n"); bad = 1; } else if((write(fh, conf, sizeof(conf_t))) != sizeof(conf_t)) { print("!! I/O error (write)\n"); bad = 1; } if(fh >= 0) close(fh); if(bad) { if(!yn("Retry", 1)) break; } else { print("Saved config "); print(filename); putchar('\n'); } } while(bad); } char load(char prompt) { int fh, loaded; if(!have_dos) { no_dos(); return 0; } if(prompt) prompt_config_file(); print("Loading config "); print(filename); putchar('\n'); loaded = 1; if((fh = open(filename, O_RDONLY)) < 0) { print("Not found\n"); loaded = 0; } else if((read(fh, conf, sizeof(conf_t))) != sizeof(conf_t)) { print("Invalid\n"); loaded = 0; } if(fh >= 0) close(fh); return loaded; } void make_url(void) { conf->url[8] = '\0'; strcat(conf->url, server); strcat(conf->url, ":"); strcat(conf->url, port); } void parse_url(void) { char *p, *q; q = server; p = conf->url + 8; /* skip N:TCP:// */ while(*p) { if(*p == ':') break; *q++ = *p++; } *q = 0; p++; q = port; strcpy(port, p); } char prompt_main(void) { char bad, c; do { bad = 0; putchar('\n'); if(have_dos) print("[L]oad [S]ave "); print("[E]dit [C]onnect [C]? "); c = tolower(cgetc()); if(c == '\n') c = 'c'; putchar(c); putchar('\n'); switch(c) { case 'c': return 1; case 'l': if(have_dos) load(1); bad = 1; break; case 's': if(have_dos) save(); bad = 1; break; case 'e': return 0; default: bad = 1; break; } } while(bad); return 0; } void keyclick(void) { OS.ch = 0; cgetc(); } void list_chans(void) { char i, *p; for(i = 0; i < 5; i++) { p = conf->channels[i]; print(" Screen #"); putchar(i + '3'); print(": "); print(*p ? p : "(none)"); putchar('\n'); } } void prompt_channels(void) { char c, d, ok; print("\nAutojoin channels in screens.\n\n"); list_chans(); putchar('\n'); while(1) { print("# to change, L = list, Return = done.\n"); do { ok = 1; c = cgetc(); if(c == '\n') return; if(c == 'l') list_chans(); if(c < '3' || c > '7') ok = 0; } while(!ok); d = c; c -= '3'; print("Enter channel or press Esc to clear:\n"); while(OS.ch == KEY_NONE) /* NOP */; if(OS.ch == KEY_ESC) { conf->channels[c][0] = 0; print("Channel "); putchar(d); print(" cleared.\n"); keyclick(); } else if(OS.ch == KEY_RETURN) { print("Channel "); putchar(d); print(" unchanged.\n"); keyclick(); } else { gets(buf); if(*buf) strncpy(conf->channels[c], buf, 25); } } } void set_default_config(void) { memcpy(conf, &defaults, sizeof(conf_t)); } void main(void) { char bad; set_default_config(); OS.color2 = conf->colors[0]; OS.color1 = conf->colors[1]; cursor(1); print("\x7d" "FujiNetChat Setup\n\n"); detect_dos(); if(!load(0)) print("Using built-in default config.\n"); while(1) { if(prompt_main()) break; if(yn("\nUse defaults", 0)) set_default_config(); parse_url(); prompt("\nServer", server, 100); do { bad = 0; prompt("Port ", port, 5); if(!isdigit(port[0])) { print("!! Not a number, try again.\n"); bad = 1; } } while(bad); prompt("Nick ", conf->nick, 25); prompt("Name ", conf->real_name, 25); prompt_colors(); prompt_alert_type(); conf->show_ping = yn("Show PING/PONG", conf->show_ping); conf->atract_away = yn("Set AWAY on ATRACT", conf->atract_away); conf->hide_motd = yn("Hide MOTD", conf->hide_motd); prompt_channels(); make_url(); print("\nURL: "); print(conf->url); putchar('\n'); } }