示例#1
0
const char* translate_path_common(const char* path, bool symlink)
{
    static thread_local char resolved_path[1024];
    std::string str;
    std::list<std::string> path_components;

    if (!path)
        return nullptr;

    if (g_prefix.empty())
        return path;

    // std::cout << "\tCWD is " << g_cwd << std::endl;

    if (path[0] != '/')
    {
        pthread_rwlock_rdlock(&g_cwdLock);
        str = g_cwd;
        pthread_rwlock_unlock(&g_cwdLock);
    }
    str += path;
    // std::cout << "*** Before explode: " << str << std::endl;

    path_components = explode_path(str);
    str = resolve_path(path_components, symlink);

    strncpy(resolved_path, str.c_str(), sizeof(resolved_path)-1);
    resolved_path[sizeof(resolved_path)-1] = '\0';

    // std::cout << "*** In: " << path << "; out: " << resolved_path << std::endl;

    return resolved_path;
}
示例#2
0
void __prefix_cwd(const char* in_path)
{
    if (!*in_path)
        return;

    std::string path;
    std::list<std::string> path_components;

    // std::cout << "CWD to " << in_path << std::endl;

    pthread_rwlock_wrlock(&g_cwdLock);
    if (in_path[0] != '/')
    {
        path = g_cwd;
        path += in_path;
    }
    else
        path = in_path;

    path_components = explode_path(path);
    g_cwd = join_path(canonicalize_path(path_components));

    if (g_cwd[g_cwd.length()-1] != '/')
        g_cwd += '/';

    // std::cout << "\t+++ CWD In: " << in_path << "; out: " << g_cwd << std::endl;

    pthread_rwlock_unlock(&g_cwdLock);
}
示例#3
0
std::string resolve_path(std::list<std::string>& path_components, bool symlink)
{
    std::string path, real_path;
    bool had_failure = false;

    real_path = g_prefix;

    // The resolution process is restarted when a symlink is encountered
restart_process:

    canonicalize_path(path_components);
    path.clear();

    for (std::list<std::string>::iterator it = path_components.begin();
            it != path_components.end(); it++)
    {
        std::string& comp = *it;

        path += '/';

        if (!had_failure) // check if there is any sense in using opendir() or lstat() again
        {
            DIR* dir;
            struct dirent* ent;
            struct stat st;
            bool isLink = false;
            bool is_system_root;

            real_path.replace(g_prefix.size(), std::string::npos, path);
            real_path += comp;

            // Do NOT perform symlink resolution on /system-root,
            // because that should look like a bind mount rather than
            // a symlink from inside the DPREFIX
            is_system_root = (it == path_components.begin())
                             && (comp == (SYSTEM_ROOT+1));

            // We try an lstat() first as an optimization,
            // because the opendir() path below is VERY slow on NFS mounts.
            if (lstat(real_path.c_str(), &st) == 0)
            {
                isLink = S_ISLNK(st.st_mode);
            }
            else
            {
                // std::cout << "*** opendir: " << real_path << std::endl;
                real_path.resize(real_path.length() - comp.length());

                dir = opendir(real_path.c_str());

                if (dir != nullptr)
                {
                    std::string best_match;
                    unsigned char best_match_type;

                    while ((ent = readdir(dir)) != nullptr)
                    {
                        // Commented out: replaced with lstat() above
                        /* if (comp == ent->d_name)
                        	break;
                        else*/ if (strcasecmp(comp.c_str(), ent->d_name) == 0)
                        {
                            best_match = ent->d_name;
                            best_match_type = ent->d_type;
                        }
                    }

                    if (ent != nullptr || !best_match.empty())
                    {
                        if (ent == nullptr)
                        {
                            // correct the case
                            comp = best_match;
                        }
                        else
                            best_match_type = ent->d_type;

                        if (best_match_type == DT_LNK && !is_system_root)
                        {
                            isLink = true;
                            real_path += comp;
                        }
                    }
                    else
                        had_failure = true;

                    closedir(dir);
                }
                else
                    had_failure = true;
            }

            if (symlink && it == --path_components.end())
                isLink = false;

            // Perform symlink resolution
            if (isLink && !is_system_root)
            {
                char link[4096];
                int len;

                // std::cout << "*** readlink: " << real_path << std::endl;
                len = readlink(real_path.c_str(), link, sizeof(link)-1);

                if (len > 0)
                {
                    std::list<std::string> link_components;

                    link[len] = '\0';

                    /*
                    if (strncmp(link, "@darling_prefix@", 16) == 0)
                    {
                    	std::string copy;

                    	copy = link;
                    	copy.replace(0, 16, INSTALL_PREFIX);

                    	strcpy(link, copy.c_str());
                    }
                    */
                    link_components = explode_path(link);

                    if (link[0] == '/')
                    {
                        // absolute symlink
                        it++;
                        it = path_components.erase(path_components.begin(), it);
                    }
                    else
                    {
                        // relative symlink
                        it = path_components.erase(it);
                    }

                    path_components.insert(it,
                                           link_components.begin(),
                                           link_components.end());

                    // We always restart the process
                    // 1) For absolute symlinks, because we're moving to a completely different path
                    // 2) For relative symlinks, because they may contain '..'
                    goto restart_process;
                }
            }
        }

        path += comp;
    }

    if (!path_components.empty())
    {
        if (*path_components.begin() == "proc" || path == "/dev/mach")
        {
            return path;
        }
        else if (*path_components.begin() == (SYSTEM_ROOT+1))
        {
            if (!symlink || path_components.size() > 1)
            {
                // Exit virtual prefix
                path = path.substr(sizeof(SYSTEM_ROOT)-1);

                if (path.empty())
                    return "/";
                else
                    return path;
            }
        }
    }
    if (path.compare(0, sizeof(SHARE_PATH "/")-1, SHARE_PATH "/") == 0)
    {
        return path;
    }

    // Apply virtual prefix
    real_path.replace(g_prefix.size(), std::string::npos, path);
    return real_path;
}
示例#4
0
文件: dcc.c 项目: Toeger/f-irc
void init_recv_dcc(const char *filename, const char *addr_in, int port, int server_nr, int channel_nr)
{
	int di = n_dcc;
	char *addr = NULL;
	char *real_name = NULL;
	char *local_filename = NULL;
	char *dummy = NULL;
	char *message = NULL;
	struct stat st;

	if (strcmp(addr_in, "0") == 0) /* irc bouncer most of the times */
		addr = strdup(server_list[server_nr].server_host);
	else if (strchr(addr_in, '.')) /* dotted ipv4 */
		addr = strdup(addr_in);
	else if (strchr(addr_in, ':')) /* dotted ipv6 */
		addr = strdup(addr_in);
	else
	{
		int ip = atoi(addr_in);

		asprintf(&addr, "%d.%d.%d.%d", (ip >> 24) & 255, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255);
	}

	update_statusline(server_nr, channel_nr, "DCC: IPv4 address is [%s]:%d", addr, port);

	n_dcc++;
	dcc_list = (DCC_t *)realloc(dcc_list, n_dcc * sizeof(DCC_t));
	memset(&dcc_list[di], 0x00, sizeof(DCC_t));

	dcc_list[di].server_nr = server_nr;
	dcc_list[di].channel_nr = channel_nr;

	dcc_list[di].last_update = 0;

	dcc_list[di].filename = strdup(filename);

	if (resolve(addr, port, &dcc_list[di].ri, &message) == FALSE)
	{
		update_statusline(server_nr, channel_nr, "Failed converting network address: %s", message);
		free(message);

		set_dcc_state(di, DSTATE_ERROR);
	}
	else
	{
		BOOL first_attempt = TRUE;
		const char *dcc_path_exploded = (dcc_path && strlen(dcc_path)) ? (char *)explode_path(dcc_path) : NULL;

		/* strip slashes from filename */
		dummy = strrchr(filename, '/');
		if (dummy)
			filename = dummy + 1;

		dummy = strrchr(filename, '\\');
		if (dummy)
			filename = dummy + 1;

		for(;;)
		{
			local_filename = NULL;

			if (first_attempt)
			{
				if (dcc_path_exploded)
					asprintf(&local_filename, "%s/%s", dcc_path_exploded, filename);
				else
					local_filename = strdup(filename);

				first_attempt = FALSE;
			}
			else
			{
				if (dcc_path_exploded)
					asprintf(&local_filename, "%s/%s.%d", dcc_path_exploded, filename, rand());
				else
					asprintf(&local_filename, "%s.%d", filename, rand());
			}

			if (stat(local_filename, &st) == -1)
				break;

			LOG("DCC create file, tested %s: %s\n", local_filename, strerror(errno));

			free(local_filename);
		}

		myfree(dcc_path_exploded);

		dcc_list[di].fd_file = open(local_filename, O_WRONLY | O_CREAT | O_EXCL, S_IRWXU | S_IRGRP | S_IROTH);
		if (dcc_list[di].fd_file == -1)
		{
			update_statusline(server_nr, channel_nr, "DCC: failed to create local file %s, reason: %s (%d)", local_filename, strerror(errno), errno);

			set_dcc_state(di, DSTATE_ERROR);
		}
		else
		{
			dcc_list[di].mode = DCC_RECEIVE_FILE;

			set_dcc_state(di, DSTATE_TCP_CONNECT);
		}

		myfree(local_filename);

		free(real_name);

		free(addr);
	}
}
示例#5
0
文件: config.c 项目: Toeger/f-irc
int load_config(const char *file)
{
	char *description = NULL, *server_host = NULL, *username = NULL, *password = NULL, *nickname = NULL, *user_complete_name = NULL;
	int server_index = -1;
	int linenr = 0;
	int fd = open(file, O_RDONLY);

	if (fd == -1)
	{
		if (errno == ENOENT)
			return -1;

		error_exit(TRUE, "Cannot open config file %s\n", file);
	}

	conf_file = strdup(file);

	for(;;)
	{
		char *line = read_line_fd(fd);
		char *cmd, *par;
		char *is;

		if (!line)
			break;

		linenr++;

		if (strlen(line) == 0)
		{
			myfree(line);
			continue;
		}

		if (line[0] == '#' || line[0] == ';')
		{
			myfree(line);
			continue;
		}

		is = strchr(line, '=');
		if (!is)
			error_exit(FALSE, "config: line %d is missing either command or parameter! (%s)", linenr, line);

		/* find parameter */
		par = is + 1;
		while(*par == ' ')
			par++;

		/* remove spaces around command */
		/* spaces at the start */
		cmd = line;
		while(*cmd == ' ')
			cmd++;
		/* spaces at the end */
		*is = 0x00;
		is--;
		while(*is == ' ')
		{
			*is = 0x00;
			is--;
		}

		if (strcmp(cmd, "server") == 0 || strcmp(cmd, "send_after_login") == 0 || strcmp(cmd, "auto_join") == 0 || strcmp(cmd, "channel") == 0 || strcmp(cmd, "rejoin") == 0)
		{
			/* all stuff already known? */
			if (server_host)
			{
				if (nickname == NULL)
					error_exit(FALSE, "nickname must be set for %s", server_host);

				server_index = add_server(server_host, username, password, nickname, user_complete_name, description ? description : server_host);
				myfree(server_host);
				server_host = NULL;
				myfree(username);
				myfree(password);
				myfree(nickname);
				myfree(user_complete_name);
				myfree(description);

				username = password = nickname = user_complete_name = description = NULL;
			}
		}

		if (strcmp(cmd, "server") == 0)
		{
			/* new server */
			server_host = strdup(par);
		}
		else if (strcmp(cmd, "favorite") == 0)
		{
			int n = -1;
			string_array_t parts;

			init_string_array(&parts);

			split_string(par, " ", TRUE, &parts);
			n = string_array_get_n(&parts);

			if (n != 1 && n != 2)
				error_exit(FALSE, "favorite needs either be in format \"server channel\" or \"channel\"");

			if (n == 2)
				add_favorite(string_array_get(&parts, 0), string_array_get(&parts, 1));
			else
				add_favorite(NULL, string_array_get(&parts, 0));

			free_splitted_string(&parts);
		}
		else if (strcmp(cmd, "username") == 0)
			username = strdup(par);
		else if (strcmp(cmd, "password") == 0)
			password = strdup(par);
		else if (strcmp(cmd, "nick") == 0 || strcmp(cmd, "nickname") == 0)
			nickname = strdup(par);
		else if (strcmp(cmd, "name") == 0)
			user_complete_name = strdup(par);
		else if (strcmp(cmd, "dictionary_file") == 0)
		{
			const char *filename = explode_path(par);

			if (!filename)
				error_exit(TRUE, "Path '%s' is not understood\n", par);

			dictionary_file = filename;

			if (load_dictionary() == FALSE)
				error_exit(TRUE, "Failure loading dictionary file %s (%s)", filename, par);
		}
		else if (strcmp(cmd, "description") == 0)
			description = strdup(par);
		else if (strcmp(cmd, "server_exit_message") == 0)
			server_exit_message = strdup(par);
		else if (strcmp(cmd, "log_dir") == 0)
			log_dir = strdup(par);
		else if (strcmp(cmd, "part_message") == 0)
			part_message = strdup(par);
		else if (strcmp(cmd, "notify_nick") == 0)
			notify_nick = strdup(par);
		else if (strcmp(cmd, "userinfo") == 0)
			userinfo = strdup(par);
		else if (strcmp(cmd, "finger_str") == 0)
			finger_str = strdup(par);
		else if (strcmp(cmd, "mark_personal_messages") == 0)
			mark_personal_messages = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "meta-colors") == 0)
			colors_meta = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "headline_matcher") == 0)
			add_headline_matcher(par);
		else if (strcmp(cmd, "all-colors") == 0)
			colors_all = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "dcc_bind_to") == 0)
			dcc_bind_to = strdup(par);
		else if (strcmp(cmd, "update_clock_at_data") == 0)
			update_clock_at_data = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "nick-color") == 0)
			nick_color = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "use_nonbasic_colors") == 0)
			use_nonbasic_colors = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "ignore_unknown_irc_protocol_msgs") == 0)
			ignore_unknown_irc_protocol_msgs = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "auto_markerline") == 0)
			auto_markerline = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "inverse_window_heading") == 0)
			inverse_window_heading = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "keep_channels_sorted") == 0)
			keep_channels_sorted = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "allow_invite") == 0)
			allow_invite = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "show_headlines") == 0)
			show_headlines = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "remember_channels") == 0)
			remember_channels = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "allow_userinfo") == 0)
			allow_userinfo = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "extra_highlights") == 0)
			add_to_string_array(&extra_highlights, par);
		else if (strcmp(cmd, "only_one_markerline") == 0)
			only_one_markerline = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "auto_rejoin") == 0)
			auto_rejoin = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "ignore_mouse") == 0)
			ignore_mouse = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "irc_keepalive") == 0)
			irc_keepalive = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "space_after_start_marker") == 0)
			space_after_start_marker = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "jumpy_navigation") == 0)
			jumpy_navigation = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "mark_meta") == 0)
			mark_meta = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "user_column") == 0)
			user_column = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "full_user") == 0)
			full_user = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "grep_filter") == 0)
			add_filter(gp, par, linenr);
		else if (strcmp(cmd, "headline_filter") == 0)
			add_filter(hlgp, par, linenr);
		else if (strcmp(cmd, "show_parts") == 0)
			show_parts = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "show_mode_changes") == 0)
			show_mode_changes = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "show_nick_change") == 0)
			show_nick_change = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "show_joins") == 0)
			show_joins = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "store_config_on_exit") == 0)
			store_config_on_exit = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "partial_highlight_match") == 0)
			partial_highlight_match = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "topic_scroll") == 0)
			topic_scroll = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "notice_in_serverchannel") == 0)
			notice_in_server_channel = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "highlight") == 0)
			highlight = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "fuzzy_highlight") == 0)
			fuzzy_highlight = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "theme") == 0)
		{
			struct stat status;
			const char *filename = explode_path(par);

			if (!filename)
				error_exit(TRUE, "Path '%s' is not understood\n", par);

			if (stat(filename, &status) == -1) 	/* file doesn't exist, look for it under SYSCONFDIR */
			{
				int len = strlen(SYSCONFDIR) + strlen(par) + 2;
				char *theme_path = malloc(len * sizeof(char));

				snprintf(theme_path, len, "%s/%s", SYSCONFDIR, par);
				load_theme(theme_path);

				theme_file = theme_path;
			} 
			else
			{
				load_theme(filename);

				theme_file = strdup(par);
			}

			myfree(filename);
		}
		else if (strcmp(cmd, "ignore_file") == 0)
		{
			struct stat status;
			const char *filename = explode_path(par);

			if (!filename)
				error_exit(TRUE, "Path '%s' is not understood\n", par);

			if (load_ignore_list(par) == TRUE)
			{
			}
			else if (load_ignore_list(filename) == TRUE)
			{
			}
			else if (stat(filename, &status) == -1) 	/* file doesn't exist, look elsewhere */
			{
				int len = strlen(SYSCONFDIR) + strlen(par) + 2;
				char *ignore_file = malloc(len * sizeof(char));

				/* look for it under SYSCONFDIR */
				snprintf(ignore_file, len, "%s/%s", SYSCONFDIR, par);

				/* look for it under ~/.firc location */
				if (stat(ignore_file, &status) == -1)
					snprintf(ignore_file, len, "%s/%s", dirname(conf_file), par);

				load_ignore_list(ignore_file);

				myfree(ignore_file);
			} 

			myfree(filename);
		}
		else if (strcmp(cmd, "send_after_login") == 0)
		{
			server *ps = &server_list[server_index];

			if (server_index == -1)
				error_exit(FALSE, "send_after_login: you need to define a server first\n");

			add_to_string_array(&ps -> send_after_login, par);
		}
		else if (strcmp(cmd, "auto_join") == 0 || strcmp(cmd, "channel") == 0)
		{
			if (server_index == -1)
				error_exit(FALSE, "auto_join: you need to define a server first\n");

			add_autojoin(server_index, par);
		}
		else if (strcmp(cmd, "rejoin") == 0)
		{
			add_channel(server_index, par);

			if (keep_channels_sorted)
				sort_channels(server_index);
		}
		else if (strcmp(cmd, "auto_private_channel") == 0)
			auto_private_channel = parse_false_true(par, cmd, linenr);
		else if (strcmp(cmd, "dcc_path") == 0)
			dcc_path = strdup(par);
		else if (strcmp(cmd, "default_colorpair") == 0)
			default_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "markerline_colorpair") == 0)
			markerline_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "highlight_colorpair") == 0)
			highlight_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "meta_colorpair") == 0)
			meta_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "error_colorpair") == 0)
			error_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "temp_colorpair") == 0)
			temp_colorpair = parse_color_spec(par, linenr, cmd);
		else if (strcmp(cmd, "check_for_mail") == 0)
			check_for_mail = atoi(par);
		else if (strcmp(cmd, "user_column_width") == 0)
			user_column_width = atoi(par);
		else if (strcmp(cmd, "delay_before_reconnect") == 0)
			delay_before_reconnect = atoi(par);
		else if (strcmp(cmd, "word_cloud_n") == 0)
			word_cloud_n = atoi(par);
		else if (strcmp(cmd, "word_cloud_refresh") == 0)
		{
			word_cloud_refresh = atoi(par);
			word_cloud_last_refresh = time(NULL);
		}
		else if (strcmp(cmd, "word_cloud_win_height") == 0)
			word_cloud_win_height = atoi(par);
		else if (strcmp(cmd, "max_channel_record_lines") == 0)
			max_channel_record_lines = atoi(par);
		else if (strcmp(cmd, "word_cloud_min_word_size") == 0)
			word_cloud_min_word_size = atoi(par);
		else
		{
			error_exit(FALSE, "'%s=%s' is not understood\n", cmd, par);
		}

		myfree(line);
	}

	close(fd);

	if (server_host)
	{
		if (nickname == NULL)
			error_exit(FALSE, "nickname must be set for %s", server_host);
		add_server(server_host, username, password, nickname, user_complete_name, description);
		myfree(server_host);
		myfree(username);
		myfree(password);
		myfree(nickname);
		myfree(user_complete_name);
		myfree(description);
	}

	return 0;
}