Search
lxdream.org :: lxdream/src/lxpaths.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/lxpaths.c
changeset 1286:8376a612a79d
prev1283:2cbafe321d6f
next1296:30ecee61f811
author nkeynes
date Sun Jul 01 13:19:27 2012 +1000 (10 years ago)
permissions -rw-r--r--
last change Add glib/gfileutils.h includes, as some required defines were moved there in recent versions of glib
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@1205
    21
#include <stdlib.h>
nkeynes@1286
    22
#include <glib/gfileutils.h>
nkeynes@1041
    23
#include <glib/gstrfuncs.h>
nkeynes@1041
    24
#include <glib/gutils.h>
nkeynes@1041
    25
nkeynes@1041
    26
#include "gui.h"
nkeynes@1041
    27
#include "config.h"
nkeynes@1041
    28
nkeynes@1041
    29
static gchar *gui_paths[CONFIG_KEY_MAX];
nkeynes@1041
    30
nkeynes@1041
    31
/**
nkeynes@1041
    32
 * Test if we need to escape a path to prevent substitution mangling. 
nkeynes@1041
    33
 * @return TRUE if the input value contains any character that doesn't
nkeynes@1041
    34
 * match [a-zA-Z0-9._@%/] (this will escape slightly more than it needs to,
nkeynes@1041
    35
 * but is safe)
nkeynes@1041
    36
 */
nkeynes@1041
    37
static gboolean path_needs_escaping( const gchar *value )
nkeynes@1041
    38
{
nkeynes@1041
    39
   const gchar *p = value;
nkeynes@1041
    40
   while( *p ) {
nkeynes@1041
    41
       if( !isalnum(*p) && *p != '.' && *p != '_' &&
nkeynes@1041
    42
               *p != '@' && *p != '%' && *p != '/' ) {
nkeynes@1041
    43
           return TRUE;
nkeynes@1041
    44
       }
nkeynes@1041
    45
       p++;
nkeynes@1041
    46
   }
nkeynes@1041
    47
   return FALSE;
nkeynes@1041
    48
}
nkeynes@1041
    49
nkeynes@1041
    50
gchar *get_escaped_path( const gchar *value )
nkeynes@1041
    51
{
nkeynes@1041
    52
    if( value != NULL && path_needs_escaping(value) ) {
nkeynes@1041
    53
        /* Escape with "", and backslash the remaining characters:
nkeynes@1041
    54
         *   \ " $ `
nkeynes@1041
    55
         */
nkeynes@1041
    56
        char buf[strlen(value)*2+3];  
nkeynes@1041
    57
        const char *s = value;
nkeynes@1041
    58
        char *p = buf;
nkeynes@1041
    59
        *p++ = '\"';
nkeynes@1041
    60
        while( *s ) {
nkeynes@1041
    61
            if( *s == '\\' || *s == '"' || *s == '$' || *s == '`' ) {
nkeynes@1041
    62
                *p++ = '\\';
nkeynes@1041
    63
            }
nkeynes@1041
    64
            *p++ = *s++;
nkeynes@1041
    65
        }
nkeynes@1041
    66
        *p++ = '\"';
nkeynes@1041
    67
        *p = '\0';
nkeynes@1041
    68
        return g_strdup(buf);
nkeynes@1041
    69
    } else {
nkeynes@1041
    70
        return g_strdup(value);
nkeynes@1041
    71
    }
nkeynes@1041
    72
}
nkeynes@1041
    73
nkeynes@1041
    74
gchar *get_expanded_path( const gchar *input )
nkeynes@1041
    75
{
nkeynes@1205
    76
    char result[PATH_MAX];
nkeynes@1205
    77
nkeynes@1205
    78
    char *d, *e;
nkeynes@1205
    79
    const char *s;
nkeynes@1205
    80
    d = result;
nkeynes@1205
    81
    e = result+sizeof(result)-1;
nkeynes@1205
    82
    s = input;
nkeynes@1283
    83
    gboolean inDQstring = FALSE;
nkeynes@1205
    84
nkeynes@1205
    85
    if( input == NULL )
nkeynes@1041
    86
        return NULL;
nkeynes@1205
    87
nkeynes@1205
    88
    while( *s ) {
nkeynes@1205
    89
        if( d == e ) {
nkeynes@1205
    90
            return g_strdup(input); /* expansion too long */
nkeynes@1205
    91
        }
nkeynes@1205
    92
        char c = *s++;
nkeynes@1205
    93
        if( c == '$' ) {
nkeynes@1205
    94
            if( *s == '{' ) {
nkeynes@1205
    95
                s++;
nkeynes@1205
    96
                const char *q = s;
nkeynes@1205
    97
                while( *q != '}' ) {
nkeynes@1205
    98
                    if( ! *q ) {
nkeynes@1205
    99
                        return g_strdup(input); /* unterminated variable */
nkeynes@1205
   100
                    }
nkeynes@1205
   101
                    q++;
nkeynes@1205
   102
                }
nkeynes@1205
   103
                char *tmp = g_strndup(s, (q-s));
nkeynes@1205
   104
                s = q+1;
nkeynes@1205
   105
                char *value = getenv(tmp);
nkeynes@1205
   106
                g_free(tmp);
nkeynes@1205
   107
                if( value != NULL ) {
nkeynes@1205
   108
                    int len = strlen(value);
nkeynes@1205
   109
                    if( d + len > e )
nkeynes@1205
   110
                        return g_strdup(input);
nkeynes@1205
   111
                    strcpy(d, value);
nkeynes@1205
   112
                    d+=len;
nkeynes@1205
   113
                } /* Else, empty string */
nkeynes@1205
   114
            } else {
nkeynes@1205
   115
                const char *q = s;
nkeynes@1205
   116
                while( isalnum(*q) || *q == '_' ) {
nkeynes@1205
   117
                    q++;
nkeynes@1205
   118
                }
nkeynes@1205
   119
                if( q == s ) {
nkeynes@1205
   120
                    *d++ = '$';
nkeynes@1205
   121
                } else {
nkeynes@1205
   122
                    char *tmp = g_strndup(s,q-s);
nkeynes@1205
   123
                    s = q;
nkeynes@1205
   124
                    char *value = getenv(tmp);
nkeynes@1205
   125
                    g_free(tmp);
nkeynes@1205
   126
                    if( value != NULL ) {
nkeynes@1205
   127
                        int len = strlen(value);
nkeynes@1205
   128
                        if( d + len > e )
nkeynes@1205
   129
                            return g_strdup(input);
nkeynes@1205
   130
                        strcpy(d, value);
nkeynes@1205
   131
                        d += len;
nkeynes@1205
   132
                    }
nkeynes@1205
   133
                }
nkeynes@1205
   134
            }
nkeynes@1205
   135
        } else if( c == '\\' ) {
nkeynes@1205
   136
            c = *s++;
nkeynes@1205
   137
            if( c ) {
nkeynes@1205
   138
                *d++ = c;
nkeynes@1205
   139
            } else {
nkeynes@1205
   140
                *d++ = '\\';
nkeynes@1205
   141
            }
nkeynes@1283
   142
        } else if( c == '\"' ) {
nkeynes@1283
   143
            /* Unescaped double-quotes start a DQ string. Although we treat the
nkeynes@1283
   144
             * string as if it were double-quoted for most purposes anyway, so
nkeynes@1283
   145
             * this has little effect.
nkeynes@1283
   146
             */
nkeynes@1283
   147
            inDQstring = !inDQstring;
nkeynes@1205
   148
        } else {
nkeynes@1205
   149
            *d++ = c;
nkeynes@1205
   150
        }
nkeynes@1041
   151
    }
nkeynes@1205
   152
    *d = '\0';
nkeynes@1283
   153
    if( inDQstring ) {
nkeynes@1283
   154
        WARN( "Unterminated double-quoted string '%s'", input );
nkeynes@1283
   155
    }
nkeynes@1205
   156
    return g_strdup(result);
nkeynes@1041
   157
}
nkeynes@1041
   158
gchar *get_absolute_path( const gchar *in_path )
nkeynes@1041
   159
{
nkeynes@1041
   160
    char tmp[PATH_MAX];
nkeynes@1041
   161
    if( in_path == NULL ) {
nkeynes@1041
   162
        return NULL;
nkeynes@1041
   163
    }
nkeynes@1041
   164
    if( in_path[0] == '/' || in_path[0] == 0 ) {
nkeynes@1041
   165
        return g_strdup(in_path);
nkeynes@1041
   166
    } else {
nkeynes@1041
   167
        getcwd(tmp, sizeof(tmp));
nkeynes@1041
   168
        return g_strdup_printf("%s%c%s", tmp, G_DIR_SEPARATOR, in_path);
nkeynes@1041
   169
    }
nkeynes@1041
   170
}
nkeynes@1041
   171
nkeynes@1041
   172
gchar *get_filename_at( const gchar *at, const gchar *filename )
nkeynes@1041
   173
{
nkeynes@1041
   174
    char tmp[PATH_MAX];
nkeynes@1056
   175
    char *p = strrchr( at, '/' );
nkeynes@1041
   176
    if( p == NULL ) {
nkeynes@1041
   177
        /* No path at all, so just return filename */
nkeynes@1041
   178
        return g_strdup(filename);
nkeynes@1041
   179
    } else {
nkeynes@1056
   180
        int off = p-at;
nkeynes@1041
   181
        return g_strdup_printf("%.*s%c%s", off, at, G_DIR_SEPARATOR, filename );
nkeynes@1041
   182
    }
nkeynes@1041
   183
}
nkeynes@1041
   184
nkeynes@1041
   185
const gchar *get_gui_path( int key )
nkeynes@1041
   186
{
nkeynes@1041
   187
    if( gui_paths[key] == NULL ) {
nkeynes@1041
   188
        gui_paths[key] = lxdream_get_global_config_path_value(key);
nkeynes@1041
   189
        /* If no path defined, go with the current working directory */
nkeynes@1041
   190
        if( gui_paths[key] == NULL ) {
nkeynes@1041
   191
            gui_paths[key] = get_absolute_path(".");
nkeynes@1041
   192
        }
nkeynes@1041
   193
    }
nkeynes@1041
   194
    return gui_paths[key];
nkeynes@1041
   195
}
nkeynes@1041
   196
nkeynes@1041
   197
void set_gui_path( int key, const gchar *path )
nkeynes@1041
   198
{
nkeynes@1041
   199
    g_free(gui_paths[key]);
nkeynes@1041
   200
    gui_paths[key] = g_strdup(path);
nkeynes@1041
   201
}
nkeynes@1041
   202
nkeynes@1041
   203
void reset_gui_paths()
nkeynes@1041
   204
{
nkeynes@1041
   205
    int i;
nkeynes@1041
   206
    for( i=0; i < CONFIG_KEY_MAX; i++ ) {
nkeynes@1041
   207
        g_free(gui_paths[i]);
nkeynes@1041
   208
        gui_paths[i] = NULL;
nkeynes@1041
   209
    }
nkeynes@1041
   210
}
.