const char * x_basename (const char *s) { const char *url_delim, *path_sep; url_delim = g_strrstr (s, VFS_PATH_URL_DELIMITER); path_sep = strrchr (s, PATH_SEP); if (path_sep == NULL) return s; if (url_delim == NULL || url_delim < path_sep - strlen (VFS_PATH_URL_DELIMITER) || url_delim - s + strlen (VFS_PATH_URL_DELIMITER) < strlen (s)) { /* avoid trailing PATH_SEP, if present */ if (!IS_PATH_SEP (s[strlen (s) - 1])) return (path_sep != NULL) ? path_sep + 1 : s; while (--path_sep > s && !IS_PATH_SEP (*path_sep)) ; return (path_sep != s) ? path_sep + 1 : s; } while (--url_delim > s && !IS_PATH_SEP (*url_delim)) ; while (--url_delim > s && !IS_PATH_SEP (*url_delim)) ; return (url_delim == s) ? s : url_delim + 1; }
/* On Unix, this has no effect. * C:zzz ==> returns zzz (DOS/Windows, VMS) * //drive/zzz ==> returns zzz (DOS/Windows) */ static SLFUTURE_CONST char *skip_drive (SLFUTURE_CONST char *file) { #ifdef DRIVE_SPECIFIER SLFUTURE_CONST char *f; /* look for A:/foo form */ f = file + strlen (file); while (f != file) { f--; if (*f == DRIVE_SPECIFIER) return f+1; } #endif #ifdef IBMPC_SYSTEM /* windows //netdrive/dir form */ if (IS_PATH_SEP(file[0]) && IS_PATH_SEP(file[1])) { file += 2; while (*file && (0 == IS_PATH_SEP(*file))) file++; return file; } #endif return file; }
static void undelfs_get_path (const vfs_path_t * vpath, char **fsname, char **file) { const char *p, *dirname; const vfs_path_element_t *path_element; path_element = vfs_path_get_by_index (vpath, -1); /* To look like filesystem, we have virtual directories undel://XXX, which have no subdirectories. XXX is replaced with hda5, sdb8 etc, which is assumed to live under /dev. -- [email protected] */ dirname = path_element->path; *fsname = NULL; if (strncmp (dirname, "undel://", 8) != 0) return; dirname += 8; /* Since we don't allow subdirectories, it's easy to get a filename, * just scan backwards for a slash */ if (*dirname == 0) return; p = dirname + strlen (dirname); #if 0 /* Strip trailing ./ */ if (p - dirname > 2 && IS_PATH_SEP (p[-1]) && p[-2] == '.') *(p = p - 2) = 0; #endif while (p > dirname) { if (IS_PATH_SEP (*p)) { char *tmp; *file = g_strdup (p + 1); tmp = g_strndup (dirname, p - dirname); *fsname = g_strconcat ("/dev/", tmp, (char *) NULL); g_free (tmp); return; } p--; } *file = g_strdup (""); *fsname = g_strconcat ("/dev/", dirname, (char *) NULL); }
int SLpath_is_absolute_path (SLFUTURE_CONST char *name) { if (name == NULL) return -1; #ifdef UNIX_PATHNAMES_OK return (*name == '/'); #else if (IS_PATH_SEP (*name)) return 1; # ifdef DRIVE_SPECIFIER /* Look for a drive specifier */ while (*name) { if (*name == DRIVE_SPECIFIER) return 1; name++; } # endif return 0; #endif }
/* If path looks like: A/B/C/D/whatever, it returns A/B/C/D as a malloced * string. */ char *SLpath_dirname (SLFUTURE_CONST char *file) { SLCONST char *b; if (file == NULL) return NULL; b = file + strlen (file); while (b != file) { b--; if (IS_PATH_SEP(*b)) { #ifdef VMS b++; /* make sure final ] is included */ #else if (b == file) b++; #endif break; } #ifdef DRIVE_SPECIFIER if (*b == DRIVE_SPECIFIER) { b++; break; } #endif } if (b == file) return SLmake_string (THIS_DIR_STRING); return SLmake_nstring (file, (unsigned int) (b - file)); }
/* Returns a malloced string */ char *SLpath_pathname_sans_extname (SLFUTURE_CONST char *file) { char *b; file = SLmake_string (file); if (file == NULL) return NULL; b = (char *) file + strlen (file); while (b != file) { b--; if (IS_PATH_SEP(*b)) break; #ifdef DRIVE_SPECIFIER if (*b == DRIVE_SPECIFIER) { b++; break; } #endif if (*b == '.') { *b = 0; return (char *) file; } } return (char *) file; }
static int findInclude( const char *path, const char *filename, size_t len, char *fullfilename ) { char *p; char c; while( (c = *path) != '\0' ) { p = fullfilename; do { ++path; if( IS_PATH_LIST_SEP( c ) ) { break; } *p++ = c; } while( (c = *path) != '\0' ); c = p[-1]; if( !IS_PATH_SEP( c ) ) { *p++ = DIR_SEP; } memcpy( p, filename, len ); p[len] = '\0'; if( access( fullfilename, R_OK ) == 0 ) { return( 0 ); } } return( -1 ); }
static void tempFname( char *fname ) { char *env; int i; #if defined(__UNIX__) env = CppGetEnv( "TMPDIR" ); if( env == NULL ) env = CppGetEnv( "TMP" ); #else env = CppGetEnv( "TMP" ); #endif if( env == NULL ) env = ""; #define TMP_EXT ".tmp" #define MAX_TMP_PATH (_MAX_PATH - sizeof( workFile ) - sizeof( TMP_EXT ) - 2) strncpy( fname, env, MAX_TMP_PATH ); fname[ MAX_TMP_PATH ] = '\0'; i = strlen( fname ); if( i > 0 && !IS_PATH_SEP( fname[i-1] ) ) { fname[i++] = PATH_SEP; } strcpy( &fname[i], workFile ); strcpy( &fname[i+sizeof(workFile)-1], TMP_EXT ); }
/* This returns a MALLOCED string */ char *SLpath_dircat (SLFUTURE_CONST char *dir, SLFUTURE_CONST char *name) { unsigned int len, dirlen; char *file; #ifndef VMS int requires_fixup; #endif if (name == NULL) name = ""; if ((dir == NULL) #if !TEST_VMS_ON_UNIX || (SLpath_is_absolute_path (name)) #endif ) dir = ""; /* Both VMS and MSDOS have default directories associated with each drive. * That is, the meaning of something like C:X depends upon more than just * the syntax of the string. Since this concept has more power under VMS * it will be honored here. However, I am going to treat C:X as C:\X * under MSDOS. * * Note!!! * VMS has problems of its own regarding path names, so I am simply * going to strcat. Hopefully the VMS RTL is smart enough to deal with * the result. */ dirlen = strlen (dir); #ifndef VMS # if TEST_VMS_ON_UNIX requires_fixup = 0; # else requires_fixup = (dirlen && (0 == IS_PATH_SEP(dir[dirlen - 1]))); # endif #endif len = dirlen + strlen (name) + 2; if (NULL == (file = (char *)SLmalloc (len))) return NULL; strcpy (file, dir); #ifndef VMS if (requires_fixup) file[dirlen++] = PATH_SEP; #endif strcpy (file + dirlen, name); #if defined(IBMPC_SYSTEM) convert_slashes (file); #endif #if TEST_VMS_ON_UNIX || defined (VMS) return vms_fixup_filename (file); #else return file; #endif }
/* Returns a malloced string */ char *SLpath_pathname_sans_extname (SLFUTURE_CONST char *drivefile) { char *b; char *file; drivefile = SLmake_string (drivefile); if (drivefile == NULL) return NULL; file = (char *)skip_drive (drivefile); b = file + strlen (file); while (b != file) { b--; if (IS_PATH_SEP(*b)) break; if (*b == '.') { *b = 0; break; } } return drivefile; }
static int name_file_check(char *s) { int i; if(IS_PATH_SEP(s[0])) return 1; if(strncasecmp(s, "file:", 5) == 0) return 1; #ifdef __W32__ /* [A-Za-z]: (for Windows) */ if((('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z')) && s[1] == ':') return 1; #endif /* __W32__ */ for(i = 0; s[i] && s[i] != ':' && s[i] != '/'; i++) ; if(s[i] == ':' && s[i + 1] == '/') return 0; return 1; }
static lib_handle SearchPath( char *path_list, char *name ) { //=========================================================== char *p; lib_handle lp; char buff[2 * _MAX_PATH]; char c; lp = NULL; while( (c = *path_list) != '\0' ) { p = buff; do { ++path_list; if( IS_PATH_LIST_SEP( c ) ) break; *p++ = c; } while( (c = *path_list) != '\0' ); c = p[-1]; if( !IS_PATH_SEP( c ) ) { *p++ = DIR_SEP; } strcpy( p, name ); lp = FindSrcFile( buff ); if( lp != NULL ) { break; } } return( lp ); }
/* * first_path_separator * * Find the location of the first path separator (i.e. ':' on * Unix, ';' on Windows), return NULL if not found. */ char * first_path_separator(const char *pathlist) { const char *p; /* skip_drive is not needed */ for (p = pathlist; *p; p++) if (IS_PATH_SEP(*p)) return (char *) p; return NULL; }
static vfs_path_t * get_absolute_name (const vfs_path_t * vpath) { if (vpath == NULL) return NULL; if (IS_PATH_SEP (*vfs_path_get_by_index (vpath, 0)->path)) return vfs_path_clone (vpath); return vfs_path_append_vpath_new (vfs_get_raw_current_dir (), vpath, NULL); }
char * tilde_expand (const char *directory) { struct passwd *passwd; const char *p, *q; if (*directory != '~') return g_strdup (directory); p = directory + 1; /* d = "~" or d = "~/" */ if (*p == '\0' || IS_PATH_SEP (*p)) { passwd = getpwuid (geteuid ()); q = IS_PATH_SEP (*p) ? p + 1 : ""; } else { q = strchr (p, PATH_SEP); if (!q) { passwd = getpwnam (p); } else { char *name; name = g_strndup (p, q - p); passwd = getpwnam (name); q++; g_free (name); } } /* If we can't figure the user name, leave tilde unexpanded */ if (!passwd) return g_strdup (directory); return g_strconcat (passwd->pw_dir, PATH_SEP_STR, q, (char *) NULL); }
/* Return: 0: - not modified * 1: - modified */ int nodirectory_form(char *buffer) { char *lastp = buffer + strlen(buffer); char *p = lastp; while(p > buffer && IS_PATH_SEP(*(p - 1))) p--; if(p == lastp) return 0; *p = '\0'; return 1; }
char * mc_build_filenamev (const char *first_element, va_list args) { gboolean absolute; const char *element = first_element; GString *path; char *ret; if (element == NULL) return NULL; path = g_string_new (""); absolute = IS_PATH_SEP (*first_element); do { if (*element == '\0') element = va_arg (args, char *); else { char *tmp_element; size_t len; const char *start; tmp_element = g_strdup (element); element = va_arg (args, char *); canonicalize_pathname (tmp_element); len = strlen (tmp_element); start = IS_PATH_SEP (tmp_element[0]) ? tmp_element + 1 : tmp_element; g_string_append (path, start); if (!IS_PATH_SEP (tmp_element[len - 1]) && element != NULL) g_string_append_c (path, PATH_SEP); g_free (tmp_element); } }
void dir_list_load (dir_list * list, const vfs_path_t * vpath, GCompareFunc sort, const dir_sort_options_t * sort_op, const char *fltr) { DIR *dirp; struct dirent *dp; int link_to_dir, stale_link; struct stat st; file_entry_t *fentry; const char *vpath_str; /* ".." (if any) must be the first entry in the list */ if (!dir_list_init (list)) return; fentry = &list->list[0]; if (dir_get_dotdot_stat (vpath, &st)) fentry->st = st; dirp = mc_opendir (vpath); if (dirp == NULL) { message (D_ERROR, MSG_ERROR, _("Cannot read directory contents")); return; } tree_store_start_check (vpath); vpath_str = vfs_path_as_str (vpath); /* Do not add a ".." entry to the root directory */ if (IS_PATH_SEP (vpath_str[0]) && vpath_str[1] == '\0') dir_list_clean (list); while ((dp = mc_readdir (dirp)) != NULL) { if (!handle_dirent (dp, fltr, &st, &link_to_dir, &stale_link)) continue; if (!dir_list_append (list, dp->d_name, &st, link_to_dir != 0, stale_link != 0)) goto ret; if ((list->len & 31) == 0) rotate_dash (TRUE); } dir_list_sort (list, sort, sort_op); ret: mc_closedir (dirp); tree_store_end_check (); rotate_dash (FALSE); }
/* Return: 0: - not modified * 1: - modified */ int directory_form(char *buffer) { int len; len = strlen(buffer); if(len == 0 || buffer[len - 1] == PATH_SEP) return 0; if(IS_PATH_SEP(buffer[len - 1])) len--; buffer[len++] = PATH_SEP; buffer[len] = '\0'; return 1; }
int pathcmp(const char *p1, const char *p2, int ignore_case) { int c1, c2; #ifdef __W32__ ignore_case = 1; /* Always ignore the case */ #endif do { c1 = *p1++ & 0xff; c2 = *p2++ & 0xff; if(ignore_case) { c1 = tolower(c1); c2 = tolower(c2); } if(IS_PATH_SEP(c1)) c1 = *p1 ? 0x100 : 0; if(IS_PATH_SEP(c2)) c2 = *p2 ? 0x100 : 0; } while(c1 == c2 && c1 /* && c2 */); return c1 - c2; }
static void ConcatDirElem( char *dir, const char *elem ) /******************************************************/ { size_t len; len = strlen( dir ); if( len > 0 ) { char c = dir[len - 1]; if( !IS_PATH_SEP( c ) ) { dir[len++] = DIR_SEP; } } strcpy( dir + len, elem ); }
static void ConcatDirSep( char *dir ) /************************************/ { size_t len; len = strlen( dir ); if( len > 0 ) { char c = dir[len - 1]; if( !IS_PATH_SEP( c ) ) { dir[len++] = DIR_SEP; dir[len] = '\0'; } } }
static char *concSep( // CONCATENATE PATH SEPARATOR AS REQUIRED char *pp, // - pointer into buffer char *buffer ) // - buffer { char *pred; // - preceding char in buffer if( pp > buffer ) { pred = pp - 1; if( !IS_PATH_SEP( *pred ) ) { *pp++ = PATH_SEP; } } return pp; }
void mkdir_cmd (void) { char *dir; const char *name = ""; /* If 'on' then automatically fills name with current selected item name */ if (auto_fill_mkdir_name && !DIR_IS_DOTDOT (selection (current_panel)->fname)) name = selection (current_panel)->fname; dir = input_expand_dialog (_("Create a new Directory"), _("Enter directory name:"), MC_HISTORY_FM_MKDIR, name, INPUT_COMPLETE_FILENAMES); if (dir != NULL && *dir != '\0') { vfs_path_t *absdir; if (IS_PATH_SEP (dir[0]) || dir[0] == '~') absdir = vfs_path_from_str (dir); else { /* possible escaped '~' */ /* allow create directory with name '~' */ char *tmpdir = dir; if (dir[0] == '\\' && dir[1] == '~') tmpdir = dir + 1; absdir = vfs_path_append_new (current_panel->cwd_vpath, tmpdir, NULL); } save_cwds_stat (); if (my_mkdir (absdir, 0777) == 0) { update_panels (UP_OPTIMIZE, dir); repaint_screen (); select_item (current_panel); } else { message (D_ERROR, MSG_ERROR, "%s", unix_error_string (errno)); } vfs_path_free (absdir); } g_free (dir); }
static void nice_cd (const char *text, const char *xtext, const char *help, const char *history_name, const char *prefix, int to_home, gboolean strip_password) { char *machine; char *cd_path; if (!SELECTED_IS_PANEL) return; machine = input_dialog_help (text, xtext, help, history_name, INPUT_LAST_TEXT, strip_password, INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_USERNAMES); if (machine == NULL) return; to_home = 0; /* FIXME: how to solve going to home nicely? /~/ is ugly as hell and leads to problems in vfs layer */ if (strncmp (prefix, machine, strlen (prefix)) == 0) cd_path = g_strconcat (machine, to_home ? "/~/" : (char *) NULL, (char *) NULL); else cd_path = g_strconcat (prefix, machine, to_home ? "/~/" : (char *) NULL, (char *) NULL); g_free (machine); if (!IS_PATH_SEP (*cd_path)) { char *tmp = cd_path; cd_path = g_strconcat (PATH_SEP_STR, tmp, (char *) NULL); g_free (tmp); } { vfs_path_t *cd_vpath; cd_vpath = vfs_path_from_str_flags (cd_path, VPF_NO_CANON); if (!do_panel_cd (MENU_PANEL, cd_vpath, cd_parse_command)) message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\""), cd_path); vfs_path_free (cd_vpath); } g_free (cd_path); }
/* Include search order is intended to be compatible with C/C++ compilers * and is as follows: * * 1) For absolute pathnames, try only that pathname and nothing else * * 2) For includes in double quotes only, search current directory * * 3) For includes in double quotes only, search the directory * of including file * * 4) Search include directories specified by IncludePath1 (usually command * line -I argument(s) * * 5) Search include directories specified by IncludePath2 (usualy INCLUDE path) * * 6) Directory 'h' adjacent to current directory (../h) * * Note that some of these steps will be skipped if PPFLAG_IGNORE_CWD and/or * PPFLAG_IGNORE_INCLUDE is set. */ int PP_FindInclude( const char *filename, size_t len, char *fullfilename, int incl_type ) { int rc = -1; char drivebuf[_MAX_DRIVE]; char dirbuf[_MAX_DIR]; memcpy( fullfilename, filename, len ); fullfilename[len] = '\0'; if( HAS_PATH( fullfilename ) ) { rc = access( fullfilename, R_OK ); } else { if( rc == -1 && incl_type != PPINCLUDE_SYS && (PPFlags & PPFLAG_IGNORE_CWD) == 0 ) { rc = access( fullfilename, R_OK ); } if( rc == -1 && incl_type == PPINCLUDE_USR && PP_File != NULL ) { size_t len1; _splitpath( PP_File->filename, drivebuf, dirbuf, NULL, NULL ); _makepath( fullfilename, drivebuf, dirbuf, NULL, NULL ); len1 = strlen( fullfilename ); if( len1 > 0 ) { char c = fullfilename[len1 - 1]; if( !IS_PATH_SEP( c ) ) { fullfilename[len1++] = DIR_SEP; } } memcpy( fullfilename + len1, filename, len ); fullfilename[len1 + len] = '\0'; rc = access( fullfilename, R_OK ); } if( rc == -1 && IncludePath1 != NULL ) { rc = findInclude( IncludePath1, filename, len, fullfilename ); } if( rc == -1 && IncludePath2 != NULL ) { rc = findInclude( IncludePath2, filename, len, fullfilename ); } if( rc == -1 && incl_type == PPINCLUDE_USR && (PPFlags & PPFLAG_IGNORE_DEFDIRS) == 0 ) { memcpy( fullfilename, H_DIR, sizeof( H_DIR ) - 1 ); memcpy( fullfilename + sizeof( H_DIR ) - 1, filename, len ); fullfilename[sizeof( H_DIR ) - 1 + len] = '\0'; rc = access( fullfilename, R_OK ); } } return( rc ); }
extern void RcTmpFileName( char *tmpfilename ) /********************************************/ /* uses the TMP env. var. if it is set and puts the result into tmpfilename */ /* which is assumed to be a buffer of at least _MAX_PATH characters */ { char *nextchar; char *tmpdir; tmpdir = RcGetEnv( "TMP" ); nextchar = tmpfilename; if( tmpdir != NULL && *tmpdir != '\0' ) { GetPathElement( tmpdir, NULL, &nextchar ); if( !IS_PATH_SEP( nextchar[-1] ) ) { *nextchar++ = DIR_SEP; } } tmpnam( nextchar ); }
int SLpath_is_absolute_path (SLFUTURE_CONST char *name) { if (name == NULL) return -1; #ifdef UNIX_PATHNAMES_OK return (*name == '/'); #else if (IS_PATH_SEP (*name)) return 1; /* If it contains a drive specifier, regard it as absolute */ if (name != skip_drive (name)) return 1; return 0; #endif }
/* If file is /a/b/c/basename, this function returns a pointer to basename */ SLFUTURE_CONST char *SLpath_basename (SLFUTURE_CONST char *drivefile) { SLFUTURE_CONST char *b, *file; if (drivefile == NULL) return NULL; file = skip_drive (drivefile); b = file + strlen (file); while (b != file) { b--; if (IS_PATH_SEP(*b)) return b + 1; } return b; }
/* Include search order is intended to be compatible with C/C++ compilers * and is as follows: * * 1) For absolute pathnames, try only that pathname and nothing else * * 2) For includes in double quotes only, search current directory * * 3) For includes in double quotes only, search the directory * of including file * * 4) Search include directories specified by IncludePath1 (usually command * line -I argument(s) * * 5) Search include directories specified by IncludePath2 (usualy INCLUDE path) * * 6) Directory 'h' adjacent to current directory (../h) * * Note that some of these steps will be skipped if PPFLAG_IGNORE_CWD and/or * PPFLAG_IGNORE_INCLUDE is set. */ int PP_FindInclude( const char *filename, char *fullfilename, int incl_type ) { int rc = -1; char drivebuf[ _MAX_DRIVE ]; char dirbuf[ _MAX_DIR ]; if( HAS_PATH( filename ) ) { if( (rc = access( filename, R_OK )) == 0 ) { strcpy( fullfilename, filename ); } } else { if( rc == -1 && incl_type != PPINCLUDE_SYS && (PPFlags & PPFLAG_IGNORE_CWD) == 0 ) { if( (rc = access( filename, R_OK )) == 0 ) { strcpy( fullfilename, filename ); } } if( rc == -1 && incl_type == PPINCLUDE_USR && PP_File != NULL ) { size_t len; _splitpath( PP_File->filename, drivebuf, dirbuf, NULL, NULL ); _makepath( fullfilename, drivebuf, dirbuf, NULL, NULL ); len = strlen( fullfilename ); if( len > 0 ) { char c = fullfilename[len - 1]; if( !IS_PATH_SEP( c ) ) { fullfilename[len++] = c; } } strcpy( fullfilename + len, filename ); rc = access( fullfilename, R_OK ); } if( rc == -1 && IncludePath1 != NULL ) { rc = findInclude( IncludePath1, filename, fullfilename ); } if( rc == -1 && IncludePath2 != NULL ) { rc = findInclude( IncludePath2, filename, fullfilename ); } if( rc == -1 && incl_type == PPINCLUDE_USR && (PPFlags & PPFLAG_IGNORE_DEFDIRS) == 0 ) { sprintf( fullfilename, H_DIR "%s", filename ); rc = access( fullfilename, R_OK ); } } return( rc ); }