pfile get_file( char *name ) { pfile cbase = root; pfile rv = NULL; int start = 0; int end = 0; int max = 0; char sdir[256]; if ( name == NULL ) { return NULL; } /// Handle the base case if ( name[0] != '/') { rv = retrieve_sub( cbase, name ); return rv; } start = 1; max = strlen(name); while ( end != -1 ) { end = find_next_slash( name, start, max ); if ( end == -1 ) { memset( sdir, 0, 256 ); memcpy( sdir, name+start, max-start); rv = retrieve_sub( cbase, sdir ); return rv; } memset( sdir, 0, 256 ); memcpy( sdir, name+start, end-start); cbase = retrieve_sub( cbase, sdir ); start = end + 1; if ( cbase ) { if (cbase->type != DIR ) { printf("[ERROR] $s is not a directory\n", sdir ); return NULL; } } else { return cbase; } } return NULL; }
static int find_slash_before_offset (const char *path, int to) { int result; int next_offset; result = -1; next_offset = 0; for (;;) { next_offset = find_next_slash (path, next_offset); if (next_offset < 0 || next_offset >= to) { break; } result = next_offset; next_offset++; } return result; }
static inline gint find_slash_before_offset (const gchar *path, gint to) { gint next_offset; gint result = -1; for (next_offset = 0;; ++next_offset) { next_offset = find_next_slash (path, next_offset); if (next_offset < 0 || next_offset >= to) break; result = next_offset; } return result; }
/* Canonicalize path, and return a new path. Do everything in situ. The new path differs from path in: Multiple `/'s are collapsed to a single `/'. Leading `./'s and trailing `/.'s are removed. Non-leading `../'s and trailing `..'s are handled by removing portions of the path. */ static gchar * mate_vfs_canonicalize_pathname (gchar *path) { int i, marker; if (path == NULL || strlen (path) == 0) { return ""; } /* Walk along path looking for things to compact. */ for (i = 0, marker = 0;;) { if (!path[i]) break; /* Check for `../', `./' or trailing `.' by itself. */ if (path[i] == '.') { /* Handle trailing `.' by itself. */ if (path[i + 1] == '\0') { if (i > 1 && path[i - 1] == MATE_VFS_URI_PATH_CHR) { /* strip the trailing /. */ path[i - 1] = '\0'; } else { /* convert path "/." to "/" */ path[i] = '\0'; } break; } /* Handle `./'. */ if (path[i + 1] == MATE_VFS_URI_PATH_CHR) { memmove (path + i, path + i + 2, strlen (path + i + 2) + 1); if (i == 0) { /* don't leave leading '/' for paths that started * as relative (.//foo) */ collapse_slash_runs (path, i); marker = 0; } continue; } /* Handle `../' or trailing `..' by itself. * Remove the previous xxx/ part */ if (path[i + 1] == '.' && (path[i + 2] == MATE_VFS_URI_PATH_CHR || path[i + 2] == '\0')) { /* ignore ../ at the beginning of a path */ if (i != 0) { marker = find_slash_before_offset (path, i - 1); /* Either advance past '/' or point to the first character */ marker ++; if (path [i + 2] == '\0' && marker > 1) { /* If we are looking at a /.. at the end of the uri and we * need to eat the last '/' too. */ marker--; } g_assert(marker < i); if (path[i + 2] == MATE_VFS_URI_PATH_CHR) { /* strip the entire ../ string */ i++; } memmove (path + marker, path + i + 2, strlen (path + i + 2) + 1); i = marker; } else { i = 2; if (path[i] == MATE_VFS_URI_PATH_CHR) { i++; } } collapse_slash_runs (path, i); continue; } } /* advance to the next '/' */ i = find_next_slash (path, i); /* If we didn't find any slashes, then there is nothing left to do. */ if (i < 0) { break; } marker = i++; collapse_slash_runs (path, i); } return path; }
int add_file( pfile nf ) { int start = 0; int end = 0; char base[256]; char *nd = NULL; int max = 0; pfile cbase_dir = root; pfile temp = NULL; if ( nf == NULL ) { return 0; } // If it does not start with a slash then it is just added to root // It is possible to have '/' in the name but it won't affect it if ( nf->name[0] != '/' ) { if ( add_file_to_dir( cbase_dir, nf ) == 0 ) { printf("[ERROR] Failed to add file to root\n"); return 0; } return 1; } start = 1; max = strlen(nf->name); /// Handle the case where the name is just '/' if ( max == 1 ) { printf("[ERROR] You cannot add '/'\n"); return 0; } while ( end != -1 ) { end = find_next_slash( nf->name, start, max ); /// If this is the end then copy out the name and add it in if ( end == -1 ) { memset(base, 0, 256); memcpy( base, nf->name+start, max-start ); memset( nf->name, 0, 256); memcpy( nf->name, base, max - start ); if ( does_sub_file_exist( cbase_dir, nf->name) == 1) { printf("[ERROR] File already exists\n"); return 0; } if ( add_file_to_dir( cbase_dir, nf) == 0 ) { printf("[ERROR] Failed to add file to $s\n", cbase_dir->name); return 0; } return 1; } else { memset( base, 0, 256); /// Copy the dir name and determine if it is valid memcpy( base, nf->name+start, end-start); temp = retrieve_sub( cbase_dir, base ); if ( temp == NULL ) { printf("[ERROR] Directory $s does not exist.\n", base); return 0; } else if ( temp->type != DIR ) { printf("[ERROR] $s is not a directory\n", base ); return 0; } else { cbase_dir = temp; } start = end + 1; } } return 1; }
int delete_file( char *name ) { pfile base = root; char nm[256]; int start = 0; int end = 0; int max = 0; if ( name == NULL ) { return 0; } /// Handle base case if ( name[0] != '/' ) { if ( does_sub_file_exist( base, name ) == 0 ) { printf("[ERROR] Could not locate $s\n", name); return 0; } if ( remove_sub_file( base, name ) != 0 ) { printf("[INFO] $s removed\n", name ); return 1; } else { return 0; } } start = 1; max = strlen(name); if ( max > 256 ) { printf("[ERROR] Name too long\n"); return 0; } while ( end != -1 ) { end = find_next_slash( name, start, max ); memset(nm, 0, 256); if ( end == -1 ) { if ( (max - start) > 256 ) { printf("[ERROR] Size calculation failed\n"); return 0; } memcpy( nm, name+start, max-start); if ( does_sub_file_exist( base, nm ) == 0 ) { printf("[ERROR] Could not locate $s\n", name ); return 0; } if ( remove_sub_file( base, nm ) != 0 ) { printf("[INFO] $s removed\n", nm ); return 1; } else { return 0; } } if ( (end-start) > 256 ) { printf("[ERROR] Size calculation failed\n"); return 0; } memcpy( nm, name+start, end-start); base = retrieve_sub( base, nm ); if ( base == NULL ) { printf("[ERROR] Failed to locate directory $s\n", nm); return 0; } if ( base->type != DIR ) { return 0; } start = end + 1; } return 0; }
/** * thunar_vfs_canonicalize_filename: * @filename : a local filename. * * Canonicalizes @filename and returns a new path. The new path * differs from @filename in: * * <simplelist> * <member>Multiple `/'s are collapsed to a single `/'.</member> * <member>Leading `./'s and trailing `/.'s are removed.</member> * <member>Non-leading `../'s and trailing `..'s are handled by removing portions of the path.</member> * </simplelist> * * The caller is responsible to free the returned string using * g_free() when no longer needed. * * Return value: the canonicalized path for @filename. **/ gchar* thunar_vfs_canonicalize_filename (const gchar *filename) { gchar *path; gint marker; gint i; g_return_val_if_fail (filename != NULL, NULL); /* take a copy of the filename to operate on */ path = g_strdup (filename); if (G_UNLIKELY (*path == '\0')) return path; /* Walk along path looking for things to compact. */ for (i = 0, marker = 0;;) { if (G_UNLIKELY (path[i] == '\0')) break; /* Check for `../', `./' or trailing `.' by itself. */ if (path[i] == '.') { /* Handle trailing `.' by itself. */ if (path[i + 1] == '\0') { if (i > 1 && path[i - 1] == G_DIR_SEPARATOR) { /* strip the trailing /. */ path[i - 1] = '\0'; } else { /* convert path "/." to "/" */ path[i] = '\0'; } break; } /* Handle `./'. */ if (path[i + 1] == G_DIR_SEPARATOR) { memmove (path + i, path + i + 2, strlen (path + i + 2) + 1); if (i == 0) { /* don't leave leading '/' for paths that started * as relative (.//foo) */ collapse_slash_runs (path, i); marker = 0; } continue; } /* Handle `../' or trailing `..' by itself. * Remove the previous xxx/ part */ if (path[i + 1] == '.' && (path[i + 2] == G_DIR_SEPARATOR || path[i + 2] == '\0')) { /* ignore ../ at the beginning of a path */ if (i != 0) { marker = find_slash_before_offset (path, i - 1); /* Either advance past '/' or point to the first character */ marker ++; if (path [i + 2] == '\0' && marker > 1) { /* If we are looking at a /.. at the end of the uri and we * need to eat the last '/' too. */ marker--; } /* strip the entire ../ string */ if (path[i + 2] == G_DIR_SEPARATOR) ++i; memmove (path + marker, path + i + 2, strlen (path + i + 2) + 1); i = marker; } else { i = 2; if (path[i] == G_DIR_SEPARATOR) i++; } collapse_slash_runs (path, i); continue; } } /* advance to the next '/' */ i = find_next_slash (path, i); /* If we didn't find any slashes, then there is nothing left to do. */ if (i < 0) break; marker = i++; collapse_slash_runs (path, i); } return path; }