Exemplo n.º 1
0
void core_init_paths(int argc, char *argv[])
{
	static struct poptOption options[] = {
		{ "config", 0, POPT_ARG_STRING, NULL, 0, "Configuration file location (~/.irssi/config)", "PATH" },
		{ "home", 0, POPT_ARG_STRING, NULL, 0, "Irssi home dir location (~/.irssi)", "PATH" },
		{ NULL, '\0', 0, NULL }
	};
	const char *home;
	char *str;
	int n, len;

	for (n = 1; n < argc; n++) {
		if (strncmp(argv[n], "--home=", 7) == 0) {
                        g_free_not_null(irssi_dir);
                        irssi_dir = convert_home(argv[n]+7);
                        len = strlen(irssi_dir);
			if (irssi_dir[len-1] == G_DIR_SEPARATOR)
				irssi_dir[len-1] = '\0';
		} else if (strncmp(argv[n], "--config=", 9) == 0) {
                        g_free_not_null(irssi_config_file);
			irssi_config_file = convert_home(argv[n]+9);
		}
	}

	if (irssi_dir != NULL && !g_path_is_absolute(irssi_dir)) {
		str = irssi_dir;
		irssi_dir = g_strdup_printf("%s/%s", g_get_current_dir(), str);
		g_free(str);
	}

	if (irssi_config_file != NULL &&
	    !g_path_is_absolute(irssi_config_file)) {
		str = irssi_config_file;
		irssi_config_file =
			g_strdup_printf("%s/%s", g_get_current_dir(), str);
		g_free(str);
	}

	args_register(options);

	if (irssi_dir == NULL) {
		home = g_get_home_dir();
		if (home == NULL)
			home = ".";

		irssi_dir = g_strdup_printf(IRSSI_DIR_FULL, home);
	}
	if (irssi_config_file == NULL)
		irssi_config_file = g_strdup_printf("%s/"IRSSI_HOME_CONFIG, irssi_dir);

	session_set_binary(argv[0]);
}
Exemplo n.º 2
0
static void autolog_log(void *server, const char *target)
{
    LOG_REC *log;
    char *fname, *dir, *str;

    log = log_find_item(target);
    if (log != NULL) return;

    fname = parse_special_string(autolog_path, server, NULL, target, NULL);
    if (log_find(fname) == NULL) {
        str = convert_home(fname);
        dir = g_dirname(str);
        g_free(str);

        mkdir(dir, LOG_DIR_CREATE_MODE);
        g_free(dir);

        log = log_create_rec(fname, autolog_level, target);
        if (log != NULL) {
            log->temp = TRUE;
            log_update(log);
            log_start_logging(log);
        }
    }
    g_free(fname);
}
Exemplo n.º 3
0
/* Returns full path for the script */
char *perl_script_get_path(const char *name)
{
	struct stat statbuf;
	char *file, *path;

	if (g_path_is_absolute(name) || (name[0] == '~' && name[1] == '/')) {
		/* full path specified */
                return convert_home(name);
	}

	/* add .pl suffix if it's missing */
	file = IS_PERL_SCRIPT(name) ? g_strdup(name) :
		g_strdup_printf("%s.pl", name);

	/* check from ~/.irssi/scripts/ */
	path = g_strdup_printf("%s/scripts/%s", get_irssi_dir(), file);
	if (stat(path, &statbuf) != 0) {
		/* check from SCRIPTDIR */
		g_free(path);
		path = g_strdup_printf(SCRIPTDIR"/%s", file);
		if (stat(path, &statbuf) != 0) {
			g_free(path);
			path = NULL;
		}
	}
	g_free(file);
	return path;
}
Exemplo n.º 4
0
int settings_reread(const char *fname)
{
	CONFIG_REC *tempconfig;
	char *str;

	str = fname == NULL ? NULL : convert_home(fname);
	tempconfig = parse_configfile(str);
        g_free_not_null(str);

	if (tempconfig == NULL) {
		signal_emit("gui dialog", 2, "error", g_strerror(errno));
		return FALSE;
	}

	if (config_last_error(tempconfig) != NULL) {
		str = g_strdup_printf("Errors in configuration file:\n%s",
				      config_last_error(tempconfig));
		signal_emit("gui dialog", 2, "error", str);
		g_free(str);

		config_close(tempconfig);
                return FALSE;
	}

	config_close(mainconfig);
	mainconfig = tempconfig;
	config_last_modifycounter = mainconfig->modifycounter;

	signal_emit("setup changed", 0);
	signal_emit("setup reread", 1, mainconfig->fname);
        return TRUE;
}
Exemplo n.º 5
0
int settings_reread(const char *fname)
{
	CONFIG_REC *tempconfig;
	char *str;

	if (fname == NULL) fname = "~/.irssi/config";

	str = convert_home(fname);
	tempconfig = parse_configfile(str);
	g_free(str);

	if (tempconfig == NULL) {
		signal_emit("gui dialog", 2, "error", g_strerror(errno));
		return FALSE;
	}

	if (config_last_error(tempconfig) != NULL) {
		str = g_strdup_printf(_("Errors in configuration file:\n%s"),
				      config_last_error(tempconfig));
		signal_emit("gui dialog", 2, "error", str);
		g_free(str);

		config_close(tempconfig);
                return FALSE;
	}

	config_close(mainconfig);
	mainconfig = tempconfig;

	signal_emit("setup changed", 0);
	signal_emit("setup reread", 0);
        return TRUE;
}
Exemplo n.º 6
0
/* Load a sub module. */
int module_load_sub(const char *path, const char *submodule, char **prefixes)
{
        GString *full_path;
	char *exppath, *name, *rootmodule;
        int start, end, ret;

	g_return_val_if_fail(path != NULL, FALSE);
	g_return_val_if_fail(submodule != NULL, FALSE);

        exppath = convert_home(path);

	name = module_get_name(exppath, &start, &end);
	rootmodule = module_get_root(name, prefixes);
	g_free(name);

        full_path = g_string_new(exppath);
	if (strcmp(submodule, "core") == 0)
		g_string_insert(full_path, end, "_core");
	else {
		g_string_insert_c(full_path, start, '_');
		g_string_insert(full_path, start, submodule);
	}

	ret = module_load_full(full_path->str, rootmodule, submodule,
			       start, end, NULL);

	g_string_free(full_path, TRUE);
	g_free(rootmodule);
	g_free(exppath);
        return ret;
}
Exemplo n.º 7
0
/* SYNTAX: CAT <file> */
static void cmd_cat(const char *data)
{
	LINEBUF_REC *buffer = NULL;
	char *fname, *fposstr;
	char tmpbuf[1024], *str;
	void *free_arg;
	int f, ret, recvlen, fpos;

	if (!cmd_get_params(data, &free_arg, 2, &fname, &fposstr))
		return;

	fname = convert_home(fname);
	fpos = atoi(fposstr);
        cmd_params_free(free_arg);

	f = open(fname, O_RDONLY);
	g_free(fname);

	if (f == -1) {
		/* file not found */
                printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "%s", g_strerror(errno));
		return;
	}

        lseek(f, fpos, SEEK_SET);
	do {
		recvlen = read(f, tmpbuf, sizeof(tmpbuf));

		ret = line_split(tmpbuf, recvlen, &str, &buffer);
		if (ret > 0) printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s", str);
	} while (ret > 0);
	line_split_free(buffer);

	close(f);
}
Exemplo n.º 8
0
void rawlog_open(RAWLOG_REC *rawlog, const char *fname)
{
	char *path;

        g_return_if_fail(rawlog != NULL);
	g_return_if_fail(fname != NULL);

	if (rawlog->logging)
		return;

	path = convert_home(fname);
#ifdef HAVE_CAPSICUM
	rawlog->handle = capsicum_open_wrapper(path,
					       O_WRONLY | O_APPEND | O_CREAT,
					       log_file_create_mode);
#else
	rawlog->handle = open(path, O_WRONLY | O_APPEND | O_CREAT,
			      log_file_create_mode);
#endif

	g_free(path);

	if (rawlog->handle == -1) {
		g_warning("rawlog open() failed: %s", strerror(errno));
		return;
	}

	rawlog_dump(rawlog, rawlog->handle);
	rawlog->logging = TRUE;
}
Exemplo n.º 9
0
void rawlog_save(RAWLOG_REC *rawlog, const char *fname)
{
	char *path, *dir;
	int f;

        dir = g_path_get_dirname(fname);
#ifdef HAVE_CAPSICUM
        capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode);
#else
        g_mkdir_with_parents(dir, log_dir_create_mode);
#endif
        g_free(dir);

	path = convert_home(fname);
#ifdef HAVE_CAPSICUM
	f = capsicum_open_wrapper(path, O_WRONLY | O_APPEND | O_CREAT,
				  log_file_create_mode);
#else
	f = open(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode);
#endif
	g_free(path);

	if (f < 0) {
		g_warning("rawlog open() failed: %s", strerror(errno));
		return;
	}

	rawlog_dump(rawlog, f);
	close(f);
}
Exemplo n.º 10
0
static char *dcc_send_get_file(const char *fname)
{
	char *str, *path;

	str = convert_home(fname);
	if (!g_path_is_absolute(str)) {
		/* full path not given to file, use dcc_upload_path */
		g_free(str);

		path = convert_home(settings_get_str("dcc_upload_path"));
		str = *path == '\0' ? g_strdup(fname) :
			g_strconcat(path, G_DIR_SEPARATOR_S, fname, NULL);
		g_free(path);
	}

        return str;
}
Exemplo n.º 11
0
char *dcc_get_download_path(const char *fname)
{
	char *str, *downpath;

	downpath = convert_home(settings_get_str("dcc_download_path"));
	str = g_strconcat(downpath, G_DIR_SEPARATOR_S, g_basename(fname), NULL);
	g_free(downpath);

	return str;
}
Exemplo n.º 12
0
/* SYNTAX: LASTLOG [-] [-file <filename>] [-window <ref#|name>] [-new | -away]
		   [-<level> -<level...>] [-clear] [-count] [-case] [-date]
		   [-regexp | -word] [-before [<#>]] [-after [<#>]]
		   [-<# before+after>] [<pattern>] [<count> [<start>]] */
static void cmd_lastlog(const char *data)
{
	GHashTable *optlist;
	char *text, *countstr, *start, *fname;
	void *free_arg;
        int count, fd;
	FILE *fhandle;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_UNKNOWN_OPTIONS, "lastlog", &optlist,
			    &text, &countstr, &start))
		return;

	if (*start == '\0' && is_numeric(text, 0) && *text != '0' &&
	    (*countstr == '\0' || is_numeric(countstr, 0))) {
		start = countstr;
		countstr = text;
		text = "";
	}
	count = atoi(countstr);
	if (count == 0) count = -1;

	/* target where to print it */
        fhandle = NULL;
	fname = g_hash_table_lookup(optlist, "file");
	if (fname != NULL) {
                fname = convert_home(fname);
		fd = open(fname, O_WRONLY | O_APPEND | O_CREAT,
			  octal2dec(settings_get_int("log_create_mode")));
		if (fd != -1) {
			fhandle = fdopen(fd, "a");
			if (fhandle == NULL)
				close(fd);
		}
                g_free(fname);
	}

	if (fname != NULL && fhandle == NULL) {
		printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
			  "Could not open lastlog: %s", g_strerror(errno));
	} else {
		show_lastlog(text, optlist, atoi(start), count, fhandle);
		if (fhandle != NULL) {
			if (ferror(fhandle))
				printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
				  	  "Could not write lastlog: %s", g_strerror(errno));
			fclose(fhandle);
		}
	}

	cmd_params_free(free_arg);
}
Exemplo n.º 13
0
void rawlog_save(RAWLOG_REC *rawlog, const char *fname)
{
	char *path;
	int f;

	path = convert_home(fname);
	f = open(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode);
	g_free(path);

	rawlog_dump(rawlog, f);
	close(f);
}
Exemplo n.º 14
0
GList *filename_complete(const char *path)
{
        GList *list;
	DIR *dirp;
	struct dirent *dp;
	char *realpath, *dir, *basename, *name;
	int len;

	g_return_val_if_fail(path != NULL, NULL);

	list = NULL;

	/* get directory part of the path - expand ~/ */
	realpath = convert_home(path);
	dir = g_dirname(realpath);
	g_free(realpath);

	/* open directory for reading */
	dirp = opendir(dir);
	g_free(dir);
	if (dirp == NULL) return NULL;

	dir = g_dirname(path);
	if (*dir == G_DIR_SEPARATOR && dir[1] == '\0')
		*dir = '\0'; /* completing file in root directory */
	basename = g_basename(path);
	len = strlen(basename);

	/* add all files in directory to completion list */
	while ((dp = readdir(dirp)) != NULL) {
		if (dp->d_name[0] == '.') {
			if (dp->d_name[1] == '\0' ||
			    (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
				continue; /* skip . and .. */

			if (basename[0] != '.')
				continue;
		}

		if (len == 0 || strncmp(dp->d_name, basename, len) == 0) {
			name = g_strdup_printf("%s"G_DIR_SEPARATOR_S"%s", dir, dp->d_name);
			list = list_add_file(list, name);
			g_free(name);
		}
	}
	closedir(dirp);

	g_free(dir);
        return list;
}
Exemplo n.º 15
0
/* SYNTAX: CAT <file> */
static void cmd_cat(const char *data)
{
	char *fname, *fposstr;
	void *free_arg;
	int fpos;
	GIOChannel *handle;
	GString *buf;
	gsize tpos;
#ifdef HAVE_CAPSICUM
	int fd;
#endif

	if (!cmd_get_params(data, &free_arg, 2, &fname, &fposstr))
		return;

	fname = convert_home(fname);
	fpos = atoi(fposstr);
        cmd_params_free(free_arg);

#ifdef HAVE_CAPSICUM
	fd = capsicum_open_wrapper(fname, O_RDONLY, 0);
	if (fd > 0)
		handle = g_io_channel_unix_new(fd);
	else
		handle = NULL;
#else
	handle = g_io_channel_new_file(fname, "r", NULL);
#endif
	g_free(fname);

	if (handle == NULL) {
		/* file not found */
		printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
			  "%s", g_strerror(errno));
		return;
	}

	g_io_channel_set_encoding(handle, NULL, NULL);
	g_io_channel_seek_position(handle, fpos, G_SEEK_SET, NULL);
	buf = g_string_sized_new(512);
	while (g_io_channel_read_line_string(handle, buf, &tpos, NULL) == G_IO_STATUS_NORMAL) {
		buf->str[tpos] = '\0';
		printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP |
			  MSGLEVEL_NEVER, "%s", buf->str);
	}
	g_string_free(buf, TRUE);

	g_io_channel_unref(handle);
}
Exemplo n.º 16
0
GList *list_add_file(GList *list, const char *name)
{
	struct stat statbuf;
	char *fname;

	g_return_val_if_fail(name != NULL, NULL);

	fname = convert_home(name);
	if (stat(fname, &statbuf) == 0) {
		list = g_list_append(list, !S_ISDIR(statbuf.st_mode) ? g_strdup(name) :
				     g_strconcat(name, G_DIR_SEPARATOR_S, NULL));
	}

        g_free(fname);
	return list;
}
Exemplo n.º 17
0
Arquivo: core.c Projeto: Liaf/irssi
static char *fix_path(const char *str)
{
	char *new_str = convert_home(str);

	if (!g_path_is_absolute(new_str)) {
		char *tmp_str = new_str;
		char *current_dir = g_get_current_dir();

		new_str = g_build_path(G_DIR_SEPARATOR_S, current_dir, tmp_str, NULL);

		g_free(current_dir);
		g_free(tmp_str);
	}

	return new_str;
}
Exemplo n.º 18
0
Arquivo: rawlog.c Projeto: Liaf/irssi
void rawlog_save(RAWLOG_REC *rawlog, const char *fname)
{
	char *path, *dir;
	int f;

        dir = g_path_get_dirname(fname);
        mkpath(dir, log_dir_create_mode);
        g_free(dir);

	path = convert_home(fname);
	f = open(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode);
	g_free(path);

	rawlog_dump(rawlog, f);
	close(f);
}
Exemplo n.º 19
0
void rawlog_open(RAWLOG_REC *rawlog, const char *fname)
{
	char *path;

        g_return_if_fail(rawlog != NULL);
	g_return_if_fail(fname != NULL);

	if (rawlog->logging)
		return;

	path = convert_home(fname);
	rawlog->handle = open(path, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode);
	g_free(path);

	rawlog_dump(rawlog, rawlog->handle);
	rawlog->logging = rawlog->handle != -1;
}
Exemplo n.º 20
0
static GList *list_add_file(GList *list, const char *name, const char *default_path)
{
	struct stat statbuf;
	char *fname;

	g_return_val_if_fail(name != NULL, NULL);

	fname = convert_home(name);
	if (USE_DEFAULT_PATH(fname, default_path)) {
                g_free(fname);
		fname = g_strconcat(default_path, G_DIR_SEPARATOR_S,
				    name, NULL);
	}
	if (stat(fname, &statbuf) == 0) {
		list = g_list_append(list, !S_ISDIR(statbuf.st_mode) ? g_strdup(name) :
				     g_strconcat(name, G_DIR_SEPARATOR_S, NULL));
	}

        g_free(fname);
	return list;
}
Exemplo n.º 21
0
static char *log_filename(LOG_REC *log)
{
	char *str, fname[1024];
	struct tm *tm;
        size_t ret;
	time_t now;

	now = time(NULL);
	tm = localtime(&now);

	str = convert_home(log->fname);
	ret = strftime(fname, sizeof(fname), str, tm);
	g_free(str);

	if (ret <= 0) {
		g_warning("log_filename() : strftime() failed");
                return NULL;
	}

	return g_strdup(fname);
}
Exemplo n.º 22
0
/* Load module - automatically tries to load also the related non-core
   modules given in `prefixes' (like irc, fe, fe_text, ..) */
int module_load(const char *path, char **prefixes)
{
	char *exppath, *name, *submodule, *rootmodule;
        int start, end, ret;

	g_return_val_if_fail(path != NULL, FALSE);

	exppath = convert_home(path);

	name = module_get_name(exppath, &start, &end);
	rootmodule = module_get_root(name, prefixes);
	submodule = module_get_sub(name, rootmodule);
	g_free(name);

	ret = module_load_full(exppath, rootmodule, submodule,
			       start, end, prefixes);

	g_free(rootmodule);
	g_free(submodule);
        g_free(exppath);
        return ret;
}
Exemplo n.º 23
0
/* command: DCC SEND */
static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, WI_IRC_REC *item)
{
	char *params, *target, *fname, *str, *ptr;
	char host[MAX_IP_LEN];
	int hfile, hlisten, port;
	long fsize;
	DCC_REC *dcc, *chat;
	IPADDR own_ip;

	g_return_if_fail(data != NULL);

	params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &fname);
	if (*target == '\0' || *fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	/* if we're in dcc chat, send the request via it. */
	chat = item_get_dcc(item);

	if (chat != NULL && (chat->mirc_ctcp || g_strcasecmp(target, chat->nick) != 0))
		chat = NULL;

	if ((server == NULL || !server->connected) && chat == NULL)
		cmd_param_error(CMDERR_NOT_CONNECTED);

	if (dcc_find_item(DCC_TYPE_SEND, target, fname)) {
		signal_emit("dcc error send exists", 2, target, fname);
		g_free(params);
		return;
	}

	str = convert_home(fname);
	if (!g_path_is_absolute(str)) {
		char *path;

		g_free(str);
		path = convert_home(settings_get_str("dcc_upload_path"));
		str = g_strconcat(path, G_DIR_SEPARATOR_S, fname, NULL);
		g_free(path);
	}

	hfile = open(str, O_RDONLY);
	g_free(str);

	if (hfile == -1) {
		signal_emit("dcc error file not found", 2, target, fname);
		g_free(params);
		return;
	}
	fsize = lseek(hfile, 0, SEEK_END);
	lseek(hfile, 0, SEEK_SET);

	/* get the IP address we use with IRC server */
	if (net_getsockname(chat != NULL ? chat->handle : server->handle, &own_ip, NULL) == -1) {
		close(hfile);
		cmd_param_error(CMDERR_ERRNO);
	}

	/* start listening */
	port = settings_get_int("dcc_port");
	hlisten = net_listen(&own_ip, &port);
	if (hlisten == -1) {
		close(hfile);
		cmd_param_error(CMDERR_ERRNO);
	}

	/* skip path, change all spaces to _ */
	fname = g_strdup(g_basename(fname));
	for (ptr = fname; *ptr != '\0'; ptr++)
		if (*ptr == ' ') *ptr = '_';

	dcc = dcc_create(DCC_TYPE_SEND, hlisten, target, fname, server, chat);
	dcc->port = port;
	dcc->size = fsize;
	dcc->fhandle = hfile;
	dcc->tagread = g_input_add(hlisten, G_INPUT_READ,
				   (GInputFunction) dcc_send_init, dcc);

	/* send DCC request */
	dcc_make_address(&own_ip, host);
	str = g_strdup_printf("DCC SEND %s %s %d %lu",
			      fname, host, port, fsize);
	dcc_ctcp_message(target, server, chat, FALSE, str);
	g_free(str);

	g_free(fname);
	g_free(params);
}
Exemplo n.º 24
0
GList *filename_complete(const char *path, const char *default_path)
{
        GList *list;
	DIR *dirp;
	struct dirent *dp;
	const char *basename;
	char *realpath, *dir, *name;
	int len;

	g_return_val_if_fail(path != NULL, NULL);

	list = NULL;

	/* get directory part of the path - expand ~/ */
	realpath = convert_home(path);
	if (USE_DEFAULT_PATH(realpath, default_path)) {
                g_free(realpath);
		realpath = g_strconcat(default_path, G_DIR_SEPARATOR_S,
				       path, NULL);
	}

	/* open directory for reading */
	dir = g_dirname(realpath);
	dirp = opendir(dir);
	g_free(dir);
        g_free(realpath);

	if (dirp == NULL)
		return NULL;

	dir = g_dirname(path);
	if (*dir == G_DIR_SEPARATOR && dir[1] == '\0') {
                /* completing file in root directory */
		*dir = '\0';
	} else if (IS_CURRENT_DIR(dir) && !IS_CURRENT_DIR(path)) {
		/* completing file in default_path
		   (path not set, and leave it that way) */
		g_free_and_null(dir);
	}

	basename = g_basename(path);
	len = strlen(basename);

	/* add all files in directory to completion list */
	while ((dp = readdir(dirp)) != NULL) {
		if (dp->d_name[0] == '.') {
			if (dp->d_name[1] == '\0' ||
			    (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
				continue; /* skip . and .. */

			if (basename[0] != '.')
				continue;
		}

		if (len == 0 || strncmp(dp->d_name, basename, len) == 0) {
			name = dir == NULL ? g_strdup(dp->d_name) :
				g_strdup_printf("%s"G_DIR_SEPARATOR_S"%s", dir, dp->d_name);
			list = list_add_file(list, name, default_path);
			g_free(name);
		}
	}
	closedir(dirp);

	g_free_not_null(dir);
        return list;
}
Exemplo n.º 25
0
GList *filename_complete(const char *path, const char *default_path)
{
        GList *list;
	DIR *dirp;
	struct dirent *dp;
	char *basename;
	char *realpath, *dir, *name;
	size_t len;

	g_return_val_if_fail(path != NULL, NULL);

	if (path[0] == '\0') {
	    return NULL;
	}

	list = NULL;

	/* get directory part of the path - expand ~/ */
	realpath = convert_home(path);
	if (USE_DEFAULT_PATH(realpath, default_path)) {
                g_free(realpath);
		realpath = g_strconcat(default_path, G_DIR_SEPARATOR_S,
				       path, NULL);
	}

	/* open directory for reading */
	dir = g_path_get_dirname(realpath);
	dirp = opendir(dir);
	g_free(dir);
        g_free(realpath);

	if (dirp == NULL)
		return NULL;

	dir = g_path_get_dirname(path);
	if (*dir == G_DIR_SEPARATOR && dir[1] == '\0') {
                /* completing file in root directory */
		*dir = '\0';
	} else if (IS_CURRENT_DIR(dir) && !IS_CURRENT_DIR(path)) {
		/* completing file in default_path
		   (path not set, and leave it that way) */
		g_free_and_null(dir);
	}

	len = strlen(path);
	/* g_path_get_basename() returns the component before the last slash if
	 * the path ends with a directory separator, that's not what we want */
	if (len > 0 && path[len - 1] == G_DIR_SEPARATOR) {
	    basename = g_strdup("");
	} else {
	    basename = g_path_get_basename(path);
	}
	len = strlen(basename);

	/* add all files in directory to completion list */
	while ((dp = readdir(dirp)) != NULL) {
		if (dp->d_name[0] == '.') {
			if (dp->d_name[1] == '\0' ||
			    (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
				continue; /* skip . and .. */

			/* Skip the dotfiles unless the user explicitly asked us
			 * to do so. Basename might be './', beware of that */
			if (basename[0] != '.' || basename[1] == '\0')
				continue;
		}

		if (len == 0 || strncmp(dp->d_name, basename, len) == 0) {
			name = dir == NULL ? g_strdup(dp->d_name) :
				g_strdup_printf("%s"G_DIR_SEPARATOR_S"%s", dir, dp->d_name);
			list = list_add_file(list, name, default_path);
			g_free(name);
		}
	}
	closedir(dirp);
	g_free(basename);

	g_free_not_null(dir);
        return list;
}
Exemplo n.º 26
0
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server)
{
	GIOSSLChannel *chan;
	GIOChannel *gchan;
	int fd;
	SSL *ssl;
	SSL_CTX *ctx = NULL;

	const char *mycert = server->connrec->tls_cert;
	const char *mypkey = server->connrec->tls_pkey;
	const char *mypass = server->connrec->tls_pass;
	const char *cafile = server->connrec->tls_cafile;
	const char *capath = server->connrec->tls_capath;
	const char *ciphers = server->connrec->tls_ciphers;
	gboolean verify = server->connrec->tls_verify;

	g_return_val_if_fail(handle != NULL, NULL);

	if(!ssl_inited && !irssi_ssl_init())
		return NULL;

	if(!(fd = g_io_channel_unix_get_fd(handle)))
		return NULL;

	ERR_clear_error();
	ctx = SSL_CTX_new(SSLv23_client_method());
	if (ctx == NULL) {
		g_error("Could not allocate memory for SSL context");
		return NULL;
	}
	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
	SSL_CTX_set_default_passwd_cb(ctx, get_pem_password_callback);
	SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)mypass);

	if (ciphers != NULL && ciphers[0] != '\0') {
		if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1)
			g_warning("No valid SSL cipher suite could be selected");
	}

	if (mycert && *mycert) {
		char *scert = NULL, *spkey = NULL;
		FILE *fp;
		scert = convert_home(mycert);
		if (mypkey && *mypkey)
			spkey = convert_home(mypkey);

		if ((fp = fopen(scert, "r"))) {
			X509 *cert;
			/* Let's parse the certificate by hand instead of using
			 * SSL_CTX_use_certificate_file so that we can validate
			 * some parts of it. */
			cert = PEM_read_X509(fp, NULL, get_pem_password_callback, (void *)mypass);
			if (cert != NULL) {
				/* Only the expiration date is checked right now */
				if (X509_cmp_current_time(X509_get_notAfter(cert))  <= 0 ||
				    X509_cmp_current_time(X509_get_notBefore(cert)) >= 0)
					g_warning("The client certificate is expired");

				ERR_clear_error();
				if (! SSL_CTX_use_certificate(ctx, cert))
					g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error()));
				else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM))
					g_warning("Loading of private key '%s' failed: %s", mypkey ? mypkey : mycert, ERR_reason_error_string(ERR_get_error()));
				else if (! SSL_CTX_check_private_key(ctx))
					g_warning("Private key does not match the certificate");

				X509_free(cert);
			} else
				g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error()));

			fclose(fp);
		} else
			g_warning("Could not find client certificate '%s'", scert);
		g_free(scert);
		g_free(spkey);
	}

	if ((cafile && *cafile) || (capath && *capath)) {
		char *scafile = NULL;
		char *scapath = NULL;
		if (cafile && *cafile)
			scafile = convert_home(cafile);
		if (capath && *capath)
			scapath = convert_home(capath);
		if (! SSL_CTX_load_verify_locations(ctx, scafile, scapath)) {
			g_warning("Could not load CA list for verifying TLS server certificate");
			g_free(scafile);
			g_free(scapath);
			SSL_CTX_free(ctx);
			return NULL;
		}
		g_free(scafile);
		g_free(scapath);
		verify = TRUE;
	} else if (store != NULL) {
		/* Make sure to increment the refcount every time the store is
		 * used, that's essential not to get it free'd by OpenSSL when
		 * the SSL_CTX is destroyed. */
		X509_STORE_up_ref(store);
		SSL_CTX_set_cert_store(ctx, store);
	}

	if(!(ssl = SSL_new(ctx)))
	{
		g_warning("Failed to allocate SSL structure");
		SSL_CTX_free(ctx);
		return NULL;
	}

	if(!SSL_set_fd(ssl, fd))
	{
		g_warning("Failed to associate socket to SSL stream");
		SSL_free(ssl);
		SSL_CTX_free(ctx);
		return NULL;
	}

#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	SSL_set_tlsext_host_name(ssl, server->connrec->address);
#endif

	SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
			SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

	chan = g_new0(GIOSSLChannel, 1);
	chan->fd = fd;
	chan->giochan = handle;
	chan->ssl = ssl;
	chan->ctx = ctx;
	chan->server = server;
	chan->port = port;
	chan->verify = verify;

	gchan = (GIOChannel *)chan;
	gchan->funcs = &irssi_ssl_channel_funcs;
	g_io_channel_init(gchan);
	gchan->is_readable = gchan->is_writeable = TRUE;
	gchan->use_buffer = FALSE;

	return gchan;
}