void prepare_addshit(UserhostItem *stuff, char *nick, char *args) { char *uh; char *channels, *reason; char listbuf[BIG_BUFFER_SIZE+1]; int thetype = 0, shit = 0; if (!stuff || !stuff->nick || !nick || !strcmp(stuff->user, "<UNKNOWN>") || my_stricmp(stuff->nick, nick)) { bitchsay("No such nick [%s] found", nick); return; } thetype = my_atol(args); next_arg(args, &args); shit = my_atol(args); next_arg(args, &args); channels = next_arg(args, &args); reason = args; uh = clear_server_flags(stuff->user); while (strlen(uh) > 7) uh++; sprintf(listbuf, "*%s@%s", uh, stuff->host); add_to_a_list(listbuf, thetype, "*", channels, reason, shit); }
/* * create_timer_ref: returns the lowest unused reference number for a timer * All refnums that are not already in use are valid. * * The user is allowed to use any string as a refnum, we dont really care. * Automatically assigned refnums (when the user doesnt specify one) will * always be one more than the highest pending refnum. * * "refnum_gets" must be REFNUM_MAX + 1 bytes by definition of API. */ static int create_timer_ref (const char *refnum_wanted, char **refnum_gets) { Timer *tmp; int refnum = 0; char *refnum_want; refnum_want = LOCAL_COPY(refnum_wanted); /* If the user doesnt care */ if (*refnum_want == 0) { /* Find the lowest refnum available */ for (tmp = PendingTimers; tmp; tmp = tmp->next) { if (refnum < my_atol(tmp->ref)) refnum = my_atol(tmp->ref); } malloc_sprintf(refnum_gets, "%d", refnum + 1); } else { /* See if the refnum is available */ if (get_timer(refnum_want)) return -1; /* Already in use */ malloc_strcpy(refnum_gets, refnum_want); } return 0; }
char *set_cset(char *var, ChannelList *chan, char *value) { int var_index, cnt = 0; var_index = find_cset_variable(cset_array, var, &cnt); if (cnt == 1) { CSetArray *var; var = &(cset_array[var_index]); switch(var->type) { case BOOL_TYPE_VAR: { int i = my_atol(value); set_cset_int_var(chan->csets, var_index, i? 1 : 0); break; } case INT_TYPE_VAR: { int i = my_atol(value); set_cset_int_var(chan->csets, var_index, i); break; } case STR_TYPE_VAR: { set_cset_str_var(chan->csets, var_index, value); break; } default: return NULL; } return value; } return NULL; }
/* * create_timer_ref: returns the lowest unused reference number for a timer * All refnums that are not already in use are valid. * * The user is allowed to use any string as a refnum, we dont really care. * Automatically assigned refnums (when the user doesnt specify one) will * always be one more than the highest pending refnum. * * "refnum_gets" must be REFNUM_MAX + 1 bytes by definition of API. */ static int create_timer_ref (const char *refnum_wanted, char *refnum_gets) { Timer *tmp; int refnum = 0; char *refnum_want; /* Max of 10 characters. */ refnum_want = LOCAL_COPY(refnum_wanted); if (strlen(refnum_want) > REFNUM_MAX) refnum_want[REFNUM_MAX] = 0; /* If the user doesnt care */ if (*refnum_want == 0) { /* Find the lowest refnum available */ for (tmp = PendingTimers; tmp; tmp = tmp->next) { if (refnum < my_atol(tmp->ref)) refnum = my_atol(tmp->ref); } strlcpy(refnum_gets, ltoa(refnum+1), REFNUM_MAX + 1); } else { /* See if the refnum is available */ if (get_timer(refnum_want)) return -1; /* Already in use */ strlcpy(refnum_gets, refnum_want, REFNUM_MAX + 1); } return 0; }
/* * target_file_write: "Send" a "message" to a file or logfile * * Arguments: * fd - A logical target to a logfile: * Syntax: @ + [<domain>] + <number> * Specifically: * @W<winref> Write to the /WINDOW LOG for <winref> * @L<logref> Write to a /LOG file * @<openref> Write to an $open() file * stuff - A UTF8 string to be sent to the log * * Return value: * -1 The "fd" argument was invalid becuase; * 1. It was not in the form @W<number>, @L<number> * or @<number>. * or, the return value of file_write() above: * -1 The "fd" argument was not a valid logfile * (ie, the window has no log, the /log refnum * does not exist or is off) * -1 The message was not written() becuase * fflush() returned EOF * or, the return value of fprintf(). * * This function is nothing but a bald wrapper to file_write which does * all of the heavy lifting. */ int target_file_write (const char *fd, const char *stuff) { if (*fd != '@') return -1; fd++; if (*fd == 'W' || *fd == 'w' || *fd == 'L' || *fd == 'l') fd++; if (!is_number(fd)) return -1; /* * We specifically do not rewrite the UTF8 string. * All writes to files are done in UTF8 only. */ /* XXX Really we should call add_to_log() here */ /* XXX file_write() should not know or care about logfiles */ if (toupper(*fd) == 'W' && is_number(fd + 1)) return file_write(1, my_atol(fd + 1), stuff); else if (toupper(*fd) == 'L' && is_number(fd + 1)) return file_write(2, my_atol(fd + 1), stuff); else if (is_number(fd)) return file_write(0, my_atol(fd), stuff); else return -1; }
/* * target_file_write: "Send" a "message" to a file or logfile * Examples: * /msg @<fileref> This is logged to an $open() file. * /msg @W<winref> This is logged to a window's logfile * /msg @L<logref> This is logged to a general logfile * This function is nothing but a bald wrapper to file_write which does * all of the heavy lifting. */ int target_file_write (const char *fd, const char *stuff) { /* XXX Really we should call add_to_log() here */ /* XXX file_write() should not know or care about logfiles */ if (toupper(*fd) == 'W' && is_number(fd + 1)) return file_write(1, my_atol(fd + 1), stuff); else if (toupper(*fd) == 'L' && is_number(fd + 1)) return file_write(2, my_atol(fd + 1), stuff); else if (is_number(fd)) return file_write(0, my_atol(fd), stuff); else return -1; }
/* * is_valid_process: tells me if the spec is a process that is either * running or still has not closed its pipes, or both. */ int is_valid_process (const char *arg) { if (!arg || *arg != '%') return -1; arg++; if (is_number(arg) && valid_process_index(my_atol(arg))) return my_atol(arg); else return logical_to_index(arg); return -1; }
void nap_firewall_start1(int snum) { GetFile *gf; unsigned char buffer[BIG_BUFFER_SIZE+1]; SocketList *s; int rc; unsigned long resume = 0; s = get_socket(snum); if (!s || !(gf = (GetFile *)get_socketinfo(snum))) { close_socketread(snum); return; } if ((rc = read(snum, buffer, BIG_BUFFER_SIZE)) < 1) { break_from_list((List **)&transfer_struct, (List *)gf); if (gf->write != -1) { close(gf->write); gf->write = -1; } nap_finished_file(snum, PREMATURE_FINISH); return; } buffer[rc+1] = 0; resume = my_atol(buffer); put_it("Maybe this is where firewall resume is? %s", buffer); if (lseek(gf->write, resume, SEEK_SET) != -1) gf->resume = resume; gf->starttime = now; s->is_write = s->is_read; s->func_write = s->func_read = napfile_sendfile; napfile_sendfile(snum); }
static inline void wset_variable_case1(Window *win, char *name, int var_index, char *args) { Window *tmp = NULL; int count = 0; int i; if (!name) { set_wset_var_value(win, var_index, args); return; } while ((traverse_all_windows(&tmp))) { i = var_index; if (*name == '*') { set_wset_var_value(tmp, i, args); count++; } else if ((tmp->name && wild_match(name, tmp->name)) || (tmp->refnum == my_atol(name))) { set_wset_var_value(tmp, i, args); count++; } } if (!count) say("No such window name [%s]", name); }
static inline void wset_variable_casedef(Window *win, char *name, int cnt, int var_index, char *args) { Window *tmp = NULL; int count = 0; int c, i; if (!name) { for (cnt +=var_index; var_index < cnt; var_index++) set_wset_var_value(win, var_index, args); return; } while ((traverse_all_windows(&tmp))) { c = cnt; i = var_index; if (*name == '*') { for (c += i; i < c; i++) set_wset_var_value(tmp, i, empty_string); count++; } else if ((tmp->name && wild_match(name, tmp->name)) || (tmp->refnum == my_atol(name)) ) { for (c += i; i < c; i++) set_wset_var_value(tmp, i, empty_string); count++; } } if (!count) say("No such window name [%s]", name); }
static inline void wset_variable_noargs(Window *win, char *name) { Window *tmp = NULL; int var_index = 0; if (!name) { for (var_index = 0; var_index < NUMBER_OF_WSETS; var_index++) set_wset_var_value(win, var_index, empty_string); } else { int count = 0; while ((traverse_all_windows(&tmp))) { if (*name == '*') { for (var_index = 0; var_index < NUMBER_OF_WSETS; var_index++) set_wset_var_value(tmp, var_index, empty_string); count++; } else if ((tmp->name && wild_match(name, tmp->name)) || (tmp->refnum == my_atol(name))) { for (var_index = 0; var_index < NUMBER_OF_WSETS; var_index++) set_wset_var_value(tmp, var_index, empty_string); count++; } } if (!count) say("No such window name [%s]", name); } }
int real_check_auto (void *arg, char *sub) { char *nick, *host, *channel; char *p = (char *)arg; char *args = (char *)arg; char *serv_num = NULL; int this_server = from_server; channel = next_arg(args, &args); nick = next_arg(args, &args); host = next_arg(args, &args); if ((serv_num = next_arg(args, &args))) from_server = my_atol(serv_num); if (channel && *channel && nick && *nick && host && *host) { ChannelList *chan; if ((chan = lookup_channel(channel, from_server, CHAN_NOUNLINK))) check_auto(channel, find_nicklist_in_channellist(nick, chan, 0), NULL); } this_server = from_server; new_free(&p); return 0; }
//android bionic glibc int main() { char data[1024]; my_strcpy(data, "hehe"); printf("%s\n", data); my_strcat(data, "来自中国1024"); printf("%s\n", data); char hehe[1024]; my_memset(hehe, 0, sizeof(hehe)); my_memccpy(hehe, data, '1', my_strlen(data)); printf("%s\n", hehe); printf("%d\n", my_strlen(hehe)); char s[] = "-abc-=-def"; char *x = my_strtok(s, "-"); // x = "abc" printf("%s\n", x); x = my_strtok(NULL, "-="); // x = "def" printf("%s\n", x); x = my_strtok(NULL, "="); // x = NULL printf("%s\n", x); printf("%f %d %ld\n", my_atof("1.245"), my_atoi("1024"), my_atol("152.63")); return 0; }
static inline void fset_variable_casedef(char *name, int cnt, int var_index, char *args) { FsetNumber *tmp; for (cnt += var_index; var_index < cnt; var_index++) set_fset_var_value(var_index, NULL, args); if (!is_number(name)) return; for (tmp = numeric_fset; tmp; tmp = tmp->next) if (my_atol(name) == tmp->numeric) put_it("%s", convert_output_format(fget_string_var(FORMAT_SET_FSET), "%d %s", tmp->numeric, tmp->format)); }
static Logfile * logfile_remove (Logfile *log, char **args) { char *arg = next_arg(*args, args); char *ptr; WNickList *new_nl; int i; if (!log) { say("REMOVE: You need to specify a logfile first"); return NULL; } if (!arg) say("Remove: Remove nicknames/channels logged to this file"); else while (arg) { if ((ptr = strchr(arg, ',')) != NULL) *ptr++ = 0; if (log->type == LOG_TARGETS) { if ((new_nl = (WNickList *)remove_from_list((List **)&(log->targets), arg))) { say("Removed %s from log target list", new_nl->nick); new_free(&new_nl->nick); new_free((char **)&new_nl); } else say("%s is not on the list for this log!", arg); } else if (log->type == LOG_SERVERS || log->type == LOG_WINDOWS) { int refnum = my_atol(ptr); for (i = 0; i < MAX_TARGETS; i++) { if (log->refnums[i] == refnum) { say("Removed %d to log refnum list", refnum); log->refnums[i] = -1; break; } } if (i >= MAX_TARGETS) say("%s is not on the refnum list for this log!", arg); } arg = ptr; } return log; }
/* * create_timer_ref: returns the lowest unused reference number for a timer * All refnums that are not already in use are valid. * * The user is allowed to use any string as a refnum, we dont really care. * Automatically assigned refnums (when the user doesnt specify one) will * always be one more than the highest pending refnum. * * "refnum_gets" must be REFNUM_MAX + 1 bytes by definition of API. */ static int create_timer_ref (const char *refnum_wanted, char **refnum_gets) { Timer *tmp; int refnum = 0; char *refnum_want; int i, pts; refnum_want = LOCAL_COPY(refnum_wanted); /* If the user doesnt care */ if (*refnum_want == 0) { /* So ... we count the number of times that exist. */ for (pts = 0, tmp = PendingTimers; tmp; tmp = tmp->next) pts++; /* * Now, for all the numbers (0 .. [timer count + 1]), * at least one of those numbers *has* to be available, */ for (i = 0; i <= pts + 1; i++) { /* Are any timers named 'i'? */ for (tmp = PendingTimers; tmp; tmp = tmp->next) { if (!is_number(tmp->ref)) continue; if (i == my_atol(tmp->ref)) break; } /* * If 'tmp' is null, then we didn't find a refnum 'i'. * So 'i' is our winner! */ if (tmp == NULL) { malloc_sprintf(refnum_gets, "%d", i); break; } } } else { /* See if the refnum is available */ if (get_timer(refnum_want)) return -1; /* Already in use */ malloc_strcpy(refnum_gets, refnum_want); } return 0; }
char *get_cset(char *var, ChannelList *chan, char *value) { int var_index, cnt = 0; var_index = find_cset_variable(cset_array, var, &cnt); if (cnt == 1) { char s[81]; CSetArray *var; var = &(cset_array[var_index]); *s = 0; switch (var->type) { case BOOL_TYPE_VAR: { strcpy(s, get_cset_int_var(chan->csets, var_index)?var_settings[ON] : var_settings[OFF]); if (value) { int val = -1; if (!my_stricmp(value, on)) val = 1; else if (!my_stricmp(value, off)) val = 0; else { if (isdigit((unsigned char)*value)) val = (int)(*value - '0'); } if (val != -1) set_cset_int_var(chan->csets, var_index, val); } break; } case INT_TYPE_VAR: { strncpy(s, ltoa(get_cset_int_var(chan->csets, var_index)), 30); if (value && isdigit((unsigned char)*value)) set_cset_int_var(chan->csets, var_index, my_atol(value)); break; } case STR_TYPE_VAR: { char *t; t = m_strdup(get_cset_str_var(chan->csets, var_index)); if (value) set_cset_str_var(chan->csets, var_index, value); return t; } } return m_strdup(s && *s ? s : empty_string); } return m_strdup(empty_string); }
int main(int argc, const char * argv[]) { // insert code here... std::cout << "ltoa(" << argv[1] << ") = "; double l; std::cout.precision(10); if ( my_atol(argv[1], l) ) std::cout << l << "\n"; else std::cout << "ERR\n"; return 0; }
void CFilter::loadIp(const char* ip_file){ ifstream infile; string line,low,high; infile.open(ip_file,ifstream::in); if(!infile) { cout<<ip_file<<" open error!"<<endl; return; } while(getline(infile,line)) { IPRange ir; istringstream stream(line); stream>>low; ir.low=my_atol(low.c_str()); stream>>high; ir.high=my_atol(high.c_str()); ipVec.push_back(ir); } infile.close(); }
int delay_opz (void *arg, char *sub) { char * args = (char *)arg; char * from = NULL; char * host = NULL; char * channel = NULL; char * mode = NULL; char * serv_num = NULL; ChannelList *chan = NULL; int this_server = from_server; char *p = (char *) arg; /* original args unmodified so we can free them */ channel = next_arg(args, &args); from = next_arg(args, &args); host = next_arg(args, &args); mode = next_arg(args, &args); if ((serv_num = next_arg(args, &args))) this_server = my_atol(serv_num); chan = lookup_channel(channel, this_server, 0); if (chan && is_on_channel(channel, this_server, from) && chan->chop) { NickList *nick; for (nick = next_nicklist(chan, NULL); nick; nick = next_nicklist(chan, nick)) { if (!my_stricmp(nick->nick, from)) { if (!my_stricmp(host, nick->host)) break; else { new_free(&p); new_free(&sub); return 0; } } } if (nick && ((!nick_isop(nick) && *mode == 'o') || (!nick_isvoice(nick) && *mode == 'v'))) { my_send_to_server(this_server, "MODE %s +%s %s", channel, mode, from); if (get_int_var(SEND_OP_MSG_VAR)) my_send_to_server(this_server, "NOTICE %s :You have been delay Auto-%s'd", from, *mode == 'o'? "op":"voice"); } } new_free(&p); new_free(&sub); return 0; }
void add_numeric_fset(char *name, int remove, char *args, int verbose) { FsetNumber *tmp = numeric_fset, *last = NULL; int num = my_atol(name); for (tmp = numeric_fset; tmp; tmp = tmp->next) { if (num == tmp->numeric) { if (remove) { if (last) last->next = tmp->next; else numeric_fset = tmp->next; new_free(&tmp->format); new_free(&tmp); return; } else { if (args && *args) malloc_strcpy(&tmp->format, args); if (verbose) bitchsay("Numeric %d is %s", num, tmp->format); return; } } last = tmp; } if (!args || !*args) { if (verbose) bitchsay("No such Numeric Fset %d", num); return; } tmp = (FsetNumber *) new_malloc(sizeof(FsetNumber)); tmp->numeric = num; tmp->format = m_strdup(args); add_to_list_ext((List **)&numeric_fset, (List *)tmp, compare_number); if (verbose) bitchsay("Added Numeric %d as %s", num, tmp->format); }
static void set_speed(Window *win, char *value, int unused) { int def_speed = 0; if (value && *value) { for (def_speed = 0; _n_speed[def_speed]; def_speed++) { if (!my_strnicmp(value, _n_speed[def_speed], strlen(value))) break; } if (def_speed > MAX_SPEED) if (isdigit(*value)) def_speed = my_atol(value); if (def_speed > MAX_SPEED) def_speed = 0; } send_all_servers(CMDS_CHANGESPEED, "%d", def_speed); set_int_var(DEFAULT_SPEED_VAR, def_speed); set_string_var(DEFAULT_SPEED_VAR, _n_speed[def_speed]); return; }
char *make_fstring_var(const char *var_name) { IrcVariable *var = NULL; int cnt, msv_index; char *ret = NULL; char *tmp_var; tmp_var = LOCAL_COPY(var_name); upper(tmp_var); if ((var = find_ext_fset_var(tmp_var))) return m_strdup(var->string); if (!strncmp(tmp_var, "FORMAT_", 7)) tmp_var += 7; if ((find_fixed_array_item (fset_array, sizeof(IrcVariable), NUMBER_OF_FSET, tmp_var, &cnt, &msv_index) == NULL)) { if ((ret = find_numeric_fset(my_atol(tmp_var)))) return m_strdup(ret); return NULL; } if (cnt >= 0) return NULL; switch (fset_array[msv_index].type) { case STR_TYPE_VAR: ret = m_strdup(fset_array[msv_index].string); break; case INT_TYPE_VAR: ret = m_strdup(ltoa(fset_array[msv_index].integer)); break; case BOOL_TYPE_VAR: ret = m_strdup(var_settings[fset_array[msv_index].integer]); break; case CHAR_TYPE_VAR: ret = m_dupchar(fset_array[msv_index].integer); break; } return ret; }
int delay_kick (void *arg, char *sub) { char * args = (char *)arg; char * from = NULL; char * channel = NULL; char * serv_num = NULL; int this_server = from_server; int server; ChannelList *chan; char *p = (char *) arg; /* original args unmodified so we can free them */ if (protected) { from = next_arg(args, &args); channel = next_arg(args, &args); if ((serv_num = next_arg(args, &args))) this_server = my_atol(serv_num); if ((chan = prepare_command(&server, channel, 3))) my_send_to_server(this_server, "KICK %s %s :\002%s\002 Kick/ban me will ya", channel, from, _VERSION_); new_free(&protected); } new_free(&p); new_free(&sub); return 0; }
static char *parse_args (char *argv[], int argc, char **envp) { int ac; int add_servers = 0; char *channel = NULL; char *ptr; *nickname = 0; *password = 0; if ((ptr = getenv("NAPNICK"))) strmcpy(nickname, ptr, NICKNAME_LEN); if ((ptr = getenv("NAPPASS"))) strmcpy(password, ptr, NICKNAME_LEN); if ((ptr = getenv("NAP_HOST")) || (ptr = getenv("NAPHOST"))) malloc_strcpy(&LocalHostName, ptr); for ( ac = 1; ac < argc; ac++ ) { if (argv[ac][0] == '-') { switch (argv[ac][1]) { case 'r': /* Load list of servers from this file */ { char *what = empty_string; if (argv[ac][2]) what = &argv[ac][2]; else if (argv[ac+1] && argv[ac+1][0] != '-') { what = argv[ac+1]; ac++; } else fprintf(stderr, "Missing argumenT to -r\n"); if (*what) { add_servers = 1; malloc_strcpy(&ircservers_file, what); } break; } case 'a': /* add server, not replace */ { add_servers = 1; if (argv[ac][2]) fprintf(stderr, "Ignoring junk after -a\n"); break; } case 'H': { char *what = empty_string; if (argv[ac][2]) what = &(argv[ac][2]); else if (argv[ac+1] && argv[ac+1][0] != '-') { what = argv[ac+1]; ac++; } else { fprintf(stderr, "Specify a hostname\n"); exit(1); } malloc_strcpy(&LocalHostName, what); break; } case 'S': { if (argv[ac][2]) { char *what; what = &argv[ac][2]; starting_server = my_atol(what); } else { ac++; starting_server = my_atol(argv[ac]); } break; } case 'n': { char *what = empty_string; if (argv[ac][2]) what = &(argv[ac][2]); else if (argv[ac+1] && argv[ac+1][0] != '-') { what = argv[ac+1]; ac++; } else { fprintf(stderr,"Missing argument for -n\n"); exit(1); } strmcpy(nickname, what, NICKNAME_LEN); break; } case 'p': { char *pass = NULL; if ((pass = getpass("Enter Password :"******"%s %s\n", nap_version, internal_version); exit(1); #if defined(WINNT) || defined(EMX) case 's': setup_autoexec(); exit(1); #endif default: fprintf(stderr, "Unknown flag: %s\n",argv[ac]); case 'h': fprintf(stderr, "%s", switch_help); #if defined(WINNT) || defined(EMX) fprintf(stderr, "%s", switch_help_w); #endif exit(1); } /* End of switch */ } else { if (!strchr(argv[ac], '.')) strmcpy(nickname, argv[ac], NICKNAME_LEN); else build_server_list(argv[ac]); } } if ((ptr = getenv("NAPLIB"))) irc_lib = m_opendup("/", ptr, "/", NULL); else { char *s; if ((s = expand_twiddle(NAPLIB))) irc_lib = s; else malloc_strcpy(&irc_lib, NAPLIB); } if ((ptr = getenv("NAPPATH"))) malloc_strcpy(&irc_path, ptr); else { #ifdef NAPPATH malloc_strcpy(&irc_path, NAPPATH); #else #ifdef WINNT malloc_strcpy(&irc_path, ".:~/TekNap:"); #else malloc_strcpy(&irc_path, ".:~/.TekNap:"); #endif irc_path = m_opendup(irc_lib, "/", "script", NULL); #endif } if (LocalHostName) { struct hostent *hp; printf("Your hostname appears to be [%s]\n", LocalHostName); memset((void *)&LocalHostAddr, 0, sizeof(LocalHostAddr)); if ((hp = gethostbyname(LocalHostName))) memcpy((void *)&LocalHostAddr.sin_addr, hp->h_addr, sizeof(struct in_addr)); } if (!check_nickname(nickname)) { fprintf(stderr, "\n Invalid Nickname\n"); exit(1); } set_string_var(LOAD_PATH_VAR, irc_path); new_free(&irc_path); if ((ptr = getenv("HOME"))) malloc_strcpy(&my_path, ptr); if (!my_path || !*my_path) #ifdef WINNT { malloc_strcpy(&my_path, "//c/TekNap/"); bsd_setenv("HOME", "//c/TekNap", 1); } if (access("//c/TekNap", F_OK) != 0) { fprintf(stderr, "Directory doesn't exist, creating //c/TekNap\n"); mkdir("//c/TekNap", S_IWUSR|S_IRUSR|S_IXUSR); } #else malloc_strcpy(&my_path, "/"); #endif #if defined(WINNT) || defined(__EMX__) convert_unix(my_path); #endif if (!bircrc_file) malloc_sprintf(&bircrc_file, "%s%s", my_path, IRCRC_NAME); if ((ptr = getenv("NAPPORT"))) nap_port = my_atol(ptr); if ((ptr = getenv("NAPSERVER"))) build_server_list(ptr); #ifdef DEFAULT_SERVER { if (!read_server_list()) { ptr = LOCAL_COPY(DEFAULT_SERVER); build_server_list(ptr); } } #endif return (channel); }
void napfile_read(int snum) { GetFile *gf; int rc; SocketList *s; s = get_socket(snum); if (!(gf = (GetFile *)get_socketinfo(snum))) { unsigned char buff[2*BIG_BUFFER_SIZE+1]; unsigned char fbuff[2*BIG_BUFFER_SIZE+1]; char *nick, *filename, *args; alarm(10); if ((rc = read(snum, buff, 2 * BIG_BUFFER_SIZE)) < 0) { alarm(0); nap_finished_file(snum, PREMATURE_FINISH); return; } alarm(0); buff[rc] = 0; args = &buff[0]; if (!*args || !strcmp(buff, "FILE NOT FOUND") || !strcmp(buff, "INVALID REQUEST") || !strcmp(buff, "FILE NOT REQUESTED")) { say("Error in napfile_read(%d/%s) %s", snum, (rc == 0) ? strerror(errno) : "", *args ? args : "unknown read"); nap_finished_file(snum, PREMATURE_FINISH); return; } nick = next_arg(args, &args); if ((filename = new_next_arg(args, &args)) && *filename) { strcpy(fbuff, filename); convertnap_unix(fbuff); } if (!nick || !filename || !*filename || !args || !*args || !(gf = find_in_getfile(0, nick, NULL, fbuff, 0, NAP_UPLOAD)) || (gf->write == -1)) { memset(buff, 0, 80); if (!gf) sprintf(buff, "INVALID REQUEST"); else { sprintf(buff, "FILE NOT FOUND"); break_from_list((List **)&transfer_struct, (List *)gf); gf->socket = snum; if (gf->write == -1) { send_ncommand(CMDS_REMOVEFILE, "%s", fbuff); say("Unable to open [%s]", fbuff); } else { close(gf->write); gf->write = -1; } } write(snum, buff, strlen(buff)); nap_finished_file(snum, PREMATURE_FINISH); return; } gf->resume = my_atol(next_arg(args, &args)); if (gf->resume >= gf->filesize) { break_from_list((List **)&transfer_struct, (List *)gf); close(gf->write); gf->write = -1; nap_finished_file(snum, PREMATURE_FINISH); return; } if (gf->socket != -1) { put_it("ERROR gf->socket != -1 %d %s %s", snum, nick, filename); break_from_list((List **)&transfer_struct, (List *)gf); close(gf->write); gf->write = -1; nap_finished_file(snum, PREMATURE_FINISH); return; } gf->socket = snum; lseek(gf->write, SEEK_SET, gf->resume); set_socketinfo(snum, gf); memset(buff, 0, 80); sprintf(buff, "%lu", gf->filesize); write(snum, buff, strlen(buff)); s->func_write = s->func_read; s->is_write = s->is_read; if (do_hook(NAPSEND_LIST, "%s %s %lu \"%s\"", gf->resume ? "RESUME":"SEND", gf->nick, gf->filesize, gf->filename) && !get_int_var(QUIET_SENDS_VAR)) put_it("* %sing file to %s [%s] (%s)", gf->resume ? "Resum" : "Send", gf->nick, base_name(gf->filename), longcomma(gf->filesize)); set_non_blocking(snum); build_status(current_window, NULL, 0); send_ncommand(CMDS_UPDATE_SEND1, NULL); return; } else if (!gf->starttime) gf->starttime = now; s->func_write = s->func_read = napfile_sendfile; napfile_sendfile(snum); }
static Logfile * logfile_add (Logfile *log, char **args) { char *ptr; WNickList *new_w; char *arg = next_arg(*args, args); int i; if (!log) { say("ADD: You need to specify a logfile first"); return NULL; } if (!arg) say("ADD: Add nicknames/channels to be logged to this file"); else while (arg) { if ((ptr = strchr(arg, ','))) *ptr++ = 0; if (log->type == LOG_TARGETS) { if (!find_in_list((List **)&log->targets, arg, !USE_WILDCARDS)) { say("Added %s to log name list", arg); new_w = (WNickList *)new_malloc(sizeof(WNickList)); new_w->nick = malloc_strdup(arg); add_to_list((List **)&(log->targets), (List *)new_w); } else say("%s already on log name list", arg); } else if (log->type == LOG_SERVERS || log->type == LOG_WINDOWS) { int refnum; if (log->type == LOG_SERVERS && !my_strnicmp("ALL", arg, 1)) refnum = NOSERV; else refnum = my_atol(arg); for (i = 0; i < MAX_TARGETS; i++) { if (log->refnums[i] == refnum) { say("%s already on log refnum list", arg); break; } } for (i = 0; i < MAX_TARGETS; i++) { if (log->refnums[i] == -1) { say("Added %d to log name list", refnum); log->refnums[i] = refnum; break; } } if (i >= MAX_TARGETS) say("Could not add %d to log name list!", refnum); } arg = ptr; } return log; }
void set_var_value(int var_index, char *value, IrcVariable *dll) { char *rest; IrcVariable *var; int old; var = &(irc_variable[var_index]); switch (var->type) { case BOOL_TYPE_VAR: if (value && *value && (value = next_arg(value, &rest))) { old = var->integer; if (do_boolean(value, &(var->integer))) { say("Value must be either ON, OFF, or TOGGLE"); break; } if (!(var->int_flags & VIF_CHANGED)) { if (old != var->integer) var->int_flags |= VIF_CHANGED; } if (var->func) (var->func) (current_window, NULL, var->integer); say("Value of %s set to %s", var->name, var->integer ? var_settings[ON] : var_settings[OFF]); } else say("Value of %s -> %s", var->name, var->integer?var_settings[ON] : var_settings[OFF]); break; case CHAR_TYPE_VAR: if (!value) { if (!(var->int_flags & VIF_CHANGED)) { if (var->integer) var->int_flags |= VIF_CHANGED; } var->integer = ' '; if (var->func) (var->func) (current_window, NULL, var->integer); say("Value of %s set to '%c'", var->name, var->integer); } else if (value && *value && (value = next_arg(value, &rest))) { if (strlen(value) > 1) say("Value of %s must be a single character", var->name); else { if (!(var->int_flags & VIF_CHANGED)) { if (var->integer != *value) var->int_flags |= VIF_CHANGED; } var->integer = *value; if (var->func) (var->func) (current_window, NULL, var->integer); say("Value of %s set to '%c'", var->name, var->integer); } } else say("Value of %s -> %c", var->name, var->integer); break; case INT_TYPE_VAR: if (value && *value && (value = next_arg(value, &rest))) { int val; if (!is_number(value)) { say("Value of %s must be numeric!", var->name); break; } if ((val = my_atol(value)) < 0) { say("Value of %s must be greater than 0", var->name); break; } if (!(var->int_flags & VIF_CHANGED)) { if (var->integer != val) var->int_flags |= VIF_CHANGED; } var->integer = val; if (var->func) (var->func) (current_window, NULL, var->integer); say("Value of %s set to %d", var->name, var->integer); } else say("Value of %s -> %d", var->name, var->integer); break; case STR_TYPE_VAR: if (value) { if (*value) { char *temp = NULL; if (var->flags & VF_EXPAND_PATH) { temp = expand_twiddle(value); if (temp) value = temp; else say("SET: no such user"); } if ((!var->int_flags & VIF_CHANGED)) { if ((var->string && ! value) || (! var->string && value) || my_stricmp(var->string, value)) var->int_flags |= VIF_CHANGED; } malloc_strcpy(&(var->string), value); if (temp) new_free(&temp); } else { say("Value of %s -> %s", var->name, var->string ? var->string : "<null>"); return; } } else new_free(&(var->string)); if (var->func && !(var->int_flags & VIF_PENDING)) { var->int_flags |= VIF_PENDING; (var->func) (current_window, var->string, 0); var->int_flags &= ~VIF_PENDING; } say("Value of %s set to %s", var->name, var->string ? var->string : "<EMPTY>"); break; } }
/* * numbered_command: does (hopefully) the right thing with the numbered * responses from the server. I wasn't real careful to be sure I got them * all, but the default case should handle any I missed (sorry) * * The format of a numeric looks like so: * * :server-name XXX our-nick Arg1 Arg2 Arg3 ... :ArgN * * The last argument traditionally has a colon before it, but this is not * compulsary. The BreakArgs function has already broken this up into * words for us, so that what we get, looks like this: * * server-name -> from parameter * XXX -> comm parameter * our-nick -> ArgList[0] * Arg1 -> ArgList[1] * Arg2 -> ArgList[2] * ... ... * * BUT! There's a wrinkle in the ointment. The first thing we do is slurp * up ArgList[0] (our-nick) and put it in 'user'. Then we increment the * ArgList array, so what we actually end up with is: * * server-name -> from parameter * XXX -> comm parameter * our-nick -> user * Arg1 -> ArgList[0] * Arg2 -> ArgList[1] * ... ... * ArgN -> ArgList[N-1] * NULL -> ArgList[N] */ void numbered_command (const char *from, const char *comm, char const **ArgList) { const char *target; char *copy; int i; int lastlog_level; int old_current_numeric = current_numeric; int numeric; /* All numerics must have a target (our nickname) */ if (!comm || !*comm) { rfc1459_odd(from, comm, ArgList); return; } numeric = atol(comm); if (numeric < 0 || numeric > 999) { rfc1459_odd(from, comm, ArgList); return; } if (!(target = ArgList[0])) { rfc1459_odd(from, comm, ArgList); return; } ArgList++; lastlog_level = set_lastlog_msg_level(LOG_CRAP); if (ArgList[0] && is_channel(ArgList[0])) message_from(ArgList[0], LOG_CRAP); else message_from(NULL, LOG_CRAP); current_numeric = -numeric; /* must be negative of numeric! */ /* * This first switch statement is only used for those numerics * which either need to perform some action before the numeric * is offered to the user, or by those actions which need to offer * the numeric to the user in some special manner. * * Those numerics which require only special display if the user * does not hook them, are handled below. * * Those numerics which require special action after the numeric * is offered to the user, are also handled below. * * Each of these numerics must either "break" (go to step 2) * or must "goto END" (goto step 3). */ switch (numeric) { /* * I added the "set_server_nickname" here because the client * when auto-fudging your nick will sometimes be confused as * what your nickname really is when you connect. Since the * server always tells us who the message was set to (ie, us) * we just kind of take it at its word. */ case 001: /* #define RPL_WELCOME 001 */ { Timeval i; i.tv_sec = 0; i.tv_usec = 50000; select(0, NULL, NULL, NULL, &i); accept_server_nickname(from_server, target); server_is_registered(from_server, 1); userhostbase(from_server, NULL, got_my_userhost, 1); break; } /* * Now instead of the terribly horrible hack using numeric 002 * to get the server name/server version info, we use the 004 * numeric which is what is the most logical choice for it. * * If any of the arguments are missing, we don't abort, because * the client needs 004 to sync. Instead, we just pass in the * NULL values and hope for the best... */ case 004: /* #define RPL_MYINFO 004 */ { const char *server = NULL, *version = NULL, *umodes = NULL; /* The 004 numeric is too import to "odd server stuff" over. */ /* So if the reply is useless, we'll just wing it */ if (!(server = ArgList[0])) server = version = umodes = NULL; else if (!(version = ArgList[1])) server = version = umodes = NULL; else if (!(umodes = ArgList[2])) server = version = umodes = NULL; else { /* Work around ratbox-1.2-3. */ if (!my_stricmp(umodes, "(brown")) if (ArgList[3] && !my_stricmp(ArgList[3], "paper")) if (ArgList[4] && !my_stricmp(ArgList[4], "bag")) if (ArgList[5] && !my_stricmp(ArgList[5], "release)")) { if (!(umodes = ArgList[6])) { rfc1459_odd(from, comm, ArgList); goto END; } } } got_initial_version_28(server, version, umodes); break; } case 005: { int arg; char *set, *value; for (arg = 0; ArgList[arg] && !strchr(ArgList[arg], ' '); arg++) { set = LOCAL_COPY(ArgList[arg]); value = strchr(set, '='); if (value && *value) *value++ = 0; if (*set == '+') /* parameter append */ { const char *ov = get_server_005(from_server, ++set); value = malloc_strdup2(ov, value); set_server_005(from_server, set, value); new_free(&value); } else if (*set == '-') /* parameter removal */ set_server_005(from_server, ++set, NULL); else if (value && *value) set_server_005(from_server, set, value); else set_server_005(from_server, set, space); } break; } case 10: /* EFNext "Use another server" 010 */ { const char *new_server, *new_port_s, *message; int new_port, old_server; PasteArgs(ArgList, 2); if (!(new_server = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(new_port_s = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } new_port = atol(ArgList[1]); /* Must do these things before calling "display_msg" */ old_server = from_server; add_to_server_list(new_server, new_port, NULL, NULL, get_server_group(from_server), NULL, 0); server_reconnects_to(old_server, from_server); from_server = old_server; break; } case 14: /* Erf/TS4 "cookie" numeric 014 */ { const char * cookie; PasteArgs(ArgList, 0); if (!(cookie = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } use_server_cookie(from_server); set_server_cookie(from_server, cookie); goto END; } case 42: /* ircnet's "unique id" numeric 042 */ { const char * unique_id; const char * message; PasteArgs(ArgList, 1); if (!(unique_id = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } else if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } set_server_unique_id(from_server, unique_id); if (do_hook(current_numeric, "%s %s %s", from, unique_id, message)) goto DISPLAY; goto END; } case 301: /* #define RPL_AWAY 301 */ { const char *nick, *message; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } /* Ach. /on 301 doesn't offer 'from' as $0. Bummer. */ if (do_hook(current_numeric, "%s %s", nick, message)) goto DISPLAY; goto END; } case 340: /* #define RPL_USERIP 307 */ if (!get_server_005(from_server, "USERIP")) break; /* FALLTHROUGH */ case 302: /* #define RPL_USERHOST 302 */ userhost_returned(from_server, from, comm, ArgList); goto END; case 303: /* #define RPL_ISON 303 */ ison_returned(from_server, from, comm, ArgList); goto END; case 315: /* #define RPL_ENDOFWHO 315 */ who_end(from_server, from, comm, ArgList); goto END; case 321: /* #define RPL_LISTSTART 321 */ { const char *channel, *user_cnt, *line; channel = ArgList[0] = "Channel"; user_cnt = ArgList[1] = "Users"; line = ArgList[2] = "Topic"; ArgList[3] = NULL; /* Then see if they want to hook /ON LIST */ if (!do_hook(LIST_LIST, "%s %s %s", channel, user_cnt, line)) goto END; /* * Otherwise, this line is ok. */ break; } case 322: /* #define RPL_LIST 322 */ { const char *channel, *user_cnt, *line; int cnt; int funny_flags, funny_min, funny_max; const char *funny_match; PasteArgs(ArgList, 2); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(user_cnt = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(line = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } funny_flags = get_server_funny_flags(from_server); funny_min = get_server_funny_min(from_server); funny_max = get_server_funny_max(from_server); funny_match = get_server_funny_match(from_server); /* * Do not display if the channel has no topic and the user asked * for only channels with topics. */ if (funny_flags & FUNNY_TOPIC && !(line && *line)) goto END; /* * Do not display if the channel does not have the necessary * number of users the user asked for */ cnt = my_atol(user_cnt); if (funny_min && (cnt < funny_min)) goto END; if (funny_max && (cnt > funny_max)) goto END; /* * Do not display if the channel is not private or public as the * user requested. */ if ((funny_flags & FUNNY_PRIVATE) && (*channel != '*')) goto END; if ((funny_flags & FUNNY_PUBLIC) && (*channel == '*')) goto END; /* * Do not display if the channel does not match the user's * supplied wildcard pattern */ if (funny_match && wild_match(funny_match, channel) == 0) goto END; /* Then see if they want to hook /ON LIST */ if (!do_hook(LIST_LIST, "%s %s %s", channel, user_cnt, line)) goto END; /* * Otherwise, this line is ok. */ break; } case 324: /* #define RPL_CHANNELMODEIS 324 */ { const char *mode, *channel; PasteArgs(ArgList, 1); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(mode = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } /* If we're waiting for MODE reply. */ if (channel_is_syncing(channel, from_server)) { int numonchannel, maxnum; copy = LOCAL_COPY(channel); update_channel_mode(channel, mode); update_all_status(); maxnum = get_server_max_cached_chan_size(from_server); if (maxnum >= 0) { numonchannel = number_on_channel(copy, from_server); if (numonchannel <= maxnum) whobase(from_server, copy, add_user_who, add_user_end); else channel_not_waiting(copy, from_server); } else whobase(from_server, copy, add_user_who, add_user_end); #if 0 goto END; #endif } break; } case 352: /* #define RPL_WHOREPLY 352 */ whoreply(from_server, NULL, comm, ArgList); goto END; case 353: /* #define RPL_NAMREPLY 353 */ { const char *type, *channel, *line; PasteArgs(ArgList, 2); if (!(type = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channel = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(line = ArgList[2])) { line = empty_string; } if (channel_is_syncing(channel, from_server)) { char *line_copy = LOCAL_COPY(line); char *nick; while ((nick = next_arg(line_copy, &line_copy)) != NULL) { /* XXX - Hack to work around space at end of 353 */ forcibly_remove_trailing_spaces(nick, NULL); /* * 1999 Oct 29 -- This is a hack to compensate for * a bug in older ircd implementations that can result * in a truncated nickname at the end of a names reply. * The last nickname in a names list is then always * treated with suspicion until the WHO reply is * completed and we know that its not truncated. --esl */ if (!line || !*line) add_to_channel(channel, nick, from_server, 1, 0, 0, 0); else add_to_channel(channel, nick, from_server, 0, 0, 0, 0); } message_from(channel, LOG_CRAP); break; } else { int cnt; const char *ptr; int funny_flags, funny_min, funny_max; const char *funny_match; funny_flags = get_server_funny_flags(from_server); funny_min = get_server_funny_min(from_server); funny_max = get_server_funny_max(from_server); funny_match = get_server_funny_match(from_server); ptr = line; for (cnt = -1; ptr; cnt++) { if ((ptr = strchr(ptr, ' ')) != NULL) ptr++; } if (funny_min && (cnt < funny_min)) goto END; else if (funny_max && (cnt > funny_max)) goto END; if ((funny_flags & FUNNY_PRIVATE) && (*type == '=')) goto END; if ((funny_flags & FUNNY_PUBLIC) && ((*type == '*') || (*type == '@'))) goto END; if (funny_match && wild_match(funny_match, channel) == 0) goto END; } /* Everything is OK. */ break; } case 354: /* #define RPL_XWHOREPLY 354 */ xwhoreply(from_server, NULL, comm, ArgList); goto END; /* XXX Yea yea, these are out of order. so shoot me. */ case 346: /* #define RPL_INVITELIST (+I for erf) */ case 348: /* #define RPL_EXCEPTLIST (+e for erf) */ case 367: /* #define RPL_BANLIST */ number_of_bans++; break; case 347: /* #define END_OF_INVITELIST */ case 349: /* #define END_OF_EXCEPTLIST */ case 368: /* #define END_OF_BANLIST */ { const char *channel; if (!get_int_var(SHOW_END_OF_MSGS_VAR)) goto END; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } #ifdef IRCII_LIKE_BAN_SUMMARY if (do_hook(current_numeric, "%s %s %d", from, channel, number_of_bans)) #else if (do_hook(current_numeric, "%s %d %s", from, number_of_bans, channel)) #endif { put_it("%s Total number of %s on %s - %d", banner(), numeric == 347 ? "invites" : (numeric == 349 ? "exceptions" : (numeric == 368 ? "bans" : "wounds")), channel, number_of_bans); } goto END; } /* XXX Shouldn't this set "You're operator" flag for hybrid? */ case 381: /* #define RPL_YOUREOPER 381 */ if (!is_server_registered(from_server)) { rfc1459_odd(from, comm, ArgList); goto END; } break; /* ":%s 401 %s %s :No such nick/channel" */ case 401: /* #define ERR_NOSUCHNICK 401 */ { const char *nick; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!is_channel(nick)) { notify_mark(from_server, nick, 0, 0); if (get_int_var(AUTO_WHOWAS_VAR)) { int foo = get_int_var(NUM_OF_WHOWAS_VAR); if (foo > -1) send_to_server("WHOWAS %s %d", nick, foo); else send_to_server("WHOWAS %s", nick); } } break; } /* Bizarre dalnet extended who replies. */ /* ":%s 402 %s %s :No such server" */ case 402: { const char *server; if (!(server = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } fake_who_end(from_server, from, comm, server); break; } /* Yet more bizarre dalnet extended who replies. */ /* ":%s 522 %s :/WHO Syntax incorrect, use /who ? for help" */ /* ":%s 523 %s :Error, /who limit of %d exceed." */ case 522: case 523: { /* * This dalnet error message doesn't even give us the * courtesy of telling us which who request was in error, * so we have to guess. Whee. */ fake_who_end(from_server, from, comm, NULL); break; } case 403: /* #define ERR_NOSUCHCHANNEL 403 */ { const char * s; const char * channel; const char * message; PasteArgs(ArgList, 1); /* Some servers BBC and send back an empty reply. */ if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } /* Do not accept 403's from remote servers. */ s = get_server_itsname(from_server); if (my_strnicmp(s, from, strlen(s))) { rfc1459_odd(from, comm, ArgList); goto END; } /* * Some servers BBC and send this instead of a * 315 numeric when a who request has been completed. */ if (fake_who_end(from_server, from, comm, channel)) ; /* * If you try to JOIN or PART the "*" named channel, as may * happen if epic gets confused, the server may tell us that * channel does not exist. But it would be death to try to * destroy that channel as epic will surely do the wrong thing! * Otherwise, we somehow tried to reference a channel that * this server claims does not exist; we blow the channel away * for good measure. */ else if (strcmp(channel, "*")) remove_channel(channel, from_server); break; } case 421: /* #define ERR_UNKNOWNCOMMAND 421 */ { const char *token; if (!(token = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (check_server_redirect(from_server, token)) goto END; if (check_server_wait(from_server, token)) goto END; break; } case 432: /* #define ERR_ERRONEUSNICKNAME 432 */ { const char *nick; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!my_stricmp(target, nick)) yell("WARNING: Strange invalid nick message received." " You are probably lagged."); else if (get_int_var(AUTO_NEW_NICK_VAR)) fudge_nickname(from_server); else reset_nickname(from_server); break; } case 437: /* av2.9's "Nick collision" numeric 437 */ /* Also, undernet/dalnet "You are banned" */ /* Also, av2.10's "Can't do that" numeric */ /* Also, cs's "too many nick changes" num */ { /* * Ugh. What a total trainwreck this is. Sometimes, I * really hate all the ircd's out there in the world that * have to be supported. * * Well, there are at least four different, occasionally * scrutable ways we can get this numeric. * * 1a) On ircnet -- As an unregistered user, the NICK that * we are trying to register was used in the past 90 * seconds or so. The server expects us to send * another NICK request. * ARGV[0] IS NICK, REGISTERED IS NO * 1b) On ircnet -- As a registered user, the NICK that * we are trying to register was used in the past 90 * seconds or so. The server expects us not to do * anything (like a 432 numeric). * ARGV[0] IS NICK, REGISTERED IS YES * 2) On ircnet -- As a registered user, we are trying to * join a channel that was netsplit in the past 24 hours * or so. The server expects us not to do anything. * ARGV[0] IS CHANNEL, REGISTERED IS YES * 3) On undernet/dalnet -- As a registered user, who is * on a channel where we are banned, a NICK request * was rejected (because we are banned). The server * expects us not to do anything. * ARGV[0] IS CHANNEL, REGISTERED IS YES * 4) On a comstud efnet servers -- As a registered user, * we have changed our nicknames too many times in * too short a time. The server expects us not to do * anything. * ARGV[0] IS ERROR, ARGV[1] IS NULL. * I understand this numeric will be moving to 439. */ /* * Weed out the comstud one first, since it's the most bizarre. */ if (ArgList[0] && ArgList[1] == NULL) { accept_server_nickname(from_server, target); break; } /* * Now if it's a channel, it might be ircnet telling us we * can't join the channel, or undernet telling us that we * can't change our nickname because we're banned. The * easiest way to tell is to see if we are on the channel. */ if (is_channel(ArgList[0])) { /* XXX Is this really neccesary? */ if (!im_on_channel(ArgList[0], from_server)) remove_channel(ArgList[0], from_server); break; } /* * Otherwise, a nick command failed. Oh boy. * If we are registered, abort the nick change and * hope for the best. */ if (is_server_registered(from_server)) { accept_server_nickname(from_server, target); break; } /* * Otherwise, it's an ircnet "nick not available" error. * Let the nickname reset numerics handle this mess. */ /* FALLTHROUGH */ } case 433: /* #define ERR_NICKNAMEINUSE 433 */ case 438: /* EFnet/TS4 "nick collision" numeric 438 */ case 453: /* EFnet/TS4 "nickname lost" numeric 453 */ { const char *nick; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!my_stricmp(target, nick)) /* * This should stop the "rolling nicks" in their tracks. */ yell("WARNING: Strange invalid nick message received." " You are probably lagged."); else if (get_int_var(AUTO_NEW_NICK_VAR)) fudge_nickname(from_server); else reset_nickname(from_server); if (!from) from = "-1"; break; } case 439: /* Comstud's "Can't change nickname" */ { accept_server_nickname(from_server, target); break; } case 442: /* #define ERR_NOTONCHANNEL 442 */ { const char * s; const char * channel; const char * message; PasteArgs(ArgList, 1); /* Some servers BBC and send back an empty reply. */ if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } /* Do not accept this numeric from remote servers */ s = get_server_itsname(from_server); if (my_strnicmp(s, from, strlen(s))) { rfc1459_odd(from, comm, ArgList); goto END; } /* Do not ever delete the "*" channel */ if (strcmp(ArgList[0], "*")) remove_channel(ArgList[0], from_server); break; } case 451: /* #define ERR_NOTREGISTERED 451 */ /* * Sometimes the server doesn't catch the USER line, so * here we send a simplified version again -lynx */ register_server(from_server, NULL); break; case 462: /* #define ERR_ALREADYREGISTRED 462 */ change_server_nickname(from_server, NULL); break; case 465: /* #define ERR_YOUREBANNEDCREEP 465 */ { /* * There used to be a say() here, but if we arent * connected to a server, then doing say() is not * a good idea. So now it just doesnt do anything. */ server_reconnects_to(from_server, NOSERV); break; } case 477: /* #define ERR_NEEDREGGEDNICK 477 */ /* IRCnet has a different 477 numeric. */ if (ArgList[0] && *ArgList[0] == '+') break; /* FALLTHROUGH */ case 471: /* #define ERR_CHANNELISFULL 471 */ case 473: /* #define ERR_INVITEONLYCHAN 473 */ case 474: /* #define ERR_BANNEDFROMCHAN 474 */ case 475: /* #define ERR_BADCHANNELKEY 475 */ case 476: /* #define ERR_BADCHANMASK 476 */ { const char *channel; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } cant_join_channel(ArgList[0], from_server); break; } } /* DEFAULT OFFER */ /* * This is the "default hook" case, where we offer to the user all of * the numerics that were not offered above. We simply catenate * all of the arguments into a string and offer to the user. * If the user bites, then we skip the "default display" section. */ copy = alloca(IRCD_BUFFER_SIZE + 1); *copy = 0; for (i = 0; ArgList[i]; i++) { if (i) strlcat(copy, " ", IRCD_BUFFER_SIZE); strlcat(copy, ArgList[i], IRCD_BUFFER_SIZE); } if (!do_hook(current_numeric, "%s %s", from, copy)) goto END; DISPLAY: /* DEFAULT DISPLAY */ /* * This is the "default display" case, where if the user does not * hook the numeric, we output the message in some special way. * If a numeric does not require special outputting, then we will * just display it with ``display_msg'' */ switch (numeric) { case 221: /* #define RPL_UMODEIS 221 */ { const char *umode; PasteArgs(ArgList, 0); if (!(umode = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s Your user mode is \"%s\"", banner(), umode); break; } case 271: /* #define SILENCE_LIST 271 */ { const char *perp, *victim; PasteArgs(ArgList, 1); if (!(perp = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(victim = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s is ignoring %s", banner(), perp, victim); break; } case 301: /* #define RPL_AWAY 301 */ { const char *nick, *message; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s is away: %s", banner(), nick, message); break; } case 311: /* #define RPL_WHOISUSER 311 */ { const char *nick, *user, *host, *channel, *name; PasteArgs(ArgList, 4); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(user = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(host = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channel = ArgList[3])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(name = ArgList[4])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s is %s@%s (%s)", banner(), nick, user, host, name); break; } case 312: /* #define RPL_WHOISSERVER 312 */ { const char *nick, *server, *pithy; PasteArgs(ArgList, 2); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(server = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(pithy = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s on irc via server %s (%s)", banner(), server, pithy); break; } case 313: /* #define RPL_WHOISOPERATOR 313 */ { const char *nick, *message; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s %s", banner(), ArgList[0], ArgList[1]); break; } case 314: /* #define RPL_WHOWASUSER 314 */ { const char *nick, *user, *host, *unused, *name; PasteArgs(ArgList, 4); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(user = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(host = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(unused = ArgList[3])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(name = ArgList[4])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s was %s@%s (%s)",banner(), nick, user, host, name); break; } case 317: /* #define RPL_WHOISIDLE 317 */ { const char *nick, *idle_str, *startup_str; int idle; const char * unit; char startup_ctime[128]; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(idle_str = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(startup_str = ArgList[2])) { /* No problem */; } *startup_ctime = 0; if (startup_str) /* Undernet/TS4 */ { time_t startup; if ((startup = atol(startup_str)) != 0) snprintf(startup_ctime, 128, ", signed on at %s", my_ctime(startup)); } if ((idle = atoi(idle_str)) > 59) { idle /= 60; unit = "minute"; } else unit = "second"; put_it ("%s %s has been idle %d %ss%s", banner(), nick, idle, unit, startup_ctime); break; } case 318: /* #define RPL_ENDOFWHOIS 318 */ { PasteArgs(ArgList, 0); if (get_int_var(SHOW_END_OF_MSGS_VAR)) display_msg(from, comm, ArgList); break; } case 319: /* #define RPL_WHOISCHANNELS 319 */ { const char *nick, *channels; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channels = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s on channels: %s", banner(), channels); break; } case 321: /* #define RPL_LISTSTART 321 */ /* Our screwy 321 handling demands this. BAH! */ put_it("%s Channel Users Topic", banner()); break; case 322: /* #define RPL_LIST 322 */ { static char format[25]; static int last_width = -1; const char *channel, *user_cnt, *line; PasteArgs(ArgList, 2); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(user_cnt = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(line = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } /* Figure out how to display this to the user. */ if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR)) { if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR))) snprintf(format, 25, "%%-%u.%us %%-5s %%s", (unsigned) last_width, (unsigned) last_width); else strlcpy(format, "%s\t%-5s %s", sizeof format); } if (*channel == '*') say(format, "Prv", user_cnt, line); else say(format, check_channel_type(channel), user_cnt, line); break; } case 324: /* #define RPL_CHANNELMODEIS 324 */ { const char *mode, *channel; PasteArgs(ArgList, 1); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(mode = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s Mode for channel %s is \"%s\"", banner(), channel, mode); break; } case 329: /* #define CREATION_TIME 329 */ { const char *channel, *time1_str, *time2_str, *time3_str; time_t time1, time2, time3; PasteArgs(ArgList, 2); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(time1_str = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(time2_str = ArgList[2])) { /* No problem */; } if (!(time3_str = ArgList[3])) { /* No problem */; } /* Erf/TS4 support */ if (time2_str && time3_str) { time1 = (time_t)my_atol(time1_str); time2 = (time_t)my_atol(time2_str); time3 = (time_t)my_atol(time3_str); put_it("%s Channel %s was created at %ld, " "+c was last set at %ld, " "and has been opless since %ld", banner(), channel, time1, time2, time3); } else { time1 = (time_t)my_atol(time1_str); put_it("%s Channel %s was created at %s", banner(), channel, my_ctime(time1)); } break; } case 330: /* #define RPL_WHOISLOGGEDIN 330 */ { const char *nick, *login, *reason; PasteArgs(ArgList, 2); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(login = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(reason = ArgList[2])) { reason = "is logged in as"; } put_it("%s %s %s %s", banner(), nick, reason, login); break; } case 332: /* #define RPL_TOPIC 332 */ { const char *channel, *topic; PasteArgs(ArgList, 1); if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(topic = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s Topic for %s: %s", banner(), channel, topic); break; } case 333: /* #define RPL_TOPICWHOTIME 333 */ { const char *channel, *nick, *when_str; time_t howlong; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(nick = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(when_str = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } howlong = time(NULL) - my_atol(when_str); put_it("%s The topic was set by %s %ld sec ago",banner(), nick, howlong); break; } case 341: /* #define RPL_INVITING 341 */ { const char *nick, *channel; if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channel = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } message_from(channel, LOG_CRAP); put_it("%s Inviting %s to channel %s", banner(), nick, channel); break; } case 351: /* #define RPL_VERSION 351 */ { const char *version, *itsname, *stuff; PasteArgs(ArgList, 2); if (!(version = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(itsname = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(stuff = ArgList[2])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s Server %s: %s %s",banner(), itsname, version, stuff); break; } case 353: /* #define RPL_NAMREPLY 353 */ { static int last_width; char format[41]; const char *type, *channel, *line; PasteArgs(ArgList, 2); if (!(type = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(channel = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(line = ArgList[2])) { line = empty_string; } /* This is only for when the user joined the channel */ if (channel_is_syncing(channel, from_server)) { /* If the user bites on /ON NAMES, then skip the rest */ message_from(channel, LOG_CRAP); if (do_hook(NAMES_LIST, "%s %s", channel, line)) if (get_int_var(SHOW_CHANNEL_NAMES_VAR)) say("Users on %s: %s", check_channel_type(channel), line); break; } /* If the user grabs /ON NAMES then just stop right here */ if (!do_hook(NAMES_LIST, "%s %s", channel, line)) break; /* This all is for when the user has not just joined channel */ if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR)) { if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR))) snprintf(format, 40, "%%s: %%-%u.%us %%s", (unsigned char) last_width, (unsigned char) last_width); else strlcpy(format, "%s: %s\t%s", sizeof format); } else strlcpy(format, "%s: %s\t%s", sizeof format); message_from(channel, LOG_CRAP); if (*type == '=') { if (last_width && ((int)strlen(channel) > last_width)) { char *channel_copy = LOCAL_COPY(channel); channel_copy[last_width-1] = '>'; channel_copy[last_width] = 0; channel = channel_copy; } put_it(format, "Pub", check_channel_type(channel), line); } else if (*type == '*') put_it(format, "Prv", check_channel_type(channel), line); else if (*type == '@') put_it(format, "Sec", check_channel_type(channel), line); break; } case 364: /* #define RPL_LINKS 364 */ { const char *itsname, *uplink, *stuff; PasteArgs(ArgList, 2); if (!(itsname = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(uplink = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(stuff = ArgList[2])) { stuff = empty_string; } if (stuff) put_it("%s %-20s %-20s %s", banner(), itsname, uplink, stuff); else put_it("%s %-20s %s", banner(), itsname, uplink); break; } case 366: /* #define RPL_ENDOFNAMES 366 */ { const char *channel; if (!get_int_var(SHOW_END_OF_MSGS_VAR)) break; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!channel_is_syncing(channel, from_server)) display_msg(from, comm, ArgList); break; } case 346: /* +I on erf */ case 348: /* +e on erf */ case 367: /* +b */ { const char *channel, *ban, *perp, *when_str; time_t howlong; if (!(channel = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(ban = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(perp = ArgList[2])) { /* No problem. */ } if (!(when_str = ArgList[3])) { /* No problem. */ } if (perp && when_str) { howlong = time(NULL) - my_atol(when_str); put_it("%s %s %-25s set by %-10s %ld sec ago", banner(), channel, ban, perp, howlong); } else put_it("%s %s %s", banner(), channel, ban); break; } case 401: /* #define ERR_NOSUCHNICK 401 */ { const char *nick, *stuff; PasteArgs(ArgList, 1); if (!(nick = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } if (!(stuff = ArgList[1])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s: %s", banner(), nick, stuff); break; } case 219: /* #define RPL_ENDOFSTATS 219 */ case 232: /* #define RPL_ENDOFSERVICES 232 */ case 365: /* #define RPL_ENDOFLINKS 365 */ case 369: /* #define RPL_ENDOFWHOWAS 369 */ case 374: /* #define RPL_ENDOFINFO 374 */ case 394: /* #define RPL_ENDOFUSERS 394 */ { PasteArgs(ArgList, 0); if (get_int_var(SHOW_END_OF_MSGS_VAR)) display_msg(from, comm, ArgList); break; } case 471: /* #define ERR_CHANNELISFULL 471 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (Channel is full)", banner(), message); break; } case 473: /* #define ERR_INVITEONLYCHAN 473 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (You must be invited)", banner(), message); break; } case 474: /* #define ERR_BANNEDFROMCHAN 474 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (You are banned)", banner(), message); break; } case 475: /* #define ERR_BADCHANNELKEY 475 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (You must give the correct key)", banner(), message); break; } case 476: /* #define ERR_BADCHANMASK 476 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } put_it("%s %s (Bad channel mask)", banner(), message); break; } case 477: /* #define ERR_NEEDREGGEDNICK 477 */ { const char *message; PasteArgs(ArgList, 0); if (!(message = ArgList[0])) { rfc1459_odd(from, comm, ArgList); goto END; } /* IRCnet has a different 477 numeric. */ if (message && *message == '+') { display_msg(from, comm, ArgList); break; } PasteArgs(ArgList, 0); put_it("%s %s (You must use a registered nickname)", banner(), message); break; } default: display_msg(from, comm, ArgList); } END: /* * This is where we clean up after our numeric. Numeric-specific * cleanups can occur here, and then below we reset the display * settings. */ switch (numeric) { case 347: /* #define END_OF_INVITELIST */ case 349: /* #define END_OF_EXCEPTLIST */ case 368: number_of_bans = 0; break; case 464: /* #define ERR_PASSWDMISMATCH 464 */ { char server_num[8]; if (oper_command) oper_command = 0; else if (!is_server_registered(from_server)) { server_reconnects_to(from_server, NOSERV); say("Password required for connection to server %s", get_server_name(from_server)); if (!dumb_mode) { strlcpy(server_num, ltoa(from_server), sizeof server_num); add_wait_prompt("Server Password:", password_sendline, server_num, WAIT_PROMPT_LINE, 0); } } } } current_numeric = old_current_numeric; set_lastlog_msg_level(lastlog_level); message_from(NULL, LOG_CRAP); }
/* * set_var_value: Given the variable structure and the string representation * of the value, this sets the value in the most verbose and error checking * of manors. It displays the results of the set and executes the function * defined in the var structure */ int set_variable (const char *name, IrcVariable *var, const char *orig_value, int noisy) { char *rest; int changed = 0; unsigned char *value; int retval = 0; if (orig_value) value = LOCAL_COPY(orig_value); else value = NULL; switch (var->type) { case BOOL_VAR: { if (value && *value && (value = next_arg(value, &rest))) { if (do_boolean(value, &(var->data->integer))) { say("Value must be either ON, OFF, or TOGGLE"); retval = -1; } else changed = 1; } break; } case CHAR_VAR: { int codepoint; if (!value || !*value) { var->data->integer = ' '; changed = 1; break; } if ((codepoint = next_code_point((const unsigned char **)&value, 0)) == -1) { say("New value of %s could not be determined", name); retval = -1; break; } if (codepoint_numcolumns(codepoint) != 1) { say("New value of %s must be exactly 1 column wide", name); retval = -1; break; } var->data->integer = codepoint; changed = 1; break; } case INT_VAR: { if (value && *value && (value = next_arg(value, &rest))) { int val; if (!is_number(value)) { say("Value of %s must be numeric!", name); retval = -1; } else if ((val = my_atol(value)) < 0) { say("Value of %s must be a non-negative number", name); retval = -1; } else { var->data->integer = val; changed = 1; } } break; } case STR_VAR: { if (!value) { new_free(&(var->data->string)); changed = 1; } else if (*value) { malloc_strcpy(&(var->data->string), value); changed = 1; } } } if (changed) { if ((var->func || var->script) && !(var->flags & VIF_PENDING)) { var->flags |= VIF_PENDING; if (var->func) (var->func)(var->data); if (var->script) { char *s; int owd = window_display; s = make_string_var_bydata(var->type, (void *)var->data); window_display = 0; call_lambda_command("SET", var->script, s); window_display = owd; new_free(&s); } var->flags &= ~VIF_PENDING; } } if (noisy) show_var_value(name, var, changed); return retval; }