void VFS::Mount(const std::string& ps3_path, const std::string& local_path, vfsDevice* device) { std::string simpl_ps3_path = simplify_path(ps3_path, true, true); UnMount(simpl_ps3_path); device->SetPath(simpl_ps3_path, simplify_path(local_path, true, false)); m_devices.push_back(device); if (m_devices.size() > 1) { std::sort(m_devices.begin(), m_devices.end(), [](vfsDevice *a, vfsDevice *b) { return b->GetPs3Path().length() < a->GetPs3Path().length(); }); } }
/* ** note: it modifies it's first argument */ void simplify_path(char **buf) { unsigned int last1slash = 0; unsigned int last2slash = 0; while (!strncmp(*buf, "/../", 4)) memmove(*buf, *buf + 3, strlen(*buf + 3) + 1); for (unsigned int i = 0; i < strlen(*buf) - 2; i++) while (!strncmp(*buf + i, "/./", 3)) memmove(*buf + i, *buf + i + 2, strlen(*buf + i + 2) + 1); for (unsigned int i = 0; i < strlen(*buf) - 3; i++) { if (*(*buf + i) == '/') { last2slash = last1slash; last1slash = i; } if (!strncmp(*buf + i, "/../", 4)) { memmove(*buf + last2slash, *buf + i + 3, strlen(*buf + i + 3) + 1); return simplify_path(buf); } } }
void BackupSystem::create_new_version(const OpaqueTimestamp &start_time){ { auto version = this->versions.back(); ArchiveReader archive(this->get_version_path(version), &this->get_aux_fso_path(version), this->keypair.get()); auto manifest = archive.read_manifest(); this->old_objects = this->get_old_objects(archive, version); this->next_stream_id = manifest->next_stream_id; this->next_differential_chain_id = manifest->next_differential_chain_id; } this->set_old_objects_map(); this->set_base_objects(); for (auto &base_object : this->base_objects){ for (auto &fso : base_object->get_iterator()){ auto search_path = simplify_path(fso->get_mapped_path().wstring()); auto it = this->old_objects_map.find(search_path); FileSystemObject *found = nullptr; if (it == this->old_objects_map.end()){ for (auto &fso2 : this->old_objects){ if (!fso2->get_is_encrypted()) continue; found = fso2->find(search_path); if (found) break; } }else found = it->second; if (!found) continue; fso->set_stream_id(found->get_stream_id()); break; } } this->generate_archive(start_time, &BackupSystem::check_and_maybe_add, this->get_new_version_number()); }
vfsDevice* VFS::GetDevice(const std::string& ps3_path, std::string& path) const { auto try_get_device = [this, &path](const std::string& ps3_path) -> vfsDevice* { std::vector<std::string> ps3_path_blocks = simplify_path_blocks(ps3_path); size_t max_eq = 0; int max_i = -1; for (u32 i = 0; i < m_devices.size(); ++i) { std::vector<std::string> dev_ps3_path_blocks = simplify_path_blocks(m_devices[i]->GetPs3Path()); if (ps3_path_blocks.size() < dev_ps3_path_blocks.size()) continue; size_t eq = 0; for (; eq < dev_ps3_path_blocks.size(); ++eq) { if (strcmp(ps3_path_blocks[eq].c_str(), dev_ps3_path_blocks[eq].c_str())) { break; } } if (eq > max_eq) { max_eq = eq; max_i = i; } } if (max_i < 0) return nullptr; path = m_devices[max_i]->GetLocalPath(); for (size_t i = max_eq; i < ps3_path_blocks.size(); i++) { path += "/" + ps3_path_blocks[i]; } path = simplify_path(path, false, false); return m_devices[max_i]; }; if (!ps3_path.size() || ps3_path[0] != '/') { return nullptr; } return try_get_device(GetLinked(ps3_path)); // What is it? cwd is real path, ps3_path is ps3 path, but GetLinked accepts ps3 path //if (auto res = try_get_device(GetLinked(cwd + ps3_path))) // return res; }
void BackupSystem::set_old_objects_map(){ this->old_objects_map.clear(); for (auto &old_object : this->old_objects){ if (old_object->get_is_encrypted()) continue; for (auto &fso : old_object->get_iterator()) this->old_objects_map[simplify_path(fso->get_mapped_path().wstring())] = fso; } }
void __TIMM_OSAL_TraceFunction(const __TIMM_OSAL_TRACE_LOCATION * loc, const char *fmt, ...) { if (trace_level == -1) { char *val = getenv("TIMM_OSAL_DEBUG_TRACE_LEVEL"); trace_level = val ? strtol(val, NULL, 0) : DEFAULT_TRACE_LEVEL; } if (trace_level >= loc->level) { va_list ap; va_start(ap, fmt); /* make ap point to first arg after 'fmt' */ #ifdef _Android #if ( TIMM_OSAL_DEBUG_TRACE_DETAIL > 1 ) LOGD("%s:%d\t%s()\t", simplify_path(loc->file), loc->line, loc->function); #endif char string[1000]; vsprintf(string, fmt, ap); LOGD("%s",string); #else #if ( TIMM_OSAL_DEBUG_TRACE_DETAIL > 1 ) printf("%s:%d\t%s()\t", simplify_path(loc->file), loc->line, loc->function); #endif vprintf(fmt, ap); #endif va_end(ap); } }
/** \fn ADM_PathCanonize \brief Canonize the path, returns a copy of the absolute path given as parameter */ char *ADM_PathCanonize(const char *tmpname) { char path[300]; char *out; if (!getcwd(path, 300)) { fprintf(stderr, "\ngetcwd() failed with: %s (%u)\n", strerror(errno), errno); path[0] = '\0'; } if (!tmpname || tmpname[0] == 0) { out = new char[strlen(path) + 2]; strcpy(out, path); #ifndef __WIN32 strcat(out, "/"); #else strcat(out, "\\"); #endif printf("\n Canonizing null string ??? (%s)\n", out); } else if (tmpname[0] == '/' #if defined(__WIN32) || tmpname[1] == ':' #endif ) { out = new char[strlen(tmpname) + 1]; strcpy(out, tmpname); return out; } else { out = new char[strlen(path) + strlen(tmpname) + 6]; strcpy(out, path); #ifndef __WIN32 strcat(out, "/"); #else strcat(out, "\\"); #endif strcat(out, tmpname); } simplify_path(&out); return out; }
void VFS::UnMount(const std::string& ps3_path) { std::string simpl_ps3_path = simplify_path(ps3_path, true, true); for (u32 i = 0; i < m_devices.size(); ++i) { if (!strcmp(m_devices[i]->GetPs3Path().c_str(), simpl_ps3_path.c_str())) { delete m_devices[i]; m_devices.erase(m_devices.begin() +i); return; } } }
bool vfsDir::Open(const std::string& path) { Close(); m_stream.reset(Emu.GetVFS().OpenDir(path)); DirEntryInfo info; m_cwd = simplify_path(Emu.GetVFS().GetLinked(0 && m_stream && m_stream->IsOpened() ? m_stream->GetPath() : path), true, true); auto blocks = simplify_path_blocks(GetPath()); for (auto dev : Emu.GetVFS().m_devices) { auto dev_blocks = simplify_path_blocks(dev->GetPs3Path()); if (dev_blocks.size() < (blocks.size() + 1)) { continue; } bool is_ok = true; for (size_t i = 0; i < blocks.size(); ++i) { if (strcmp(dev_blocks[i].c_str(), blocks[i].c_str())) { is_ok = false; break; } } if (is_ok) { info.name = dev_blocks[blocks.size()]; m_entries.push_back(info); } } if (m_stream && m_stream->IsOpened()) { m_entries.insert(m_entries.begin(), m_stream->GetEntries().begin(), m_stream->GetEntries().end()); } return !m_entries.empty(); }
char * single_path_relocation(const char *from, const char *to) { #if defined(__MINGW32__) char exe_path[PATH_MAX]; get_executable_path (NULL, &exe_path[0], sizeof(exe_path)/sizeof(exe_path[0])); if (strrchr (exe_path, '/') != NULL) { strrchr (exe_path, '/')[1] = '\0'; } char * rel_to_datadir = get_relative_path (from, to); strcat (exe_path, rel_to_datadir); simplify_path (&exe_path[0]); return malloc_copy_string(exe_path); #else return malloc_copy_string(to); #endif }
vfsDevice* VFS::GetDeviceLocal(const std::string& local_path, std::string& path) const { int max_eq = -1; int max_i = -1; std::vector<std::string> local_path_blocks = simplify_path_blocks(local_path); for (u32 i = 0; i < m_devices.size(); ++i) { std::vector<std::string> dev_local_path_blocks = simplify_path_blocks(m_devices[i]->GetLocalPath()); if (local_path_blocks.size() < dev_local_path_blocks.size()) continue; int dev_blocks = dev_local_path_blocks.size(); bool prefix_equal = std::equal( std::begin(dev_local_path_blocks), std::end(dev_local_path_blocks), std::begin(local_path_blocks), [](const std::string& a, const std::string& b){ return strcmp(a.c_str(), b.c_str()) == 0; } ); if (prefix_equal && dev_blocks > max_eq) { max_eq = dev_blocks; max_i = i; } } if (max_i < 0) return nullptr; path = m_devices[max_i]->GetPs3Path(); for (size_t i = max_eq; i < local_path_blocks.size(); i++) { path += "/" + local_path_blocks[i]; } path = simplify_path(path, false, true); return m_devices[max_i]; }
void VFS::Init(const std::string& path) { cwd = simplify_path(path, true, false); UnMountAll(); std::vector<VFSManagerEntry> entries; SaveLoadDevices(entries, true); for(const VFSManagerEntry& entry : entries) { vfsDevice* dev; switch(entry.device) { case vfsDevice_LocalFile: dev = new vfsDeviceLocalFile(); break; case vfsDevice_HDD: dev = new vfsDeviceHDD(entry.device_path); break; default: continue; } std::string mpath = entry.path; // TODO: This shouldn't use current dir // If no value assigned to SysEmulationDirPath in INI, use the path that with executable. if (rpcs3::config.system.emulation_dir_path_enable.value()) { fmt::Replace(mpath, "$(EmulatorDir)", rpcs3::config.system.emulation_dir_path.value()); } else { fmt::Replace(mpath, "$(EmulatorDir)", Emu.GetEmulatorPath()); } fmt::Replace(mpath, "$(GameDir)", cwd); Mount(entry.mount, mpath, dev); } Link("/app_home/", "/host_root/" + cwd); }
int main(void) { int rv; char *cp, cdpath[256], pwd[256], file[256], result[256]; printf("enter CDPATH: "); gets(cdpath); printf("enter PWD: "); gets(pwd); while (1) { if (printf("Enter file: "), gets(file) == 0) return (0); cp = cdpath; do { rv = make_path(pwd, file, &cp, result, sizeof(result)); printf("make_path returns (%d), \"%s\" ", rv, result); simplify_path(result); printf("(simpifies to \"%s\")\n", result); } while (cp); } }
void simplify_path_debug (const char * input, const char * expected) { char * input_copy = malloc_copy_string (input); if ( input_copy == NULL ) { _exit(1); } simplify_path (input_copy); int ok = (strcmp(input_copy, expected) == 0) ? 1 : 0; if (ok) { printf ("PASS: %s simplifies to %s\n", input, input_copy); } else { printf ("FAIL: %s simplifies to %s, should be %s\n", input, input_copy, expected); _exit(1); } free ((void *)input_copy); }
int c_cd(const char **wp) { int optc, rv, phys_path; bool physical = tobool(Flag(FPHYSICAL)); /* was a node from cdpath added in? */ int cdnode; /* show where we went?, error for $PWD */ bool printpath = false, eflag = false; struct tbl *pwd_s, *oldpwd_s; XString xs; char *dir, *allocd = NULL, *tryp, *pwd, *cdpath; while ((optc = ksh_getopt(wp, &builtin_opt, "eLP")) != -1) switch (optc) { case 'e': eflag = true; break; case 'L': physical = false; break; case 'P': physical = true; break; case '?': return (2); } wp += builtin_opt.optind; if (Flag(FRESTRICTED)) { bi_errorf("restricted shell - can't cd"); return (2); } pwd_s = global("PWD"); oldpwd_s = global("OLDPWD"); if (!wp[0]) { /* No arguments - go home */ if ((dir = str_val(global("HOME"))) == null) { bi_errorf("no home directory (HOME not set)"); return (2); } } else if (!wp[1]) { /* One argument: - or dir */ strdupx(allocd, wp[0], ATEMP); if (ksh_isdash((dir = allocd))) { afree(allocd, ATEMP); allocd = NULL; dir = str_val(oldpwd_s); if (dir == null) { bi_errorf("no OLDPWD"); return (2); } printpath = true; } } else if (!wp[2]) { /* Two arguments - substitute arg1 in PWD for arg2 */ size_t ilen, olen, nlen, elen; char *cp; if (!current_wd[0]) { bi_errorf("can't determine current directory"); return (2); } /* * substitute arg1 for arg2 in current path. * if the first substitution fails because the cd fails * we could try to find another substitution. For now * we don't */ if ((cp = strstr(current_wd, wp[0])) == NULL) { bi_errorf("bad substitution"); return (2); } /*- * ilen = part of current_wd before wp[0] * elen = part of current_wd after wp[0] * because current_wd and wp[1] need to be in memory at the * same time beforehand the addition can stay unchecked */ ilen = cp - current_wd; olen = strlen(wp[0]); nlen = strlen(wp[1]); elen = strlen(current_wd + ilen + olen) + 1; dir = allocd = alloc(ilen + nlen + elen, ATEMP); memcpy(dir, current_wd, ilen); memcpy(dir + ilen, wp[1], nlen); memcpy(dir + ilen + nlen, current_wd + ilen + olen, elen); printpath = true; } else { bi_errorf("too many arguments"); return (2); } #ifdef MKSH__NO_PATH_MAX /* only a first guess; make_path will enlarge xs if necessary */ XinitN(xs, 1024, ATEMP); #else XinitN(xs, PATH_MAX, ATEMP); #endif cdpath = str_val(global("CDPATH")); do { cdnode = make_path(current_wd, dir, &cdpath, &xs, &phys_path); if (physical) rv = chdir(tryp = Xstring(xs, xp) + phys_path); else { simplify_path(Xstring(xs, xp)); rv = chdir(tryp = Xstring(xs, xp)); } } while (rv < 0 && cdpath != NULL); if (rv < 0) { if (cdnode) bi_errorf("%s: %s", dir, "bad directory"); else bi_errorf("%s: %s", tryp, cstrerror(errno)); afree(allocd, ATEMP); Xfree(xs, xp); return (2); } rv = 0; /* allocd (above) => dir, which is no longer used */ afree(allocd, ATEMP); allocd = NULL; /* Clear out tracked aliases with relative paths */ flushcom(false); /* * Set OLDPWD (note: unsetting OLDPWD does not disable this * setting in AT&T ksh) */ if (current_wd[0]) /* Ignore failure (happens if readonly or integer) */ setstr(oldpwd_s, current_wd, KSH_RETURN_ERROR); if (!mksh_abspath(Xstring(xs, xp))) { pwd = NULL; } else if (!physical) { goto norealpath_PWD; } else if ((pwd = allocd = do_realpath(Xstring(xs, xp))) == NULL) { if (eflag) rv = 1; norealpath_PWD: pwd = Xstring(xs, xp); } /* Set PWD */ if (pwd) { char *ptmp = pwd; set_current_wd(ptmp); /* Ignore failure (happens if readonly or integer) */ setstr(pwd_s, ptmp, KSH_RETURN_ERROR); } else { set_current_wd(null); pwd = Xstring(xs, xp); /* XXX unset $PWD? */ if (eflag) rv = 1; } if (printpath || cdnode) shprintf("%s\n", pwd); afree(allocd, ATEMP); Xfree(xs, xp); return (rv); }
extern int mount_main(int argc, char **argv) { struct stat statbuf; char *string_flags = xstrdup(""); char *extra_opts; int flags = 0; char *filesystemType = "auto"; int got_filesystemType = 0; char *device = xmalloc(PATH_MAX); char *directory = xmalloc(PATH_MAX); struct mntent *m = NULL; int all = FALSE; int fakeIt = FALSE; int useMtab = TRUE; int rc = EXIT_FAILURE; FILE *f = 0; int opt; /* Parse options */ while ((opt = getopt(argc, argv, "o:rt:wafnv")) > 0) { switch (opt) { case 'o': parse_mount_options(optarg, &flags, &string_flags); break; case 'r': flags |= MS_RDONLY; break; case 't': filesystemType = optarg; got_filesystemType = 1; break; case 'w': flags &= ~MS_RDONLY; break; case 'a': all = TRUE; break; case 'f': fakeIt = TRUE; break; #ifdef BB_FEATURE_MTAB_SUPPORT case 'n': useMtab = FALSE; break; #endif case 'v': break; /* ignore -v */ } } if (!all && optind == argc) show_mounts(got_filesystemType ? filesystemType : 0); if (optind < argc) { /* if device is a filename get its real path */ if (stat(argv[optind], &statbuf) == 0) { char *tmp = simplify_path(argv[optind]); safe_strncpy(device, tmp, PATH_MAX); } else { safe_strncpy(device, argv[optind], PATH_MAX); } } if (optind + 1 < argc) directory = simplify_path(argv[optind + 1]); if (all || optind + 1 == argc) { f = setmntent("/etc/fstab", "r"); if (f == NULL) perror_msg_and_die( "\nCannot read /etc/fstab"); while ((m = getmntent(f)) != NULL) { if (! all && optind + 1 == argc && ( (strcmp(device, m->mnt_fsname) != 0) && (strcmp(device, m->mnt_dir) != 0) ) ) { continue; } if (all && ( // If we're mounting 'all' (strstr(m->mnt_opts, "noauto")) || // and the file system isn't noauto, (strstr(m->mnt_type, "swap")) || // and isn't swap or nfs, then mount it (strstr(m->mnt_type, "nfs")) ) ) { continue; } if (all || flags == 0) { // Allow single mount to override fstab flags flags = 0; string_flags[0] = 0; parse_mount_options(m->mnt_opts, &flags, &string_flags); } strcpy(device, m->mnt_fsname); strcpy(directory, m->mnt_dir); filesystemType = xstrdup(m->mnt_type); singlemount: extra_opts = string_flags; rc = EXIT_SUCCESS; #ifdef BB_NFSMOUNT if (strchr(device, ':') != NULL) { filesystemType = "nfs"; if (nfsmount (device, directory, &flags, &extra_opts, &string_flags, 1)) { perror_msg("nfsmount failed"); rc = EXIT_FAILURE; } } #endif if (!mount_one(device, directory, filesystemType, flags, string_flags, useMtab, fakeIt, extra_opts, TRUE, all)) rc = EXIT_FAILURE; if (! all) break; } if (f) endmntent(f); if (! all && f && m == NULL) fprintf(stderr, "Can't find %s in /etc/fstab\n", device); return rc; } goto singlemount; }
// This function is called once, from main.c. void maze_solve() { // Loop until we have solved the maze. while(1) { // FIRST MAIN LOOP BODY follow_segment(); // Drive straight a bit. This helps us in case we entered the // intersection at an angle. // Note that we are slowing down - this prevents the robot // from tipping forward too much. set_motors(50,50); delay_ms(50); // These variables record whether the robot has seen a line to the // left, straight ahead, and right, whil examining the current // intersection. unsigned char found_left=0; unsigned char found_straight=0; unsigned char found_right=0; // Now read the sensors and check the intersection type. unsigned int sensors[5]; read_line(sensors,IR_EMITTERS_ON); // Check for left and right exits. if(sensors[0] > 100) found_left = 1; if(sensors[4] > 100) found_right = 1; // Drive straight a bit more - this is enough to line up our // wheels with the intersection. set_motors(40,40); delay_ms(200); // Check for a straight exit. read_line(sensors,IR_EMITTERS_ON); if(sensors[1] > 200 || sensors[2] > 200 || sensors[3] > 200) found_straight = 1; // Check for the ending spot. // If all three middle sensors are on dark black, we have // solved the maze. if(sensors[1] > 600 && sensors[2] > 600 && sensors[3] > 600) break; // Intersection identification is complete. // If the maze has been solved, we can follow the existing // path. Otherwise, we need to learn the solution. unsigned char dir = select_turn(found_left, found_straight, found_right); // Make the turn indicated by the path. turn(dir); // Store the intersection in the path variable. path[path_length] = dir; path_length ++; // You should check to make sure that the path_length does not // exceed the bounds of the array. We'll ignore that in this // example. // Simplify the learned path. simplify_path(); // Display the path on the LCD. display_path(); } // Solved the maze! // Now enter an infinite loop - we can re-run the maze as many // times as we want to. while(1) { // Beep to show that we finished the maze. set_motors(0,0); play(">>a32"); // Wait for the user to press a button, while displaying // the solution. while(!button_is_pressed(BUTTON_B)) { if(get_ms() % 2000 < 1000) { clear(); print("Solved!"); lcd_goto_xy(0,1); print("Press B"); } else display_path(); delay_ms(30); } while(button_is_pressed(BUTTON_B)); delay_ms(1000); // Re-run the maze. It's not necessary to identify the // intersections, so this loop is really simple. int i; for(i=0;i<path_length;i++) { // SECOND MAIN LOOP BODY follow_segment(); // Drive straight while slowing down, as before. set_motors(50,50); delay_ms(50); set_motors(40,40); delay_ms(200); // Make a turn according to the instruction stored in // path[i]. turn(path[i]); } // Follow the last segment up to the finish. follow_segment(); // Now we should be at the finish! Restart the loop. } }
char * get_relocated_path_list(char const * from, char const * to_path_list) { char exe_path[MAX_PATH]; char * temp; get_executable_path (NULL, &exe_path[0], sizeof (exe_path) / sizeof (exe_path[0])); if ((temp = strrchr (exe_path, '/')) != NULL) { temp[1] = '\0'; } char **arr = NULL; /* Ask Alexey why he added this. Are we not 100% sure that we're dealing with unix paths here? */ char split_char = ':'; if (strchr (to_path_list, ';')) { split_char = ';'; } size_t count = split_path_list (to_path_list, split_char, &arr); int result_size = 1 + (count - 1); /* count - 1 is for ; delim. */ size_t exe_path_size = strlen (exe_path); size_t i; /* Space required is: count * (exe_path_size + strlen (rel_to_datadir)) rel_to_datadir upper bound is: (count * strlen (from)) + (3 * num_slashes (from)) + strlen(arr[i]) + 1. .. pathalogically num_slashes (from) is strlen (from) (from = ////////) */ size_t space_required = (count * (exe_path_size + 4 * strlen (from))) + count - 1; for (i = 0; i < count; ++i) { space_required += strlen (arr[i]); } char * scratch = (char *) alloca (space_required); if (scratch == NULL) return NULL; for (i = 0; i < count; ++i) { char * rel_to_datadir = get_relative_path (from, arr[i]); scratch[0] = '\0'; arr[i] = scratch; strcat (scratch, exe_path); strcat (scratch, rel_to_datadir); simplify_path (arr[i]); size_t arr_i_size = strlen (arr[i]); result_size += arr_i_size; scratch = arr[i] + arr_i_size + 1; } char * result = (char *) malloc (result_size); if (result == NULL) { return NULL; } result[0] = '\0'; for (i = 0; i < count; ++i) { strcat (result, arr[i]); if (i != count-1) { #if defined(_WIN32) strcat (result, ";"); #else strcat (result, ":"); #endif } } free ((void*)arr); return result; }
char * get_relative_path(char const * from_in, char const * to_in) { size_t from_size = (from_in == NULL) ? 0 : strlen (from_in); size_t to_size = (to_in == NULL) ? 0 : strlen (to_in); size_t max_size = (from_size + to_size) * 2 + 4; char * scratch_space = (char *) alloca (from_size + 1 + to_size + 1 + max_size + max_size); char * from; char * to; char * common_part; char * result; size_t count; /* No to, return "./" */ if (to_in == NULL) { return malloc_copy_string ("./"); } /* If alloca failed or no from was given return a copy of to */ if ( from_in == NULL || scratch_space == NULL ) { return malloc_copy_string (to_in); } from = scratch_space; strcpy (from, from_in); to = from + from_size + 1; strcpy (to, to_in); common_part = to + to_size + 1; result = common_part + max_size; simplify_path (from); simplify_path (to); result[0] = '\0'; size_t match_size_dirsep = 0; /* The match size up to the last /. Always wind back to this - 1 */ size_t match_size = 0; /* The running (and final) match size. */ size_t largest_size = (from_size > to_size) ? from_size : to_size; int to_final_is_slash = (to[to_size-1] == '/') ? 1 : 0; char from_c; char to_c; for (match_size = 0; match_size < largest_size; ++match_size) { /* To simplify the logic, always pretend the strings end with '/' */ from_c = (match_size < from_size) ? from[match_size] : '/'; to_c = (match_size < to_size) ? to[match_size] : '/'; if (from_c != to_c) { if (from_c != '\0' || to_c != '\0') { match_size = match_size_dirsep; } break; } else if (from_c == '/') { match_size_dirsep = match_size; } } strncpy (common_part, from, match_size); common_part[match_size] = '\0'; from += match_size; to += match_size; size_t ndotdots = 0; char const* from_last = from + strlen(from) - 1; while ((from = strchr (from, '/')) && from != from_last) { ++ndotdots; ++from; } for (count = 0; count < ndotdots; ++count) { strcat(result, "../"); } if (strlen(to) > 0) { strcat(result, to+1); } /* Make sure that if to ends with '/' result does the same, and vice-versa. */ size_t size_result = strlen(result); if ((to_final_is_slash == 1) && (!size_result || result[size_result-1] != '/')) { strcat (result, "/"); } else if (!to_final_is_slash && size_result && result[size_result-1] == '/') { result[size_result-1] = '\0'; } return malloc_copy_string (result); }
static int main_init(int argc, const char *argv[], Source **sp, struct block **lp) { int argi, i; Source *s = NULL; struct block *l; unsigned char restricted_shell, errexit, utf_flag; char *cp; const char *ccp, **wp; struct tbl *vp; struct stat s_stdin; #if !defined(_PATH_DEFPATH) && defined(_CS_PATH) ssize_t k; #endif #if defined(MKSH_EBCDIC) || defined(MKSH_FAUX_EBCDIC) ebcdic_init(); #endif set_ifs(TC_IFSWS); #ifdef __OS2__ os2_init(&argc, &argv); #endif /* do things like getpgrp() et al. */ chvt_reinit(); /* make sure argv[] is sane, for weird OSes */ if (!*argv) { argv = empty_argv; argc = 1; } kshname = argv[0]; /* initialise permanent Area */ ainit(&aperm); /* max. name length: -2147483648 = 11 (+ NUL) */ vtemp = alloc(offsetof(struct tbl, name[0]) + 12, APERM); /* set up base environment */ env.type = E_NONE; ainit(&env.area); /* set up global l->vars and l->funs */ newblock(); /* Do this first so output routines (eg, errorf, shellf) can work */ initio(); /* determine the basename (without '-' or path) of the executable */ ccp = kshname; goto begin_parsing_kshname; while ((i = ccp[argi++])) { if (mksh_cdirsep(i)) { ccp += argi; begin_parsing_kshname: argi = 0; if (*ccp == '-') ++ccp; } } if (!*ccp) ccp = empty_argv[0]; /* * Turn on nohup by default. (AT&T ksh does not have a nohup * option - it always sends the hup). */ Flag(FNOHUP) = 1; /* * Turn on brace expansion by default. AT&T kshs that have * alternation always have it on. */ Flag(FBRACEEXPAND) = 1; /* * Turn on "set -x" inheritance by default. */ Flag(FXTRACEREC) = 1; /* define built-in commands and see if we were called as one */ ktinit(APERM, &builtins, /* currently up to 54 builtins: 75% of 128 = 2^7 */ 7); for (i = 0; mkshbuiltins[i].name != NULL; i++) if (!strcmp(ccp, builtin(mkshbuiltins[i].name, mkshbuiltins[i].func))) Flag(FAS_BUILTIN) = 1; if (!Flag(FAS_BUILTIN)) { /* check for -T option early */ argi = parse_args(argv, OF_FIRSTTIME, NULL); if (argi < 0) return (1); #if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED) /* are we called as -sh or /bin/sh or so? */ if (!strcmp(ccp, "sh" MKSH_EXE_EXT)) { /* either also turns off braceexpand */ #ifdef MKSH_BINSHPOSIX /* enable better POSIX conformance */ change_flag(FPOSIX, OF_FIRSTTIME, true); #endif #ifdef MKSH_BINSHREDUCED /* enable kludge/compat mode */ change_flag(FSH, OF_FIRSTTIME, true); #endif } #endif } initvar(); inittraps(); coproc_init(); /* set up variable and command dictionaries */ ktinit(APERM, &taliases, 0); ktinit(APERM, &aliases, 0); #ifndef MKSH_NOPWNAM ktinit(APERM, &homedirs, 0); #endif /* define shell keywords */ initkeywords(); init_histvec(); /* initialise tty size before importing environment */ change_winsz(); #ifdef _PATH_DEFPATH def_path = _PATH_DEFPATH; #else #ifdef _CS_PATH if ((k = confstr(_CS_PATH, NULL, 0)) > 0 && confstr(_CS_PATH, cp = alloc(k + 1, APERM), k + 1) == k + 1) def_path = cp; else #endif /* * this is uniform across all OSes unless it * breaks somewhere hard; don't try to optimise, * e.g. add stuff for Interix or remove /usr * for HURD, because e.g. Debian GNU/HURD is * "keeping a regular /usr"; this is supposed * to be a sane 'basic' default PATH */ def_path = MKSH_UNIXROOT "/bin" MKSH_PATHSEPS MKSH_UNIXROOT "/usr/bin" MKSH_PATHSEPS MKSH_UNIXROOT "/sbin" MKSH_PATHSEPS MKSH_UNIXROOT "/usr/sbin"; #endif /* * Set PATH to def_path (will set the path global variable). * (import of environment below will probably change this setting). */ vp = global(TPATH); /* setstr can't fail here */ setstr(vp, def_path, KSH_RETURN_ERROR); #ifndef MKSH_NO_CMDLINE_EDITING /* * Set edit mode to emacs by default, may be overridden * by the environment or the user. Also, we want tab completion * on in vi by default. */ change_flag(FEMACS, OF_SPECIAL, true); #if !MKSH_S_NOVI Flag(FVITABCOMPLETE) = 1; #endif #endif /* import environment */ init_environ(); /* override default PATH regardless of environment */ #ifdef MKSH_DEFPATH_OVERRIDE vp = global(TPATH); setstr(vp, MKSH_DEFPATH_OVERRIDE, KSH_RETURN_ERROR); #endif /* for security */ typeset(TinitIFS, 0, 0, 0, 0); /* assign default shell variable values */ typeset("PATHSEP=" MKSH_PATHSEPS, 0, 0, 0, 0); substitute(initsubs, 0); /* Figure out the current working directory and set $PWD */ vp = global(TPWD); cp = str_val(vp); /* Try to use existing $PWD if it is valid */ set_current_wd((mksh_abspath(cp) && test_eval(NULL, TO_FILEQ, cp, Tdot, true)) ? cp : NULL); if (current_wd[0]) simplify_path(current_wd); /* Only set pwd if we know where we are or if it had a bogus value */ if (current_wd[0] || *cp) /* setstr can't fail here */ setstr(vp, current_wd, KSH_RETURN_ERROR); for (wp = initcoms; *wp != NULL; wp++) { c_builtin(wp); while (*wp != NULL) wp++; } setint_n(global("OPTIND"), 1, 10); kshuid = getuid(); kshgid = getgid(); kshegid = getegid(); safe_prompt = ksheuid ? "$ " : "# "; vp = global("PS1"); /* Set PS1 if unset or we are root and prompt doesn't contain a # */ if (!(vp->flag & ISSET) || (!ksheuid && !strchr(str_val(vp), '#'))) /* setstr can't fail here */ setstr(vp, safe_prompt, KSH_RETURN_ERROR); setint_n((vp = global("BASHPID")), 0, 10); vp->flag |= INT_U; setint_n((vp = global("PGRP")), (mksh_uari_t)kshpgrp, 10); vp->flag |= INT_U; setint_n((vp = global("PPID")), (mksh_uari_t)kshppid, 10); vp->flag |= INT_U; setint_n((vp = global("USER_ID")), (mksh_uari_t)ksheuid, 10); vp->flag |= INT_U; setint_n((vp = global("KSHUID")), (mksh_uari_t)kshuid, 10); vp->flag |= INT_U; setint_n((vp = global("KSHEGID")), (mksh_uari_t)kshegid, 10); vp->flag |= INT_U; setint_n((vp = global("KSHGID")), (mksh_uari_t)kshgid, 10); vp->flag |= INT_U; setint_n((vp = global("RANDOM")), rndsetup(), 10); vp->flag |= INT_U; setint_n((vp_pipest = global("PIPESTATUS")), 0, 10); /* Set this before parsing arguments */ Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0; /* this to note if monitor is set on command line (see below) */ #ifndef MKSH_UNEMPLOYED Flag(FMONITOR) = 127; #endif /* this to note if utf-8 mode is set on command line (see below) */ UTFMODE = 2; if (!Flag(FAS_BUILTIN)) { argi = parse_args(argv, OF_CMDLINE, NULL); if (argi < 0) return (1); } /* process this later only, default to off (hysterical raisins) */ utf_flag = UTFMODE; UTFMODE = 0; if (Flag(FAS_BUILTIN)) { /* auto-detect from environment variables, always */ utf_flag = 3; } else if (Flag(FCOMMAND)) { s = pushs(SSTRINGCMDLINE, ATEMP); if (!(s->start = s->str = argv[argi++])) errorf(Tf_optfoo, "", "", 'c', Treq_arg); while (*s->str) { if (ctype(*s->str, C_QUOTE)) break; s->str++; } if (!*s->str) s->flags |= SF_MAYEXEC; s->str = s->start; #ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT /* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */ if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--")) ++argi; #endif if (argv[argi]) kshname = argv[argi++]; } else if (argi < argc && !Flag(FSTDIN)) { s = pushs(SFILE, ATEMP); #ifdef __OS2__ /* * A bug in OS/2 extproc (like shebang) handling makes * it not pass the full pathname of a script, so we need * to search for it. This changes the behaviour of a * simple "mksh foo", but can't be helped. */ s->file = argv[argi++]; if (search_access(s->file, X_OK) != 0) s->file = search_path(s->file, path, X_OK, NULL); if (!s->file || !*s->file) s->file = argv[argi - 1]; #else s->file = argv[argi++]; #endif s->u.shf = shf_open(s->file, O_RDONLY, 0, SHF_MAPHI | SHF_CLEXEC); if (s->u.shf == NULL) { shl_stdout_ok = false; warningf(true, Tf_sD_s, s->file, cstrerror(errno)); /* mandated by SUSv4 */ exstat = 127; unwind(LERROR); } kshname = s->file; } else { Flag(FSTDIN) = 1; s = pushs(SSTDIN, ATEMP); s->file = "<stdin>"; s->u.shf = shf_fdopen(0, SHF_RD | can_seek(0), NULL); if (isatty(0) && isatty(2)) { Flag(FTALKING) = Flag(FTALKING_I) = 1; /* The following only if isatty(0) */ s->flags |= SF_TTY; s->u.shf->flags |= SHF_INTERRUPT; s->file = NULL; } } /* this bizarreness is mandated by POSIX */ if (fstat(0, &s_stdin) >= 0 && S_ISCHR(s_stdin.st_mode) && Flag(FTALKING)) reset_nonblock(0); /* initialise job control */ j_init(); /* do this after j_init() which calls tty_init_state() */ if (Flag(FTALKING)) { if (utf_flag == 2) { #ifndef MKSH_ASSUME_UTF8 /* auto-detect from locale or environment */ utf_flag = 4; #else /* this may not be an #elif */ #if MKSH_ASSUME_UTF8 utf_flag = 1; #else /* always disable UTF-8 (for interactive) */ utf_flag = 0; #endif #endif } #ifndef MKSH_NO_CMDLINE_EDITING x_init(); #endif } #ifdef SIGWINCH sigtraps[SIGWINCH].flags |= TF_SHELL_USES; setsig(&sigtraps[SIGWINCH], x_sigwinch, SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP); #endif l = e->loc; if (Flag(FAS_BUILTIN)) { l->argc = argc; l->argv = argv; l->argv[0] = ccp; } else { l->argc = argc - argi; /* * allocate a new array because otherwise, when we modify * it in-place, ps(1) output changes; the meaning of argc * here is slightly different as it excludes kshname, and * we add a trailing NULL sentinel as well */ l->argv = alloc2(l->argc + 2, sizeof(void *), APERM); l->argv[0] = kshname; memcpy(&l->argv[1], &argv[argi], l->argc * sizeof(void *)); l->argv[l->argc + 1] = NULL; getopts_reset(1); } /* divine the initial state of the utf8-mode Flag */ ccp = null; switch (utf_flag) { /* auto-detect from locale or environment */ case 4: #if HAVE_SETLOCALE_CTYPE ccp = setlocale(LC_CTYPE, ""); #if HAVE_LANGINFO_CODESET if (!isuc(ccp)) ccp = nl_langinfo(CODESET); #endif if (!isuc(ccp)) ccp = null; #endif /* FALLTHROUGH */ /* auto-detect from environment */ case 3: /* these were imported from environ earlier */ if (ccp == null) ccp = str_val(global("LC_ALL")); if (ccp == null) ccp = str_val(global("LC_CTYPE")); if (ccp == null) ccp = str_val(global("LANG")); UTFMODE = isuc(ccp); break; /* not set on command line, not FTALKING */ case 2: /* unknown values */ default: utf_flag = 0; /* FALLTHROUGH */ /* known values */ case 1: case 0: UTFMODE = utf_flag; break; } /* Disable during .profile/ENV reading */ restricted_shell = Flag(FRESTRICTED); Flag(FRESTRICTED) = 0; errexit = Flag(FERREXIT); Flag(FERREXIT) = 0; /* * Do this before profile/$ENV so that if it causes problems in them, * user will know why things broke. */ if (!current_wd[0] && Flag(FTALKING)) warningf(false, "can't determine current directory"); if (Flag(FLOGIN)) include(MKSH_SYSTEM_PROFILE, 0, NULL, true); if (!Flag(FPRIVILEGED)) { if (Flag(FLOGIN)) include(substitute("$HOME/.profile", 0), 0, NULL, true); if (Flag(FTALKING)) { cp = substitute("${ENV:-" MKSHRC_PATH "}", DOTILDE); if (cp[0] != '\0') include(cp, 0, NULL, true); } } else { include(MKSH_SUID_PROFILE, 0, NULL, true); /* turn off -p if not set explicitly */ if (Flag(FPRIVILEGED) != 1) change_flag(FPRIVILEGED, OF_INTERNAL, false); } if (restricted_shell) { c_builtin(restr_com); /* After typeset command... */ Flag(FRESTRICTED) = 1; } Flag(FERREXIT) = errexit; if (Flag(FTALKING) && s) hist_init(s); else /* set after ENV */ Flag(FTRACKALL) = 1; alarm_init(); *sp = s; *lp = l; return (0); }
int main(int argc, char *argv[]) { #define BINDIR "/mingw64/bin" #define DATADIR "/mingw64/share" char exe_path[PATH_MAX]; get_executable_path (argv[0], &exe_path[0], sizeof (exe_path) / sizeof (exe_path[0])); printf ("executable path is %s\n", exe_path); char * rel_to_datadir = get_relative_path (BINDIR, DATADIR); if (strrchr (exe_path, '/') != NULL) { strrchr (exe_path, '/')[1] = '\0'; } strcat (exe_path, rel_to_datadir); simplify_path (&exe_path[0]); printf("real path of DATADIR is %s\n", exe_path); if (argc >= 2) { get_relative_path_debug (argv[argc-2], argv[argc-1], 0); } get_relative_path_debug (NULL, NULL, "./"); get_relative_path_debug ("/mingw64/bin", "/mingw64/etc/pkcs11/pkcs11.conf", "../etc/pkcs11/pkcs11.conf"); get_relative_path_debug ("/a/b/c/d", "/a/b/c", ".."); get_relative_path_debug ("/a/b/c/d/", "/a/b/c/", "../"); get_relative_path_debug ("/", "/", "/"); get_relative_path_debug ("/a/testone/c/d", "/a/testtwo/c", "../../../testtwo/c"); get_relative_path_debug ("/a/testone/c/d/", "/a/testtwo/c/", "../../../testtwo/c/"); get_relative_path_debug ("/home/part2/part3/part4", "/work/proj1/proj2", "../../../../work/proj1/proj2"); simplify_path_debug ("a/b/..", "a"); simplify_path_debug ("a/b/c/../../", "a/"); simplify_path_debug ("a/../a/..", ""); simplify_path_debug ("../a/../a/", "../a/"); simplify_path_debug ("./././", "./"); simplify_path_debug ("/test/", "/test/"); simplify_path_debug (".", "."); simplify_path_debug ("..", ".."); simplify_path_debug ("../", "../"); simplify_path_debug ("././.", "."); simplify_path_debug ("../..", "../.."); simplify_path_debug ("/", "/"); simplify_path_debug ("./test/", "./test/"); simplify_path_debug ("./test", "./test"); simplify_path_debug ("/test", "/test"); simplify_path_debug ("../test", "../test"); simplify_path_debug ("../../test", "../../test"); simplify_path_debug ("../test/..", ".."); simplify_path_debug (".././../", "../../"); sanitise_path_debug ("C:\\windows\\path", "C:/windows/path"); sanitise_path_debug ("", ""); sanitise_path_debug ("\\\\", "/"); char const * win_path = X509_get_default_private_dir (); printf ("%s -> %s\n", X509_PRIVATE_DIR, win_path); char * trusts = msys2_get_relocated_path_list (TRUST_PATHS); printf ("%s -> %s\n", TRUST_PATHS, trusts); free ((void*)trusts); char * single = msys2_get_relocated_path_list (SINGLE_PATH_LIST); printf ("%s -> %s\n", SINGLE_PATH_LIST, single); free ((void*)single); char *multi = get_relocated_path_list(BINDIR, TRUST_PATHS); printf ("Source pathlist: %s \n", TRUST_PATHS); printf ("Real pathlist: %s\n", multi); free ((void*)multi); return 0; }
// This function is called once, from main.c. void maze_solve() { // Loop until we have record the maze. while(1) { // FIRST MAIN LOOP BODY follow_segment(); // Drive straight a bit. This helps us in case we entered the // intersection at an angle. // Note that we are slowing down - this prevents the robot // from tipping forward too much. set_motors(50,50); delay_ms(50); // These variables record whether the robot has seen a line to the // left, straight ahead, and right, while examining the current // intersection. unsigned char found_left=0; unsigned char found_straight=0; unsigned char found_right=0; // Now read the sensors and check the intersection type. unsigned int sensors[5]; read_line_white(sensors,IR_EMITTERS_ON); // Check for left and right exits. if(sensors[0] < 200){ found_left = 1; } if(sensors[4] < 200){ found_right = 1; } // Drive straight a bit more - this is enough to line up our // wheels with the intersection. set_motors(40,40); delay_ms(200); // Check for a straight exit. read_line_white(sensors,IR_EMITTERS_ON); if(sensors[1] < 200 || sensors[2] < 200 || sensors[3] < 200) { found_straight = 1; } // Check for the ending spot. // If all 3 center sensors are on white, we have solved the maze. if(sensors[1] < 200 && sensors[2] < 200 && sensors[3] < 200) { break; } // Intersection identification is complete. // If the maze has been solved, we can follow the existing // path. Otherwise, we need to learn the solution. unsigned char dir = select_turn(found_left, found_straight, found_right); int recint = record_intersec(found_left, found_straight, found_right); // Make the turn indicated by the path. turn(dir); // Store the intersection in the path variable. path[path_length] = dir; intersection[path_length] = recint; path_length ++; // You should check to make sure that the path_length does not // exceed the bounds of the array. We'll ignore that in this // example. } // Maze Recorded! while(1) { // Beep to show that we finished the maze. paths_length=0; set_motors(0,0); play(">>a32"); // Wait for the user to press a button. while(!button_is_pressed(BUTTON_B)) { clear(); print("Recorded!"); lcd_goto_xy(0,1); print("Press B"); delay_ms(30); } while(button_is_pressed(BUTTON_B)) { clear(); print("Here we"); lcd_goto_xy(0,1); print("Go!"); delay_ms(1000); } int i=0; while (i<4) { follow_segment(); // Drive straight a bit. This helps us in case we entered the // intersection at an angle. // Note that we are slowing down - this prevents the robot // from tipping forward too much. set_motors(50,50); delay_ms(50); // These variables record whether the robot has seen a line to the // left, straight ahead, and right, while examining the current // intersection. unsigned char found_left=0; unsigned char found_straight=0; unsigned char found_right=0; // Now read the sensors and check the intersection type. unsigned int sensors[5]; read_line_white(sensors,IR_EMITTERS_ON); // Check for left and right exits. if(sensors[0] < 200) { found_left = 1; } if(sensors[4] < 200) { found_right = 1; } // Drive straight a bit more - this is enough to line up our // wheels with the intersection. set_motors(40,40); delay_ms(200); // Check for a straight exit. read_line_white(sensors,IR_EMITTERS_ON); if(sensors[1] < 200 || sensors[2] < 200 || sensors[3] < 200) { found_straight = 1; } unsigned char dir = select_turn(found_left, found_straight, found_right); int recint = record_intersec(found_left, found_straight, found_right); // Make the turn indicated by the path. turn(dir); // Store the intersection in the path variable. paths[paths_length] = dir; intersections[paths_length] = recint; if (paths[paths_length] != 'B') { i++; paths_length ++; } else { paths_length ++; } } // Find the robot location with respect to the end. // The Robot location code can be simplified more. // Its Possible to modify this code, so we start by running the robot two steps, // then we check how many values of m we have, if we have more than one value we add another step and so on until we have one m value. int i2; int c2; for (i=0;i<100;i++) { if (i<(100-paths_length)) { i2=0; while (i2<paths_length) { c2=0; if (paths[i2]==path[i+i2] && intersections[i2]==intersection[i+i2]) { c2=1; i2++; } if (c2!=1) { i2=100; } if (i2 == paths_length ) { m=i+paths_length; } } } } // We found the Robot location, now find the shortest way to the end. for(i=0;i<(100-m);i++) { pathsol[pathsol_length]=path[i+m]; pathsol_length ++; simplify_path(); } // Go to the end. i=0; while(i<pathsol_length) { // Re-run the maze. It's not necessary to identify the // intersections, so this loop is really simple. follow_segment(); // Drive straight while slowing down, as before. set_motors(50,50); delay_ms(50); set_motors(40,40); delay_ms(200); // Make a turn according to the instruction stored in // pathsol[i]. turn(pathsol[i]); i+=1; unsigned int sensors[5]; read_line_white(sensors,IR_EMITTERS_ON); // The end is reached. if(sensors[1] < 200 && sensors[2] < 200 && sensors[3] < 200) { pathsol_length=0; } } // Now we should be at the finish! Restart the loop. } }
void GUI_FileSel(const char *label, SELFILE_CB * cb, int rw,char **rname) { /* Create the selector */ GtkWidget *dialog; char *name=NULL; char *tmpname; gchar *selected_filename; uint8_t res; if(rname) *rname=NULL; if(rw) { dialog=dialog = gtk_file_chooser_dialog_new ("Save", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); } else { dialog=dialog = gtk_file_chooser_dialog_new ("Open File", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); } /**********/ initFileSelector(); setFilter(dialog); /**********/ gtk_window_set_title (GTK_WINDOW (dialog),label); gtk_register_dialog(dialog); if(rw) res=prefs->get(LASTDIR_WRITE,&tmpname); else res=prefs->get(LASTDIR_READ,&tmpname); if(res) { DIR *dir; char *str=PathCanonize(tmpname); PathStripName(str); /* LASTDIR may have gone; then do nothing and use current dir instead (implied) */ if( (dir=opendir(str)) ) { closedir(dir); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),(gchar *)str); } delete [] str; } if(gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_ACCEPT) { selected_filename= (gchar *) gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); #ifdef CYG_MANGLING if (*(selected_filename + strlen(selected_filename) - 1) == '\\') { #else if (*(selected_filename + strlen(selected_filename) - 1) == '/') { #endif GUI_Error_HIG("Cannot open directory as a file", NULL); } else { name=ADM_strdup(selected_filename); char *str=PathCanonize(name); PathStripName(str); if(rw) prefs->set(LASTDIR_WRITE,str); else prefs->set(LASTDIR_READ,str); delete [] str; } } gtk_unregister_dialog(dialog); gtk_widget_destroy(dialog); // CYB 2005.02.23 if(cb) { fileReadWrite(cb, rw, name); } else { *rname=name; } } //------------------------------------------------------------------ /* ** note: it modifies it's first argument */ void simplify_path(char **buf) { unsigned int last1slash = 0; unsigned int last2slash = 0; while( !strncmp(*buf,"/../",4) ) memmove(*buf,*buf+3,strlen(*buf+3)+1); for(unsigned int i=0; i<strlen(*buf)-2; i++) while( !strncmp(*buf+i,"/./",3) ) memmove(*buf+i,*buf+i+2,strlen(*buf+i+2)+1); for(unsigned int i=0; i<strlen(*buf)-3; i++) { if( *(*buf+i) == '/' ) { last2slash = last1slash; last1slash = i; } if( !strncmp(*buf+i,"/../",4) ) { memmove(*buf+last2slash,*buf+i+3,strlen(*buf+i+3)+1); return simplify_path(buf); } } }