void cmdLs(void) { // Pede o nome do diretorio de trabalho char cwd[1024]; int err = getcwd2(cwd, 1024); if (err) { printf ("Working directory not found\n"); return; } // Abre o diretório de trabalho DIR2 d; d = opendir2(cwd); if (d<0) { printf ("Open dir error: %d\n", err); return; } // Coloca diretorio na tela DIRENT2 dentry; while ( readdir2(d, &dentry) == 0 ) { printf ("%c %8ld %s\n", (dentry.fileType?'d':'-'), dentry.fileSize, dentry.name); } closedir2(d); }
void cmdGetcwd(void) { char name[1024]; int err = getcwd2(name, 1024); if (err) { printf ("Error: %d\n", err); return; } printf ("Working Directory is %s\n", name); }
/** * Copy in @result the equivalent of "@tracee->root + canon(@dir_fd + * @user_path)". If @user_path is not absolute then it is relative to * the directory referred by the descriptor @dir_fd (AT_FDCWD is for * the current working directory). See the documentation of * canonicalize() for the meaning of @deref_final. This function * returns -errno if an error occured, otherwise 0. */ int translate_path(Tracee *tracee, char result[PATH_MAX], int dir_fd, const char *user_path, bool deref_final) { char guest_path[PATH_MAX]; int status; /* Use "/" as the base if it is an absolute guest path. */ if (user_path[0] == '/') { strcpy(result, "/"); } /* It is relative to a directory referred by a descriptor, see * openat(2) for details. */ else if (dir_fd != AT_FDCWD) { /* /proc/@tracee->pid/fd/@dir_fd -> result. */ status = readlink_proc_pid_fd(tracee->pid, dir_fd, result); if (status < 0) return status; /* Named file descriptors may reference special * objects like pipes, sockets, inodes, ... Such * objects do not belong to the file-system. */ if (result[0] != '/') return -ENOTDIR; /* Remove the leading "root" part of the base * (required!). */ status = detranslate_path(tracee, result, NULL); if (status < 0) return status; } /* It is relative to the current working directory. */ else { status = getcwd2(tracee, result); if (status < 0) return status; } VERBOSE(tracee, 2, "pid %d: translate(\"%s\" + \"%s\")", tracee != NULL ? tracee->pid : 0, result, user_path); status = notify_extensions(tracee, GUEST_PATH, (intptr_t) result, (intptr_t) user_path); if (status < 0) return status; if (status > 0) goto skip; /* So far "result" was used as a base path, it's time to join * it to the user path. */ assert(result[0] == '/'); status = join_paths(2, guest_path, result, user_path); if (status < 0) return status; strcpy(result, "/"); /* Canonicalize regarding the new root. */ status = canonicalize(tracee, guest_path, deref_final, result, 0); if (status < 0) return status; /* Final binding substitution to convert "result" into a host * path, since canonicalize() works from the guest * point-of-view. */ status = substitute_binding(tracee, GUEST, result); if (status < 0) return status; skip: VERBOSE(tracee, 2, "pid %d: -> \"%s\"", tracee != NULL ? tracee->pid : 0, result); return 0; }
/** * Put in @host_path the full path to the given shell @command. The * @command is searched in @paths if not null, otherwise in $PATH * (relatively to the @tracee's file-system name-space). This * function always returns -1 on error, otherwise 0. */ int which(Tracee *tracee, const char *paths, char host_path[PATH_MAX], char *const command) { char path[PATH_MAX]; const char *cursor; struct stat statr; int status; bool is_explicit; bool found; assert(command != NULL); is_explicit = (strchr(command, '/') != NULL); /* Is the command available without any $PATH look-up? */ status = realpath2(tracee, host_path, command, true); if (status == 0 && stat(host_path, &statr) == 0) { if (!S_ISREG(statr.st_mode)) { notice(tracee, ERROR, USER, "'%s' is not a regular file", command); return -EACCES; } if ((statr.st_mode & S_IXUSR) == 0) { notice(tracee, ERROR, USER, "'%s' is not executable", command); return -EACCES; } found = true; } else found = false; /* Is the the explicit command was found? */ if (is_explicit) { if (found) return 0; else goto not_found; } /* Otherwise search the command in $PATH. */ paths = paths ?: getenv("PATH"); if (paths == NULL || strcmp(paths, "") == 0) goto not_found; cursor = paths; do { size_t length; length = strcspn(cursor, ":"); cursor += length + 1; if (length >= PATH_MAX) continue; else if (length == 0) strcpy(path, "."); else { strncpy(path, cursor - length - 1, length); path[length] = '\0'; } /* Avoid buffer-overflow. */ if (length + strlen(command) + 2 >= PATH_MAX) continue; strcat(path, "/"); strcat(path, command); status = realpath2(tracee, host_path, path, true); if (status == 0 && stat(host_path, &statr) == 0 && S_ISREG(statr.st_mode) && (statr.st_mode & S_IXUSR) != 0) return 0; } while (*(cursor - 1) != '\0'); not_found: status = getcwd2(tracee, path); if (status < 0) strcpy(path, "<unknown>"); notice(tracee, ERROR, USER, "'%s' not found (root = %s, cwd = %s, $PATH=%s)", command, get_root(tracee), path, paths); /* Check if the command was found without any $PATH look-up * but it didn't contain "/". */ if (found && !is_explicit) notice(tracee, ERROR, USER, "to execute a local program, use the './' prefix, for example: ./%s", command); return -1; }
/** * Copy in @host_path the equivalent of "@tracee->root + * canonicalize(@dir_fd + @guest_path)". If @guest_path is not * absolute then it is relative to the directory referred by the * descriptor @dir_fd (AT_FDCWD is for the current working directory). * See the documentation of canonicalize() for the meaning of * @deref_final. This function returns -errno if an error occured, * otherwise 0. */ int translate_path(Tracee *tracee, char host_path[PATH_MAX], int dir_fd, const char *guest_path, bool deref_final) { int status; /* Use "/" as the base if it is an absolute guest path. */ if (guest_path[0] == '/') { strcpy(host_path, "/"); } /* It is relative to the current working directory or to a * directory referred by a descriptors, see openat(2) for * details. */ else if (dir_fd == AT_FDCWD) { status = getcwd2(tracee, host_path); if (status < 0) return status; } else { struct stat statl; /* /proc/@tracee->pid/fd/@dir_fd -> host_path. */ status = readlink_proc_pid_fd(tracee->pid, dir_fd, host_path); if (status < 0) return status; /* Ensure it points to a directory. */ status = stat(host_path, &statl); if (status < 0) return -errno; if (!S_ISDIR(statl.st_mode)) return -ENOTDIR; /* Remove the leading "root" part of the base * (required!). */ status = detranslate_path(tracee, host_path, NULL); if (status < 0) return status; } VERBOSE(tracee, 2, "pid %d: translate(\"%s\" + \"%s\")", tracee != NULL ? tracee->pid : 0, host_path, guest_path); status = notify_extensions(tracee, GUEST_PATH, (intptr_t)host_path, (intptr_t)guest_path); if (status < 0) return status; if (status > 0) goto skip; /* Canonicalize regarding the new root. */ status = canonicalize(tracee, guest_path, deref_final, host_path, 0); if (status < 0) return status; /* Final binding substitution to convert "host_path" into a host * path, since canonicalize() works from the guest * point-of-view. */ status = substitute_binding(tracee, GUEST, host_path); if (status < 0) return status; skip: VERBOSE(tracee, 2, "pid %d: -> \"%s\"", tracee != NULL ? tracee->pid : 0, host_path); return 0; }