Пример #1
0
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);
}
Пример #2
0
void print_load_message(void) {

    printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
              "Hello, World. xxx \"%s\"", MODULE_NAME);

}
Пример #3
0
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);
	}
}
Пример #4
0
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);
}
Пример #5
0
void print_unload_message(void) {

    printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
              "Goodbye, Cruel World. ~signed \"%s\"", MODULE_NAME);

}
Пример #6
0
/* why doesn't this get called? */
static void intr_catch(int sig)
{
    printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "got sig %d", sig);
    PyErr_SetInterrupt();
}
Пример #7
0
static void cmd_load(const char *data)
{
	printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
		  "Dynamic modules loading not supported");
}
Пример #8
0
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");
}
Пример #9
0
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);
}
Пример #10
0
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]);
		}
	}
}
Пример #11
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;
}
Пример #12
0
/**
 * 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);
}
Пример #13
0
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.");
	}
}
Пример #14
0
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");
}