static void help_category(GSList *cmdlist, int items) { WINDOW_REC *window; TEXT_DEST_REC dest; GString *str; GSList *tmp; int *columns, cols, rows, col, row, last_col_rows, max_width; char *linebuf, *format, *stripped; window = window_find_closest(NULL, NULL, MSGLEVEL_CLIENTCRAP); max_width = window->width; /* remove width of timestamp from max_width */ format_create_dest(&dest, NULL, NULL, MSGLEVEL_CLIENTCRAP, NULL); format = format_get_line_start(current_theme, &dest, time(NULL)); if (format != NULL) { stripped = strip_codes(format); max_width -= strlen(stripped); g_free(stripped); g_free(format); } /* calculate columns */ cols = get_max_column_count(cmdlist, get_cmd_length, max_width, 6, 1, 3, &columns, &rows); cmdlist = columns_sort_list(cmdlist, rows); /* rows in last column */ last_col_rows = rows-(cols*rows-g_slist_length(cmdlist)); if (last_col_rows == 0) last_col_rows = rows; str = g_string_new(NULL); linebuf = g_malloc(max_width+1); col = 0; row = 0; for (tmp = cmdlist; tmp != NULL; tmp = tmp->next) { COMMAND_REC *rec = tmp->data; memset(linebuf, ' ', columns[col]); linebuf[columns[col]] = '\0'; memcpy(linebuf, rec->cmd, strlen(rec->cmd)); g_string_append(str, linebuf); if (++col == cols) { printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s", str->str); g_string_truncate(str, 0); col = 0; row++; if (row == last_col_rows) cols--; } } if (str->len != 0) printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s", str->str); g_slist_free(cmdlist); g_string_free(str, TRUE); g_free(columns); g_free(linebuf); }
void print_load_message(void) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Hello, World. xxx \"%s\"", MODULE_NAME); }
static void show_help(const char *data) { COMMAND_REC *rec, *last; GSList *tmp, *cmdlist; int items, findlen; int header, found, fullmatch; g_return_if_fail(data != NULL); /* sort the commands list */ commands = g_slist_sort(commands, (GCompareFunc) commands_equal); /* print command, sort by category */ cmdlist = NULL; last = NULL; header = FALSE; fullmatch = FALSE; items = 0; findlen = strlen(data); found = FALSE; for (tmp = commands; tmp != NULL; last = rec, tmp = tmp->next) { rec = tmp->data; if (last != NULL && rec->category != NULL && (last->category == NULL || strcmp(rec->category, last->category) != 0)) { /* category changed */ if (items > 0) { if (!header) { printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "Irssi commands:"); header = TRUE; } if (last->category != NULL) { printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, ""); printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s:", last->category); } help_category(cmdlist, items); } g_slist_free(cmdlist); cmdlist = NULL; items = 0; } if (last != NULL && g_strcasecmp(rec->cmd, last->cmd) == 0) continue; /* don't display same command twice */ if ((int)strlen(rec->cmd) >= findlen && g_strncasecmp(rec->cmd, data, findlen) == 0) { if (rec->cmd[findlen] == '\0') { fullmatch = TRUE; found = TRUE; break; } else if (strchr(rec->cmd+findlen+1, ' ') == NULL) { /* not a subcommand (and matches the query) */ items++; cmdlist = g_slist_append(cmdlist, rec); found = TRUE; } } } if ((!found || fullmatch) && !show_help_file(data)) { printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "No help for %s", data); } if (*data != '\0' && data[strlen(data)-1] != ' ' && command_have_sub(data)) { char *cmd; cmd = g_strconcat(data, " ", NULL); show_help(cmd); g_free(cmd); } if (items != 0) { /* display the last category */ if (!header) { printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "Irssi commands:"); header = TRUE; } if (last->category != NULL) { printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, ""); printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s:", last->category); } help_category(cmdlist, items); g_slist_free(cmdlist); } }
static void display_sorted_nicks(CHANNEL_REC *channel, GSList *nicklist) { WINDOW_REC *window; TEXT_DEST_REC dest; GString *str; GSList *tmp; char *format, *stripped, *prefix_format; char *aligned_nick, nickmode[2] = { 0, 0 }; int *columns, cols, rows, last_col_rows, col, row, max_width; int item_extra, formatnum; window = window_find_closest(channel->server, channel->visible_name, MSGLEVEL_CLIENTCRAP); max_width = window->width; /* get the length of item extra stuff ("[ ] ") */ format = format_get_text(MODULE_NAME, NULL, channel->server, channel->visible_name, TXT_NAMES_NICK, " ", ""); stripped = strip_codes(format); item_extra = strlen(stripped); g_free(stripped); g_free(format); if (settings_get_int("names_max_width") > 0 && settings_get_int("names_max_width") < max_width) max_width = settings_get_int("names_max_width"); /* remove width of the timestamp from max_width */ format_create_dest(&dest, channel->server, channel->visible_name, MSGLEVEL_CLIENTCRAP, NULL); format = format_get_line_start(current_theme, &dest, time(NULL)); if (format != NULL) { stripped = strip_codes(format); max_width -= strlen(stripped); g_free(stripped); g_free(format); } /* remove width of the prefix from max_width */ prefix_format = format_get_text(MODULE_NAME, NULL, channel->server, channel->visible_name, TXT_NAMES_PREFIX, channel->visible_name); if (prefix_format != NULL) { stripped = strip_codes(prefix_format); max_width -= strlen(stripped); g_free(stripped); } if (max_width <= 0) { /* we should always have at least some space .. if we really don't, it won't show properly anyway. */ max_width = 10; } /* calculate columns */ cols = get_max_column_count(nicklist, get_nick_length, max_width, settings_get_int("names_max_columns"), item_extra, 3, &columns, &rows); nicklist = columns_sort_list(nicklist, rows); /* rows in last column */ last_col_rows = rows-(cols*rows-g_slist_length(nicklist)); if (last_col_rows == 0) last_col_rows = rows; str = g_string_new(prefix_format); col = 0; row = 0; for (tmp = nicklist; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; if (rec->prefixes[0]) nickmode[0] = rec->prefixes[0]; else nickmode[0] = ' '; aligned_nick = get_alignment(rec->nick, columns[col]-item_extra, ALIGN_PAD, ' '); formatnum = rec->op ? TXT_NAMES_NICK_OP : rec->halfop ? TXT_NAMES_NICK_HALFOP : rec->voice ? TXT_NAMES_NICK_VOICE : TXT_NAMES_NICK; format = format_get_text(MODULE_NAME, NULL, channel->server, channel->visible_name, formatnum, nickmode, aligned_nick); g_string_append(str, format); g_free(aligned_nick); g_free(format); if (++col == cols) { printtext(channel->server, channel->visible_name, MSGLEVEL_CLIENTCRAP, "%s", str->str); g_string_truncate(str, 0); if (prefix_format != NULL) g_string_assign(str, prefix_format); col = 0; row++; if (row == last_col_rows) cols--; } } if (prefix_format != NULL && str->len > strlen(prefix_format)) { printtext(channel->server, channel->visible_name, MSGLEVEL_CLIENTCRAP, "%s", str->str); } g_slist_free(nicklist); g_string_free(str, TRUE); g_free_not_null(columns); g_free_not_null(prefix_format); }
void print_unload_message(void) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Goodbye, Cruel World. ~signed \"%s\"", MODULE_NAME); }
/* why doesn't this get called? */ static void intr_catch(int sig) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "got sig %d", sig); PyErr_SetInterrupt(); }
static void cmd_load(const char *data) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Dynamic modules loading not supported"); }
void printstatus(void) { int c, d, color; int cc = cursorcolortable[cursorflash]; menu = 0; if ((mouseb > MOUSEB_LEFT) && (mousey <= 1) && (!eamode)) menu = 1; printblankc(0, 0, 15+16, MAX_COLUMNS); if (!menu) { if (!strlen(loadedsongfilename)) sprintf(textbuffer, "%s", programname); else sprintf(textbuffer, "%s - %s", programname, loadedsongfilename); textbuffer[49] = 0; printtext(0, 0, 15+16, textbuffer); if (usefinevib) printtext(40+10, 0, 15+16, "FV"); if (optimizepulse) printtext(43+10, 0, 15+16, "PO"); if (optimizerealtime) printtext(46+10, 0, 15+16, "RO"); if (ntsc) printtext(49+10, 0, 15+16, "NTSC"); else printtext(49+10, 0, 15+16, " PAL"); if (!sidmodel) printtext(54+10, 0, 15+16, "6581"); else printtext(54+10, 0, 15+16, "8580"); sprintf(textbuffer, "HR:%04X", adparam); printtext(59+10, 0, 15+16, textbuffer); if (eamode) printbg(62+10+eacolumn, 0, cc, 1); if (multiplier) { sprintf(textbuffer, "%2dX", multiplier); printtext(67+10, 0, 15+16, textbuffer); } else printtext(67+10, 0, 15+16, "25Hz"); printtext(72+20, 0, 15+16, "F12=HELP"); } else { printtext(0, 0, 15+16, " PLAY | PLAYPOS | PLAYPATT | STOP | LOAD | SAVE | PACK/RL | HELP | CLEAR | QUIT |"); } if ((followplay) && (isplaying())) { for (c = 0; c < MAX_CHN; c++) { int newpos = chn[c].pattptr / 4; if (chn[c].advance) epnum[c] = chn[c].pattnum; if (newpos > pattlen[epnum[c]]) newpos = pattlen[epnum[c]]; if (c == epchn) { eppos = newpos; epview = newpos-VISIBLEPATTROWS/2; } newpos = chn[c].songptr; newpos--; if (newpos < 0) newpos = 0; if (newpos > songlen[esnum][c]) newpos = songlen[esnum][c]; if ((c == eschn) && (chn[c].advance)) { eseditpos = newpos; if (newpos - esview < 0) { esview = newpos; } if (newpos - esview >= VISIBLEORDERLIST) { esview = newpos - VISIBLEORDERLIST + 1; } } } } for (c = 0; c < MAX_CHN; c++) { sprintf(textbuffer, "CHN %d PATT.%02X", c+1, epnum[c]); printtext(2+c*15, 2, CTITLE, textbuffer); for (d = 0; d < VISIBLEPATTROWS; d++) { int p = epview+d; color = CNORMAL; if ((epnum[c] == chn[c].pattnum) && (isplaying())) { int chnrow = chn[c].pattptr / 4; if (chnrow > pattlen[chn[c].pattnum]) chnrow = pattlen[chn[c].pattnum]; if (chnrow == p) color = CPLAYING; } if (chn[c].mute) color = CMUTE; if (p == eppos) color = CEDIT; if ((p < 0) || (p > pattlen[epnum[c]])) { sprintf(textbuffer, " "); } else { if (!patternhex) { if (p < 100) sprintf(textbuffer, " %02d", p); else sprintf(textbuffer, "%03d", p); } else sprintf(textbuffer, " %02X", p); if (pattern[epnum[c]][p*4] == ENDPATT) { sprintf(&textbuffer[3], " PATT. END"); if (color == CNORMAL) color = CCOMMAND; } else { sprintf(&textbuffer[3], " %s %02X%01X%02X", notename[pattern[epnum[c]][p*4]-FIRSTNOTE], pattern[epnum[c]][p*4+1], pattern[epnum[c]][p*4+2], pattern[epnum[c]][p*4+3]); } } textbuffer[3] = 0; if (p%stepsize) { printtext(2+c*15, 3+d, CNORMAL, textbuffer); } else { printtext(2+c*15, 3+d, CCOMMAND, textbuffer); } printtext(6+c*15, 3+d, color, &textbuffer[4]); if (c == epmarkchn) { if (epmarkstart <= epmarkend) { if ((p >= epmarkstart) && (p <= epmarkend)) printbg(2+c*15+4, 3+d, 1, 9); } else { if ((p <= epmarkstart) && (p >= epmarkend)) printbg(2+c*15+4, 3+d, 1, 9); } } if ((color == CEDIT) && (editmode == EDIT_PATTERN) && (epchn == c)) { switch(epcolumn) { case 0: if (!eamode) printbg(2+c*15+4, 3+d, cc, 3); break; default: if (!eamode) printbg(2+c*15+7+epcolumn, 3+d, cc, 1); break; } } } } sprintf(textbuffer, "CHN ORDERLIST (SUBTUNE %02X, POS %02X)", esnum, eseditpos); printtext(40+10, 2, CTITLE, textbuffer); for (c = 0; c < MAX_CHN; c++) { sprintf(textbuffer, " %d ", c+1); printtext(40+10, 3+c, 15, textbuffer); for (d = 0; d < VISIBLEORDERLIST; d++) { int p = esview+d; color = CNORMAL; if (isplaying()) { int chnpos = chn[c].songptr; chnpos--; if (chnpos < 0) chnpos = 0; if ((p == chnpos) && (chn[c].advance)) color = CPLAYING; } if (p == espos[c]) color = CEDIT; if ((esend[c]) && (p == esend[c])) color = CEDIT; if ((p < 0) || (p > (songlen[esnum][c]+1)) || (p > MAX_SONGLEN+1)) { sprintf(textbuffer, " "); } else { if (songorder[esnum][c][p] < LOOPSONG) { if ((songorder[esnum][c][p] < REPEAT) || (p >= songlen[esnum][c])) { sprintf(textbuffer, "%02X ", songorder[esnum][c][p]); if ((p >= songlen[esnum][c]) && (color == CNORMAL)) color = CCOMMAND; } else { if (songorder[esnum][c][p] >= TRANSUP) { sprintf(textbuffer, "+%01X ", songorder[esnum][c][p]&0xf); if (color == CNORMAL) color = CCOMMAND; } else { if (songorder[esnum][c][p] >= TRANSDOWN) { sprintf(textbuffer, "-%01X ", 16-(songorder[esnum][c][p] & 0x0f)); if (color == CNORMAL) color = CCOMMAND; } else { sprintf(textbuffer, "R%01X ", (songorder[esnum][c][p]+1) & 0x0f); if (color == CNORMAL) color = CCOMMAND; } } } } if (songorder[esnum][c][p] == LOOPSONG) { sprintf(textbuffer, "RST"); if (color == CNORMAL) color = CCOMMAND; } } printtext(44+10+d*3, 3+c, color, textbuffer); if (c == esmarkchn) { if (esmarkstart <= esmarkend) { if ((p >= esmarkstart) && (p <= esmarkend)) { if (p != esmarkend) printbg(44+10+d*3, 3+c, 1, 3); else printbg(44+10+d*3, 3+c, 1, 2); } } else { if ((p <= esmarkstart) && (p >= esmarkend)) { if (p != esmarkstart) printbg(44+10+d*3, 3+c, 1, 3); else printbg(44+10+d*3, 3+c, 1, 2); } } } if ((p == eseditpos) && (editmode == EDIT_ORDERLIST) && (eschn == c)) { if (!eamode) printbg(44+10+d*3+escolumn, 3+c, cc, 1); } } } sprintf(textbuffer, "INSTRUMENT NUM. %02X %-16s", einum, instr[einum].name); printtext(40+10, 7, CTITLE, textbuffer); sprintf(textbuffer, "Attack/Decay %02X", instr[einum].ad); if (eipos == 0) color = CEDIT; else color = CNORMAL; printtext(40+10, 8, color, textbuffer); sprintf(textbuffer, "Sustain/Release %02X", instr[einum].sr); if (eipos == 1) color = CEDIT; else color = CNORMAL; printtext(40+10, 9, color, textbuffer); sprintf(textbuffer, "Wavetable Pos %02X", instr[einum].ptr[WTBL]); if (eipos == 2) color = CEDIT; else color = CNORMAL; printtext(40+10, 10, color, textbuffer); sprintf(textbuffer, "Pulsetable Pos %02X", instr[einum].ptr[PTBL]); if (eipos == 3) color = CEDIT; else color = CNORMAL; printtext(40+10, 11, color, textbuffer); sprintf(textbuffer, "Filtertable Pos %02X", instr[einum].ptr[FTBL]); if (eipos == 4) color = CEDIT; else color = CNORMAL; printtext(40+10, 12, color, textbuffer); sprintf(textbuffer, "Vibrato Param %02X", instr[einum].ptr[STBL]); if (eipos == 5) color = CEDIT; else color = CNORMAL; printtext(60+10, 8, color, textbuffer); sprintf(textbuffer, "Vibrato Delay %02X", instr[einum].vibdelay); if (eipos == 6) color = CEDIT; else color = CNORMAL; printtext(60+10, 9, color, textbuffer); sprintf(textbuffer, "HR/Gate Timer %02X", instr[einum].gatetimer); if (eipos == 7) color = CEDIT; else color = CNORMAL; printtext(60+10, 10, color, textbuffer); sprintf(textbuffer, "1stFrame Wave %02X", instr[einum].firstwave); if (eipos == 8) color = CEDIT; else color = CNORMAL; printtext(60+10, 11, color, textbuffer); if (editmode == EDIT_INSTRUMENT) { if (eipos < 9) { if (!eamode) printbg(56+10+eicolumn+20*(eipos/5), 8+(eipos%5), cc, 1); } else { if (!eamode) printbg(60+10+strlen(instr[einum].name), 7, cc, 1); } } sprintf(textbuffer, "WAVE TBL PULSETBL FILT.TBL SPEEDTBL"); printtext(40+10, 14, CTITLE, textbuffer); for (c = 0; c < MAX_TABLES; c++) { for (d = 0; d < VISIBLETABLEROWS; d++) { int p = etview[c]+d; color = CNORMAL; switch (c) { case WTBL: if (ltable[c][p] >= WAVECMD) color = CCOMMAND; break; case PTBL: if (ltable[c][p] >= 0x80) color = CCOMMAND; break; case FTBL: if ((ltable[c][p] >= 0x80) || ((!ltable[c][p]) && (rtable[c][p]))) color = CCOMMAND; break; } if ((p == etpos) && (etnum == c)) color = CEDIT; sprintf(textbuffer, "%02X:%02X %02X", p+1, ltable[c][p], rtable[c][p]); printtext(40+10+10*c, 15+d, color, textbuffer); if (etmarknum == c) { if (etmarkstart <= etmarkend) { if ((p >= etmarkstart) && (p <= etmarkend)) printbg(40+10+10*c+3, 15+d, 1, 5); } else { if ((p <= etmarkstart) && (p >= etmarkend)) printbg(40+10+10*c+3, 15+d, 1, 5); } } } } if (editmode == EDIT_TABLES) { if (!eamode) printbg(43+10+etnum*10+(etcolumn & 1)+(etcolumn/2)*3, 15+etpos-etview[etnum], cc, 1); } printtext(40+10, 31, CTITLE, "NAME "); sprintf(textbuffer, "%-32s", songname); printtext(47+10, 31, CEDIT, textbuffer); printtext(40+10, 32, CTITLE, "AUTHOR "); sprintf(textbuffer, "%-32s", authorname); printtext(47+10, 32, CEDIT, textbuffer); printtext(40+10, 33, CTITLE, "COPYR. "); sprintf(textbuffer, "%-32s", copyrightname); printtext(47+10, 33, CEDIT, textbuffer); if ((editmode == EDIT_NAMES) && (!eamode)) { switch(enpos) { case 0: printbg(47+10+strlen(songname), 31, cc, 1); break; case 1: printbg(47+10+strlen(authorname), 32, cc, 1); break; case 2: printbg(47+10+strlen(copyrightname), 33, cc, 1); break; } } sprintf(textbuffer, "OCTAVE %d", epoctave); printtext(0, 35, CTITLE, textbuffer); switch(autoadvance) { case 0: color = 10; break; case 1: color = 14; break; case 2: color = 12; break; } if (recordmode) printtext(0, 36, color, "EDITMODE"); else printtext(0, 36, color, "JAM MODE"); if (isplaying()) printtext(10, 35, CTITLE, "PLAYING"); else printtext(10, 35, CTITLE, "STOPPED"); if (multiplier) { if (!ntsc) sprintf(textbuffer, " %02d%c%02d ", timemin, timechar[timeframe/(25*multiplier) & 1], timesec); else sprintf(textbuffer, " %02d%c%02d ", timemin, timechar[timeframe/(30*multiplier) & 1], timesec); } else { if (!ntsc) sprintf(textbuffer, " %02d%c%02d ", timemin, timechar[(timeframe/13) & 1], timesec); else sprintf(textbuffer, " %02d%c%02d ", timemin, timechar[(timeframe/15) & 1], timesec); } printtext(10, 36, CEDIT, textbuffer); printtext(80, 35, CTITLE, " CHN1 CHN2 CHN3 "); for (c = 0; c < MAX_CHN; c++) { int chnpos = chn[c].songptr; int chnrow = chn[c].pattptr/4; chnpos--; if (chnpos < 0) chnpos = 0; if (chnrow > pattlen[chn[c].pattnum]) chnrow = pattlen[chn[c].pattnum]; if (chnrow >= 100) chnrow -= 100; sprintf(textbuffer, "%03d/%02d", chnpos,chnrow); printtext(80+7*c, 36, CEDIT, textbuffer); } if (etlock) printtext(78, 36, CTITLE, " "); else printtext(78, 36, CTITLE, "U"); }
static void handle_exec(const char *args, GHashTable *optlist, WI_ITEM_REC *item) { PROCESS_REC *rec; char *target, *level; int notice, signum, interactive, target_nick, target_channel; /* check that there's no unknown options. we allowed them because signals can be used as options, but there should be only one unknown option: the signal name/number. */ signum = cmd_options_get_signal("exec", optlist); if (signum == -2) return; if (*args == '\0') { exec_show_list(); return; } target = NULL; notice = FALSE; if (g_hash_table_lookup(optlist, "in") != NULL) { rec = process_find(g_hash_table_lookup(optlist, "in"), TRUE); if (rec != NULL) { net_sendbuffer_send(rec->out, args, strlen(args)); net_sendbuffer_send(rec->out, "\n", 1); } return; } /* check if args is a process ID or name. if it's ID but not found, complain about it and fail immediately */ rec = process_find(args, *args == '%'); if (*args == '%' && rec == NULL) return; /* common options */ target_channel = target_nick = FALSE; if (g_hash_table_lookup(optlist, "out") != NULL) { /* redirect output to active channel/query */ if (item == NULL) cmd_return_error(CMDERR_NOT_JOINED); target = (char *) window_item_get_target(item); target_channel = IS_CHANNEL(item); target_nick = IS_QUERY(item); } else if (g_hash_table_lookup(optlist, "msg") != NULL) { /* redirect output to /msg <nick> */ target = g_hash_table_lookup(optlist, "msg"); } else if (g_hash_table_lookup(optlist, "notice") != NULL) { target = g_hash_table_lookup(optlist, "notice"); notice = TRUE; } /* options that require process ID/name as argument */ if (rec == NULL && (signum != -1 || g_hash_table_lookup(optlist, "close") != NULL)) { printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Unknown process name: %s", args); return; } if (g_hash_table_lookup(optlist, "close") != NULL) { /* forcibly close the process */ process_destroy(rec, -1); return; } if (signum != -1) { /* send a signal to process */ kill(rec->pid, signum); return; } interactive = g_hash_table_lookup(optlist, "interactive") != NULL; if (*args == '%') { /* do something to already existing process */ char *name; if (target != NULL) { /* redirect output to target */ g_free_and_null(rec->target); rec->target = g_strdup(target); rec->notice = notice; } name = g_hash_table_lookup(optlist, "name"); if (name != NULL) { /* change window name */ g_free_not_null(rec->name); rec->name = *name == '\0' ? NULL : g_strdup(name); } else if (target == NULL && (rec->target_item == NULL || interactive)) { /* no parameters given, redirect output to the active window */ g_free_and_null(rec->target); rec->target_win = active_win; if (rec->target_item != NULL) exec_wi_destroy(rec->target_item); if (interactive) { rec->target_item = exec_wi_create(active_win, rec); } } return; } /* starting a new process */ rec = g_new0(PROCESS_REC, 1); rec->pid = -1; rec->shell = g_hash_table_lookup(optlist, "nosh") == NULL; process_exec(rec, args); if (rec->pid == -1) { /* pipe() or fork() failed */ g_free(rec); cmd_return_error(CMDERR_ERRNO); } rec->id = process_get_new_id(); rec->target = g_strdup(target); rec->target_win = active_win; rec->target_channel = target_channel; rec->target_nick = target_nick; rec->args = g_strdup(args); rec->notice = notice; rec->silent = g_hash_table_lookup(optlist, "-") != NULL; rec->quiet = g_hash_table_lookup(optlist, "quiet") != NULL; rec->name = g_strdup(g_hash_table_lookup(optlist, "name")); level = g_hash_table_lookup(optlist, "level"); rec->level = level == NULL ? MSGLEVEL_CLIENTCRAP : level2bits(level); rec->read_tag = g_input_add(rec->in, G_INPUT_READ, (GInputFunction) sig_exec_input_reader, rec); processes = g_slist_append(processes, rec); if (rec->target == NULL && interactive) rec->target_item = exec_wi_create(active_win, rec); signal_emit("exec new", 1, rec); }
static void cmdout_co(ICB_SERVER_REC *server, char **args) { char *p, *group, *topic; int len; static const char match_group[] = "Group: "; static const char match_topic[] = "Topic: "; static const char match_topicunset[] = "(None)"; static const char match_topicis[] = "The topic is"; static const char match_total[] = "Total: "; /* * Use 'co' as the marker to denote wl lines have finished, so * reset the nick updates */ server->updatenicks = FALSE; /* If we're running in silent mode, parse the output for nicks/topic */ if (server->silentwho) { /* Match group lines */ len = strlen(match_group); if (strncmp(args[0], match_group, len) == 0) { group = g_strdup(args[0] + len); p = strchr(group, ' '); *p = '\0'; /* Check for our particular group */ len = strlen(group); if (g_ascii_strncasecmp(group, server->group->name, len) == 0) { /* Start matching nicks */ server->updatenicks = TRUE; p = strstr(args[0], match_topic); if (p != NULL && p != args[0]) { topic = p + strlen(match_topic); if (topic != NULL) { len = strlen(match_topicunset); if (strncmp(topic, match_topicunset, len) != 0) { /* No way to find who set the topic, mark as unknown */ icb_change_topic(server, topic, "unknown", time(NULL)); } } } } g_free(group); } /* * End of /who output, stop silent mode and signal front-end * to display /names list */ len = strlen(match_total); if (strncmp(args[0], match_total, len) == 0) { server->silentwho = FALSE; signal_emit("channel joined", 1, server->group); } } else { /* Now that /topic works correctly, ignore server output */ len = strlen(match_topicis); if (strncmp(args[0], match_topicis, len) != 0) { printtext(server, NULL, MSGLEVEL_CRAP, "%s", args[0]); } } }
void showhelp(const char *filename) { char nc,nr,ph; char *title,*text; union { char *buffer; void *vbuf; } buf; // This is to avoild type-punning issues char line[512]; size_t size; char scan; int rv,numlines,curr_line; nc = getnumcols(); nr = getnumrows(); ph = nr - HELP_BOTTOM_MARGIN - HELP_BODY_ROW - 1; cls(); drawbox(0,0,nr,nc-1,HELPPAGE,0x07,HELPBOX); drawhorizline(2,0,nc-1,HELPPAGE,0x07,HELPBOX,0); // dumb==0 if (filename == NULL) { // print file contents gotoxy(HELP_BODY_ROW,HELP_LEFT_MARGIN,HELPPAGE); cswprint("Filename not given",0x07,HELP_LEFT_MARGIN); while (1) { inputc(&scan); if (scan == ESCAPE) break; } cls(); return; } rv = loadfile(filename,(void **)&buf.vbuf, &size); // load entire file into memory if (rv < 0) { // Error reading file or no such file sprintf(line, "Error reading file or file not found\n file=%s",filename); gotoxy(HELP_BODY_ROW,HELP_LEFT_MARGIN,HELPPAGE); cswprint(line,0x07,HELP_LEFT_MARGIN); while (1) { inputc(&scan); if (scan == ESCAPE) break; } cls(); return; } title = buf.buffer; text = findline(title,1); // end of first line *text++='\0'; // end the title string and increment text // Now we have a file just print it. gotoxy(1,(nc-strlen(title))/2,HELPPAGE); csprint(title,0x07); numlines = countlines(text); curr_line = 0; scan = ESCAPE+1; // anything except ESCAPE while(scan != ESCAPE) { printtext(text,curr_line); gotoxy(HELP_BODY_ROW-1,nc-HELP_RIGHT_MARGIN,HELPPAGE); if (curr_line > 0) putch(HELP_MORE_ABOVE,0x07,HELPPAGE); else putch(' ',0x07,HELPPAGE); gotoxy(nr-HELP_BOTTOM_MARGIN+1,nc-HELP_RIGHT_MARGIN,HELPPAGE); if (curr_line < numlines - ph) putch(HELP_MORE_BELOW,0x07,HELPPAGE); else putch(' ',0x07,HELPPAGE); inputc(&scan); // wait for user keypress switch(scan) { case HOMEKEY: curr_line = 0; break; case ENDKEY: curr_line = numlines; break; case UPARROW: curr_line--; break; case DNARROW: curr_line++; break; case PAGEUP: curr_line -= ph; break; case PAGEDN: curr_line += ph; break; default: break; } if (curr_line > numlines - ph) curr_line = numlines-ph; if (curr_line < 0) curr_line = 0; } cls(); return; }
/** * Sets the key for a nick / channel in a server * @param data command * @param server irssi server record * @param item irssi window/item */ void cmd_setkey(const char *data, SERVER_REC * server, WI_ITEM_REC * item) { GHashTable *optlist; char contactName[CONTACT_SIZE] = "", encryptedKey[150] = ""; const char *target, *key; void *free_arg; if (IsNULLorEmpty(data)) { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 No parameters. Usage: /setkey [-<server tag>] [<nick | #channel>] <key>"); return; } if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, "setkey", &optlist, &target, &key)) return; if (*target == '\0') { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 No parameters. Usage: /setkey [-<server tag>] [<nick | #channel>] <key>"); cmd_params_free(free_arg); return; } server = cmd_options_get_server("setkey", optlist, server); if (server == NULL || !server->connected) cmd_param_error(CMDERR_NOT_CONNECTED); if (*key == '\0') { // one paramter given - it's the key key = target; if (item != NULL) target = window_item_get_target(item); else { printtext(NULL, NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Please define nick/#channel. Usage: /setkey [-<server tag>] [<nick | #channel>] <key>"); cmd_params_free(free_arg); return; } } encrypt_key((char *)key, encryptedKey); if (getIniSectionForContact(server, target, contactName) == FALSE) return; if (setIniValue(contactName, "key", encryptedKey, iniPath) == -1) { ZeroMemory(encryptedKey, sizeof(encryptedKey)); printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH ERROR:\002 Unable to write to blow.ini, probably out of space or permission denied."); cmd_params_free(free_arg); return; } ZeroMemory(encryptedKey, sizeof(encryptedKey)); printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Key for %s@%s successfully set!", target, server->tag); cmd_params_free(free_arg); }
void cmd_setinipw(const char *iniPW, SERVER_REC * server, WI_ITEM_REC * item) { int pw_len, re_enc = 0; char B64digest[50] = { '\0' }; char key[32] = { '\0' }; char hash[32] = { '\0' }; char new_iniKey[KEYBUF_SIZE], old_iniKey[KEYBUF_SIZE], iniPath_new[300]; strcpy(old_iniKey, iniKey); if (iniPW != NULL) { pw_len = strlen(iniPW); if (pw_len < 1 || (size_t) pw_len > sizeof(new_iniKey)) { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 No parameters. Usage: /setinipw <sekure_blow.ini_password>"); return; } if (strfcpy(new_iniKey, (char *)iniPW, sizeof(new_iniKey)) == NULL) return; ZeroMemory(iniPW, pw_len); pw_len = strlen(new_iniKey); if (pw_len < 8) { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Password too short, at least 8 characters needed! Usage: /setinipw <sekure_blow.ini_password>"); return; } key_from_password(new_iniKey, key); htob64(key, B64digest, 32); ZeroMemory(new_iniKey, sizeof(new_iniKey)); strcpy(iniKey, B64digest); // this is used for encrypting blow.ini } else { strcpy(iniKey, default_iniKey); // use default blow.ini key } key_hash(key, hash); htob64(hash, B64digest, 32); // this is used to verify the entered password ZeroMemory(hash, sizeof(hash)); ZeroMemory(key, sizeof(key)); // re-encrypt blow.ini with new password strcpy(iniPath_new, iniPath); strcat(iniPath_new, "_new"); re_enc = recrypt_ini_file(iniPath, iniPath_new, old_iniKey); if (re_enc < 0) { ZeroMemory(B64digest, sizeof(B64digest)); ZeroMemory(old_iniKey, sizeof(old_iniKey)); printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH ERROR:\002 Unable to write new blow.ini, probably out of disc space."); return; } else { ZeroMemory(old_iniKey, sizeof(old_iniKey)); } if (setIniValue("FiSH", "ini_password_Hash", B64digest, iniPath) == -1) { ZeroMemory(B64digest, sizeof(B64digest)); printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH ERROR:\002 Unable to write to blow.ini, probably out of space or permission denied."); return; } ZeroMemory(B64digest, sizeof(B64digest)); if (re_enc) { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH: Re-encrypted blow.ini\002 with new password."); } if (iniPW != NULL) { printtext(server, item != NULL ? window_item_get_target(item) : NULL, MSGLEVEL_CRAP, "\002FiSH:\002 blow.ini password hash saved."); } }
void fish_init(void) { char iniPasswordHash[50], B64digest[50]; strcpy(iniPath, get_irssi_config()); // path to irssi config file strcpy(strrchr(iniPath, '/'), blow_ini); if (DH1080_Init() == FALSE) return; getIniValue("FiSH", "ini_password_Hash", "0", iniPasswordHash, sizeof(iniPasswordHash), iniPath); if (strlen(iniPasswordHash) == 43) { prompt_for_password(iniKey); calculate_password_key_and_hash(iniKey, iniKey, B64digest); if (strcmp(B64digest, iniPasswordHash) != 0) { printtext(NULL, NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Wrong blow.ini password entered, try again..."); printtext(NULL, NULL, MSGLEVEL_CRAP, "\002FiSH module NOT loaded.\002"); return; } printtext(NULL, NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Correct blow.ini password entered, lets go!"); } else { strcpy(iniKey, default_iniKey); printtext(NULL, NULL, MSGLEVEL_CRAP, "\002FiSH:\002 Using default password to decrypt blow.ini... Try /setinipw to set a custom password."); } signal_add_first("server sendmsg", (SIGNAL_FUNC) encrypt_msg); signal_add_first("message private", (SIGNAL_FUNC) decrypt_msg); signal_add_first("message public", (SIGNAL_FUNC) decrypt_msg); signal_add_first("message irc notice", (SIGNAL_FUNC) decrypt_notice); signal_add_first("message irc action", (SIGNAL_FUNC) decrypt_action); signal_add_first("message own_private", (SIGNAL_FUNC) format_msg); signal_add_first("message own_public", (SIGNAL_FUNC) format_msg); signal_add_first("channel topic changed", (SIGNAL_FUNC) decrypt_changed_topic); signal_add_first("message topic", (SIGNAL_FUNC) decrypt_topic); signal_add_first("server incoming", (SIGNAL_FUNC) raw_handler); signal_add("query created", (SIGNAL_FUNC) do_auto_keyx); signal_add("query nick changed", (SIGNAL_FUNC) query_nick_changed); command_bind("topic+", NULL, (SIGNAL_FUNC) cmd_crypt_topic); command_bind("notice+", NULL, (SIGNAL_FUNC) cmd_crypt_notice); command_bind("notfish", NULL, (SIGNAL_FUNC) cmd_crypt_notice); command_bind("me+", NULL, (SIGNAL_FUNC) cmd_crypt_action); command_bind("setkey", NULL, (SIGNAL_FUNC) cmd_setkey); command_bind("delkey", NULL, (SIGNAL_FUNC) cmd_delkey); command_bind("key", NULL, (SIGNAL_FUNC) cmd_key); command_bind("showkey", NULL, (SIGNAL_FUNC) cmd_key); command_bind("keyx", NULL, (SIGNAL_FUNC) cmd_keyx); command_bind("setinipw", NULL, (SIGNAL_FUNC) cmd_setinipw); command_bind("unsetinipw", NULL, (SIGNAL_FUNC) cmd_unsetinipw); command_bind("fishhelp", NULL, (SIGNAL_FUNC) cmd_helpfish); command_bind("helpfish", NULL, (SIGNAL_FUNC) cmd_helpfish); settings_add_bool_module("fish", "FiSH", "process_outgoing", 1); settings_add_bool_module("fish", "FiSH", "process_incoming", 1); settings_add_bool_module("fish", "FiSH", "auto_keyxchange", 1); settings_add_bool_module("fish", "FiSH", "nicktracker", 1); settings_add_str_module("fish", "FiSH", "mark_broken_block", " \002&\002"); settings_add_str_module("fish", "FiSH", "mark_encrypted", ""); settings_add_str_module("fish", "FiSH", "plain_prefix", "+p "); settings_add_int_module("fish", "FiSH", "mark_position", 0); printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "FiSH v1.00 - encryption module for irssi loaded! URL: https://github.com/falsovsky/FiSH-irssi\n" "Try /helpfish or /fishhelp for a short command overview"); module_register("fish", "core"); }