Пример #1
0
/* SYNTAX: CTCP <targets> <ctcp command> [<ctcp data>] */
static void cmd_ctcp(const char *data, IRC_SERVER_REC *server,
		     WI_ITEM_REC *item)
{
	const char *target;
	char *ctcpcmd, *ctcpdata;
	void *free_arg;

        CMD_IRC_SERVER(server);

	if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
			    &target, &ctcpcmd, &ctcpdata))
		return;
	if (strcmp(target, "*") == 0)
		target = item == NULL ? NULL : window_item_get_target(item);
	if (*target == '\0' || *ctcpcmd == '\0')
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	g_strup(ctcpcmd);
	if (*ctcpdata == '\0')
		g_string_sprintf(tmpstr, "PRIVMSG %s :\001%s\001", target, ctcpcmd);
	else {
		char *recoded;

		recoded = recode_out(SERVER(server), ctcpdata, target);
		g_string_sprintf(tmpstr, "PRIVMSG %s :\001%s %s\001", target, ctcpcmd, recoded);
		g_free(recoded);
	}

	irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd);

	cmd_params_free(free_arg);
}
Пример #2
0
static gint
slng_verbose(int argc, char *argv[], const gchar *mode, GOptionContext *ctx)
{
  gint ret = 0;
  GString *rsp = NULL;
  gchar buff[256];

  if (!verbose_set)
    g_snprintf(buff, 255, "LOG %s\n", mode);
  else
    g_snprintf(buff, 255, "LOG %s %s\n", mode,
               strncasecmp(verbose_set, "on", 2) == 0 || verbose_set[0] == '1' ? "ON" : "OFF");

  g_strup(buff);

  rsp = slng_run_command(buff);
  if (rsp == NULL)
    return 1;

  ret = _process_response_status(rsp);
  printf("%s\n", rsp->str);

  g_string_free(rsp, TRUE);

  return ret;
}
Пример #3
0
static void cmd_ctcp(const char *data, IRC_SERVER_REC *server,
		     WI_ITEM_REC *item)
{
	const char *target;
	char *ctcpcmd, *ctcpdata;
	void *free_arg;

        CMD_IRC_SERVER(server);

	if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
			    &target, &ctcpcmd, &ctcpdata))
		return;
	if (strcmp(target, "*") == 0)
		target = item == NULL ? "" : window_item_get_target(item);
	if (*target == '\0' || *ctcpcmd == '\0')
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	if (*target == '=') {
		/* don't handle DCC CTCPs */
		cmd_params_free(free_arg);
		return;
	}

	g_strup(ctcpcmd);
	signal_emit("message irc own_ctcp", 4,
		    server, ctcpcmd, ctcpdata, target);

	cmd_params_free(free_arg);
}
Пример #4
0
static void cmd_ctcp(const char *data, SERVER_REC *server)
{
	char *params, *target, *ctcpcmd, *ctcpdata;
	DCC_REC *dcc;

	g_return_if_fail(data != NULL);
	if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED);

	params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata);
	if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	if (*target != '=') {
		/* handle only DCC CTCPs */
		g_free(params);
		return;
	}

	dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL);
	if (dcc == NULL) {
		printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
			    IRCTXT_DCC_CHAT_NOT_FOUND, target+1);
	} else {
		g_strup(ctcpcmd);
		printformat(server, target, MSGLEVEL_DCC, IRCTXT_OWN_DCC_CTCP,
			    target, ctcpcmd, ctcpdata);
	}

	g_free(params);
}
Пример #5
0
void browser_search_entry_changed(GtkWidget *w, gpointer data)
{
	string search = g_strup((gchar*)gtk_entry_get_text(GTK_ENTRY(w)));

	for (int a = 0; a < tex_names.size(); a++)
	{
		if (tex_names[a].size() < search.size())
			continue;

		bool match = true;
		for (int c = 0; c < search.size(); c++)
		{
			if (tex_names[a][c] != search[c])
				match = false;
		}

		if (match)
		{
			selected_tex = tex_names[a];
			scroll_to_selected_texture(GTK_WIDGET(data));
			gdk_window_invalidate_rect(GTK_WIDGET(data)->window, &GTK_WIDGET(data)->allocation, false);
			return;
		}
	}
}
Пример #6
0
static gint
slng_verbose(int argc, char *argv[], const gchar *mode)
{
  gint ret = 0;
  GString *rsp = NULL;
  gchar buff[256];

  if (!verbose_set)
    snprintf(buff, 255, "LOG %s\n", mode);
  else
    snprintf(buff, 255, "LOG %s %s\n", mode,
        strncasecmp(verbose_set, "on", 2) == 0 || verbose_set[0] == '1' ? "ON" : "OFF");

  g_strup(buff);

  if (!(slng_send_cmd(buff) && ((rsp = slng_read_response()) != NULL)))
    return 1;

  if (!verbose_set)
    printf("%s\n", rsp->str);
  else
    ret = g_str_equal(rsp->str, "OK");

  g_string_free(rsp, TRUE);

  return ret;
}
Пример #7
0
static void cmd_ctcp(const char *data, IRC_SERVER_REC *server)
{
	char *params, *target, *ctcpcmd, *ctcpdata;
	DCC_REC *dcc;
	char *str;

	g_return_if_fail(data != NULL);
	if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED);

	params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata);
	if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	if (*target != '=') {
		/* handle only DCC CTCPs */
		g_free(params);
		return;
	}

	dcc = dcc_find_item(DCC_TYPE_CHAT, target+1, NULL);
	if (dcc != NULL) {
		g_strup(ctcpcmd);

		str = g_strdup_printf("%s %s", ctcpcmd, ctcpdata);
		dcc_ctcp_message(dcc->nick, NULL, dcc, FALSE, str);
		g_free(str);
	}

	g_free(params);
	signal_stop();
}
Пример #8
0
void change_case (gint UpDown)
{	
  gint CurrentPage, l_min, l_max;
  gchar *buffer ;

  CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));
  l_min = min_from_selection (GTK_EDITABLE(FPROPS(CurrentPage, Text)));
  l_max = max_from_selection (GTK_EDITABLE(FPROPS(CurrentPage, Text)));
  buffer = gtk_editable_get_chars (GTK_EDITABLE(FPROPS(CurrentPage, Text)),
				   l_min, l_max);
  if (UpDown == 1) g_strup (buffer);
  else if (UpDown == 2) g_strdown (buffer);
  else if (UpDown == 3)
    {
      gint l_len, i, j;
      gchar *Delimiters = " \t\b\n\f\'\"{}()[]<>%^&*~-+=_@#$\\|/:;,.?!";

      l_len = l_max - l_min;
      if ((buffer[0] >= 'a') && (buffer[0] <= 'z'))
	buffer[0] = buffer[0] - 'a' + 'A';
      for (i = 1; i < l_len; i++)
	{
	  for (j = 0; j <= (gint)strlen (Delimiters); j++)
	    {
	      if (buffer [i] == Delimiters[j])
		{
		  if ((buffer[i+1] >= 'a') && (buffer[i+1] <= 'z'))
		    buffer[i+1] = buffer[i+1] - 'a' + 'A';
		  break;
		}
	    }
	}
    }
  else if (UpDown == 4)
    {
      gint l_len, change_case, i;

      l_len = l_max - l_min;
      change_case = 'a' - 'A';
      for (i = 0; i <= l_len; i++)
	{
	  if ((buffer[i] >= 'A') && (buffer[i] <= 'Z'))
	    buffer[i] = buffer[i] + change_case;
	  else if ((buffer[i] >= 'a') && (buffer[i] <= 'z'))
	    buffer[i] = buffer[i] - change_case;
	}
    }
  gtk_editable_delete_selection (GTK_EDITABLE(FPROPS(CurrentPage, Text)));
  gtk_editable_insert_text (GTK_EDITABLE(FPROPS(CurrentPage, Text)),
			    buffer, strlen(buffer), &l_min);
  g_free (buffer);
}
Пример #9
0
static void cmd_nctcp(const char *data, IRC_SERVER_REC *server)
{
	gchar *params, *target, *ctcpcmd, *ctcpdata;

	g_return_if_fail(data != NULL);
	if (server == NULL || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED);

	params = cmd_get_params(data, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata);
	if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	if (*target == '@' && ischannel(target[1]))
		target++; /* Hybrid 6 feature, send notice to all ops in channel */

	g_strup(ctcpcmd);
	printformat(server, target, MSGLEVEL_NOTICES, IRCTXT_OWN_NOTICE, target, ctcpcmd, ctcpdata);

	g_free(params);
}
Пример #10
0
/* SYNTAX: DCC CLOSE <type> <nick> [<file>] */
static void cmd_dcc_close(char *data, IRC_SERVER_REC *server)
{
    DCC_REC *dcc;
    GSList *tmp, *next;
    char *type, *nick, *arg;
    void *free_arg;
    gboolean found;
    int itype;

    g_return_if_fail(data != NULL);

    if (!cmd_get_params(data, &free_arg, 3, &type, &nick, &arg))
	    return;

    if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

    g_strup(type);
    itype = dcc_str2type(type);
    if (itype == 0)
    {
        signal_emit("dcc error unknown type", 1, type);
	cmd_params_free(free_arg);
        return;
    }

    dcc = NULL; found = FALSE;
    for (tmp = dcc_conns; tmp != NULL; tmp = next)
    {
	dcc = tmp->data;
	next = tmp->next;

        if (dcc->type == itype && g_strcasecmp(nick, dcc->nick) == 0)
        {
	    dcc_reject(dcc, server);
	    found = TRUE;
        }
    }

    if (!found)
        signal_emit("dcc error close not found", 3, type, nick, arg);

    cmd_params_free(free_arg);
}
Пример #11
0
/* SYNTAX: NCTCP <targets> <ctcp command> [<ctcp data>] */
static void cmd_nctcp(const char *data, IRC_SERVER_REC *server)
{
	char *target, *ctcpcmd, *ctcpdata;
	void *free_arg;

	g_return_if_fail(data != NULL);
	if (!IS_IRC_SERVER(server) || !server->connected)
		cmd_return_error(CMDERR_NOT_CONNECTED);

	if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, &target, &ctcpcmd, &ctcpdata))
		return;
	if (*target == '\0' || *ctcpcmd == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	g_strup(ctcpcmd);
	g_string_sprintf(tmpstr, "NOTICE %s :\001%s %s\001", target, ctcpcmd, ctcpdata);
	irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd);

	cmd_params_free(free_arg);
}
Пример #12
0
/* SYNTAX: DCC CLOSE <type> <nick> [<file>] */
static void cmd_dcc_close(char *data, IRC_SERVER_REC *server)
{
	GSList *tmp, *next;
	char *typestr, *nick, *arg;
	void *free_arg;
	int found, type;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
			    &typestr, &nick, &arg))
		return;

	if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	g_strup(typestr);
	type = dcc_str2type(typestr);
	if (type == -1) {
		signal_emit("dcc error unknown type", 1, typestr);
		cmd_params_free(free_arg);
		return;
	}

	found = FALSE;
	for (tmp = dcc_conns; tmp != NULL; tmp = next) {
		DCC_REC *dcc = tmp->data;

		next = tmp->next;
		if (dcc->type == type && g_strcasecmp(dcc->nick, nick) == 0 &&
		    (*arg == '\0' || strcmp(dcc->arg, arg) == 0)) {
			dcc_reject(dcc, server);
			found = TRUE;
		}
	}

	if (!found) {
		signal_emit("dcc error close not found", 3,
			    typestr, nick, arg);
	}

	cmd_params_free(free_arg);
}
Пример #13
0
int combine_level(int dest, const char *src)
{
	char **list, **item;
	int itemlevel;

	g_return_val_if_fail(src != NULL, dest);

	list = g_strsplit(src, " ", -1);
	for (item = list; *item != NULL; item++) {
                g_strup(*item);
		itemlevel = level_get(*item + (**item == '+' || **item == '-' ? 1 : 0));
		if (**item == '-')
			dest &= ~(itemlevel);
		else
			dest |= itemlevel;
	}
	g_strfreev(list);

	return dest;
}
Пример #14
0
/* SYNTAX: NCTCP <targets> <ctcp command> [<ctcp data>] */
static void cmd_nctcp(const char *data, IRC_SERVER_REC *server,
		      WI_ITEM_REC *item)
{
	char *target, *ctcpcmd, *ctcpdata;
	void *free_arg;

        CMD_IRC_SERVER(server);

	if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
			    &target, &ctcpcmd, &ctcpdata))
		return;
	if (strcmp(target, "*") == 0)
		target = item == NULL ? NULL : item->name;
	if (*target == '\0' || *ctcpcmd == '\0')
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	g_strup(ctcpcmd);
	g_string_sprintf(tmpstr, "NOTICE %s :\001%s %s\001", target, ctcpcmd, ctcpdata);
	irc_send_cmd_split(server, tmpstr->str, 2, server->max_msgs_in_cmd);

	cmd_params_free(free_arg);
}
Пример #15
0
int level2bits(const char *level)
{
	char *orig, *str, *ptr;
	int ret, singlelevel, negative;

	g_return_val_if_fail(level != NULL, 0);

	if (*level == '\0')
		return 0;

	orig = str = g_strdup(level);
	g_strup(str);

	ret = 0;
	for (ptr = str; ; str++) {
		if (*str == ' ')
			*str++ = '\0';
		else if (*str != '\0')
			continue;

		negative = *ptr == '-';
		if (*ptr == '-' || *ptr == '+') ptr++;

		singlelevel = level_get(ptr);
		if (singlelevel != 0) {
			ret = !negative ? (ret | singlelevel) :
				(ret & ~singlelevel);
		}

       		while (*str == ' ') str++;
		if (*str == '\0') break;

       		ptr = str;
	}
	g_free(orig);

	return ret;
}
Пример #16
0
int combine_level(int dest, const char *src)
{
	char **list, **item, *itemname;
	int itemlevel;

	g_return_val_if_fail(src != NULL, dest);

	list = g_strsplit(src, " ", -1);
	for (item = list; *item != NULL; item++) {
		itemname = *item + (**item == '+' || **item == '-' ? 1 : 0);
                g_strup(itemname);
		itemlevel = level_get(itemname);

		if (strcmp(itemname, "NONE") == 0)
                        dest = 0;
		else if (**item == '-')
			dest &= ~(itemlevel);
		else
			dest |= itemlevel;
	}
	g_strfreev(list);

	return dest;
}
Пример #17
0
static void sig_listen_client(CLIENT_REC *client, gint handle)
{
    char tmpbuf[1024], *str, *cmd, *args, *p;
    int ret, recvlen;

    g_return_if_fail(client != NULL);

    for (;;)
    {
	recvlen = net_receive(handle, tmpbuf, sizeof(tmpbuf));
	ret = line_split(tmpbuf, recvlen, &str, &client->buffer);
        if (ret == -1)
        {
            /* connection lost */
            remove_client(proxy_data, client);
            break;
        }
	if (ret == 0) break;

	if (client->server == NULL)
	    continue;

	cmd = g_strdup(str);
	args = strchr(cmd, ' ');
	if (args != NULL) *args++ = '\0'; else args = "";
	if (*args == ':') args++;
	g_strup(cmd);

	if (!client->connected)
	{
	    if (proxy_data->password != NULL && strcmp(cmd, "PASS") == 0)
	    {
		if (strcmp(proxy_data->password, args) != 0)
		{
		    /* wrong password! */
		    remove_client(proxy_data, client);
                    break;
		}
		client->pass_sent = TRUE;
	    }
	    else if (strcmp(cmd, "NICK") == 0)
		client->nick = g_strdup(args);
	    else if (strcmp(cmd, "USER") == 0)
	    {
		if (client->nick == NULL || (proxy_data->password != NULL && !client->pass_sent))
		{
		    /* stupid client didn't send us NICK/PASS or, kill it */
		    remove_client(proxy_data, client);
		    break;
		}
		client->connected = TRUE;
		plugin_proxy_dump_data(client);
	    }
	}
        else if (strcmp(cmd, "QUIT") == 0)
        {
            remove_client(proxy_data, client);
            break;
        }
	else if (strcmp(cmd, "PING") == 0)
	{
	    net_transmit(handle, "PONG proxy :nick\n", 17);
	}
	else
	{
	    net_transmit(net_sendbuffer_handle(client->server->handle), str, strlen(str));
	    net_transmit(net_sendbuffer_handle(client->server->handle), "\n", 1);

	    if (strcmp(cmd, "WHO") == 0)
	    {
		grab_who(client, args);
	    }
	    else if (strcmp(cmd, "WHOIS") == 0)
	    {
		/* convert dots to spaces */
		for (p = args; *p != '\0'; p++)
		    if (*p == ',') *p = ' ';

		proxy_redirect_event(client, args, 2,
				     "event 318", -1, "event 402", -1,
				     "event 401", 1, "event 311", 1,
				     "event 301", 1, "event 312", 1,
				     "event 313", 1, "event 317", 1,
				     "event 319", 1, NULL);
	    }
	    else if (strcmp(cmd, "ISON") == 0)
	    {
		proxy_redirect_event(client, NULL, 1, "event 303", -1, NULL);
	    }
	    else if (strcmp(cmd, "USERHOST") == 0)
	    {
		proxy_redirect_event(client, args, 1, "event 302", -1, "event 401", 1, NULL);
	    }
	    else if (strcmp(cmd, "MODE") == 0)
	    {
		/* convert dots to spaces */
		gchar *slist, *str, mode;
		gint argc;

		p = strchr(args, ' ');
		if (p != NULL) *p++ = '\0';
		mode = p == NULL ? '\0' : *p;

		slist = g_strdup(args);
		argc = 1;
		for (p = slist; *p != '\0'; p++)
		{
		    if (*p == ',')
		    {
			*p = ' ';
			argc++;
		    }
		}

		/* get channel mode / bans / exception / invite list */
		str = g_strdup_printf("%s %s", args, slist);
		switch (mode)
		{
		    case '\0':
                        while (argc-- > 0)
			    proxy_redirect_event(client, str, 3, "event 403", 1,
						 "event 443", 1, "event 324", 1, NULL);
			break;
		    case 'b':
                        while (argc-- > 0)
			    proxy_redirect_event(client, str, 2, "event 403", 1,
						 "event 368", 1, "event 367", 1, NULL);
			break;
		    case 'e':
			while (argc-- > 0)
			    proxy_redirect_event(client, str, 4, "event 403", 1,
						 "event 482", 1, "event 472", -1,
						 "event 349", 1, "event 348", 1, NULL);
			break;
		    case 'I':
                        while (argc-- > 0)
			    proxy_redirect_event(client, str, 4, "event 403", 1,
						 "event 482", 1, "event 472", -1,
						 "event 347", 1, "event 346", 1, NULL);
			break;
		}
		g_free(str);
		g_free(slist);
	    }
	}
	g_free(cmd);
    }
}
Пример #18
0
static void scan_dir(fpick_dd *dt, DIR *dp, char *select)
{
	char full_name[PATHBUF], txt_size[64], txt_date[64], tmp_txt[64];
	char *nm, *src, *dest, *dir = dt->txt_directory;
	memx2 mem = dt->files;
	struct tm *lt;
	struct dirent *ep;
	struct stat buf;
	int *tc;
	int subdir, tf, n, l = strlen(dir), cnt = 0;

	mem.here = 0;
	getmemx2(&mem, 8000); // default size

	dt->idx = -1;
	if (strcmp(dir, DIR_SEP_STR)) // Have a parent dir to move to?
	{
		// Field #0 - original name
		addstr(&mem, "..", 0);
		// Field #1 - type flag (space) + name in GUI encoding
		addstr(&mem, " " DIR_SEP_STR " ..", 0);
		// Fields #2-4 empty for all dirs
		// Fields #5-6 are empty strings, to keep this sorted first
		addchars(&mem, 0, 3 + 2);
		cnt++;
	}

	while ((ep = readdir(dp)))
	{
		wjstrcat(full_name, PATHBUF, dir, l, ep->d_name, NULL);

		// Error getting file details
		if (stat(full_name, &buf) < 0) continue;

		if (!dt->show_hidden && (ep->d_name[0] == '.')) continue;

#ifdef WIN32
		subdir = S_ISDIR(buf.st_mode);
#else
		subdir = (ep->d_type == DT_DIR) || S_ISDIR(buf.st_mode);
#endif
		tf = 'F'; // Type flag: 'D' for dir, 'F' for file
		if (subdir)
		{
			if (!dt->allow_dirs) continue;
			// Don't look at '.' or '..'
			if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
				continue;
			tf = 'D';
		}
		else if (!dt->allow_files) continue;

		/* Remember which row has matching name */
		if (select && !strcmp(ep->d_name, select)) dt->idx = cnt;

		cnt++;

		// Field #0 - original name
		addstr(&mem, ep->d_name, 0);
		// Field #1 - type flag + name in GUI encoding
		addchars(&mem, tf, 1);
		nm = gtkuncpy(NULL, ep->d_name, 0);
		addstr(&mem, nm, 0);
		// Fields #2-4 empty for dirs
		if (subdir) addchars(&mem, 0, 3);
		else
		{
			// Field #2 - file size
#ifdef WIN32
			n = snprintf(tmp_txt, 64, "%I64u", (unsigned long long)buf.st_size);
#else
			n = snprintf(tmp_txt, 64, "%llu", (unsigned long long)buf.st_size);
#endif
			memset(txt_size, ' ', 20);
			dest = txt_size + 20; *dest-- = '\0';
			for (src = tmp_txt + n - 1; src - tmp_txt > 2; )
			{
				*dest-- = *src--;
				*dest-- = *src--;
				*dest-- = *src--;
				*dest-- = ',';
			}
			while (src - tmp_txt >= 0) *dest-- = *src--;
			addstr(&mem, txt_size, 0);
			// Field #3 - file type (extension)
			src = strrchr(nm, '.');
			if (src && (src != nm) && src[1])
			{
#if GTK_MAJOR_VERSION == 1
				g_strup(src = g_strdup(src + 1));
#else
				src = g_utf8_strup(src + 1, -1);
#endif
				addstr(&mem, src, 0);
				g_free(src);
			}
			else addchars(&mem, 0, 1);
			// Field #4 - file modification time
			strcpy(txt_date, " "); // to sort failed files after dirs
			lt = localtime(&buf.st_mtime);
			/* !!! localtime() can fail and return NULL if given
			 * "wrong" input value */
			if (lt) strftime(txt_date, 60, "%Y-%m-%d   %H:%M.%S", lt);
			addstr(&mem, txt_date, 0);
		}
		// Field #5 - case-insensitive sort key
		src = isort_key(nm);
		addstr(&mem, src, 0);
		g_free(src);
		// Field #6 - alphabetic (case-sensitive) sort key
#if GTK_MAJOR_VERSION == 1
		addstr(&mem, nm, 0);
#else /* if GTK_MAJOR_VERSION == 2 */
		src = g_utf8_collate_key(nm, -1);
		addstr(&mem, src, 0);
		g_free(src);
#endif
		g_free(nm);
	}
	dt->cnt = cnt;

	/* Now add index array and mapping arrays to all this */
	l = (~(unsigned)mem.here + 1) & (sizeof(int) - 1);
	n = cnt * COL_MAX;
	getmemx2(&mem, l + (n + cnt) * sizeof(int));
	// Fill index array
	tc = dt->fcols = (void *)(mem.buf + mem.here + l);
	src = mem.buf;
	while (n-- > 0)
	{
		*tc = src - (char *)tc;
		tc++;
		src += strlen(src) + 1;
	}
	// Setup mapping array
	dt->fmap = tc;

	dt->files = mem;
}