Exemple #1
0
static void test_strextend(void) {
        _cleanup_free_ char *str = NULL;

        assert_se(strextend(&str, NULL));
        assert_se(streq_ptr(str, ""));
        assert_se(strextend(&str, "", "0", "", "", "123", NULL));
        assert_se(streq_ptr(str, "0123"));
        assert_se(strextend(&str, "456", "78", "9", NULL));
        assert_se(streq_ptr(str, "0123456789"));
}
Exemple #2
0
int namespace_flag_to_string_many(unsigned long flags, char **ret) {
        _cleanup_free_ char *s = NULL;
        unsigned i;

        for (i = 0; namespace_flag_map[i].name; i++) {
                if ((flags & namespace_flag_map[i].flag) != namespace_flag_map[i].flag)
                        continue;

                if (!s) {
                        s = strdup(namespace_flag_map[i].name);
                        if (!s)
                                return -ENOMEM;
                } else {
                        if (!strextend(&s, " ", namespace_flag_map[i].name, NULL))
                                return -ENOMEM;
                }
        }

        if (!s) {
                s = strdup("");
                if (!s)
                        return -ENOMEM;
        }

        *ret = s;
        s = NULL;

        return 0;
}
Exemple #3
0
/*
 * help_me:  The big one.  The help procedure that handles working out
 * what was actually requested, sets up the paused topic list if it is
 * needed, does pretty much all the hard work.
 */
static	void	help_me (char *topics, char *args)
{
    char *	ptr;
    glob_t	g;
    int	entries = 0,
        cnt,
        i,
        cols;
    Stat	stat_buf;
    char	path[BIG_BUFFER_SIZE+1];
    int	help_paused_first_call = 0;
    char *	help_paused_path = (char *) 0;
    char *	help_paused_name = (char *) 0;
    char *	temp;
    char	tmp[BIG_BUFFER_SIZE+1];
    char	buffer[BIG_BUFFER_SIZE+1];
    char *	pattern = NULL;

    strlcpy(help_topic_list, topics, sizeof help_topic_list);
    ptr = get_string_var(HELP_PATH_VAR);

    snprintf(path, sizeof path, "%s/%s", ptr, topics);
    for (ptr = path; (ptr = strchr(ptr, ' '));)
        *ptr = '/';

    /*
     * first we check access to the help dir, whinge if we can't, then
     * work out we need to ask them for more help, else we check the
     * args list, and do the stuff
     */
    if (help_show_directory)
    {
        help_show_paused_topic(paused_topic, empty_string);
        help_show_directory = 0;
    }

    finished_help_paging = 0;
    if (access(path, R_OK|X_OK))
    {
        help_put_it(no_help, "*** Cannot access help directory!");
        set_help_screen((Screen *) 0);
        return;
    }

    this_arg = next_arg(args, &args);
    if (!this_arg && *help_topic_list && get_int_var(HELP_PROMPT_VAR))
    {
        if ((temp = strrchr(help_topic_list, ' ')) != NULL)
            *temp = '\0';
        else
            *help_topic_list = '\0';

        snprintf(tmp, sizeof tmp, "%s%sHelp? ", help_topic_list, *help_topic_list ? " " : empty_string);

        if (!dumb_mode)
            add_wait_prompt(tmp, help_me, help_topic_list, WAIT_PROMPT_LINE, 1);
        return;
    }

    if (!this_arg)
    {
        set_help_screen((Screen *) 0);
        return;
    }

    create_help_window();

    if (!help_window)
        return;

    /*
     * This is just a bogus while loop which is intended to allow
     * the user to do '/help alias expressions' without having to
     * include a slash inbetween the topic and subtopic.
     *
     * If all goes well, we 'break' at the bottom of the loop.
     */
    while (this_arg)
    {
        entries = 0;

        if (!*this_arg)
            help_topic(path, NULL);

        if (strcmp(this_arg, "?") == 0)
        {
            this_arg = empty_string;
            if (!dont_pause_topic)
                dont_pause_topic = 1;
        }

        /*
         * entry_size is set to the width of the longest help topic
         * (adjusted for compression extensions, of course.)
         */
        entry_size = 0;

        /*
         * Gather up the names of the files in the help directory.
         */
        {
            size_t size;
#ifndef HAVE_FCHDIR
            char 	opath[MAXPATHLEN + 1];
            getcwd(opath, MAXPATHLEN);
#else
            int 	cwd = open(".", O_RDONLY);
#endif

            size = strlen(path) + 2 + strlen(this_arg) + 3;

            chdir(path);
            pattern = alloca(size);
            snprintf(pattern, size, "%s*", this_arg);
#ifdef GLOB_INSENSITIVE
            bsd_glob(pattern, GLOB_INSENSITIVE, NULL, &g);
#else
            bsd_glob(pattern, 0, NULL, &g);
#endif

#ifndef HAVE_FCHDIR
            chdir(opath);
#else
            fchdir(cwd);
            close(cwd);
#endif
        }

        for (i = 0; i < g.gl_matchc; i++)
        {
            char	*tmp2 = g.gl_pathv[i];
            int 	len = strlen(tmp2);

            if (!end_strcmp(tmp2, ".gz", 3))
                len -= 3;
            entry_size = (len > entry_size) ? len : entry_size;
        }

        /*
         * Right here we need to check for an 'exact match'.
         * An 'exact match' would be sitting in gl_pathv[0],
         * and it is 'exact' if it is identical to what we are
         * looking for, or if it is the same except that it has
         * a compression extension on it
         */
        if (g.gl_matchc > 1)
        {
            char *str1 = g.gl_pathv[0];
            const char *str2 = this_arg;
            int len1 = strlen(str1);
            int len2 = strlen(str2);


            if (len1 == len2 && !my_stricmp(str1, str2))
                entries = 1;
            else if (len1 - 3 == len2 && !my_strnicmp(str1, str2, len2) && !end_strcmp(str1, ".gz", 3))
                entries = 1;
            else if (len1 - 2 == len2 && !my_strnicmp(str1, str2, len2) && !end_strcmp(str1, ".Z", 2))
                entries = 1;
            else if (len1 - 2 == len2 && !my_strnicmp(str1, str2, len2) && !end_strcmp(str1, ".z", 2))
                entries = 1;
        }

        if (!*help_topic_list)
            dont_pause_topic = 1;

        /* reformatted */
        /*
         * entries: -1 means something really died, 0 means there
         * was no help, 1, means it wasn't a directory, and so to
         * show the help file, and the default means to add the
         * stuff to the paused topic list..
         */
        if (!entries)
            entries = g.gl_matchc;

        switch (entries)
        {
        case -1:
        {
            help_put_it(no_help, "*** Error during help function: %s", strerror(errno));
            set_help_screen(NULL);
            if (help_paused_first_call)
            {
                help_topic(help_paused_path, help_paused_name);
                help_paused_first_call = 0;
                new_free(&help_paused_path);
                new_free(&help_paused_name);
            }
            message_from(NULL, LOG_CRAP);
            return;
        }
        case 0:
        {
            help_put_it(this_arg, "*** No help available on %s: Use ? for list of topics", this_arg);
            if (!get_int_var(HELP_PROMPT_VAR))
            {
                set_help_screen(NULL);
                break;
            }
            snprintf(tmp, sizeof tmp, "%s%sHelp? ", help_topic_list, *help_topic_list ? " " : empty_string);
            if (!dumb_mode)
                add_wait_prompt(tmp, help_me, help_topic_list, WAIT_PROMPT_LINE, 1);

            if (help_paused_first_call)
            {
                help_topic(help_paused_path, help_paused_name);
                help_paused_first_call = 0;
                new_free(&help_paused_path);
                new_free(&help_paused_name);
            }

            break;
        }
        case 1:
        {
            snprintf(tmp, sizeof tmp, "%s/%s", path, g.gl_pathv[0]);
            stat(tmp, &stat_buf);
            if (stat_buf.st_mode & S_IFDIR)
            {
                strlcpy(path, tmp, sizeof path);
                if (*help_topic_list)
                    strlcat(help_topic_list, " ", sizeof help_topic_list);

                strlcat(help_topic_list, g.gl_pathv[0], sizeof help_topic_list);

                if (!(this_arg = next_arg(args, &args)))
                {
                    help_paused_first_call = 1;
                    malloc_strcpy(&help_paused_path, path);
                    malloc_strcpy(&help_paused_name, g.gl_pathv[0]);
                    dont_pause_topic = -1;
                    this_arg = "?";
                }
                bsd_globfree(&g);
                continue;
            }
            else
            {
                help_topic(path, g.gl_pathv[0]);
                finished_help_paging = 0;
                break;
            }
        }
        default:
        {
            help_show_directory = 1;
            strlcpy(paused_topic, help_topic_list, sizeof paused_topic);
            help_pause_add_line("*** %s choices:", help_topic_list);
            entry_size += 2;
            cols = (current_term->TI_cols - 10) / entry_size;

            strlcpy(buffer, empty_string, sizeof(buffer));
            cnt = 0;

            for (i = 0; i < entries; i++)
            {
                if (!end_strcmp(g.gl_pathv[i], ".gz", 3))
                    chop(g.gl_pathv[i], 3);
                strlcat(buffer, g.gl_pathv[i], sizeof buffer);

                /*
                 * Since we already know how many columns each
                 * line will contain, we check to see if we have
                 * accumulated that many entries.  If we have, we
                 * output the line to the screen.
                 */
                if (++cnt == cols)
                {
                    help_pause_add_line("%s", buffer);
                    *buffer = 0;
                    cnt = 0;
                }

                /*
                 * If we have not finished this line, then we have
                 * to pad the name length out to the expected width.
                 * 'entry_size' is the column width.  We also have
                 * do adjust for compression extension.
                 */
                else
                    strextend(buffer, ' ', entry_size - strlen(g.gl_pathv[i]));
            }

            help_pause_add_line("%s", buffer);
            if (help_paused_first_call)
            {
                help_topic(help_paused_path, help_paused_name);
                help_paused_first_call = 0;
                new_free(&help_paused_path);
                new_free(&help_paused_name);
            }
            if (dont_pause_topic == 1)
            {
                help_show_paused_topic(paused_topic, empty_string);
                help_show_directory = 0;
            }
            break;
        }
        }
        /* end of reformatting */


        bsd_globfree(&g);
        break;
    }

    /*
     * This one is for when there was never a topic and the prompt
     * never got a topic..  and help_screen was never reset..
     * phone, jan 1993.
     */
    if (!*help_topic_list && finished_help_paging)
        set_help_screen((Screen *) 0);

    message_from(NULL, LOG_CRAP);
}
/* Go through the file and parse each line */
int config_parse(const char *unit,
                 const char *filename,
                 FILE *f,
                 const char *sections,
                 ConfigItemLookup lookup,
                 const void *table,
                 ConfigParseFlags flags,
                 void *userdata) {

        _cleanup_free_ char *section = NULL, *continuation = NULL;
        _cleanup_fclose_ FILE *ours = NULL;
        unsigned line = 0, section_line = 0;
        bool section_ignored = false;
        int r;

        assert(filename);
        assert(lookup);

        if (!f) {
                f = ours = fopen(filename, "re");
                if (!f) {
                        /* Only log on request, except for ENOENT,
                         * since we return 0 to the caller. */
                        if ((flags & CONFIG_PARSE_WARN) || errno == ENOENT)
                                log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
                                               "Failed to open configuration file '%s': %m", filename);
                        return errno == ENOENT ? 0 : -errno;
                }
        }

        fd_warn_permissions(filename, fileno(f));

        for (;;) {
                _cleanup_free_ char *buf = NULL;
                bool escaped = false;
                char *l, *p, *e;

                r = read_line(f, LONG_LINE_MAX, &buf);
                if (r == 0)
                        break;
                if (r == -ENOBUFS) {
                        if (flags & CONFIG_PARSE_WARN)
                                log_error_errno(r, "%s:%u: Line too long", filename, line);

                        return r;
                }
                if (r < 0) {
                        if (CONFIG_PARSE_WARN)
                                log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line);

                        return r;
                }

                l = buf;
                if (!(flags & CONFIG_PARSE_REFUSE_BOM)) {
                        char *q;

                        q = startswith(buf, UTF8_BYTE_ORDER_MARK);
                        if (q) {
                                l = q;
                                flags |= CONFIG_PARSE_REFUSE_BOM;
                        }
                }

                if (continuation) {
                        if (strlen(continuation) + strlen(l) > LONG_LINE_MAX) {
                                if (flags & CONFIG_PARSE_WARN)
                                        log_error("%s:%u: Continuation line too long", filename, line);
                                return -ENOBUFS;
                        }

                        if (!strextend(&continuation, l, NULL)) {
                                if (flags & CONFIG_PARSE_WARN)
                                        log_oom();
                                return -ENOMEM;
                        }

                        p = continuation;
                } else
                        p = l;

                for (e = p; *e; e++) {
                        if (escaped)
                                escaped = false;
                        else if (*e == '\\')
                                escaped = true;
                }

                if (escaped) {
                        *(e-1) = ' ';

                        if (!continuation) {
                                continuation = strdup(l);
                                if (!continuation) {
                                        if (flags & CONFIG_PARSE_WARN)
                                                log_oom();
                                        return -ENOMEM;
                                }
                        }

                        continue;
                }

                r = parse_line(unit,
                               filename,
                               ++line,
                               sections,
                               lookup,
                               table,
                               flags,
                               &section,
                               &section_line,
                               &section_ignored,
                               p,
                               userdata);
                if (r < 0) {
                        if (flags & CONFIG_PARSE_WARN)
                                log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
                        return r;
                }

                continuation = mfree(continuation);
        }

        if (continuation) {
                r = parse_line(unit,
                               filename,
                               ++line,
                               sections,
                               lookup,
                               table,
                               flags,
                               &section,
                               &section_line,
                               &section_ignored,
                               continuation,
                               userdata);
                if (r < 0) {
                        if (flags & CONFIG_PARSE_WARN)
                                log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
                        return r;
                }
        }

        return 0;
}
static void test_strextend(void) {
        _cleanup_free_ char *str = strdup("0123");
        strextend(&str, "456", "78", "9", NULL);
        assert_se(streq(str, "0123456789"));
}