Beispiel #1
0
char *
mc_build_filename (const char *first_element, ...)
{
    va_list args;
    const char *element = first_element;
    GString *path;
    char *ret;

    if (element == NULL)
        return NULL;

    path = g_string_new ("");
    va_start (args, first_element);

    do
    {
        char *tmp_element;
        size_t len;
        const char *start;

        tmp_element = g_strdup (element);

        element = va_arg (args, char *);

        canonicalize_pathname (tmp_element);
        len = strlen (tmp_element);
        start = (tmp_element[0] == PATH_SEP) ? tmp_element + 1 : tmp_element;

        g_string_append (path, start);
        if (tmp_element[len - 1] != PATH_SEP && element != NULL)
            g_string_append_c (path, PATH_SEP);

        g_free (tmp_element);
    }
    while (element != NULL);

    va_end (args);

    g_string_prepend_c (path, PATH_SEP);

    ret = g_string_free (path, FALSE);
    canonicalize_pathname (ret);

    return ret;
}
Beispiel #2
0
/*
 * Follow > 0: follow links, serves as loop protect,
 *       == -1: do not follow links
 */
static struct vfs_s_entry *
vfs_s_find_entry_tree (struct vfs_class *me, struct vfs_s_inode *root,
		       const char *a_path, int follow, int flags)
{
    size_t pseg;
    struct vfs_s_entry *ent = NULL;
    char * const pathref = g_strdup (a_path);
    char *path = pathref;

    canonicalize_pathname (path);

    while (root) {
	while (*path == PATH_SEP)	/* Strip leading '/' */
	    path++;

	if (!path[0]) {
	    g_free (pathref);
	    return ent;
	}

	for (pseg = 0; path[pseg] && path[pseg] != PATH_SEP; pseg++);

	for (ent = root->subdir; ent != NULL; ent = ent->next)
	    if (strlen (ent->name) == pseg
		&& (!strncmp (ent->name, path, pseg)))
		/* FOUND! */
		break;

	if (!ent && (flags & (FL_MKFILE | FL_MKDIR)))
	    ent = vfs_s_automake (me, root, path, flags);
	if (!ent) {
	    me->verrno = ENOENT;
	    goto cleanup;
	}
	path += pseg;
	/* here we must follow leading directories always;
	   only the actual file is optional */
	ent =
	    vfs_s_resolve_symlink (me, ent,
				   strchr (path,
					   PATH_SEP) ? LINK_FOLLOW :
				   follow);
	if (!ent)
	    goto cleanup;
	root = ent->ino;
    }
cleanup:
    g_free (pathref);
    return NULL;
}
Beispiel #3
0
char *
mc_build_filename (const char *first_element, ...)
{
    gboolean absolute;
    va_list args;
    const char *element = first_element;
    GString *path;
    char *ret;

    if (element == NULL)
        return NULL;

    path = g_string_new ("");
    va_start (args, first_element);

    absolute = (*first_element != '\0' && *first_element == PATH_SEP);

    do
    {
        if (*element == '\0')
            element = va_arg (args, char *);
        else
        {
            char *tmp_element;
            size_t len;
            const char *start;

            tmp_element = g_strdup (element);

            element = va_arg (args, char *);

            canonicalize_pathname (tmp_element);
            len = strlen (tmp_element);
            start = (tmp_element[0] == PATH_SEP) ? tmp_element + 1 : tmp_element;

            g_string_append (path, start);
            if (tmp_element[len - 1] != PATH_SEP && element != NULL)
                g_string_append_c (path, PATH_SEP);

            g_free (tmp_element);
        }
    }
Beispiel #4
0
/*
 *  doing similar to $ gtar | compression | encryption 
 */
static void
start_backup(
    dle_t      *dle,
    char       *host,
    int		dataf,
    int		mesgf,
    int		indexf)
{
    char tmppath[PATH_MAX];
    int dumpin, dumpout, compout;
    char *cmd = NULL;
    char *indexcmd = NULL;
    char *dirname = NULL;
    int l;
    char dumptimestr[80] = "UNUSED";
    struct tm *gmtm;
    amandates_t *amdates = NULL;
    time_t prev_dumptime = 0;
    char *error_pn = NULL;
    char *compopt  = NULL;
    char *encryptopt = skip_argument;
    char *tquoted;
    char *fquoted;
    char *qdisk;
    int infd, outfd;
    ssize_t nb;
    char buf[32768];
    char *amandates_file = NULL;
    am_level_t *alevel = (am_level_t *)dle->levellist->data;
    int      level  = alevel->level;
    int        native_pipe[2];
    int        client_pipe[2];
    int        data_out;

    have_filter = FALSE;
    crc32_init(&native_crc.crc);
    crc32_init(&client_crc.crc);

    /* create pipes to compute the native CRC */
    if (pipe(native_pipe) < 0) {
	char  *errmsg;
	char  *qerrmsg;
	errmsg = g_strdup_printf(_("Program '%s': can't create pipe"),
				 dle->program);
	qerrmsg = quote_string(errmsg);
	fdprintf(mesgf, _("sendbackup: error [%s]\n"), errmsg);
	dbprintf(_("ERROR %s\n"), qerrmsg);
	amfree(qerrmsg);
	amfree(errmsg);
	return;
    }

    if (dle->encrypt == ENCRYPT_CUST ||
        dle->compress == COMP_FAST ||
        dle->compress == COMP_BEST ||
        dle->compress == COMP_CUST) {

        have_filter = TRUE;

        /* create pipes to compute the client CRC */
        if (pipe(client_pipe) < 0) {
            char  *errmsg;
            char  *qerrmsg;
            errmsg = g_strdup_printf(_("Application '%s': can't create pipe"),
                                     dle->program);
            qerrmsg = quote_string(errmsg);
            fdprintf(mesgf, _("sendbackup: error [%s]\n"), errmsg);
            dbprintf(_("ERROR %s\n"), qerrmsg);
            amfree(qerrmsg);
            amfree(errmsg);
            return;
        }
        data_out = client_pipe[1];
	client_pipe[1] = -1;
    } else {
        data_out = dataf;
	dataf = -1;
    }

    error_pn = g_strconcat(get_pname(), "-smbclient", NULL);

    qdisk = quote_string(dle->disk);
    dbprintf(_("start: %s:%s lev %d\n"), host, qdisk, level);

    g_fprintf(stderr, _("%s: start [%s:%s level %d]\n"),
	    get_pname(), host, qdisk, level);

     /*  apply client-side encryption here */
     if ( dle->encrypt == ENCRYPT_CUST ) {
        encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0,
			&compout, &data_out, &mesgf,
			dle->clnt_encrypt, encryptopt, NULL);
        dbprintf(_("gnutar: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt);
	aclose(data_out);
    } else {
        compout = data_out;
	data_out = -1;
        encpid = -1;
    }
    /*  now do the client-side compression */
    if (dle->compress == COMP_FAST || dle->compress == COMP_BEST) {
        compopt = skip_argument;
#if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT)
	if(dle->compress == COMP_BEST) {
	    compopt = COMPRESS_BEST_OPT;
	} else {
	    compopt = COMPRESS_FAST_OPT;
	}
#endif
	comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0,
			    &dumpout, &compout, &mesgf,
			    COMPRESS_PATH, compopt, NULL);
	dbprintf(_("gnutar: pid %ld: %s"), (long)comppid, COMPRESS_PATH);
	if(compopt != skip_argument) {
	    dbprintf(_("pid %ld: %s %s\n"),
			(long)comppid, COMPRESS_PATH, compopt);
	} else {
	    dbprintf(_("pid %ld: %s\n"), (long)comppid, COMPRESS_PATH);
	}
	aclose(compout);
     } else if (dle->compress == COMP_CUST) {
        compopt = skip_argument;
	comppid = pipespawn(dle->compprog, STDIN_PIPE, 0,
			    &dumpout, &compout, &mesgf,
			    dle->compprog, compopt, NULL);
	if(compopt != skip_argument) {
	    dbprintf(_("pid %ld: %s %s\n"),
		     (long)comppid, dle->compprog, compopt);
	} else {
	    dbprintf(_("pid %ld: %s\n"), (long)comppid, dle->compprog);
	}
	aclose(compout);
    } else {
	dumpout = compout;
	compout = -1;
	comppid = -1;
    }

    gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR);
    if (strlen(gnutar_list_dir) == 0)
	gnutar_list_dir = NULL;

#ifdef SAMBA_CLIENT							/* { */
    if (dle->device[0] == '/' && dle->device[1]=='/')
	amfree(incrname);
    else
#endif									/* } */
    if (gnutar_list_dir) {
	char *basename = NULL;
	char number[NUM_STR_SIZE];
	char *inputname = NULL;
	int baselevel;
	char *sdisk = sanitise_filename(dle->disk);

	basename = g_strjoin(NULL, gnutar_list_dir,
			     "/",
			     host,
			     sdisk,
			     NULL);
	amfree(sdisk);

	g_snprintf(number, sizeof(number), "%d", level);
	incrname = g_strjoin(NULL, basename, "_", number, ".new", NULL);
	unlink(incrname);

	/*
	 * Open the listed incremental file from the previous level.  Search
	 * backward until one is found.  If none are found (which will also
	 * be true for a level 0), arrange to read from /dev/null.
	 */
	baselevel = level;
	infd = -1;
	while (infd == -1) {
	    if (--baselevel >= 0) {
		g_snprintf(number, sizeof(number), "%d", baselevel);
		g_free(inputname);
		inputname = g_strconcat(basename, "_", number, NULL);
	    } else {
		g_free(inputname);
		inputname = g_strdup("/dev/null");
	    }
	    if ((infd = open(inputname, O_RDONLY)) == -1) {
		int save_errno = errno;
		char *qname = quote_string(inputname);

		dbprintf(_("gnutar: error opening '%s': %s\n"),
			  qname,
			  strerror(save_errno));
		if (baselevel < 0) {
		    error(_("error [opening '%s': %s]"), qname, strerror(save_errno));
		    /*NOTREACHED*/
		}
		amfree(qname);
	    }
	}

	/*
	 * Copy the previous listed incremental file to the new one.
	 */
	if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) {
	    error(_("error [opening '%s': %s]"), incrname, strerror(errno));
	    /*NOTREACHED*/
	}

	while ((nb = read(infd, &buf, sizeof(buf))) > 0) {
	    if (full_write(outfd, &buf, (size_t)nb) < (size_t)nb) {
		error(_("error [writing to '%s': %s]"), incrname,
		       strerror(errno));
		/*NOTREACHED*/
	    }
	}

	if (nb < 0) {
	    error(_("error [reading from '%s': %s]"), inputname, strerror(errno));
	    /*NOTREACHED*/
	}

	if (close(infd) != 0) {
	    error(_("error [closing '%s': %s]"), inputname, strerror(errno));
	    /*NOTREACHED*/
	}
	if (close(outfd) != 0) {
	    error(_("error [closing '%s': %s]"), incrname, strerror(errno));
	    /*NOTREACHED*/
	}

	tquoted = quote_string(incrname);
	if(baselevel >= 0) {
	    fquoted = quote_string(inputname);
	    dbprintf(_("doing level %d dump as listed-incremental from '%s' to '%s'\n"),
		     level, fquoted, tquoted);
	    amfree(fquoted);
	} else {
	    dbprintf(_("doing level %d dump as listed-incremental to '%s'\n"),
		     level, tquoted);
	}
	amfree(tquoted);
	amfree(inputname);
	amfree(basename);
    } else {
	/* no gnutar-listdir, so we're using amandates */

	/* find previous dump time, failing completely if there's a problem */
	amandates_file = getconf_str(CNF_AMANDATES);
	if(!start_amandates(amandates_file, 0)) {
	    error(_("error [opening %s: %s]"), amandates_file, strerror(errno));
	    /*NOTREACHED*/
	}

	amdates = amandates_lookup(dle->disk);

	prev_dumptime = EPOCH;
	for(l = 0; l < level; l++) {
	    if(amdates->dates[l] > prev_dumptime)
		prev_dumptime = amdates->dates[l];
	}

	finish_amandates();
	free_amandates();

	gmtm = gmtime(&prev_dumptime);
	g_snprintf(dumptimestr, sizeof(dumptimestr),
		    "%04d-%02d-%02d %2d:%02d:%02d GMT",
		    gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday,
		    gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec);

	dbprintf(_("gnutar: doing level %d dump from amandates-derived date: %s\n"),
		  level, dumptimestr);
    }

    dirname = amname_to_dirname(dle->device);

    cur_dumptime = time(0);
    cur_level = level;
    cur_disk = g_strdup(dle->disk);
#ifdef GNUTAR
#  define PROGRAM_GNUTAR GNUTAR
#else
#  define PROGRAM_GNUTAR "tar"
#endif
    indexcmd = g_strjoin(NULL, 
			 PROGRAM_GNUTAR,
			 " -tf", " -",
			 " 2>/dev/null",
			 " | sed", " -e",
			 " \'s/^\\.//\'",
			 NULL);

#ifdef SAMBA_CLIENT							/* { */
    /* Use sambatar if the disk to back up is a PC disk */
    if (dle->device[0] == '/' && dle->device[1]=='/') {
	char *sharename = NULL, *user_and_password = NULL, *domain = NULL;
	char *share = NULL, *subdir = NULL;
	char *pwtext = NULL;
	char *taropt;
	int passwdf = -1;
	size_t lpass;
	size_t pwtext_len;
	char *pw_fd_env;

	parsesharename(dle->device, &share, &subdir);
	if (!share) {
	    amfree(share);
	    amfree(subdir);
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("cannot parse disk entry %s for share/subdir"), qdisk);
	    /*NOTREACHED*/
	}
	if ((subdir) && (SAMBA_VERSION < 2)) {
	    amfree(share);
	    amfree(subdir);
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("subdirectory specified for share %s but samba not v2 or better"), qdisk);
	    /*NOTREACHED*/
	}
	if ((user_and_password = findpass(share, &domain)) == NULL) {
	    if(domain) {
		memset(domain, '\0', strlen(domain));
		amfree(domain);
	    }
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("error [invalid samba host or password not found?]"));
	    /*NOTREACHED*/
	}
	lpass = strlen(user_and_password);
	if ((pwtext = strchr(user_and_password, '%')) == NULL) {
	    memset(user_and_password, '\0', lpass);
	    amfree(user_and_password);
	    if(domain) {
		memset(domain, '\0', strlen(domain));
		amfree(domain);
	    }
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("password field not \'user%%pass\' for %s"), qdisk);
	    /*NOTREACHED*/
	}
	*pwtext++ = '\0';
	pwtext_len = strlen(pwtext);
	if ((sharename = makesharename(share, 0)) == 0) {
	    memset(user_and_password, '\0', lpass);
	    amfree(user_and_password);
	    if(domain) {
		memset(domain, '\0', strlen(domain));
		amfree(domain);
	    }
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("error [can't make share name of %s]"), share);
	    /*NOTREACHED*/
	}

	taropt = g_strdup("-T");
	if(dle->exclude_file && dle->exclude_file->nb_element == 1) {
	    strappend(taropt, "X");
	}
#if SAMBA_VERSION >= 2
	strappend(taropt, "q");
#endif
	strappend(taropt, "c");
	if (level != 0) {
	    strappend(taropt, "g");
	} else if (dle->record) {
	    strappend(taropt, "a");
	}

	if (subdir) {
	    dbprintf(_("gnutar: backup of %s/%s\n"), sharename, subdir);
	} else {
	    dbprintf(_("gnutar: backup of %s\n"), sharename);
	}

	program->backup_name = program->restore_name = SAMBA_CLIENT;
	cmd = g_strdup(program->backup_name);
	info_tapeheader(dle);

	start_index(dle->create_index, native_pipe[1], mesgf, indexf, indexcmd);

	if (pwtext_len > 0) {
	    pw_fd_env = "PASSWD_FD";
	} else {
	    pw_fd_env = "dummy_PASSWD_FD";
	}
	dumppid = pipespawn(cmd, STDIN_PIPE|PASSWD_PIPE, 0,
			    &dumpin, &native_pipe[1], &mesgf,
			    pw_fd_env, &passwdf,
			    "smbclient",
			    sharename,
			    *user_and_password ? "-U" : skip_argument,
			    *user_and_password ? user_and_password : skip_argument,
			    "-E",
			    domain ? "-W" : skip_argument,
			    domain ? domain : skip_argument,
#if SAMBA_VERSION >= 2
			    subdir ? "-D" : skip_argument,
			    subdir ? subdir : skip_argument,
#endif
			    "-d0",
			    taropt,
			    "-",
			    dle->exclude_file && dle->exclude_file->nb_element == 1 ? dle->exclude_file->first->name : skip_argument,
			    NULL);
	if(domain) {
	    memset(domain, '\0', strlen(domain));
	    amfree(domain);
	}
	if(pwtext_len > 0 && full_write(passwdf, pwtext, pwtext_len) < pwtext_len) {
	    int save_errno = errno;

	    aclose(passwdf);
	    memset(user_and_password, '\0', lpass);
	    amfree(user_and_password);
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("error [password write failed: %s]"), strerror(save_errno));
	    /*NOTREACHED*/
	}
	memset(user_and_password, '\0', lpass);
	amfree(user_and_password);
	aclose(passwdf);
	amfree(sharename);
	amfree(share);
	amfree(subdir);
	amfree(taropt);
	tarpid = dumppid;
    } else
#endif			/*end of samba */
    {

	int nb_exclude = 0;
	int nb_include = 0;
	GPtrArray *argv_ptr = g_ptr_array_new();
	char *file_exclude = NULL;
	char *file_include = NULL;
	messagelist_t mlist = NULL;

	if (dle->exclude_file) nb_exclude+=dle->exclude_file->nb_element;
	if (dle->exclude_list) nb_exclude+=dle->exclude_list->nb_element;
	if (dle->include_file) nb_include+=dle->include_file->nb_element;
	if (dle->include_list) nb_include+=dle->include_list->nb_element;

	if (nb_exclude > 0) file_exclude = build_exclude(dle, &mlist);
	if (nb_include > 0) file_include = build_include(dle, dirname, &mlist);
	g_slist_free(mlist); // MUST also free the message

	cmd = g_strjoin(NULL, amlibexecdir, "/", "runtar", NULL);
	info_tapeheader(dle);

	start_index(dle->create_index, native_pipe[1], mesgf, indexf, indexcmd);

	g_ptr_array_add(argv_ptr, g_strdup("runtar"));
	if (g_options->config)
	    g_ptr_array_add(argv_ptr, g_strdup(g_options->config));
	else
	    g_ptr_array_add(argv_ptr, g_strdup("NOCONFIG"));
#ifdef GNUTAR
	g_ptr_array_add(argv_ptr, g_strdup(GNUTAR));
#else
	g_ptr_array_add(argv_ptr, g_strdup("tar"));
#endif
	g_ptr_array_add(argv_ptr, g_strdup("--create"));
	g_ptr_array_add(argv_ptr, g_strdup("--file"));
	g_ptr_array_add(argv_ptr, g_strdup("-"));
	g_ptr_array_add(argv_ptr, g_strdup("--directory"));
	canonicalize_pathname(dirname, tmppath);
	g_ptr_array_add(argv_ptr, g_strdup(tmppath));
	g_ptr_array_add(argv_ptr, g_strdup("--one-file-system"));
	if (gnutar_list_dir && incrname) {
	    g_ptr_array_add(argv_ptr, g_strdup("--listed-incremental"));
	    g_ptr_array_add(argv_ptr, g_strdup(incrname));
	} else {
	    g_ptr_array_add(argv_ptr, g_strdup("--incremental"));
	    g_ptr_array_add(argv_ptr, g_strdup("--newer"));
	    g_ptr_array_add(argv_ptr, g_strdup(dumptimestr));
	}
#ifdef ENABLE_GNUTAR_ATIME_PRESERVE
	/* --atime-preserve causes gnutar to call
	 * utime() after reading files in order to
	 * adjust their atime.  However, utime()
	 * updates the file's ctime, so incremental
	 * dumps will think the file has changed. */
	g_ptr_array_add(argv_ptr, g_strdup("--atime-preserve"));
#endif
	g_ptr_array_add(argv_ptr, g_strdup("--sparse"));
	g_ptr_array_add(argv_ptr, g_strdup("--ignore-failed-read"));
	g_ptr_array_add(argv_ptr, g_strdup("--totals"));

	if(file_exclude) {
	    g_ptr_array_add(argv_ptr, g_strdup("--exclude-from"));
	    g_ptr_array_add(argv_ptr, g_strdup(file_exclude));
	}

	if(file_include) {
	    g_ptr_array_add(argv_ptr, g_strdup("--files-from"));
	    g_ptr_array_add(argv_ptr, g_strdup(file_include));
	}
	else {
	    g_ptr_array_add(argv_ptr, g_strdup("."));
	}
	    g_ptr_array_add(argv_ptr, NULL);
	dumppid = pipespawnv(cmd, STDIN_PIPE, 0,
			     &dumpin, &native_pipe[1], &mesgf,
			     (char **)argv_ptr->pdata);
	tarpid = dumppid;
	amfree(file_exclude);
	amfree(file_include);
	g_ptr_array_free_full(argv_ptr);
    }
    dbprintf(_("gnutar: %s: pid %ld\n"), cmd, (long)dumppid);

    amfree(qdisk);
    amfree(dirname);
    amfree(cmd);
    amfree(indexcmd);
    amfree(error_pn);

    /* close the write ends of the pipes */

    aclose(dumpin);
    aclose(native_pipe[1]);
    aclose(mesgf);
    if (dle->create_index)
	aclose(indexf);

    if (shm_control_name) {
	shm_ring = shm_ring_link(shm_control_name);
	shm_ring_producer_set_size(shm_ring, NETWORK_BLOCK_BYTES*16, NETWORK_BLOCK_BYTES*4);
	native_crc.in  = native_pipe[0];
	if (!have_filter) {
	    native_crc.out = dumpout;
	    native_crc.shm_ring = shm_ring;
	    native_crc.thread = g_thread_create(handle_crc_to_shm_ring_thread,
					(gpointer)&native_crc, TRUE, NULL);
	} else {
	    native_crc.out = dumpout;
	    native_crc.thread = g_thread_create(handle_crc_thread,
					(gpointer)&native_crc, TRUE, NULL);
	    client_crc.in  = client_pipe[0];
	    client_crc.out = dataf;
	    client_crc.shm_ring = shm_ring;
	    client_crc.thread = g_thread_create(handle_crc_to_shm_ring_thread,
					(gpointer)&client_crc, TRUE, NULL);
	}
    } else {
	native_crc.in  = native_pipe[0];
	native_crc.out = dumpout;
	native_crc.thread = g_thread_create(handle_crc_thread,
					(gpointer)&native_crc, TRUE, NULL);

	if (have_filter) {
	    client_crc.in  = client_pipe[0];
	    client_crc.out = dataf;
	    client_crc.thread = g_thread_create(handle_crc_thread,
					(gpointer)&client_crc, TRUE, NULL);
	}
    }
}
Beispiel #5
0
static char *
filename_completion_function (const char *text, int state, input_complete_t flags)
{
    static DIR *directory = NULL;
    static char *filename = NULL;
    static char *dirname = NULL;
    static char *users_dirname = NULL;
    static size_t filename_len;
    int isdir = 1, isexec = 0;
    static vfs_path_t *dirname_vpath = NULL;

    struct dirent *entry = NULL;

    SHOW_C_CTX ("filename_completion_function");

    if (text && (flags & INPUT_COMPLETE_SHELL_ESC))
    {
        char *u_text;
        char *result;
        char *e_result;

        u_text = strutils_shell_unescape (text);

        result = filename_completion_function (u_text, state, flags & (~INPUT_COMPLETE_SHELL_ESC));
        g_free (u_text);

        e_result = strutils_shell_escape (result);
        g_free (result);

        return e_result;
    }

    /* If we're starting the match process, initialize us a bit. */
    if (state == 0)
    {
        const char *temp;

        g_free (dirname);
        g_free (filename);
        g_free (users_dirname);
        vfs_path_free (dirname_vpath);

        if ((*text != '\0') && (temp = strrchr (text, PATH_SEP)) != NULL)
        {
            filename = g_strdup (++temp);
            dirname = g_strndup (text, temp - text);
        }
        else
        {
            dirname = g_strdup (".");
            filename = g_strdup (text);
        }

        /* We aren't done yet.  We also support the "~user" syntax. */

        /* Save the version of the directory that the user typed. */
        users_dirname = dirname;
        dirname = tilde_expand (dirname);
        canonicalize_pathname (dirname);
        dirname_vpath = vfs_path_from_str (dirname);

        /* Here we should do something with variable expansion
           and `command`.
           Maybe a dream - UNIMPLEMENTED yet. */

        directory = mc_opendir (dirname_vpath);
        filename_len = strlen (filename);
    }

    /* Now that we have some state, we can read the directory. */

    while (directory && (entry = mc_readdir (directory)))
    {
        if (!str_is_valid_string (entry->d_name))
            continue;

        /* Special case for no filename.
           All entries except "." and ".." match. */
        if (filename_len == 0)
        {
            if (DIR_IS_DOT (entry->d_name) || DIR_IS_DOTDOT (entry->d_name))
                continue;
        }
        else
        {
            /* Otherwise, if these match up to the length of filename, then
               it may be a match. */
            if ((entry->d_name[0] != filename[0]) ||
                ((NLENGTH (entry)) < filename_len) ||
                strncmp (filename, entry->d_name, filename_len))
                continue;
        }
        isdir = 1;
        isexec = 0;
        {
            struct stat tempstat;
            vfs_path_t *tmp_vpath;

            tmp_vpath = vfs_path_build_filename (dirname, entry->d_name, (char *) NULL);

            /* Unix version */
            if (mc_stat (tmp_vpath, &tempstat) == 0)
            {
                uid_t my_uid = getuid ();
                gid_t my_gid = getgid ();

                if (!S_ISDIR (tempstat.st_mode))
                {
                    isdir = 0;
                    if ((!my_uid && (tempstat.st_mode & 0111)) ||
                        (my_uid == tempstat.st_uid && (tempstat.st_mode & 0100)) ||
                        (my_gid == tempstat.st_gid && (tempstat.st_mode & 0010)) ||
                        (tempstat.st_mode & 0001))
                        isexec = 1;
                }
            }
            else
            {
                /* stat failed, strange. not a dir in any case */
                isdir = 0;
            }
            vfs_path_free (tmp_vpath);
        }
        if ((flags & INPUT_COMPLETE_COMMANDS) && (isexec || isdir))
            break;
        if ((flags & INPUT_COMPLETE_CD) && isdir)
            break;
        if (flags & (INPUT_COMPLETE_FILENAMES))
            break;
    }

    if (entry == NULL)
    {
        if (directory)
        {
            mc_closedir (directory);
            directory = NULL;
        }
        g_free (dirname);
        dirname = NULL;
        vfs_path_free (dirname_vpath);
        dirname_vpath = NULL;
        g_free (filename);
        filename = NULL;
        g_free (users_dirname);
        users_dirname = NULL;
        return NULL;
    }

    {
        GString *temp;

        temp = g_string_sized_new (16);

        if (users_dirname != NULL && (users_dirname[0] != '.' || users_dirname[1] != '\0'))
        {
            g_string_append (temp, users_dirname);

            /* We need a '/' at the end. */
            if (temp->str[temp->len - 1] != PATH_SEP)
                g_string_append_c (temp, PATH_SEP);
        }
        g_string_append (temp, entry->d_name);
        if (isdir)
            g_string_append_c (temp, PATH_SEP);

        return g_string_free (temp, FALSE);
    }
}
Beispiel #6
0
const char *
mc_tmpdir (void)
{
    static char buffer[64];
    static const char *tmpdir;
    const char *sys_tmp;
    struct passwd *pwd;
    struct stat st;
    const char *error = NULL;

    /* Check if already correctly initialized */
    if (tmpdir && lstat (tmpdir, &st) == 0 && S_ISDIR (st.st_mode) &&
        st.st_uid == getuid () && (st.st_mode & 0777) == 0700)
        return tmpdir;

    sys_tmp = getenv ("TMPDIR");
    if (!sys_tmp || sys_tmp[0] != '/')
    {
        sys_tmp = TMPDIR_DEFAULT;
    }

    pwd = getpwuid (getuid ());

    if (pwd)
        g_snprintf (buffer, sizeof (buffer), "%s/mc-%s", sys_tmp, pwd->pw_name);
    else
        g_snprintf (buffer, sizeof (buffer), "%s/mc-%lu", sys_tmp, (unsigned long) getuid ());

    canonicalize_pathname (buffer);

    if (lstat (buffer, &st) == 0)
    {
        /* Sanity check for existing directory */
        if (!S_ISDIR (st.st_mode))
            error = _("%s is not a directory\n");
        else if (st.st_uid != getuid ())
            error = _("Directory %s is not owned by you\n");
        else if (((st.st_mode & 0777) != 0700) && (chmod (buffer, 0700) != 0))
            error = _("Cannot set correct permissions for directory %s\n");
    }
    else
    {
        /* Need to create directory */
        if (mkdir (buffer, S_IRWXU) != 0)
        {
            fprintf (stderr,
                     _("Cannot create temporary directory %s: %s\n"),
                     buffer, unix_error_string (errno));
            error = "";
        }
    }

    if (error != NULL)
    {
        int test_fd;
        char *test_fn, *fallback_prefix;
        int fallback_ok = 0;

        if (*error)
            fprintf (stderr, error, buffer);

        /* Test if sys_tmp is suitable for temporary files */
        fallback_prefix = g_strdup_printf ("%s/mctest", sys_tmp);
        test_fd = mc_mkstemps (&test_fn, fallback_prefix, NULL);
        g_free (fallback_prefix);
        if (test_fd != -1)
        {
            close (test_fd);
            test_fd = open (test_fn, O_RDONLY);
            if (test_fd != -1)
            {
                close (test_fd);
                unlink (test_fn);
                fallback_ok = 1;
            }
        }

        if (fallback_ok)
        {
            fprintf (stderr, _("Temporary files will be created in %s\n"), sys_tmp);
            g_snprintf (buffer, sizeof (buffer), "%s", sys_tmp);
            error = NULL;
        }
        else
        {
            fprintf (stderr, _("Temporary files will not be created\n"));
            g_snprintf (buffer, sizeof (buffer), "%s", "/dev/null/");
        }

        fprintf (stderr, "%s\n", _("Press any key to continue..."));
        getc (stdin);
    }

    tmpdir = buffer;

    if (!error)
        g_setenv ("MC_TMPDIR", tmpdir, TRUE);

    return tmpdir;
}
Beispiel #7
0
static char *
filename_completion_function (char *text, int state)
{
    static DIR *directory;
    static char *filename = NULL;
    static char *dirname = NULL;
    static char *users_dirname = NULL;
    static size_t filename_len;
    int isdir = 1, isexec = 0;

    struct dirent *entry = NULL;

    /* If we're starting the match process, initialize us a bit. */
    if (!state){
        const char *temp;

        g_free (dirname);
        g_free (filename);
        g_free (users_dirname);

	if ((*text) && (temp = strrchr (text, PATH_SEP))){
	    filename = g_strdup (++temp);
	    dirname = g_strndup (text, temp - text);
	} else {
	    dirname = g_strdup (".");
	    filename = g_strdup (text);
	}

        /* We aren't done yet.  We also support the "~user" syntax. */

        /* Save the version of the directory that the user typed. */
        users_dirname = dirname;
        {
	    dirname = tilde_expand (dirname);
	    canonicalize_pathname (dirname);
	    /* Here we should do something with variable expansion
	       and `command`.
	       Maybe a dream - UNIMPLEMENTED yet. */
        }
        directory = mc_opendir (dirname);
        filename_len = strlen (filename);
    }

    /* Now that we have some state, we can read the directory. */

    while (directory && (entry = mc_readdir (directory))){
        /* Special case for no filename.
	   All entries except "." and ".." match. */
        if (!filename_len){
	    if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name, ".."))
	        continue;
	} else {
	    /* Otherwise, if these match up to the length of filename, then
	       it may be a match. */
	    if ((entry->d_name[0] != filename[0]) ||
	        ((NLENGTH (entry)) < filename_len) ||
		strncmp (filename, entry->d_name, filename_len))
	        continue;
	}
	isdir = 1; isexec = 0;
	{
	    char *tmp = g_malloc (3 + strlen (dirname) + NLENGTH (entry));
	    struct stat tempstat;
	    
	    strcpy (tmp, dirname);
	    strcat (tmp, PATH_SEP_STR);
	    strcat (tmp, entry->d_name);
	    canonicalize_pathname (tmp);
	    /* Unix version */
	    if (!mc_stat (tmp, &tempstat)){
	    	uid_t my_uid = getuid ();
	    	gid_t my_gid = getgid ();
	    	
	        if (!S_ISDIR (tempstat.st_mode)){
	            isdir = 0;
	            if ((!my_uid && (tempstat.st_mode & 0111)) ||
	                (my_uid == tempstat.st_uid && (tempstat.st_mode & 0100)) ||
	                (my_gid == tempstat.st_gid && (tempstat.st_mode & 0010)) ||
	                (tempstat.st_mode & 0001))
	                isexec = 1;
	        }
	    }
	   g_free (tmp);
	}
	switch (look_for_executables)
	{
	    case 2: if (!isexec)
	    	        continue;
	    	    break;
	    case 1: if (!isexec && !isdir)
	    	        continue;
	    	    break;
	}
	if (ignore_filenames && !isdir)
	    continue;
	break;
    }

    if (!entry){
        if (directory){
	    mc_closedir (directory);
	    directory = NULL;
	}
	g_free (dirname);
	dirname = NULL;
	g_free (filename);
	filename = NULL;
	g_free (users_dirname);
	users_dirname = NULL;
        return NULL;
    } else {
        char *temp;

        if (users_dirname && (users_dirname[0] != '.' || users_dirname[1])){
	    int dirlen = strlen (users_dirname);
	    temp = g_malloc (3 + dirlen + NLENGTH (entry));
	    strcpy (temp, users_dirname);
	    /* We need a `/' at the end. */
	    if (users_dirname[dirlen - 1] != PATH_SEP){
	        temp[dirlen] = PATH_SEP;
	        temp[dirlen + 1] = 0;
	    }
	    strcat (temp, entry->d_name);
	} else {
	    temp = g_malloc (2 + NLENGTH (entry));
	    strcpy (temp, entry->d_name);
	}
	if (isdir)
	    strcat (temp, PATH_SEP_STR);
        return temp;
    }
}
Beispiel #8
0
/*
 * This is the function to call when the word to complete is in a position
 * where a command word can be found. It looks around $PATH, looking for
 * commands that match. It also scans aliases, function names, and the
 * table of shell built-ins.
 */
static char *
command_completion_function (char *text, int state)
{
    static const char *path_end;
    static int isabsolute;
    static int phase;
    static int text_len;
    static const char *const *words;
    static char *path;
    static char *cur_path;
    static char *cur_word;
    static int init_state;
    static const char *const bash_reserved[] = {
	"if", "then", "else", "elif", "fi", "case", "esac", "for",
	    "select", "while", "until", "do", "done", "in", "function", 0
    };
    static const char *const bash_builtins[] = {
	"alias", "bg", "bind", "break", "builtin", "cd", "command",
	    "continue", "declare", "dirs", "echo", "enable", "eval",
	    "exec", "exit", "export", "fc", "fg", "getopts", "hash",
	    "help", "history", "jobs", "kill", "let", "local", "logout",
	    "popd", "pushd", "pwd", "read", "readonly", "return", "set",
	    "shift", "source", "suspend", "test", "times", "trap", "type",
	    "typeset", "ulimit", "umask", "unalias", "unset", "wait", 0
    };
    char *p, *found;

    if (!state) {		/* Initialize us a little bit */
	isabsolute = strchr (text, PATH_SEP) != 0;
	look_for_executables = isabsolute ? 1 : 2;
	if (!isabsolute) {
	    words = bash_reserved;
	    phase = 0;
	    text_len = strlen (text);
	    if (!path && (path = g_strdup (getenv ("PATH"))) != NULL) {
		p = path;
		path_end = strchr (p, 0);
		while ((p = strchr (p, PATH_ENV_SEP))) {
		    *p++ = 0;
		}
	    }
	}
    }

    if (isabsolute) {
	p = filename_completion_function (text, state);
	if (!p)
	    look_for_executables = 0;
	return p;
    }

    found = NULL;
    switch (phase) {
    case 0:			/* Reserved words */
	while (*words) {
	    if (!strncmp (*words, text, text_len))
		return g_strdup (*(words++));
	    words++;
	}
	phase++;
	words = bash_builtins;
    case 1:			/* Builtin commands */
	while (*words) {
	    if (!strncmp (*words, text, text_len))
		return g_strdup (*(words++));
	    words++;
	}
	phase++;
	if (!path)
	    break;
	cur_path = path;
	cur_word = NULL;
    case 2:			/* And looking through the $PATH */
	while (!found) {
	    if (!cur_word) {
		char *expanded;

		if (cur_path >= path_end)
		    break;
		expanded = tilde_expand (*cur_path ? cur_path : ".");
		cur_word = concat_dir_and_file (expanded, text);
		g_free (expanded);
		canonicalize_pathname (cur_word);
		cur_path = strchr (cur_path, 0) + 1;
		init_state = state;
	    }
	    found =
		filename_completion_function (cur_word,
					      state - init_state);
	    if (!found) {
		g_free (cur_word);
		cur_word = NULL;
	    }
	}
    }

    if (!found) {
	look_for_executables = 0;
	g_free (path);
	path = NULL;
	return NULL;
    }
    if ((p = strrchr (found, PATH_SEP)) != NULL) {
	p++;
	p = g_strdup (p);
	g_free (found);
	return p;
    }
    return found;

}
Beispiel #9
0
static struct vfs_s_entry *
vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root,
			 const char *a_path, int follow, int flags)
{
    struct vfs_s_entry *ent = NULL;
    char * const path = g_strdup (a_path);
    struct vfs_s_entry *retval = NULL;

    if (root->super->root != root)
	vfs_die ("We have to use _real_ root. Always. Sorry.");

    canonicalize_pathname (path);

    if (!(flags & FL_DIR)) {
	char *dirname, *name, *save;
	struct vfs_s_inode *ino;
	split_dir_name (me, path, &dirname, &name, &save);
	ino =
	    vfs_s_find_inode (me, root->super, dirname, follow,
			      flags | FL_DIR);
	if (save)
	    *save = PATH_SEP;
	retval = vfs_s_find_entry_tree (me, ino, name, follow, flags);
	g_free (path);
	return retval;
    }

    for (ent = root->subdir; ent != NULL; ent = ent->next)
	if (!strcmp (ent->name, path))
	    break;

    if (ent && (!(MEDATA->dir_uptodate) (me, ent->ino))) {
#if 1
	print_vfs_message (_("Directory cache expired for %s"), path);
#endif
	vfs_s_free_entry (me, ent);
	ent = NULL;
    }

    if (!ent) {
	struct vfs_s_inode *ino;

	ino =
	    vfs_s_new_inode (me, root->super,
			     vfs_s_default_stat (me, S_IFDIR | 0755));
	ent = vfs_s_new_entry (me, path, ino);
	if ((MEDATA->dir_load) (me, ino, path) == -1) {
	    vfs_s_free_entry (me, ent);
	    g_free (path);
	    return NULL;
	}
	vfs_s_insert_entry (me, root, ent);

	for (ent = root->subdir; ent != NULL; ent = ent->next)
	    if (!strcmp (ent->name, path))
		break;
    }
    if (!ent)
	vfs_die ("find_linear: success but directory is not there\n");

#if 0
    if (!vfs_s_resolve_symlink (me, ent, follow)) {
    	g_free (path);
	return NULL;
    }
#endif
    g_free (path);
    return ent;
}
Beispiel #10
0
Datei: util.c Projekt: JBurant/mc
static char *
resolve_symlinks (const vfs_path_t * vpath)
{
    char *p, *p2;
    char *buf, *buf2, *q, *r, c;
    struct stat mybuf;

    if (vpath->relative)
        return NULL;

    p = p2 = g_strdup (vfs_path_as_str (vpath));
    r = buf = g_malloc (MC_MAXPATHLEN);
    buf2 = g_malloc (MC_MAXPATHLEN);
    *r++ = PATH_SEP;
    *r = 0;

    do
    {
        q = strchr (p + 1, PATH_SEP);
        if (!q)
        {
            q = strchr (p + 1, 0);
            if (q == p + 1)
                break;
        }
        c = *q;
        *q = 0;
        if (mc_lstat (vpath, &mybuf) < 0)
        {
            MC_PTR_FREE (buf);
            goto ret;
        }
        if (!S_ISLNK (mybuf.st_mode))
            strcpy (r, p + 1);
        else
        {
            int len;

            len = mc_readlink (vpath, buf2, MC_MAXPATHLEN - 1);
            if (len < 0)
            {
                MC_PTR_FREE (buf);
                goto ret;
            }
            buf2[len] = 0;
            if (IS_PATH_SEP (*buf2))
                strcpy (buf, buf2);
            else
                strcpy (r, buf2);
        }
        canonicalize_pathname (buf);
        r = strchr (buf, 0);
        if (*r == '\0' || !IS_PATH_SEP (r[-1]))
            /* FIXME: this condition is always true because r points to the EOL */
        {
            *r++ = PATH_SEP;
            *r = '\0';
        }
        *q = c;
        p = q;
    }
    while (c != '\0');

    if (*buf == '\0')
        strcpy (buf, PATH_SEP_STR);
    else if (IS_PATH_SEP (r[-1]) && r != buf + 1)
        r[-1] = '\0';

  ret:
    g_free (buf2);
    g_free (p2);
    return buf;
}
Beispiel #11
0
static char *
command_completion_function (const char *_text, int state, input_complete_t flags)
{
    char *text;
    static const char *path_end;
    static gboolean isabsolute;
    static int phase;
    static size_t text_len;
    static const char *const *words;
    static char *path;
    static char *cur_path;
    static char *cur_word;
    static int init_state;
    static const char *const bash_reserved[] = {
        "if", "then", "else", "elif", "fi", "case", "esac", "for",
        "select", "while", "until", "do", "done", "in", "function", 0
    };
    static const char *const bash_builtins[] = {
        "alias", "bg", "bind", "break", "builtin", "cd", "command",
        "continue", "declare", "dirs", "echo", "enable", "eval",
        "exec", "exit", "export", "fc", "fg", "getopts", "hash",
        "help", "history", "jobs", "kill", "let", "local", "logout",
        "popd", "pushd", "pwd", "read", "readonly", "return", "set",
        "shift", "source", "suspend", "test", "times", "trap", "type",
        "typeset", "ulimit", "umask", "unalias", "unset", "wait", 0
    };
    char *p, *found;

    SHOW_C_CTX ("command_completion_function");

    if (!(flags & INPUT_COMPLETE_COMMANDS))
        return 0;

    text = strutils_shell_unescape (_text);
    flags &= ~INPUT_COMPLETE_SHELL_ESC;

    if (state == 0)
    {                           /* Initialize us a little bit */
        isabsolute = strchr (text, PATH_SEP) != NULL;
        if (!isabsolute)
        {
            words = bash_reserved;
            phase = 0;
            text_len = strlen (text);

            if (path == NULL)
            {
                path = g_strdup (getenv ("PATH"));
                if (path != NULL)
                {
                    p = path;
                    path_end = strchr (p, '\0');
                    while ((p = strchr (p, PATH_ENV_SEP)) != NULL)
                    {
                        *p++ = '\0';
                    }
                }
            }
        }
    }

    if (isabsolute)
    {
        p = filename_completion_function (text, state, flags);

        if (p != NULL)
        {
            char *temp_p = p;
            p = strutils_shell_escape (p);
            g_free (temp_p);
        }

        g_free (text);
        return p;
    }

    found = NULL;
    switch (phase)
    {
    case 0:                    /* Reserved words */
        while (*words)
        {
            if (strncmp (*words, text, text_len) == 0)
            {
                g_free (text);
                return g_strdup (*(words++));
            }
            words++;
        }
        phase++;
        words = bash_builtins;
    case 1:                    /* Builtin commands */
        while (*words)
        {
            if (strncmp (*words, text, text_len) == 0)
            {
                g_free (text);
                return g_strdup (*(words++));
            }
            words++;
        }
        phase++;
        if (!path)
            break;
        cur_path = path;
        cur_word = NULL;
    case 2:                    /* And looking through the $PATH */
        while (!found)
        {
            if (!cur_word)
            {
                char *expanded;

                if (cur_path >= path_end)
                    break;
                expanded = tilde_expand (*cur_path ? cur_path : ".");
                cur_word = mc_build_filename (expanded, text, NULL);
                g_free (expanded);
                canonicalize_pathname (cur_word);
                cur_path = strchr (cur_path, 0) + 1;
                init_state = state;
            }
            found = filename_completion_function (cur_word, state - init_state, flags);
            if (!found)
            {
                g_free (cur_word);
                cur_word = NULL;
            }
        }
    }

    if (found == NULL)
    {
        g_free (path);
        path = NULL;
    }
    else
    {
        p = strrchr (found, PATH_SEP);
        if (p != NULL)
        {
            char *tmp = found;
            found = strutils_shell_escape (p + 1);
            g_free (tmp);
        }
    }

    g_free (text);
    return found;
}
Beispiel #12
0
/**
 * local implementation of pathfind.
 * @param[in] path  colon separated list of directories
 * @param[in] fname the name we are hunting for
 * @param[in] mode  the required file mode
 * @returns an allocated string with the full path, or NULL
 */
static char *
pathfind( char const * path,
          char const * fname,
          char const * mode )
{
    int    p_index   = 0;
    int    mode_bits = 0;
    char * res_path  = NULL;
    char   zPath[ AG_PATH_MAX + 1 ];

    if (strchr( mode, 'r' )) mode_bits |= R_OK;
    if (strchr( mode, 'w' )) mode_bits |= W_OK;
    if (strchr( mode, 'x' )) mode_bits |= X_OK;

    /*
     *  FOR each non-null entry in the colon-separated path, DO ...
     */
    for (;;) {
        DIR*  dirP;
        char* colon_unit = extract_colon_unit( zPath, path, &p_index );

        if (colon_unit == NULL)
            break;

        dirP = opendir( colon_unit );

        /*
         *  IF the directory is inaccessable, THEN next directory
         */
        if (dirP == NULL)
            continue;

        for (;;) {
            struct dirent *entP = readdir( dirP );

            if (entP == (struct dirent*)NULL)
                break;

            /*
             *  IF the file name matches the one we are looking for, ...
             */
            if (strcmp(entP->d_name, fname) == 0) {
                char * abs_name = make_absolute(fname, colon_unit);

                /*
                 *  Make sure we can access it in the way we want
                 */
                if (access(abs_name, mode_bits) >= 0) {
                    /*
                     *  We can, so normalize the name and return it below
                     */
                    res_path = canonicalize_pathname(abs_name);
                }

                free(abs_name);
                break;
            }
        }

        closedir( dirP );

        if (res_path != NULL)
            break;
    }

    return res_path;
}
Beispiel #13
0
int
etags_set_definition_hash (const char *tagfile, const char *start_path,
                           const char *match_func, etags_hash_t * def_hash)
{
    /* *INDENT-OFF* */
    enum
    {
        start,
        in_filename,
        in_define
    } state = start;
    /* *INDENT-ON* */

    FILE *f;
    static char buf[BUF_LARGE];

    char *chekedstr = NULL;

    int num = 0;                /* returned value */
    char *filename = NULL;

    if (!match_func || !tagfile)
        return 0;

    /* open file with positions */
    f = fopen (tagfile, "r");
    if (f == NULL)
        return 0;

    while (fgets (buf, sizeof (buf), f))
    {
        switch (state)
        {
        case start:
            if (buf[0] == 0x0C)
            {
                state = in_filename;
            }
            break;
        case in_filename:
            {
                size_t pos;

                pos = strcspn (buf, ",");
                g_free (filename);
                filename = g_strndup (buf, pos);
                state = in_define;
                break;
            }
        case in_define:
            if (buf[0] == 0x0C)
            {
                state = in_filename;
                break;
            }
            /* check if the filename matches the define pos */
            chekedstr = strstr (buf, match_func);
            if (chekedstr)
            {
                char *longname = NULL;
                char *shortname = NULL;
                long line = 0;

                parse_define (chekedstr, &longname, &shortname, &line);
                if (num < MAX_DEFINITIONS - 1)
                {
                    def_hash[num].filename_len = strlen (filename);
                    def_hash[num].fullpath =
                        mc_build_filename (start_path, filename, (char *) NULL);

                    canonicalize_pathname (def_hash[num].fullpath);
                    def_hash[num].filename = g_strdup (filename);
                    if (shortname)
                    {
                        def_hash[num].short_define = g_strdup (shortname);
                    }
                    else
                    {
                        def_hash[num].short_define = g_strdup (longname);
                    }
                    def_hash[num].line = line;
                    num++;
                }
            }
            break;
        default:
            break;
        }
    }

    g_free (filename);
    fclose (f);
    return num;
}
Beispiel #14
0
static char *
load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
{
    /*
       TODO: IMHO, in future, this function shall be placed in mcconfig module.
     */
    char *lc_basename, *ret;
    char *file_name;

    if (config_file_name == NULL)
        return NULL;

    /* check for .keymap suffix */
    if (g_str_has_suffix (config_file_name, ".keymap"))
        file_name = g_strdup (config_file_name);
    else
        file_name = g_strconcat (config_file_name, ".keymap", (char *) NULL);

    canonicalize_pathname (file_name);

    if (g_path_is_absolute (file_name))
        return file_name;

    lc_basename = g_path_get_basename (file_name);
    g_free (file_name);

    if (lc_basename == NULL)
        return NULL;

    if (subdir != NULL)
        ret = g_build_filename (mc_config_get_path (), subdir, lc_basename, NULL);
    else
        ret = g_build_filename (mc_config_get_path (), lc_basename, NULL);

    if (exist_file (ret))
    {
        g_free (lc_basename);
        canonicalize_pathname (ret);
        return ret;
    }
    g_free (ret);

    if (subdir != NULL)
        ret = g_build_filename (mc_global.sysconfig_dir, subdir, lc_basename, NULL);
    else
        ret = g_build_filename (mc_global.sysconfig_dir, lc_basename, NULL);

    if (exist_file (ret))
    {
        g_free (lc_basename);
        canonicalize_pathname (ret);
        return ret;
    }
    g_free (ret);

    if (subdir != NULL)
        ret = g_build_filename (mc_global.share_data_dir, subdir, lc_basename, NULL);
    else
        ret = g_build_filename (mc_global.share_data_dir, lc_basename, NULL);

    g_free (lc_basename);

    if (exist_file (ret))
    {
        canonicalize_pathname (ret);
        return ret;
    }

    g_free (ret);
    return NULL;
}
Beispiel #15
0
static char *
resolve_symlinks (const char *path)
{
    char *buf, *buf2, *q, *r, c;
    int len;
    struct stat mybuf;
    const char *p;

    if (*path != PATH_SEP)
        return NULL;
    r = buf = g_malloc (MC_MAXPATHLEN);
    buf2 = g_malloc (MC_MAXPATHLEN);
    *r++ = PATH_SEP;
    *r = 0;
    p = path;
    for (;;)
    {
        q = strchr (p + 1, PATH_SEP);
        if (!q)
        {
            q = strchr (p + 1, 0);
            if (q == p + 1)
                break;
        }
        c = *q;
        *q = 0;
        if (mc_lstat (path, &mybuf) < 0)
        {
            g_free (buf);
            g_free (buf2);
            *q = c;
            return NULL;
        }
        if (!S_ISLNK (mybuf.st_mode))
            strcpy (r, p + 1);
        else
        {
            len = mc_readlink (path, buf2, MC_MAXPATHLEN - 1);
            if (len < 0)
            {
                g_free (buf);
                g_free (buf2);
                *q = c;
                return NULL;
            }
            buf2[len] = 0;
            if (*buf2 == PATH_SEP)
                strcpy (buf, buf2);
            else
                strcpy (r, buf2);
        }
        canonicalize_pathname (buf);
        r = strchr (buf, 0);
        if (!*r || *(r - 1) != PATH_SEP)
        {
            *r++ = PATH_SEP;
            *r = 0;
        }
        *q = c;
        p = q;
        if (!c)
            break;
    }
    if (!*buf)
        strcpy (buf, PATH_SEP_STR);
    else if (*(r - 1) == PATH_SEP && r != buf + 1)
        *(r - 1) = 0;
    g_free (buf2);
    return buf;
}