예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
/* 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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
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;
}