Search
lxdream.org :: lxdream/src/lxpaths.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/lxpaths.c
changeset 1283:2cbafe321d6f
prev1205:a486ac64f34b
next1286:8376a612a79d
author nkeynes
date Tue Mar 27 17:39:05 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Treat quotes as entering a double-quoted string (mostly redundant, but we
generate them in the path escaping for some reason)
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * GUI helper functions that aren't specific to any particular implementation.
     5  *
     6  * Copyright (c) 2009 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <ctype.h>
    20 #include <unistd.h>
    21 #include <stdlib.h>
    22 #include <glib/gstrfuncs.h>
    23 #include <glib/gutils.h>
    25 #include "gui.h"
    26 #include "config.h"
    28 static gchar *gui_paths[CONFIG_KEY_MAX];
    30 /**
    31  * Test if we need to escape a path to prevent substitution mangling. 
    32  * @return TRUE if the input value contains any character that doesn't
    33  * match [a-zA-Z0-9._@%/] (this will escape slightly more than it needs to,
    34  * but is safe)
    35  */
    36 static gboolean path_needs_escaping( const gchar *value )
    37 {
    38    const gchar *p = value;
    39    while( *p ) {
    40        if( !isalnum(*p) && *p != '.' && *p != '_' &&
    41                *p != '@' && *p != '%' && *p != '/' ) {
    42            return TRUE;
    43        }
    44        p++;
    45    }
    46    return FALSE;
    47 }
    49 gchar *get_escaped_path( const gchar *value )
    50 {
    51     if( value != NULL && path_needs_escaping(value) ) {
    52         /* Escape with "", and backslash the remaining characters:
    53          *   \ " $ `
    54          */
    55         char buf[strlen(value)*2+3];  
    56         const char *s = value;
    57         char *p = buf;
    58         *p++ = '\"';
    59         while( *s ) {
    60             if( *s == '\\' || *s == '"' || *s == '$' || *s == '`' ) {
    61                 *p++ = '\\';
    62             }
    63             *p++ = *s++;
    64         }
    65         *p++ = '\"';
    66         *p = '\0';
    67         return g_strdup(buf);
    68     } else {
    69         return g_strdup(value);
    70     }
    71 }
    73 gchar *get_expanded_path( const gchar *input )
    74 {
    75     char result[PATH_MAX];
    77     char *d, *e;
    78     const char *s;
    79     d = result;
    80     e = result+sizeof(result)-1;
    81     s = input;
    82     gboolean inDQstring = FALSE;
    84     if( input == NULL )
    85         return NULL;
    87     while( *s ) {
    88         if( d == e ) {
    89             return g_strdup(input); /* expansion too long */
    90         }
    91         char c = *s++;
    92         if( c == '$' ) {
    93             if( *s == '{' ) {
    94                 s++;
    95                 const char *q = s;
    96                 while( *q != '}' ) {
    97                     if( ! *q ) {
    98                         return g_strdup(input); /* unterminated variable */
    99                     }
   100                     q++;
   101                 }
   102                 char *tmp = g_strndup(s, (q-s));
   103                 s = q+1;
   104                 char *value = getenv(tmp);
   105                 g_free(tmp);
   106                 if( value != NULL ) {
   107                     int len = strlen(value);
   108                     if( d + len > e )
   109                         return g_strdup(input);
   110                     strcpy(d, value);
   111                     d+=len;
   112                 } /* Else, empty string */
   113             } else {
   114                 const char *q = s;
   115                 while( isalnum(*q) || *q == '_' ) {
   116                     q++;
   117                 }
   118                 if( q == s ) {
   119                     *d++ = '$';
   120                 } else {
   121                     char *tmp = g_strndup(s,q-s);
   122                     s = q;
   123                     char *value = getenv(tmp);
   124                     g_free(tmp);
   125                     if( value != NULL ) {
   126                         int len = strlen(value);
   127                         if( d + len > e )
   128                             return g_strdup(input);
   129                         strcpy(d, value);
   130                         d += len;
   131                     }
   132                 }
   133             }
   134         } else if( c == '\\' ) {
   135             c = *s++;
   136             if( c ) {
   137                 *d++ = c;
   138             } else {
   139                 *d++ = '\\';
   140             }
   141         } else if( c == '\"' ) {
   142             /* Unescaped double-quotes start a DQ string. Although we treat the
   143              * string as if it were double-quoted for most purposes anyway, so
   144              * this has little effect.
   145              */
   146             inDQstring = !inDQstring;
   147         } else {
   148             *d++ = c;
   149         }
   150     }
   151     *d = '\0';
   152     if( inDQstring ) {
   153         WARN( "Unterminated double-quoted string '%s'", input );
   154     }
   155     return g_strdup(result);
   156 }
   157 gchar *get_absolute_path( const gchar *in_path )
   158 {
   159     char tmp[PATH_MAX];
   160     if( in_path == NULL ) {
   161         return NULL;
   162     }
   163     if( in_path[0] == '/' || in_path[0] == 0 ) {
   164         return g_strdup(in_path);
   165     } else {
   166         getcwd(tmp, sizeof(tmp));
   167         return g_strdup_printf("%s%c%s", tmp, G_DIR_SEPARATOR, in_path);
   168     }
   169 }
   171 gchar *get_filename_at( const gchar *at, const gchar *filename )
   172 {
   173     char tmp[PATH_MAX];
   174     char *p = strrchr( at, '/' );
   175     if( p == NULL ) {
   176         /* No path at all, so just return filename */
   177         return g_strdup(filename);
   178     } else {
   179         int off = p-at;
   180         return g_strdup_printf("%.*s%c%s", off, at, G_DIR_SEPARATOR, filename );
   181     }
   182 }
   184 const gchar *get_gui_path( int key )
   185 {
   186     if( gui_paths[key] == NULL ) {
   187         gui_paths[key] = lxdream_get_global_config_path_value(key);
   188         /* If no path defined, go with the current working directory */
   189         if( gui_paths[key] == NULL ) {
   190             gui_paths[key] = get_absolute_path(".");
   191         }
   192     }
   193     return gui_paths[key];
   194 }
   196 void set_gui_path( int key, const gchar *path )
   197 {
   198     g_free(gui_paths[key]);
   199     gui_paths[key] = g_strdup(path);
   200 }
   202 void reset_gui_paths()
   203 {
   204     int i;
   205     for( i=0; i < CONFIG_KEY_MAX; i++ ) {
   206         g_free(gui_paths[i]);
   207         gui_paths[i] = NULL;
   208     }
   209 }
.