int main() { int ret = 0; struct dir_walk dw; dir_walk_init(&dw); dw.cb_dir = dirfile; dw.cb_reg = regfile; dw.cb_lnk = lnkfile; dw.cb_fifo = fifofile; dw.base = "testdata/dir_walk"; if (mkfifo("testdata/dir_walk/fifo", 0644) == -1) { printf("fail: mkfifo: %s\n", error_str(errno)); return 1; } if (!dir_walk(&dw)) { printf("fail: dir_walk_start() returned 0: %s\n", error_str(errno)); ret = 1; goto END; } END: if (unlink("testdata/dir_walk/fifo") == -1) printf("error: unlink: %s\n", error_str(errno)); return ret; }
int truncate(const char *path, off_t newlength) { int ino = dir_walk(path, 0); if (ino < 0) return -1; return fileino_truncate(ino, newlength); }
int stat(const char *path, struct stat *statbuf) { int ino = dir_walk(path, 0); if (ino < 0) return -1; return fileino_stat(ino, statbuf); }
int mkdir(const char *path, bool verb) { if(dir_walk(path, 0) == -1) { // Error with dir_walk if(errno == ENOENT) { // Directory doesn't exist, good to go! errno = 0; int ino = dir_walk(path, S_IFDIR); if(ino == -1) { printf("mkdir: couldn't create directory %s\n", path); return 0; } // Indicate that this has changed files->fi[ino].ver++; if(verb) printf("%s\n", path); } else { return 0; // Some other error, reflected by errno } } else { // Directory already exists! errno = EINVAL; return -1; } return 0; }
/* Tries to recurse into the given directory item */ static int dir_scan_recurse(struct dir *d) { int fail = 0; char *dir; if(chdir(d->name)) { dir_setlasterr(dir_curpath); d->flags |= FF_ERR; if(dir_output.item(d) || dir_output.item(NULL)) { dir_seterr("Output error: %s", strerror(errno)); return 1; } return 0; } if((dir = dir_read(&fail)) == NULL) { dir_setlasterr(dir_curpath); d->flags |= FF_ERR; if(dir_output.item(d) || dir_output.item(NULL)) { dir_seterr("Output error: %s", strerror(errno)); return 1; } if(chdir("..")) { dir_seterr("Error going back to parent directory: %s", strerror(errno)); return 1; } else return 0; } /* readdir() failed halfway, not fatal. */ if(fail) d->flags |= FF_ERR; if(dir_output.item(d)) { dir_seterr("Output error: %s", strerror(errno)); return 1; } fail = dir_walk(dir); if(dir_output.item(NULL)) { dir_seterr("Output error: %s", strerror(errno)); return 1; } /* Not being able to chdir back is fatal */ if(!fail && chdir("..")) { dir_seterr("Error going back to parent directory: %s", strerror(errno)); return 1; } return fail; }
static int process() { char *path; char *dir; int fail = 0; struct stat fs; struct dir *d; if((path = path_real(dir_curpath)) == NULL) dir_seterr("Error obtaining full path: %s", strerror(errno)); else { dir_curpath_set(path); free(path); } if(!dir_fatalerr && path_chdir(dir_curpath) < 0) dir_seterr("Error changing directory: %s", strerror(errno)); /* Can these even fail after a chdir? */ if(!dir_fatalerr && lstat(".", &fs) != 0) dir_seterr("Error obtaining directory information: %s", strerror(errno)); if(!dir_fatalerr && !S_ISDIR(fs.st_mode)) dir_seterr("Not a directory"); if(!dir_fatalerr && !(dir = dir_read(&fail))) dir_seterr("Error reading directory: %s", strerror(errno)); if(!dir_fatalerr) { curdev = (uint64_t)fs.st_dev; d = dir_createstruct(dir_curpath); if(fail) d->flags |= FF_ERR; stat_to_dir(d, &fs); if(dir_output.item(d)) { dir_seterr("Output error: %s", strerror(errno)); fail = 1; } if(!fail) fail = dir_walk(dir); if(!fail && dir_output.item(NULL)) { dir_seterr("Output error: %s", strerror(errno)); fail = 1; } } while(dir_fatalerr && !input_handle(0)) ; return dir_output.final(dir_fatalerr || fail); }
// Find or create and open a file, optionally using a given file descriptor. // The argument 'fd' must point to a currently unused file descriptor, // or may be NULL, in which case this function finds an unused file descriptor. // The 'openflags' determines whether the file is created, truncated, etc. // Returns the opened file descriptor on success, // or returns NULL and sets errno on failure. filedesc * filedesc_open(filedesc *fd, const char *path, int openflags, mode_t mode) { if (!fd && !(fd = filedesc_alloc())) return NULL; assert(fd->ino == FILEINO_NULL); // Determine the complete file mode if it is to be created. mode_t createmode = (openflags & O_CREAT) ? S_IFREG | (mode & 0777) : 0; // Walk the directory tree to find the desired directory entry, // creating an entry if it doesn't exist and O_CREAT is set. int ino = dir_walk(path, createmode); if (ino < 0) return NULL; assert(fileino_exists(ino)); // Refuse to open conflict-marked files; // the user needs to resolve the conflict and clear the conflict flag, // or just delete the conflicted file. if (files->fi[ino].mode & S_IFCONF) { errno = ECONFLICT; return NULL; } // Truncate the file if we were asked to if (openflags & O_TRUNC) { if (!(openflags & O_WRONLY)) { warn("filedesc_open: can't truncate non-writable file"); errno = EINVAL; return NULL; } if (fileino_truncate(ino, 0) < 0) return NULL; } // Initialize the file descriptor fd->ino = ino; fd->flags = openflags; fd->ofs = (openflags & O_APPEND) ? files->fi[ino].size : 0; fd->err = 0; assert(filedesc_isopen(fd)); return fd; }
/* **************************************************************** * Remove um arquivo * **************************************************************** */ void simple_rm (const char *path) { DOSSTAT z; /* * Obtém o estado do arquivo */ if (dos_stat (path, &z) < 0) { printf ( "%s: Não consegui obter o estado de \"%s\" (%s)\n", cmd_nm, path, strerror (errno) ); return; } #undef DEBUG #ifdef DEBUG printf ( "simple_rm: entries = %d, clusno = %d\n", z.z_lfn_entries, z.z_lfn_clusno ); printf ( "simple_rm: blkno = %d, end_blkno = %d, offset = %d\n", z.z_lfn_blkno, z.z_lfn_end_blkno, z.z_lfn_offset ); #endif DEBUG /* * Se necessário, pede confirmação do usuario */ if (cmd_iflag) { fprintf ( stderr, "(%c, %d) %s? (n): ", file_type_edit (z.z_mode), GET_LONG (z.z_size), path ); if (askyesno () <= 0) return; } elif (cmd_vflag) { printf ("%s:\n", path); } /* * Verifica se é um arquivo regular */ if (Z_ISDIR (z.z_mode)) { printf ( "%s: O arquivo \"%s\" é um diretório\n", cmd_nm, path ); return; } /* * Verifica se tem o bit "r" ligado */ if (z.z_mode & Z_RO) { fprintf ( stderr, "%s: O arquivo \"%s\" só permite leituras - " "remove? (n): ", cmd_nm, path ); if (askyesno () <= 0) return; } /* * Remove o arquivo */ if (dos_unlink (&z, 1 /* trunca */) < 0) return; /* * Verifica se alterou o nome do volume principal */ if (Z_ISVOL (z.z_mode)) { vol_nm[0] = '\0'; dir_walk (vol_search, uni.u_root_cluster); } } /* end simple_rm */