Search
lxdream.org :: lxdream/src/lxpaths.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/lxpaths.c
changeset 1056:d0896e6530d6
prev1041:5fcc39857c5c
next1205:a486ac64f34b
author nkeynes
date Sun Jun 28 12:07:21 2009 +0000 (11 years ago)
permissions -rw-r--r--
last change Fix handling of rename failure
Fix boneheadedness in get_filename_at
file annotate diff log raw
nkeynes@1041
     1
/**
nkeynes@1041
     2
 * $Id$
nkeynes@1041
     3
 *
nkeynes@1041
     4
 * GUI helper functions that aren't specific to any particular implementation.
nkeynes@1041
     5
 *
nkeynes@1041
     6
 * Copyright (c) 2009 Nathan Keynes.
nkeynes@1041
     7
 *
nkeynes@1041
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@1041
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@1041
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@1041
    11
 * (at your option) any later version.
nkeynes@1041
    12
 *
nkeynes@1041
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@1041
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@1041
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@1041
    16
 * GNU General Public License for more details.
nkeynes@1041
    17
 */
nkeynes@1041
    18
nkeynes@1041
    19
#include <ctype.h>
nkeynes@1041
    20
#include <unistd.h>
nkeynes@1041
    21
#include <wordexp.h>
nkeynes@1041
    22
#include <glib/gstrfuncs.h>
nkeynes@1041
    23
#include <glib/gutils.h>
nkeynes@1041
    24
nkeynes@1041
    25
#include "gui.h"
nkeynes@1041
    26
#include "config.h"
nkeynes@1041
    27
nkeynes@1041
    28
static gchar *gui_paths[CONFIG_KEY_MAX];
nkeynes@1041
    29
nkeynes@1041
    30
/**
nkeynes@1041
    31
 * Test if we need to escape a path to prevent substitution mangling. 
nkeynes@1041
    32
 * @return TRUE if the input value contains any character that doesn't
nkeynes@1041
    33
 * match [a-zA-Z0-9._@%/] (this will escape slightly more than it needs to,
nkeynes@1041
    34
 * but is safe)
nkeynes@1041
    35
 */
nkeynes@1041
    36
static gboolean path_needs_escaping( const gchar *value )
nkeynes@1041
    37
{
nkeynes@1041
    38
   const gchar *p = value;
nkeynes@1041
    39
   while( *p ) {
nkeynes@1041
    40
       if( !isalnum(*p) && *p != '.' && *p != '_' &&
nkeynes@1041
    41
               *p != '@' && *p != '%' && *p != '/' ) {
nkeynes@1041
    42
           return TRUE;
nkeynes@1041
    43
       }
nkeynes@1041
    44
       p++;
nkeynes@1041
    45
   }
nkeynes@1041
    46
   return FALSE;
nkeynes@1041
    47
}
nkeynes@1041
    48
nkeynes@1041
    49
gchar *get_escaped_path( const gchar *value )
nkeynes@1041
    50
{
nkeynes@1041
    51
    if( value != NULL && path_needs_escaping(value) ) {
nkeynes@1041
    52
        /* Escape with "", and backslash the remaining characters:
nkeynes@1041
    53
         *   \ " $ `
nkeynes@1041
    54
         */
nkeynes@1041
    55
        char buf[strlen(value)*2+3];  
nkeynes@1041
    56
        const char *s = value;
nkeynes@1041
    57
        char *p = buf;
nkeynes@1041
    58
        *p++ = '\"';
nkeynes@1041
    59
        while( *s ) {
nkeynes@1041
    60
            if( *s == '\\' || *s == '"' || *s == '$' || *s == '`' ) {
nkeynes@1041
    61
                *p++ = '\\';
nkeynes@1041
    62
            }
nkeynes@1041
    63
            *p++ = *s++;
nkeynes@1041
    64
        }
nkeynes@1041
    65
        *p++ = '\"';
nkeynes@1041
    66
        *p = '\0';
nkeynes@1041
    67
        return g_strdup(buf);
nkeynes@1041
    68
    } else {
nkeynes@1041
    69
        return g_strdup(value);
nkeynes@1041
    70
    }
nkeynes@1041
    71
}
nkeynes@1041
    72
nkeynes@1041
    73
gchar *get_expanded_path( const gchar *input )
nkeynes@1041
    74
{
nkeynes@1041
    75
    wordexp_t we;
nkeynes@1041
    76
    if( input == NULL ) {
nkeynes@1041
    77
        return NULL;
nkeynes@1041
    78
    }
nkeynes@1041
    79
    memset(&we,0,sizeof(we));
nkeynes@1041
    80
    int result = wordexp(input, &we, WRDE_NOCMD);
nkeynes@1041
    81
    if( result != 0 || we.we_wordc == 0 ) {
nkeynes@1041
    82
        /* On failure, return the original input unchanged */
nkeynes@1041
    83
        return g_strdup(input);
nkeynes@1041
    84
    } else {
nkeynes@1041
    85
        /* On success, concatenate all 'words' together into a single 
nkeynes@1041
    86
         * space-separated string
nkeynes@1041
    87
         */
nkeynes@1041
    88
        int length = we.we_wordc, i;
nkeynes@1041
    89
        gchar *result, *p;
nkeynes@1041
    90
        
nkeynes@1041
    91
        for( i=0; i<we.we_wordc; i++ ) {
nkeynes@1041
    92
            length += strlen(we.we_wordv[i]);
nkeynes@1041
    93
        }
nkeynes@1041
    94
        p = result = g_malloc(length);
nkeynes@1041
    95
        for( i=0; i<we.we_wordc; i++ ) {
nkeynes@1041
    96
            if( i != 0 )
nkeynes@1041
    97
                *p++ = ' ';
nkeynes@1041
    98
            strcpy( p, we.we_wordv[i] );
nkeynes@1041
    99
            p += strlen(p);
nkeynes@1041
   100
        }
nkeynes@1041
   101
        wordfree(&we);
nkeynes@1041
   102
        return result;
nkeynes@1041
   103
    }        
nkeynes@1041
   104
}
nkeynes@1041
   105
nkeynes@1041
   106
gchar *get_absolute_path( const gchar *in_path )
nkeynes@1041
   107
{
nkeynes@1041
   108
    char tmp[PATH_MAX];
nkeynes@1041
   109
    if( in_path == NULL ) {
nkeynes@1041
   110
        return NULL;
nkeynes@1041
   111
    }
nkeynes@1041
   112
    if( in_path[0] == '/' || in_path[0] == 0 ) {
nkeynes@1041
   113
        return g_strdup(in_path);
nkeynes@1041
   114
    } else {
nkeynes@1041
   115
        getcwd(tmp, sizeof(tmp));
nkeynes@1041
   116
        return g_strdup_printf("%s%c%s", tmp, G_DIR_SEPARATOR, in_path);
nkeynes@1041
   117
    }
nkeynes@1041
   118
}
nkeynes@1041
   119
nkeynes@1041
   120
gchar *get_filename_at( const gchar *at, const gchar *filename )
nkeynes@1041
   121
{
nkeynes@1041
   122
    char tmp[PATH_MAX];
nkeynes@1056
   123
    char *p = strrchr( at, '/' );
nkeynes@1041
   124
    if( p == NULL ) {
nkeynes@1041
   125
        /* No path at all, so just return filename */
nkeynes@1041
   126
        return g_strdup(filename);
nkeynes@1041
   127
    } else {
nkeynes@1056
   128
        int off = p-at;
nkeynes@1041
   129
        return g_strdup_printf("%.*s%c%s", off, at, G_DIR_SEPARATOR, filename );
nkeynes@1041
   130
    }
nkeynes@1041
   131
}
nkeynes@1041
   132
nkeynes@1041
   133
const gchar *get_gui_path( int key )
nkeynes@1041
   134
{
nkeynes@1041
   135
    if( gui_paths[key] == NULL ) {
nkeynes@1041
   136
        gui_paths[key] = lxdream_get_global_config_path_value(key);
nkeynes@1041
   137
        /* If no path defined, go with the current working directory */
nkeynes@1041
   138
        if( gui_paths[key] == NULL ) {
nkeynes@1041
   139
            gui_paths[key] = get_absolute_path(".");
nkeynes@1041
   140
        }
nkeynes@1041
   141
    }
nkeynes@1041
   142
    return gui_paths[key];
nkeynes@1041
   143
}
nkeynes@1041
   144
nkeynes@1041
   145
void set_gui_path( int key, const gchar *path )
nkeynes@1041
   146
{
nkeynes@1041
   147
    g_free(gui_paths[key]);
nkeynes@1041
   148
    gui_paths[key] = g_strdup(path);
nkeynes@1041
   149
}
nkeynes@1041
   150
nkeynes@1041
   151
void reset_gui_paths()
nkeynes@1041
   152
{
nkeynes@1041
   153
    int i;
nkeynes@1041
   154
    for( i=0; i < CONFIG_KEY_MAX; i++ ) {
nkeynes@1041
   155
        g_free(gui_paths[i]);
nkeynes@1041
   156
        gui_paths[i] = NULL;
nkeynes@1041
   157
    }
nkeynes@1041
   158
}
.