/* Change nick's mode in channel */ static void nick_mode_change(IRC_CHANNEL_REC *channel, const char *nick, char mode, int type, const char *setby) { NICK_REC *nickrec; char modestr[2], typestr[2]; g_return_if_fail(IS_IRC_CHANNEL(channel)); g_return_if_fail(nick != NULL); nickrec = nicklist_find(CHANNEL(channel), nick); if (nickrec == NULL) return; /* No /names list got yet */ if (mode == '@') nickrec->op = type == '+'; else if (mode == '+') nickrec->voice = type == '+'; else if (mode == '%') nickrec->halfop = type == '+'; if (channel->server->prefix[(unsigned char) mode] != '\0') { if (type == '+') prefix_add(nickrec->prefixes, mode, (SERVER_REC *) channel->server); else prefix_del(nickrec->prefixes, mode); } modestr[0] = mode; modestr[1] = '\0'; typestr[0] = type; typestr[1] = '\0'; signal_emit("nick mode changed", 5, channel, nickrec, setby, modestr, typestr); }
/** load cty database from filename */ int load_ctydata(char *filename) { FILE *fd; char buf[181] = ""; char *loc; if ((fd = fopen(filename, "r")) == NULL) return -1; dxcc_init(); prefix_init(); // set default for empty country dxcc_add("Not Specified : --: --: --: -00.00: 00.00: 0.0: :"); while (fgets(buf, sizeof(buf), fd) != NULL) { g_strchomp(buf); /* drop CR and/or NL and */ if (*buf == '\0') /* ignore empty lines */ continue; if (buf[0] != ' ') { // data line dxcc_add(buf); } else // prefix line { loc = strtok(buf, " ,;"); while (loc != NULL) { prefix_add (loc); loc = strtok(NULL, " ,;"); } } } fclose(fd); return 0; }
int prefix_del(const char* ifname, int ifindex, const char* prefixPlain, int prefixLength) { return prefix_add(ifname, ifindex, prefixPlain, prefixLength, 0, 0); }
int prefix_update(const char* ifname, int ifindex, const char* prefixPlain, int prefixLength, unsigned long prefered, unsigned long valid) { return prefix_add(ifname, ifindex, prefixPlain, prefixLength, prefered, valid); }
static void event_names_list(IRC_SERVER_REC *server, const char *data) { IRC_CHANNEL_REC *chanrec; NICK_REC *rec; char *params, *type, *channel, *names, *ptr, *host; int op, halfop, voice; char prefixes[MAX_USER_PREFIXES+1]; const char *nick_flags, *nick_flag_cur, *nick_flag_op; g_return_if_fail(data != NULL); params = event_get_params(data, 4, NULL, &type, &channel, &names); chanrec = irc_channel_find(server, channel); if (chanrec == NULL || chanrec->names_got) { /* unknown channel / names list already read */ g_free(params); return; } nick_flags = server->get_nick_flags(SERVER(server)); nick_flag_op = strchr(nick_flags, '@'); /* type = '=' = public, '*' = private, '@' = secret. This is actually pretty useless to check here, but at least we get to know if the channel is +p or +s a few seconds before we receive the MODE reply... If the channel key is set, assume the channel is +k also until we know better, so parse_channel_modes() won't clear the key */ if (*type == '*') { parse_channel_modes(chanrec, NULL, chanrec->key ? "+kp" : "+p", FALSE); } else if (*type == '@') { parse_channel_modes(chanrec, NULL, chanrec->key ? "+ks" : "+s", FALSE); } while (*names != '\0') { while (*names == ' ') names++; ptr = names; while (*names != '\0' && *names != ' ') names++; if (*names != '\0') *names++ = '\0'; /* some servers show ".@nick", there's also been talk about showing "@+nick" and since none of these chars are valid nick chars, just check them until a non-nickflag char is found. */ op = halfop = voice = FALSE; prefixes[0] = '\0'; while (isnickflag(server, *ptr)) { prefix_add(prefixes, *ptr, (SERVER_REC *) server); switch (*ptr) { case '@': op = TRUE; break; case '%': halfop = TRUE; break; case '+': voice = TRUE; break; default: /* If this flag is listed higher than op (in the * isupport PREFIX reply), then count this user * as an op. */ nick_flag_cur = strchr(nick_flags, *ptr); if (nick_flag_cur && nick_flag_op && nick_flag_cur < nick_flag_op) { op = TRUE; } break; } ptr++; } host = strchr(ptr, '!'); if (host != NULL) *host++ = '\0'; if (nicklist_find((CHANNEL_REC *) chanrec, ptr) == NULL) { rec = irc_nicklist_insert(chanrec, ptr, op, halfop, voice, FALSE, prefixes); if (host != NULL) nicklist_set_host(CHANNEL(chanrec), rec, host); } } g_free(params); }
int main(int argc, char*argv[]) { const char *cfgfile="cfg_notion"; const char *display=NULL; char *cmd=NULL; int stflags=0; int opt; ErrorLog el; FILE *ef=NULL; char *efnam=NULL; bool may_continue=FALSE; bool noerrorlog=FALSE; char *localedir; libtu_init(argv[0]); #ifdef CF_RELOCATABLE_BIN_LOCATION prefix_set(argv[0], CF_RELOCATABLE_BIN_LOCATION); #endif localedir=prefix_add(LOCALEDIR); if(!ioncore_init(CF_EXECUTABLE, argc, argv, localedir)) return EXIT_FAILURE; if(localedir!=NULL) free(localedir); prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR); /* ion-completefile */ prefix_wrap_simple(extl_add_searchdir, MODULEDIR); prefix_wrap_simple(extl_add_searchdir, ETCDIR); prefix_wrap_simple(extl_add_searchdir, SHAREDIR); prefix_wrap_simple(extl_add_searchdir, LCDIR); extl_set_userdirs(CF_EXECUTABLE); optparser_init(argc, argv, OPTP_MIDLONG, ion_opts); while((opt=optparser_get_opt())){ switch(opt){ case OPT_ID('d'): display=optparser_get_arg(); break; case 'c': cfgfile=optparser_get_arg(); break; case 's': extl_add_searchdir(optparser_get_arg()); break; case OPT_ID('S'): ioncore_g.sm_client_id=optparser_get_arg(); break; case OPT_ID('o'): stflags|=IONCORE_STARTUP_ONEROOT; break; case OPT_ID('s'): extl_set_sessiondir(optparser_get_arg()); break; case OPT_ID('N'): noerrorlog=TRUE; break; case 'h': help(); return EXIT_SUCCESS; case 'V': printf("%s\n", ION_VERSION); return EXIT_SUCCESS; case OPT_ID('a'): printf("%s\n", ioncore_aboutmsg()); return EXIT_SUCCESS; default: warn(TR("Invalid command line.")); help(); return EXIT_FAILURE; } } if(!noerrorlog){ /* We may have to pass the file to xmessage so just using tmpfile() * isn't sufficient. */ libtu_asprintf(&efnam, "%s/ion-%d-startup-errorlog", P_tmpdir, getpid()); if(efnam==NULL){ warn_err(); }else{ ef=fopen(efnam, "wt"); if(ef==NULL){ warn_err_obj(efnam); free(efnam); efnam=NULL; }else{ cloexec_braindamage_fix(fileno(ef)); fprintf(ef, TR("Notion startup error log:\n")); errorlog_begin_file(&el, ef); } } } if(ioncore_startup(display, cfgfile, stflags)) may_continue=TRUE; if(!may_continue) warn(TR("Refusing to start due to encountered errors.")); else check_new_user_help(); if(ef!=NULL){ pid_t pid=-1; if(errorlog_end(&el) && ioncore_g.dpy!=NULL){ fclose(ef); pid=fork(); if(pid==0){ ioncore_setup_display(DefaultScreen(ioncore_g.dpy)); if(!may_continue) XCloseDisplay(ioncore_g.dpy); else close(ioncore_g.conn); libtu_asprintf(&cmd, CF_XMESSAGE " %s", efnam); if(cmd==NULL){ warn_err(); }else if(system(cmd)==-1){ warn_err_obj(cmd); } unlink(efnam); exit(EXIT_SUCCESS); } if(!may_continue && pid>0) waitpid(pid, NULL, 0); }else{ fclose(ef); } if(pid<0) unlink(efnam); free(efnam); } if(!may_continue) return EXIT_FAILURE; ioncore_mainloop(); /* The code should never return here */ return EXIT_SUCCESS; }