#include <glib.h>
Go to the source code of this file.
Data Structures | |
struct | shortcut_t |
Defines | |
#define | MAX_SHORTCUT_NESTING 5 |
#define | shortcut_free(thiz) |
free the memory allocated to a shortcut_t structure and free the memory allocated to elements it contains and clear the pointer passed as argument | |
Enumerations | |
enum | shortcut_type_t { SHORTCUT_EMPTY = 0, SHORTCUT_TO_FILE, SHORTCUT_TO_WEB_LOCATION, SHORTCUT_TO_FOLDER, SHORTCUT_TO_APPLICATION, NUM_SHORTCUTS } |
Functions | |
int | create_shortcut_file (const gchar *target_dir, const gchar *target_file, const gchar *target_display, const gchar *shortcut_dir, GString *shortcut_file) |
create a shortcut file | |
int | parse_shortcut_file (const gchar *directory, const gchar *filename, shortcut_t **p_shortcut) |
get details from shortcut file parses shortcut files recursively when applicable | |
void | shortcut_free_impl (shortcut_t *thiz) |
#define MAX_SHORTCUT_NESTING 5 |
File Name : shortcut.h
Description: Content browser functions handling shortcut files (xx.desktop) Copyright (C) 2008 iRex Technologies B.V. All rights reserved.
Definition at line 46 of file shortcut.h.
#define shortcut_free | ( | thiz | ) |
{ \ shortcut_free_impl(thiz); \ (thiz) = NULL; \ }
free the memory allocated to a shortcut_t structure and free the memory allocated to elements it contains and clear the pointer passed as argument
---------------------------------------------------------------------------
Name : shortcut_free
[in] | directory | - directory in which the shortcut file (xx.desktop) is located |
[in] | fileinfo | - details of the shortcut file |
--------------------------------------------------------------------------
Definition at line 174 of file shortcut.h.
Referenced by activate_shortcut(), check_shortcut(), get_thumbnail(), load_items_in_model(), and parse_shortcut_file().
enum shortcut_type_t |
SHORTCUT_EMPTY | |
SHORTCUT_TO_FILE | |
SHORTCUT_TO_WEB_LOCATION | |
SHORTCUT_TO_FOLDER | |
SHORTCUT_TO_APPLICATION | |
NUM_SHORTCUTS |
Definition at line 60 of file shortcut.h.
00061 { 00062 SHORTCUT_EMPTY = 0, 00063 SHORTCUT_TO_FILE, 00064 SHORTCUT_TO_WEB_LOCATION, 00065 SHORTCUT_TO_FOLDER, 00066 SHORTCUT_TO_APPLICATION, 00067 NUM_SHORTCUTS 00068 } shortcut_type_t;
int create_shortcut_file | ( | const gchar * | target_dir, | |
const gchar * | target_file, | |||
const gchar * | target_display, | |||
const gchar * | shortcut_dir, | |||
GString * | shortcut_file | |||
) |
create a shortcut file
---------------------------------------------------------------------------
Name : create_shortcut_file
[in] | target_dir | - folder in which the target is located specified as an absolute path |
[in] | target_file | - file or folder to which the shortcut must point |
[in] | target_display | - name displayed for target |
[in] | shortcut_dir | - directory in which the shortcut file (xx.desktop) must be created specified as an absolute path |
[out] | shortcut_file | - filename of the shortcut file created in shortcut_dir, or ignored when caller passes a NULL pointer here. Note: caller must allocate and release this GString. |
--------------------------------------------------------------------------
Definition at line 98 of file shortcut.c.
References ER_NOT_FOUND, ER_OK, ER_OPEN_ERROR, ER_WRITE_ERROR, FILE_EXT_SHORTCUT, FILE_EXT_SHORTCUT_TO_DIR, FILE_SHORTCUT, FOLDER_SHORTCUT, SHORTCUT_EMPTY, SHORTCUT_TO_FILE, and SHORTCUT_TO_FOLDER.
Referenced by create_shortcut_item().
00103 { 00104 int ret = ER_OK; // return code 00105 00106 g_assert( target_dir && *target_dir == '/' ); 00107 g_assert( target_file && *target_file ); 00108 g_assert( target_display && *target_display ); 00109 g_assert( shortcut_dir && *shortcut_dir == '/' ); 00110 g_assert( shortcut_file == NULL || shortcut_file->len == 0 ); 00111 g_assert( strlen(target_dir) < 256); 00112 g_assert( strlen(target_file) < 256); 00113 g_assert( strlen(shortcut_dir) < 256); 00114 00115 // determine shortcut type 00116 gchar *target_path = g_strdup_printf("%s/%s", target_dir, target_file); 00117 00118 shortcut_type_t shortcut_type = SHORTCUT_EMPTY; 00119 const gchar *shortcut_ext = ""; 00120 if ( g_file_test(target_path, G_FILE_TEST_IS_REGULAR) ) 00121 { 00122 shortcut_type = SHORTCUT_TO_FILE; 00123 shortcut_ext = FILE_EXT_SHORTCUT; 00124 } 00125 else if ( g_file_test(target_path, G_FILE_TEST_IS_DIR) ) 00126 { 00127 shortcut_type = SHORTCUT_TO_FOLDER; 00128 shortcut_ext = FILE_EXT_SHORTCUT_TO_DIR; 00129 } 00130 else 00131 { 00132 ret = ER_NOT_FOUND; 00133 goto out; 00134 } 00135 00136 // determine shortcut filename 00137 int seq = 0; 00138 char file[256]; 00139 char shortcut_fullname[512]; 00140 while (1) { 00141 seq++; 00142 sprintf(file, "%s_%03d.%s", target_file, seq, shortcut_ext); 00143 sprintf(shortcut_fullname, "%s/%s", shortcut_dir, file); 00144 if (!g_file_test(shortcut_fullname, G_FILE_TEST_EXISTS)) break; 00145 } 00146 00147 // determine relative path shortcut -> target 00148 // skip identical pre-fix 00149 gchar *cp1 = target_path; 00150 gchar *cp2 = shortcut_fullname; 00151 while ( *cp1 != '\0' && *cp1 == *cp2 ) 00152 { 00153 cp1++; 00154 cp2++; 00155 } 00156 while ( *(cp1 - 1) != '/' ) 00157 { 00158 cp1--; 00159 cp2--; 00160 } 00161 // count parent directories to traverse 00162 gboolean done = FALSE; 00163 GString *shortcut_target = g_string_new(""); 00164 while ( !done ) 00165 { 00166 while ( *cp2 == '/' ) 00167 { 00168 cp2++; 00169 } 00170 cp2 = strchr(cp2, '/'); 00171 if (cp2) 00172 { 00173 g_string_append(shortcut_target, "../"); 00174 } 00175 else 00176 { 00177 done = TRUE; 00178 } 00179 } 00180 // append remaining part of shortcut target 00181 g_string_append(shortcut_target, cp1); 00182 00183 FILE *fp = fopen(shortcut_fullname, "w"); 00184 if (fp == NULL) 00185 { 00186 ret = ER_OPEN_ERROR; 00187 goto out2; 00188 } 00189 00190 int rc = 0; 00191 // write shortcut details 00192 switch (shortcut_type) 00193 { 00194 case SHORTCUT_TO_FILE: 00195 { 00196 gchar* temp_uri = g_uri_escape_string(shortcut_target->str, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE); 00197 rc = fprintf( fp, 00198 FILE_SHORTCUT, 00199 temp_uri, // URL= 00200 target_display ); // Name= 00201 g_free(temp_uri ); 00202 break; 00203 } 00204 case SHORTCUT_TO_FOLDER: 00205 rc = fprintf( fp, 00206 FOLDER_SHORTCUT, 00207 shortcut_target->str, // Path= 00208 target_display ); // Name= 00209 break; 00210 00211 default: 00212 g_assert_not_reached(); 00213 } 00214 if (rc <= 0) 00215 { 00216 ret = ER_WRITE_ERROR; 00217 } 00218 00219 rc = fclose(fp); 00220 if (rc != 0) 00221 { 00222 ret = ER_WRITE_ERROR; 00223 } 00224 00225 // set output parameters 00226 if (ret == ER_OK && shortcut_file) 00227 { 00228 g_string_assign(shortcut_file, file); 00229 } 00230 00231 out2: 00232 g_string_free(shortcut_target, TRUE); 00233 out: 00234 g_free(target_path); 00235 return ret; 00236 }
int parse_shortcut_file | ( | const gchar * | directory, | |
const gchar * | filename, | |||
shortcut_t ** | p_shortcut | |||
) |
get details from shortcut file parses shortcut files recursively when applicable
---------------------------------------------------------------------------
Name : parse_shortcut_file
[in] | directory | - directory in which the shortcut file (xx.desktop) is located |
[in] | filename | - filename of the shortcut file |
[out] | p_shortcut | - structure with details of the requested shortcut, caller must release this with shortcut_free() |
--------------------------------------------------------------------------
Definition at line 239 of file shortcut.c.
References shortcut_t::application, shortcut_t::comment, cp, shortcut_t::details, ER_FAIL, ER_INVALID_DATA, ER_NOT_FOUND, ER_OK, ERRORPRINTF, shortcut_t::filepath, shortcut_t::folder, shortcut_t::keyfile, shortcut_t::name, parse_file_url(), parse_folder_path(), path, path_has_invalid_characters(), shortcut_free, shortcut_new(), SHORTCUT_TO_APPLICATION, SHORTCUT_TO_FILE, SHORTCUT_TO_FOLDER, SHORTCUT_TO_WEB_LOCATION, shortcut_t::type, and shortcut_t::web.
Referenced by activate_shortcut(), check_shortcut(), get_thumbnail(), and load_items_in_model().
00242 { 00243 g_assert(directory && *directory ); 00244 g_assert(filename && *filename ); 00245 g_assert(p_shortcut && *p_shortcut == NULL); 00246 00247 GKeyFile *keyfile = g_key_file_new(); 00248 shortcut_t *shortcut = shortcut_new(); 00249 shortcut->keyfile = keyfile; 00250 gchar *filepath = g_strdup_printf("%s/%s", directory, filename); 00251 shortcut->filepath = filepath; 00252 00253 int ret = ER_OK; 00254 if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR)) 00255 { 00256 ret = ER_NOT_FOUND; 00257 goto out; 00258 } 00259 00260 if (!g_key_file_load_from_file( keyfile, 00261 filepath, 00262 G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, 00263 NULL)) 00264 { 00265 ret = ER_INVALID_DATA; 00266 goto out; 00267 } 00268 00269 // get name 00270 shortcut->name = g_key_file_get_locale_string( keyfile, 00271 G_KEY_FILE_DESKTOP_GROUP, 00272 G_KEY_FILE_DESKTOP_KEY_NAME, 00273 NULL, 00274 NULL ); 00275 if (shortcut->name == NULL) 00276 { 00277 ret = ER_INVALID_DATA; 00278 goto out; 00279 } 00280 00281 // get comments 00282 shortcut->comment = g_key_file_get_locale_string( keyfile, 00283 G_KEY_FILE_DESKTOP_GROUP, 00284 G_KEY_FILE_DESKTOP_KEY_COMMENT, 00285 NULL, 00286 NULL ); 00287 00288 // get version (optional) 00289 gchar* version = g_key_file_get_string( keyfile, 00290 G_KEY_FILE_DESKTOP_GROUP, 00291 G_KEY_FILE_DESKTOP_KEY_VERSION, 00292 NULL ); 00293 if (version != NULL) 00294 { 00295 int compare = strcmp(version, "1.0"); 00296 g_free(version); 00297 if (compare != 0) { 00298 ret = ER_INVALID_DATA; 00299 goto out; 00300 } 00301 } 00302 00303 // get type 00304 gchar *type = g_key_file_get_string( keyfile, 00305 G_KEY_FILE_DESKTOP_GROUP, 00306 G_KEY_FILE_DESKTOP_KEY_TYPE, 00307 NULL ); 00308 if (type == NULL) 00309 { 00310 // type not found: error 00311 ret = ER_INVALID_DATA; 00312 goto out; 00313 } 00314 00315 // type found: store in shortcut 00316 if ( strcmp(type, G_KEY_FILE_DESKTOP_TYPE_LINK) == 0 ) 00317 { 00318 shortcut->type = SHORTCUT_TO_FILE; 00319 } 00320 else if ( strcmp(type, G_KEY_FILE_DESKTOP_TYPE_DIRECTORY) == 0 ) 00321 { 00322 shortcut->type = SHORTCUT_TO_FOLDER; 00323 } 00324 else if ( strcmp(type, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) == 0 ) 00325 { 00326 shortcut->type = SHORTCUT_TO_APPLICATION; 00327 } 00328 else 00329 { 00330 g_free(type); 00331 ret = ER_INVALID_DATA; 00332 goto out; 00333 } 00334 g_free(type); 00335 00336 // get type-dependent keys 00337 switch (shortcut->type) 00338 { 00339 case SHORTCUT_TO_FILE: 00340 { 00341 // get url 00342 gchar *url = g_key_file_get_string( keyfile, 00343 G_KEY_FILE_DESKTOP_GROUP, 00344 G_KEY_FILE_DESKTOP_KEY_URL, 00345 NULL ); 00346 if (url == NULL) 00347 { 00348 ret = ER_INVALID_DATA; 00349 goto out; 00350 } 00351 00352 // url found: convert to path, store in shortcut 00353 00354 // get scheme from url 00355 // note: scheme might indicate url points to a web location 00356 if ( g_str_has_prefix(url, "http:") || g_str_has_prefix(url, "https:") ) 00357 { 00358 // web location: remember details and leave 00359 shortcut->type = SHORTCUT_TO_WEB_LOCATION; 00360 shortcut->details.web.url = url; 00361 ret = ER_OK; 00362 break; // exit switch 00363 } 00364 else if ( g_str_has_prefix(url, "file:") ) 00365 { 00366 // local file location: get real path 00367 ret = parse_file_url( directory, url, shortcut ); 00368 } 00369 else 00370 { 00371 // scheme not implemented 00372 ret = ER_INVALID_DATA; 00373 goto out; 00374 } 00375 00376 // clean up 00377 g_free(url); 00378 break; 00379 } 00380 case SHORTCUT_TO_FOLDER: 00381 { 00382 // get path 00383 gchar *path = g_key_file_get_string( keyfile, 00384 G_KEY_FILE_DESKTOP_GROUP, 00385 G_KEY_FILE_DESKTOP_KEY_PATH, 00386 NULL ); 00387 if (path == NULL) 00388 { 00389 ret = ER_INVALID_DATA; 00390 goto out; 00391 } 00392 00393 // key found: check on invalid characters 00394 if ( path_has_invalid_characters(path) ) 00395 { 00396 ret = ER_INVALID_DATA; 00397 goto out; 00398 } 00399 00400 // path found: convert to realpath, store in shortcut 00401 ret = parse_folder_path( directory, path, shortcut ); 00402 shortcut->details.folder.path = path; 00403 break; 00404 } 00405 // note: no nesting of shortcut to application 00406 case SHORTCUT_TO_APPLICATION: 00407 { 00408 // get exec 00409 gchar *executable = g_key_file_get_string( keyfile, 00410 G_KEY_FILE_DESKTOP_GROUP, 00411 G_KEY_FILE_DESKTOP_KEY_EXEC, 00412 NULL ); 00413 if (executable == NULL) 00414 { 00415 ret = ER_INVALID_DATA; 00416 goto out; 00417 } 00418 00419 // key found: store in shortcut 00420 if (strncmp(executable, "./", 2) == 0 || strncmp(executable, "../", 3) == 0) 00421 { 00422 // relative path: prepend shortcut directory 00423 // shell quote to preserve spaces in directory 00424 gchar *directory_quoted = g_shell_quote(directory); 00425 gchar *cp = g_strdup_printf("%s/%s", directory_quoted, executable); 00426 g_free(directory_quoted); 00427 g_free(executable); 00428 executable = cp; 00429 } 00430 shortcut->details.application.command_line = executable; 00431 00432 // get path (optional) 00433 gchar* path = g_key_file_get_string( keyfile, 00434 G_KEY_FILE_DESKTOP_GROUP, 00435 G_KEY_FILE_DESKTOP_KEY_PATH, 00436 NULL ); 00437 if (path != NULL) 00438 { 00439 // key found: check on invalid characters 00440 if ( path_has_invalid_characters(path) ) 00441 { 00442 g_free(path); 00443 ret = ER_INVALID_DATA; 00444 goto out; 00445 } 00446 // path ok: store in shortcut 00447 shortcut->details.application.work_dir = path; 00448 } 00449 break; 00450 } 00451 default: 00452 ERRORPRINTF("unknown type %d", shortcut->type); 00453 ret = ER_FAIL; 00454 break; 00455 } 00456 00457 if (ret == ER_OK) 00458 { 00459 *p_shortcut = shortcut; 00460 return ER_OK; 00461 } 00462 00463 out: 00464 shortcut_free(shortcut); 00465 return ret; 00466 }
void shortcut_free_impl | ( | shortcut_t * | thiz | ) |
Definition at line 637 of file shortcut.c.
References shortcut_t::application, shortcut_t::comment, shortcut_t::details, ERRORPRINTF, shortcut_t::file, shortcut_t::filepath, shortcut_t::folder, shortcut_t::keyfile, shortcut_t::name, SHORTCUT_EMPTY, SHORTCUT_TO_APPLICATION, SHORTCUT_TO_FILE, SHORTCUT_TO_FOLDER, SHORTCUT_TO_WEB_LOCATION, shortcut_t::type, and shortcut_t::web.
00638 { 00639 if (thiz == NULL) return; 00640 00641 g_free(thiz->filepath); 00642 if (thiz->keyfile) 00643 { 00644 g_key_file_free(thiz->keyfile); 00645 } 00646 g_free(thiz->name); 00647 g_free(thiz->comment); 00648 switch (thiz->type) 00649 { 00650 case SHORTCUT_EMPTY: 00651 ; //ignore 00652 break; 00653 00654 case SHORTCUT_TO_FILE: 00655 g_free(thiz->details.file.directory); 00656 g_free(thiz->details.file.filename ); 00657 break; 00658 00659 case SHORTCUT_TO_WEB_LOCATION: 00660 g_free(thiz->details.web.url); 00661 break; 00662 00663 case SHORTCUT_TO_FOLDER: 00664 g_free(thiz->details.folder.path); 00665 g_free(thiz->details.folder.directory); 00666 g_free(thiz->details.folder.filename ); 00667 break; 00668 00669 case SHORTCUT_TO_APPLICATION: 00670 g_free(thiz->details.application.command_line); 00671 break; 00672 00673 default: 00674 ERRORPRINTF("illegal shortcut type [%d]", thiz->type); 00675 ; //ignore 00676 } 00677 00678 g_free(thiz); 00679 }