static int chunk_wrapper(lua_State* L) { char cwd[PATH_MAX]; const char* filename; char* ptr; int i, args; args = lua_gettop(L); /* Remember the current _SCRIPT and working directory so I can * restore them after this new chunk has been run. */ do_getcwd(cwd, PATH_MAX); lua_getglobal(L, "_SCRIPT"); lua_getglobal(L, "_SCRIPT_DIR"); /* Set the new _SCRIPT variable */ lua_pushvalue(L, lua_upvalueindex(1)); lua_setglobal(L, "_SCRIPT"); /* And the new _SCRIPT_DIR variable (const cheating) */ filename = lua_tostring(L, lua_upvalueindex(1)); ptr = strrchr(filename, '/'); if (ptr) *ptr = '\0'; lua_pushstring(L, filename); lua_setglobal(L, "_SCRIPT_DIR"); /* And make that the CWD (and fix the const cheat) */ if (filename[0] != '$') { do_chdir(L, filename); } if (ptr) *ptr = '/'; /* Move the function's arguments to the top of the stack and * execute the function created by luaL_loadfile() */ lua_pushvalue(L, lua_upvalueindex(2)); for (i = 1; i <= args; ++i) { lua_pushvalue(L, i); } lua_call(L, args, LUA_MULTRET); /* Finally, restore the previous _SCRIPT variable and working directory * before returning control to the previously executing script. */ do_chdir(L, cwd); lua_pushvalue(L, args + 1); lua_setglobal(L, "_SCRIPT"); lua_pushvalue(L, args + 2); lua_setglobal(L, "_SCRIPT_DIR"); return lua_gettop(L) - args - 2; }
void* func_msg(void* arg) { struct thread_info* args = arg; // struct sockaddr_in client; int sock = args->sock; int read_n, errcnt = 0; ftp_rqt request; // printf("in thread\n"); // fprintf(stderr, "sock: %d\n", sock); while (true) { memset(&request, 0, RQT_LEN); read_n = recv(sock, (char*)&request, RQT_LEN, 0); if (read_n < 0) { errcnt ++; if (errcnt > 10) break ; continue ; } if (read_n == 0) { fprintf(stderr, "quit"); break ; } // printf("msg: %d; read_n: %d\n", request.type, read_n); if (request.type == CMD_CLOSE) break; else if (request.type == CMD_CD) do_chdir(&request, sock); else if (request.type == CMD_MKDIR) do_mkdir(&request, sock); else if (request.type == CMD_RMDIR) do_rmdir(&request, sock); else if (request.type == CMD_LS) do_lsdir(&request, sock); else if (request.type == CMD_GET) { do_get(&request, sock); break; } else if (request.type == CMD_PUT) { printf("put\n"); do_put(&request, sock); break; } // send(sock, CONFIRM, strlen(CONFIRM)+1, 0); } thread_end(args); }
/* * Archive names specified in file. * * Unless --null was specified, a line containing exactly "-C" will * cause the next line to be a directory to pass to chdir(). If * --null is specified, then a line "-C" is just another filename. */ static void archive_names_from_file(struct bsdtar *bsdtar, struct archive *a) { struct lafe_line_reader *lr; const char *line; bsdtar->next_line_is_dir = 0; lr = lafe_line_reader(bsdtar->names_from_file, bsdtar->option_null); while ((line = lafe_line_reader_next(lr)) != NULL) { if (bsdtar->next_line_is_dir) { if (*line != '\0') set_chdir(bsdtar, line); else { lafe_warnc(0, "Meaningless argument for -C: ''"); bsdtar->return_value = 1; } bsdtar->next_line_is_dir = 0; } else if (!bsdtar->option_null && strcmp(line, "-C") == 0) bsdtar->next_line_is_dir = 1; else { if (*line != '/') do_chdir(bsdtar); /* Handle a deferred -C */ write_hierarchy(bsdtar, a, line); } } lafe_line_reader_free(lr); if (bsdtar->next_line_is_dir) lafe_errc(1, errno, "Unexpected end of filename list; " "directory expected after -C"); }
int main(int argc, char* argv[]) { const char* ip; const char* tmp; if (argc < 2) die1(1, "usage: relay-ctrl-check program [arguments]\n"); log_ips = getenv("RELAY_CTRL_LOG_IPS") != 0; log_env = getenv("RELAY_CTRL_LOG_ENV") != 0; if (getenv("RELAYCLIENT") == 0) { expiry = 0; if ((tmp = getenv("RELAY_CTRL_EXPIRY")) != 0) expiry = atol(tmp); if (expiry <= 0) expiry = 900; if ((rc = getenv("RELAY_CTRL_RELAYCLIENT")) == 0) rc = ""; if ((ip = getenv("TCPREMOTEIP")) == 0) warn1("$TCPREMOTEIP not set, not checking IP"); else if (do_chdir(0)) stat_ip(ip); } else { if (log_ips) msg1("$RELAYCLIENT already set, not checking IP"); } execvp(argv[1], argv+1); die1(111, "execution of program failed!\n"); return 111; argc = 0; }
static int sys_chdir(argstr_t *arg) { argstr_t kern_args; char *path; int err; if ((err = copy_from_user(&kern_args, arg, sizeof(argstr_t))) < 0) { curthr->kt_errno = -err; return -1; } path = user_strdup(&kern_args); if (!path) { curthr->kt_errno = EINVAL; return -1; } err = do_chdir(path); kfree(path); if (err < 0) { curthr->kt_errno = -err; return -1; } else return err; }
static int archive_names_from_file_helper(struct bsdtar *bsdtar, const char *line) { if (bsdtar->next_line_is_dir) { set_chdir(bsdtar, line); bsdtar->next_line_is_dir = 0; } else if (!bsdtar->option_null && strcmp(line, "-C") == 0) bsdtar->next_line_is_dir = 1; else { if (*line != '/') do_chdir(bsdtar); /* Handle a deferred -C */ write_hierarchy(bsdtar, bsdtar->archive, line); } return (0); }
int os_chdir(lua_State* L) { const char* path = luaL_checkstring(L, 1); int z = do_chdir(L, path); if (!z) { lua_pushnil(L); lua_pushfstring(L, "unable to switch to directory '%s'", path); return 2; } else { lua_pushboolean(L, 1); return 1; } }
int main(int argv, char* args[]){ disk = open("/dev/fd0",O_RDWR); if (argv > 1){ if (strcmp(format, args[1]) == 0) do_format(); else if (strcmp(mkdir, args[1]) == 0){ if (argv > 2) do_mkdir(args[2]); else printf("Usage: mkdir dir\n"); } else if (strcmp(chdir, args[1]) == 0){ if (argv > 2) do_chdir(args[2]); else printf("Usage: chdir dir\n"); } else if (strcmp(copy, args[1]) == 0) { do_copy(args[2], args[3], args[4]); } else if (strcmp(dir, args[1]) == 0) do_dir(args[2]); else if (strcmp("info", args[1]) == 0){ info(args[2]); } else if (strcmp("freeblock", args[1]) == 0) free_block(); else if (strcmp("checkblock", args[1]) == 0) check_block(args[2]); else printf("Unknown dtool command.\n"); } return 0; }
static int archive_names_from_file_helper(struct bsdtar *bsdtar, const char *line) { if (bsdtar->next_line_is_dir) { if (*line != '\0') set_chdir(bsdtar, line); else { bsdtar_warnc(bsdtar, 0, "Meaningless argument for -C: ''"); bsdtar->return_value = 1; } bsdtar->next_line_is_dir = 0; } else if (!bsdtar->option_null && strcmp(line, "-C") == 0) bsdtar->next_line_is_dir = 1; else { if (*line != '/') do_chdir(bsdtar); /* Handle a deferred -C */ write_hierarchy(bsdtar, bsdtar->archive, line); } return (0); }
static void make_file(const char* filename, int save_cwd) { int fd; int saved_umask; int mode; char tmpname[256]; char* ptr; struct timeval t; switch (do_chdir(save_cwd)) { case 0: return; case 2: mode = 0666; break; default: mode = 0600; break; } saved_umask = umask(0); gettimeofday(&t, 0); ptr = tmpname; *ptr++ = '.'; ptr = utoa2(t.tv_sec, ptr); *ptr++ = '.'; ptr = utoa2(t.tv_usec, ptr); *ptr++ = ':'; ptr = utoa2(getpid(), ptr); if ((fd = open(tmpname, O_WRONLY|O_CREAT|O_EXCL, mode)) == -1) warn3sys("Could not open '", tmpname, "' for writing"); else { if (!write_env(fd, "USER") || !write_env(fd, "DOMAIN") || close(fd) == -1) { warn3sys("Could not write to '", filename, "'"); close(fd); } else if (rename(tmpname, filename) == -1) warn5sys("Could not rename '", tmpname, "' to '", filename, "'"); unlink(tmpname); } if (save_cwd) { umask(saved_umask); do_chdir_back(); } }
int change_dir(char *path) { struct stat sb; if (access(path, F_OK) == 0) { if (stat(path, &sb) == 0) { if (S_ISDIR(sb.st_mode)) { if (access(path, X_OK) == 0) { return do_chdir(path); } else shell_warn("cd: %s: Permission denied.\n", path); } else shell_warn("cd: %s: Not a directory.\n", path); } else shell_warn("cd: %s: Permission denied.\n", path); } else shell_warn("cd: %s: No such file or directory.\n", path); return -1; }
int vfs_selftest(kshell_t *kshell, int argc, char **argv) { int fd1,fd2; char *y="/ab/fil"; char x[2]; int err; do_mkdir("/ab"); do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1)); fd1=do_open("/ab/new",2); fd2=do_dup2(fd1,NFILES+1); if(fd2<0) { dbg(DBG_PRINT,"File not created\n"); } do_mknod("/ab/notmade",4096,MKDEVID(1,1)); do_mknod("/ab/new/not",S_IFCHR,MKDEVID(1,1)); do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1)); do_mknod("", S_IFCHR,MKDEVID(1,1)); /*do_close(fd1);*/ for(fd2=1;fd2<35;fd2++) { sprintf(x,"%d",fd2); strcat(y,x); do_mknod(y,S_IFCHR,MKDEVID(1,0)); err=do_open(y,2); if(err<0) { break; } if(fd2<10) { y[strlen(y)-1]='\0'; } else { y[strlen(y)-2]='\0'; } } do_mknod("/ab/new1", S_IFCHR,MKDEVID(1,1)); err=do_dup(fd1); do_unlink("/ab/new/ab"); do_unlink("/ab/new"); do_close(fd1); for(fd2=NFILES-1;fd2>0;fd2--) { err=do_close(fd2); sprintf(x,"%d",fd2); strcat(y,x); do_unlink(y); if(err<0) { break; } if(fd2<10) { y[strlen(y)-1]='\0'; } else { y[strlen(y)-2]='\0'; } } do_link("/a","/dev"); do_link("/dev","/a"); do_link("/dev","/a"); do_rmdir("/a"); /* mkdir("/k"); do_link("/ab","/k");*/ do_rmdir("/ab"); /*do_rmdir("/k");*/ /*GS: SELF TESTS*/ dbg(DBG_PRINT,"\n*************************************************************\n"); dbg(DBG_PRINT,"\n\n\n\n(GRADING2C)(kmain.c)(selftest_proc_run) selftests begin\n"); int retVal = 0; int i = 0; /* 1. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_stat) strlen too long, return -ENAMETOOLONG\n");*/ char longPath[1024 + 1] = {0}; for(i = 0; i < 1025; i++) longPath[i] = 'a'; struct stat buf; retVal = do_stat(longPath, &buf); retVal=do_chdir(longPath); /*2. dbg(DBG_PRINT, "(GRADING2B) ENOTDIR or ENOENT\n");*/ retVal = do_stat("", &buf); /*3. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/ struct dirent dirp; retVal = do_getdent(-1, &dirp); /*4. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/ retVal = do_getdent(1, &dirp); /*5. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) File descriptor does not refer to a directory, return -ENOTDIR\n");*/ do_mknod("/./file", S_IFCHR,MKDEVID(1,1)); fd1 = do_open("/./file",2); retVal = do_getdent(fd1, &dirp); do_unlink("/./file"); do_close(fd1); /*6. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) Both are valid names \n");*/ /* and */ /*7. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) error do_link, return error\n"); \n");*/ retVal = do_rename("/./aaa", "/./bbb"); dbg(DBG_PRINT,"\n\nretVal=%d",retVal); dbg(DBG_PRINT,"\n*************************************************************\n"); return 0; }
static uint8_t mount_line(void) { FRESULT res; UINT bytesread; uint8_t i,*str,*strend, *buffer_start; uint16_t curpos; bool got_colon = false; uint8_t olderror = current_error; current_error = ERROR_OK; /* Kill all buffers */ free_multiple_buffers(FMB_USER_CLEAN); curpos = 0; strend = NULL; buffer_start = command_buffer + 1; globalflags |= SWAPLIST_ASCII; for (i=0;i<=linenum;i++) { str = buffer_start; res = f_lseek(&swaplist,curpos); if (res != FR_OK) { parse_error(res,1); return 0; } res = f_read(&swaplist, str, CONFIG_COMMAND_BUFFER_SIZE - 1, &bytesread); if (res != FR_OK) { parse_error(res,1); return 0; } /* Terminate string in buffer */ if (bytesread < CONFIG_COMMAND_BUFFER_SIZE - 1) str[bytesread] = 0; if (bytesread == 0) { if (linenum == 255) { /* Last entry requested, found it */ linenum = i-1; } else { /* End of file - restart loop to read the first entry */ linenum = 0; } i = -1; /* I could've used goto instead... */ curpos = 0; continue; } /* Skip name */ got_colon = false; while (*str != '\r' && *str != '\n') { if (*str == ':') got_colon = true; str++; } strend = str; /* Skip line terminator */ while (*str == '\r' || *str == '\n') str++; /* check for PETSCII marker */ if (curpos == 0) { if (!memcmp_P(buffer_start, petscii_marker, sizeof(petscii_marker))) { /* swaplist is in PETSCII, ignore this line */ globalflags &= ~SWAPLIST_ASCII; i--; } } curpos += str - buffer_start; } /* Terminate file name */ *strend = 0; if (partition[swappath.part].fop != &fatops) image_unmount(swappath.part); /* Start in the partition+directory of the swap list */ current_part = swappath.part; display_current_part(current_part); partition[current_part].current_dir = swappath.dir; /* add a colon if neccessary */ if (!got_colon && buffer_start[0] != '/') { command_buffer[0] = ':'; buffer_start = command_buffer; } /* recode entry if neccessary */ if (globalflags & SWAPLIST_ASCII) asc2pet(buffer_start); /* parse and change */ do_chdir(buffer_start); if (current_error != 0 && current_error != ERROR_DOSVERSION) { current_error = olderror; return 0; } return 1; }
int main(int argc, char *argv[]) { int ret, i, action = -1; char config_file[PATH_MAX] = {}; int type = 0; struct utsname u; int version, major, minor; /* Check kernel version: it must be >= 2.6.18 */ if (uname(&u) == -1) { fprintf(stderr, "Can't retrieve kernel version via uname()\n"); exit(EXIT_FAILURE); } sscanf(u.release, "%d.%d.%d", &version, &major, &minor); if (version < 2 && major < 6 && minor < 18) { fprintf(stderr, "Linux kernel version must be >= 2.6.18\n"); exit(EXIT_FAILURE); } for (i=1; i<argc; i++) { switch(argv[i][1]) { case 'd': set_operation_mode(&type, DAEMON, argv); break; case 'c': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_COMMIT, EXP_COMMIT, ALL_COMMIT, &action); break; case 'i': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_DUMP_INTERNAL, EXP_DUMP_INTERNAL, CT_DUMP_INTERNAL, &action); break; case 'e': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_DUMP_EXTERNAL, EXP_DUMP_EXTERNAL, CT_DUMP_EXTERNAL, &action); break; case 'C': if (++i < argc) { strncpy(config_file, argv[i], PATH_MAX); if (strlen(argv[i]) >= PATH_MAX){ config_file[PATH_MAX-1]='\0'; fprintf(stderr, "Path to config file " "to long. Cutting it " "down to %d characters", PATH_MAX); } break; } show_usage(argv[0]); fprintf(stderr, "Missing config filename\n"); break; case 'F': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_FLUSH_MASTER, EXP_FLUSH_MASTER, ALL_FLUSH_MASTER, &action); break; case 'f': set_operation_mode(&type, REQUEST, argv); if (i+1 < argc && argv[i+1][0] != '-') { if (strncmp(argv[i+1], "internal", strlen(argv[i+1])) == 0) { action = CT_FLUSH_INT_CACHE; i++; } else if (strncmp(argv[i+1], "external", strlen(argv[i+1])) == 0) { action = CT_FLUSH_EXT_CACHE; i++; } else { fprintf(stderr, "ERROR: unknown " "parameter `%s' for " "option `-f'\n", argv[i+1]); exit(EXIT_FAILURE); } } else { /* default to general flushing */ action = ALL_FLUSH_CACHE; } break; case 'R': set_operation_mode(&type, REQUEST, argv); i = set_action_by_table(i, argc, argv, CT_RESYNC_MASTER, EXP_RESYNC_MASTER, ALL_RESYNC_MASTER, &action); break; case 'B': set_operation_mode(&type, REQUEST, argv); action = SEND_BULK; break; case 'S': set_operation_mode(&type, REQUEST, argv); action = SEND_BULKEXP; break; case 't': set_operation_mode(&type, REQUEST, argv); action = RESET_TIMERS; break; case 'k': set_operation_mode(&type, REQUEST, argv); action = KILL; break; case 's': set_operation_mode(&type, REQUEST, argv); /* we've got a parameter */ if (i+1 < argc && argv[i+1][0] != '-') { if (strncmp(argv[i+1], "network", strlen(argv[i+1])) == 0) { action = STATS_NETWORK; i++; } else if (strncmp(argv[i+1], "cache", strlen(argv[i+1])) == 0) { action = STATS_CACHE; i++; } else if (strncmp(argv[i+1], "runtime", strlen(argv[i+1])) == 0) { action = STATS_RUNTIME; i++; } else if (strncmp(argv[i+1], "multicast", strlen(argv[i+1])) == 0) { fprintf(stderr, "WARNING: use `link' " "instead of `multicast' as " "parameter.\n"); action = STATS_LINK; i++; } else if (strncmp(argv[i+1], "link", strlen(argv[i+1])) == 0) { action = STATS_LINK; i++; } else if (strncmp(argv[i+1], "rsqueue", strlen(argv[i+1])) == 0) { action = STATS_RSQUEUE; i++; } else if (strncmp(argv[i+1], "process", strlen(argv[i+1])) == 0) { action = STATS_PROCESS; i++; } else if (strncmp(argv[i+1], "queue", strlen(argv[i+1])) == 0) { action = STATS_QUEUE; i++; } else if (strncmp(argv[i+1], "ct", strlen(argv[i+1])) == 0) { action = STATS; i++; } else if (strncmp(argv[i+1], "expect", strlen(argv[i+1])) == 0) { action = EXP_STATS; i++; } else { fprintf(stderr, "ERROR: unknown " "parameter `%s' for " "option `-s'\n", argv[i+1]); exit(EXIT_FAILURE); } } else { /* default to general statistics */ action = STATS; } break; case 'n': set_operation_mode(&type, REQUEST, argv); action = REQUEST_DUMP; break; case 'x': if (action == CT_DUMP_INTERNAL) action = CT_DUMP_INT_XML; else if (action == CT_DUMP_EXTERNAL) action = CT_DUMP_EXT_XML; else if (action == EXP_DUMP_INTERNAL) action = EXP_DUMP_INT_XML; else if (action == EXP_DUMP_EXTERNAL) action = EXP_DUMP_EXT_XML; else { show_usage(argv[0]); fprintf(stderr, "Error: Invalid parameters\n"); exit(EXIT_FAILURE); } break; case 'v': show_version(); exit(EXIT_SUCCESS); case 'h': show_usage(argv[0]); exit(EXIT_SUCCESS); default: show_usage(argv[0]); fprintf(stderr, "Unknown option: %s\n", argv[i]); return 0; break; } } if (!config_file[0]) strcpy(config_file, DEFAULT_CONFIGFILE); umask(0177); if ((ret = init_config(config_file)) == -1) { fprintf(stderr, "can't open config file `%s'\n", config_file); exit(EXIT_FAILURE); } if (type == REQUEST) { if (do_local_request(action, &conf.local, local_step) == -1) { fprintf(stderr, "can't connect: is conntrackd " "running? appropriate permissions?\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } /* * Setting up logging */ if (init_log() == -1) exit(EXIT_FAILURE); /* * lock file */ /*ret = open(CONFIG(lockfile), O_CREAT | O_EXCL | O_TRUNC, 0600); if (ret == -1) { fprintf(stderr, "lockfile `%s' exists, perhaps conntrackd " "already running?\n", CONFIG(lockfile)); exit(EXIT_FAILURE); } close(ret);*/ /* * Setting process priority and scheduler */ set_nice_value(CONFIG(nice)); if (CONFIG(sched).type != SCHED_OTHER) { struct sched_param schedparam = { .sched_priority = CONFIG(sched).prio, }; ret = sched_setscheduler(0, CONFIG(sched).type, &schedparam); if (ret == -1) { perror("sched"); exit(EXIT_FAILURE); } } /* * initialization process */ if (init() == -1) { close_log(); fprintf(stderr, "ERROR: conntrackd cannot start, please " "check the logfile for more info\n"); unlink(CONFIG(lockfile)); exit(EXIT_FAILURE); } do_chdir("/"); close(STDIN_FILENO); sd_ct_watchdog_init(); /* Daemonize conntrackd */ if (type == DAEMON) { pid_t pid; if ((pid = fork()) == -1) { perror("fork has failed: "); exit(EXIT_FAILURE); } else if (pid) { sd_ct_mainpid(pid); exit(EXIT_SUCCESS); } setsid(); close(STDOUT_FILENO); close(STDERR_FILENO); dlog(LOG_NOTICE, "-- starting in daemon mode --"); } else dlog(LOG_NOTICE, "-- starting in console mode --"); sd_ct_init(); /* * run main process */ select_main_loop(); return 0; }
void *extra_self_tests(int arg1, void *arg2) { /* creating /test1/test2/ directories */ dbg(DBG_ERROR | DBG_VFS,"TEST: Creating directories\n"); do_mkdir("dir"); do_mkdir("dir/dir1"); do_mkdir("dir/dir2"); do_mkdir("dir/dir3"); do_mkdir("dir/dir4"); dbg(DBG_ERROR | DBG_VFS,"TEST: Directories are created\n"); int fd; char *file2buf="File 2 write only test case"; char *file1buf="Testing file_1 for write operation"; char readbuf[150]; dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir1\n"); do_chdir("dir/dir1"); /* file1.txt creation with O_CREAT|O_WRONLY flag*/ dbg(DBG_ERROR | DBG_VFS,"TEST: Create file1.txt with O_CREAT|O_WRONLY flag in directory dir/dir1\n"); fd = do_open("file1.txt", O_CREAT|O_WRONLY); do_write(fd, file1buf, strlen(file1buf)); do_close(fd); /* file2.txt creation with O_CREAT|O_RDONLY flag*/ dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir2\n"); do_chdir("/dir/dir2"); dbg(DBG_ERROR | DBG_VFS,"TEST: Create file2.txt with O_CREAT | O_RDONLY flag in directory dir/dir2\n"); fd = do_open("file2.txt", O_CREAT | O_RDONLY); do_close(fd); /* Write into file2.txt using O_WRONLY flag*/ dbg(DBG_ERROR | DBG_VFS,"TEST: Write into file2.txt with O_WRONLY flag in directory dir/dir2\n"); fd = do_open("file2.txt", O_WRONLY); do_write(fd, file2buf, strlen(file2buf)); do_close(fd); dbg(DBG_ERROR | DBG_VFS,"TEST: written chars: \"%s\" in file2.txt\n",file2buf); char *appendbuf=" Appending for O_WRONLY|O_APPEND mode"; /* Append into file2.txt using O_WRONLY|O_APPEND flag*/ dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_WRONLY|O_APPEND flag in directory dir/dir2\n"); fd = do_open("file2.txt", O_WRONLY|O_APPEND); do_write(fd, appendbuf, strlen(appendbuf)); do_close(fd); dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",appendbuf); fd = do_open("file2.txt", O_RDONLY); memset(readbuf,0,sizeof(char)*150); do_read(fd,readbuf,strlen(file2buf)+strlen(appendbuf)); dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf); char *append2buf=" Appending for O_RDWR|O_APPEND mode in file2"; /* Append into file2.txt using O_RDWR|O_APPEND flag*/ dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_RDWR|O_APPEND flag in directory dir/dir2\n"); fd = do_open("file2.txt", O_RDWR|O_APPEND); do_write(fd, append2buf, strlen(append2buf)); do_close(fd); dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",append2buf); fd = do_open("file2.txt", O_RDONLY); memset(readbuf,0,sizeof(char)*150); do_read(fd,readbuf,strlen(file2buf)+strlen(append2buf)+strlen(appendbuf)); dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf); dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source directory => /dir/dir2, Destination directory => /dir/linkofdir2 \n"); do_chdir("/"); do_link("dir/dir2","dir/linkofdir2"); dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source file => /dir/dir1/file1.txt, to the Destination => /dir/linkoffile1 \n"); do_link("dir/dir1/file1.txt","dir/linkoffile1"); dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming directory from dir/dir3 to dir/renamed \n"); do_rename("dir/dir3","dir/renameddir3"); dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming file from dir/dir1/file1.txt to dir/dir1/renamedfile1.txt \n"); do_rename("dir/dir1/file1.txt","dir/dir1/renamedfile1.txt"); dbg(DBG_ERROR | DBG_VFS,"TEST: Removing directory dir/dir4 \n"); do_rmdir("dir/dir4"); dbg(DBG_ERROR | DBG_VFS,"TEST: reading 18 chars from file: /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n"); fd = do_open("dir/linkoffile2", O_RDONLY); memset(readbuf,0,sizeof(char)*150); do_close(fd); dbg(DBG_ERROR | DBG_VFS,"TEST: read 18 chars: \"%s\" from file: /dir/linkoffile1\n",readbuf); dbg(DBG_ERROR | DBG_VFS,"TEST: reading file using lseek function on /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n"); memset(readbuf,0,sizeof(char)*150); fd = do_open("dir/linkoffile2", O_RDONLY); do_lseek(fd,-19,2); do_read(fd,readbuf,19); do_close(fd); dbg(DBG_ERROR | DBG_VFS,"TEST: read chars: \"%s\" using lseek from file: /dir/linkoffile1\n",readbuf); dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup()\n"); fd = do_open("/dir/dir2/file2.txt", O_RDONLY); int fd2= do_dup(fd); dbg(DBG_ERROR | DBG_VFS,"TEST: duplicate file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2); do_close(fd); do_close(fd2); dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup2()\n"); fd = do_open("/dir/dir2/file2.txt", O_RDONLY); fd2= do_dup2(fd,20); dbg(DBG_ERROR | DBG_VFS,"TEST: custom file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2); do_close(fd); do_close(fd2); /* Testing stat struct *statbuf; dbg(DBG_ERROR | DBG_VFS,"TEST: Testing the stat system call for directory dir\n"); do_stat("dir",statbuf); dbg(DBG_ERROR | DBG_VFS,"TEST: Output of stat for directory dir is :\"%s\" \n",statbuf);*/ shellTest(); return NULL; }
/* * Write user-specified files/dirs to opened archive. */ static void write_archive(struct archive *a, struct bsdtar *bsdtar) { struct sigaction sa; const char *arg; struct archive_entry *entry, *sparse_entry; /* We want to catch SIGINFO and SIGUSR1. */ siginfo_init(bsdtar); /* We also want to catch SIGQUIT and ^Q. */ if (sigquit_init()) exit(1); /* And SIGUSR2, too. */ sa.sa_handler = sigusr2_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGUSR2, &sa, NULL)) bsdtar_errc(bsdtar, 1, 0, "cannot install signal handler"); /* Allocate a buffer for file data. */ if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL) bsdtar_errc(bsdtar, 1, 0, "cannot allocate memory"); if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, archive_format(a)); if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) bsdtar_errc(bsdtar, 1, 0, "Cannot create read_disk object"); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL) archive_names_from_file(bsdtar, a); while (*bsdtar->argv) { if (truncate_archive(bsdtar)) break; if (checkpoint_archive(bsdtar, 0)) exit(1); arg = *bsdtar->argv; if (arg[0] == '-' && arg[1] == 'C') { arg += 2; if (*arg == '\0') { bsdtar->argv++; arg = *bsdtar->argv; if (arg == NULL) { bsdtar_warnc(bsdtar, 0, "Missing argument for -C"); bsdtar->return_value = 1; goto cleanup; } if (*arg == '\0') { bsdtar_warnc(bsdtar, 0, "Meaningless argument for -C: ''"); bsdtar->return_value = 1; goto cleanup; } } set_chdir(bsdtar, arg); } else { if (arg[0] != '/' && (arg[0] != '@' || arg[1] != '/') && (arg[0] != '@' || arg[1] != '@')) do_chdir(bsdtar); /* Handle a deferred -C */ if (arg[0] == '@' && arg[1] == '@') { if (append_archive_tarsnap(bsdtar, a, arg + 2) != 0) break; } else if (arg[0] == '@') { if (append_archive_filename(bsdtar, a, arg + 1) != 0) break; } else #if defined(_WIN32) && !defined(__CYGWIN__) write_hierarchy_win(bsdtar, a, arg, write_hierarchy); #else write_hierarchy(bsdtar, a, arg); #endif } bsdtar->argv++; } /* * This code belongs to bsdtar and is used when writing archives in * "new cpio" format. It has no effect in tarsnap, since tarsnap * doesn't write archives in this format; but I'm leaving it in to * make the diffs smaller. */ entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); while (entry != NULL) { write_entry_backend(bsdtar, a, entry, NULL, NULL); archive_entry_free(entry); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); } if (archive_write_close(a)) { bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } cleanup: /* Free file data buffer. */ free(bsdtar->buff); archive_entry_linkresolver_free(bsdtar->resolver); bsdtar->resolver = NULL; archive_read_finish(bsdtar->diskreader); bsdtar->diskreader = NULL; if (bsdtar->option_totals && (bsdtar->return_value == 0)) { fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); } archive_write_finish(a); /* Restore old SIGINFO + SIGUSR1 handlers. */ siginfo_done(bsdtar); }
/* * Write user-specified files/dirs to opened archive. */ static void write_archive(struct archive *a, struct bsdtar *bsdtar) { const char *arg; struct archive_entry *entry, *sparse_entry; /* Choose a suitable copy buffer size */ bsdtar->buff_size = 64 * 1024; while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block) bsdtar->buff_size *= 2; /* Try to compensate for space we'll lose to alignment. */ bsdtar->buff_size += 16 * 1024; /* Allocate a buffer for file data. */ if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL) lafe_errc(1, 0, "cannot allocate memory"); if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) lafe_errc(1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, archive_format(a)); /* Create a read_disk object. */ if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) lafe_errc(1, 0, "Cannot create read_disk object"); /* Tell the read_disk how handle symlink. */ switch (bsdtar->symlink_mode) { case 'H': archive_read_disk_set_symlink_hybrid(bsdtar->diskreader); break; case 'L': archive_read_disk_set_symlink_logical(bsdtar->diskreader); break; default: archive_read_disk_set_symlink_physical(bsdtar->diskreader); break; } /* Register entry filters. */ archive_read_disk_set_matching(bsdtar->diskreader, bsdtar->matching, excluded_callback, bsdtar); archive_read_disk_set_metadata_filter_callback( bsdtar->diskreader, metadata_filter, bsdtar); /* Set the behavior of archive_read_disk. */ archive_read_disk_set_behavior(bsdtar->diskreader, bsdtar->readdisk_flags); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL) archive_names_from_file(bsdtar, a); while (*bsdtar->argv) { arg = *bsdtar->argv; if (arg[0] == '-' && arg[1] == 'C') { arg += 2; if (*arg == '\0') { bsdtar->argv++; arg = *bsdtar->argv; if (arg == NULL) { lafe_warnc(0, "%s", "Missing argument for -C"); bsdtar->return_value = 1; goto cleanup; } if (*arg == '\0') { lafe_warnc(0, "Meaningless argument for -C: ''"); bsdtar->return_value = 1; goto cleanup; } } set_chdir(bsdtar, arg); } else { if (*arg != '/' && (arg[0] != '@' || arg[1] != '/')) do_chdir(bsdtar); /* Handle a deferred -C */ if (*arg == '@') { if (append_archive_filename(bsdtar, a, arg + 1) != 0) break; } else write_hierarchy(bsdtar, a, arg); } bsdtar->argv++; } archive_read_disk_set_matching(bsdtar->diskreader, NULL, NULL, NULL); archive_read_disk_set_metadata_filter_callback( bsdtar->diskreader, NULL, NULL); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); while (entry != NULL) { int r; struct archive_entry *entry2; struct archive *disk = bsdtar->diskreader; /* * This tricky code here is to correctly read the cotents * of the entry because the disk reader bsdtar->diskreader * is pointing at does not have any information about the * entry by this time and using archive_read_data_block() * with the disk reader consequently must fail. And we * have to re-open the entry to read the contents. */ /* TODO: Work with -C option as well. */ r = archive_read_disk_open(disk, archive_entry_sourcepath(entry)); if (r != ARCHIVE_OK) { lafe_warnc(archive_errno(disk), "%s", archive_error_string(disk)); bsdtar->return_value = 1; archive_entry_free(entry); continue; } /* * Invoke archive_read_next_header2() to work * archive_read_data_block(), which is called via write_file(), * without failure. */ entry2 = archive_entry_new(); r = archive_read_next_header2(disk, entry2); archive_entry_free(entry2); if (r != ARCHIVE_OK) { lafe_warnc(archive_errno(disk), "%s", archive_error_string(disk)); if (r == ARCHIVE_FATAL) bsdtar->return_value = 1; else archive_read_close(disk); archive_entry_free(entry); continue; } write_file(bsdtar, a, entry); archive_entry_free(entry); archive_read_close(disk); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); } if (archive_write_close(a)) { lafe_warnc(0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } cleanup: /* Free file data buffer. */ free(bsdtar->buff); archive_entry_linkresolver_free(bsdtar->resolver); bsdtar->resolver = NULL; archive_read_free(bsdtar->diskreader); bsdtar->diskreader = NULL; if (bsdtar->option_totals) { fprintf(stderr, "Total bytes written: %s\n", tar_i64toa(archive_filter_bytes(a, -1))); } archive_write_free(a); }
/* * Handle 'x' and 't' modes. */ static void read_archive(struct bsdtar *bsdtar, char mode) { FILE *out; struct archive *a; struct archive_entry *entry; const struct stat *st; int r; while (*bsdtar->argv) { include(bsdtar, *bsdtar->argv); bsdtar->argv++; } if (bsdtar->names_from_file != NULL) include_from_file(bsdtar, bsdtar->names_from_file); a = archive_read_new(); if (bsdtar->compress_program != NULL) archive_read_support_compression_program(a, bsdtar->compress_program); else archive_read_support_compression_all(a); archive_read_support_format_all(a); if (archive_read_open_file(a, bsdtar->filename, bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block : DEFAULT_BYTES_PER_BLOCK)) bsdtar_errc(bsdtar, 1, 0, "Error opening archive: %s", archive_error_string(a)); do_chdir(bsdtar); for (;;) { /* Support --fast-read option */ if (bsdtar->option_fast_read && unmatched_inclusions(bsdtar) == 0) break; r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_OK) bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); if (r <= ARCHIVE_WARN) bsdtar->return_value = 1; if (r == ARCHIVE_RETRY) { /* Retryable error: try again */ bsdtar_warnc(bsdtar, 0, "Retrying..."); continue; } if (r == ARCHIVE_FATAL) break; /* * Exclude entries that are too old. */ st = archive_entry_stat(entry); if (bsdtar->newer_ctime_sec > 0) { if (st->st_ctime < bsdtar->newer_ctime_sec) continue; /* Too old, skip it. */ if (st->st_ctime == bsdtar->newer_ctime_sec && ARCHIVE_STAT_CTIME_NANOS(st) <= bsdtar->newer_ctime_nsec) continue; /* Too old, skip it. */ } if (bsdtar->newer_mtime_sec > 0) { if (st->st_mtime < bsdtar->newer_mtime_sec) continue; /* Too old, skip it. */ if (st->st_mtime == bsdtar->newer_mtime_sec && ARCHIVE_STAT_MTIME_NANOS(st) <= bsdtar->newer_mtime_nsec) continue; /* Too old, skip it. */ } /* * Note that pattern exclusions are checked before * pathname rewrites are handled. This gives more * control over exclusions, since rewrites always lose * information. (For example, consider a rewrite * s/foo[0-9]/foo/. If we check exclusions after the * rewrite, there would be no way to exclude foo1/bar * while allowing foo2/bar.) */ if (excluded(bsdtar, archive_entry_pathname(entry))) continue; /* Excluded by a pattern test. */ /* * Modify the pathname as requested by the user. We * do this for -t as well to give users a way to * preview the effects of their rewrites. We also do * this before extraction security checks (including * leading '/' removal). Note that some rewrite * failures prevent extraction. */ if (edit_pathname(bsdtar, entry)) continue; /* Excluded by a rewrite failure. */ if (mode == 't') { /* Perversely, gtar uses -O to mean "send to stderr" * when used with -t. */ out = bsdtar->option_stdout ? stderr : stdout; if (bsdtar->verbose < 2) safe_fprintf(out, "%s", archive_entry_pathname(entry)); else list_item_verbose(bsdtar, out, entry); fflush(out); r = archive_read_data_skip(a); if (r == ARCHIVE_WARN) { fprintf(out, "\n"); bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); } if (r == ARCHIVE_RETRY) { fprintf(out, "\n"); bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); } if (r == ARCHIVE_FATAL) { fprintf(out, "\n"); bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); bsdtar->return_value = 1; break; } fprintf(out, "\n"); } else { if (bsdtar->option_interactive && !yes("extract '%s'", archive_entry_pathname(entry))) continue; /* * Format here is from SUSv2, including the * deferred '\n'. */ if (bsdtar->verbose) { safe_fprintf(stderr, "x %s", archive_entry_pathname(entry)); fflush(stderr); } if (bsdtar->option_stdout) r = archive_read_data_into_fd(a, 1); else r = archive_read_extract(a, entry, bsdtar->extract_flags); if (r != ARCHIVE_OK) { if (!bsdtar->verbose) safe_fprintf(stderr, "%s", archive_entry_pathname(entry)); safe_fprintf(stderr, ": %s", archive_error_string(a)); if (!bsdtar->verbose) fprintf(stderr, "\n"); bsdtar->return_value = 1; } if (bsdtar->verbose) fprintf(stderr, "\n"); if (r == ARCHIVE_FATAL) break; } } if (bsdtar->verbose > 2) fprintf(stdout, "Archive Format: %s, Compression: %s\n", archive_format_name(a), archive_compression_name(a)); archive_read_finish(a); }
/* * Handle 'x' and 't' modes. */ static void read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer) { struct progress_data progress_data; FILE *out; struct archive *a; struct archive_entry *entry; const char *reader_options; int r; while (*bsdtar->argv) { if (archive_match_include_pattern(bsdtar->matching, *bsdtar->argv) != ARCHIVE_OK) lafe_errc(1, 0, "Error inclusion pattern: %s", archive_error_string(bsdtar->matching)); bsdtar->argv++; } if (bsdtar->names_from_file != NULL) if (archive_match_include_pattern_from_file( bsdtar->matching, bsdtar->names_from_file, bsdtar->option_null) != ARCHIVE_OK) lafe_errc(1, 0, "Error inclusion pattern: %s", archive_error_string(bsdtar->matching)); a = archive_read_new(); if (cset_read_support_filter_program(bsdtar->cset, a) == 0) archive_read_support_filter_all(a); archive_read_support_format_all(a); reader_options = getenv(ENV_READER_OPTIONS); if (reader_options != NULL) { char *p; /* Set default read options. */ p = malloc(sizeof(IGNORE_WRONG_MODULE_NAME) + strlen(reader_options) + 1); if (p == NULL) lafe_errc(1, errno, "Out of memory"); /* Prepend magic code to ignore options for * a format or modules which are not added to * the archive read object. */ strncpy(p, IGNORE_WRONG_MODULE_NAME, sizeof(IGNORE_WRONG_MODULE_NAME) -1); strcpy(p + sizeof(IGNORE_WRONG_MODULE_NAME) -1, reader_options); r = archive_read_set_options(a, p); free(p); if (r == ARCHIVE_FATAL) lafe_errc(1, 0, "%s", archive_error_string(a)); else archive_clear_error(a); } if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options)) lafe_errc(1, 0, "%s", archive_error_string(a)); if (archive_read_open_filename(a, bsdtar->filename, bsdtar->bytes_per_block)) lafe_errc(1, 0, "Error opening archive: %s", archive_error_string(a)); do_chdir(bsdtar); if (mode == 'x') { /* Set an extract callback so that we can handle SIGINFO. */ progress_data.bsdtar = bsdtar; progress_data.archive = a; archive_read_extract_set_progress_callback(a, progress_func, &progress_data); } if (mode == 'x' && bsdtar->option_chroot) { #if HAVE_CHROOT if (chroot(".") != 0) lafe_errc(1, errno, "Can't chroot to \".\""); #else lafe_errc(1, 0, "chroot isn't supported on this platform"); #endif } for (;;) { /* Support --fast-read option */ if (bsdtar->option_fast_read && archive_match_path_unmatched_inclusions(bsdtar->matching) == 0) break; r = archive_read_next_header(a, &entry); progress_data.entry = entry; if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_OK) lafe_warnc(0, "%s", archive_error_string(a)); if (r <= ARCHIVE_WARN) bsdtar->return_value = 1; if (r == ARCHIVE_RETRY) { /* Retryable error: try again */ lafe_warnc(0, "Retrying..."); continue; } if (r == ARCHIVE_FATAL) break; if (bsdtar->uid >= 0) { archive_entry_set_uid(entry, bsdtar->uid); archive_entry_set_uname(entry, NULL); } if (bsdtar->gid >= 0) { archive_entry_set_gid(entry, bsdtar->gid); archive_entry_set_gname(entry, NULL); } if (bsdtar->uname) archive_entry_set_uname(entry, bsdtar->uname); if (bsdtar->gname) archive_entry_set_gname(entry, bsdtar->gname); /* * Note that pattern exclusions are checked before * pathname rewrites are handled. This gives more * control over exclusions, since rewrites always lose * information. (For example, consider a rewrite * s/foo[0-9]/foo/. If we check exclusions after the * rewrite, there would be no way to exclude foo1/bar * while allowing foo2/bar.) */ if (archive_match_excluded(bsdtar->matching, entry)) continue; /* Excluded by a pattern test. */ if (mode == 't') { /* Perversely, gtar uses -O to mean "send to stderr" * when used with -t. */ out = bsdtar->option_stdout ? stderr : stdout; /* * TODO: Provide some reasonable way to * preview rewrites. gtar always displays * the unedited path in -t output, which means * you cannot easily preview rewrites. */ if (bsdtar->verbose < 2) safe_fprintf(out, "%s", archive_entry_pathname(entry)); else list_item_verbose(bsdtar, out, entry); fflush(out); r = archive_read_data_skip(a); if (r == ARCHIVE_WARN) { fprintf(out, "\n"); lafe_warnc(0, "%s", archive_error_string(a)); } if (r == ARCHIVE_RETRY) { fprintf(out, "\n"); lafe_warnc(0, "%s", archive_error_string(a)); } if (r == ARCHIVE_FATAL) { fprintf(out, "\n"); lafe_warnc(0, "%s", archive_error_string(a)); bsdtar->return_value = 1; break; } fprintf(out, "\n"); } else { /* Note: some rewrite failures prevent extraction. */ if (edit_pathname(bsdtar, entry)) continue; /* Excluded by a rewrite failure. */ if (bsdtar->option_interactive && !yes("extract '%s'", archive_entry_pathname(entry))) continue; /* * Format here is from SUSv2, including the * deferred '\n'. */ if (bsdtar->verbose) { safe_fprintf(stderr, "x %s", archive_entry_pathname(entry)); fflush(stderr); } /* TODO siginfo_printinfo(bsdtar, 0); */ if (bsdtar->option_stdout) r = archive_read_data_into_fd(a, 1); else r = archive_read_extract2(a, entry, writer); if (r != ARCHIVE_OK) { if (!bsdtar->verbose) safe_fprintf(stderr, "%s", archive_entry_pathname(entry)); safe_fprintf(stderr, ": %s", archive_error_string(a)); if (!bsdtar->verbose) fprintf(stderr, "\n"); bsdtar->return_value = 1; } if (bsdtar->verbose) fprintf(stderr, "\n"); if (r == ARCHIVE_FATAL) break; } } r = archive_read_close(a); if (r != ARCHIVE_OK) lafe_warnc(0, "%s", archive_error_string(a)); if (r <= ARCHIVE_WARN) bsdtar->return_value = 1; if (bsdtar->verbose > 2) fprintf(stdout, "Archive Format: %s, Compression: %s\n", archive_format_name(a), archive_filter_name(a, 0)); archive_read_free(a); }
/* * Handle 'x' and 't' modes. */ static void read_archive(struct bsdtar *bsdtar, char mode) { struct progress_data progress_data; FILE *out; struct archive *a; struct archive_entry *entry; const struct stat *st; int r; while (*bsdtar->argv) { lafe_include(&bsdtar->matching, *bsdtar->argv); bsdtar->argv++; } if (bsdtar->names_from_file != NULL) lafe_include_from_file(&bsdtar->matching, bsdtar->names_from_file, bsdtar->option_null); a = archive_read_new(); if (bsdtar->compress_program != NULL) archive_read_support_compression_program(a, bsdtar->compress_program); else archive_read_support_compression_all(a); archive_read_support_format_all(a); if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options)) lafe_errc(1, 0, "%s", archive_error_string(a)); if (archive_read_open_file(a, bsdtar->filename, bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block : DEFAULT_BYTES_PER_BLOCK)) lafe_errc(1, 0, "Error opening archive: %s", archive_error_string(a)); do_chdir(bsdtar); if (mode == 'x') { /* Set an extract callback so that we can handle SIGINFO. */ progress_data.bsdtar = bsdtar; progress_data.archive = a; archive_read_extract_set_progress_callback(a, progress_func, &progress_data); } if (mode == 'x' && bsdtar->option_chroot) { #if HAVE_CHROOT if (chroot(".") != 0) lafe_errc(1, errno, "Can't chroot to \".\""); #else lafe_errc(1, 0, "chroot isn't supported on this platform"); #endif } for (;;) { /* Support --fast-read option */ if (bsdtar->option_fast_read && lafe_unmatched_inclusions(bsdtar->matching) == 0) break; r = archive_read_next_header(a, &entry); progress_data.entry = entry; if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_OK) lafe_warnc(0, "%s", archive_error_string(a)); if (r <= ARCHIVE_WARN) bsdtar->return_value = 1; if (r == ARCHIVE_RETRY) { /* Retryable error: try again */ lafe_warnc(0, "Retrying..."); continue; } if (r == ARCHIVE_FATAL) break; if (bsdtar->uid >= 0) { archive_entry_set_uid(entry, bsdtar->uid); archive_entry_set_uname(entry, NULL); } if (bsdtar->gid >= 0) { archive_entry_set_gid(entry, bsdtar->gid); archive_entry_set_gname(entry, NULL); } if (bsdtar->uname) archive_entry_set_uname(entry, bsdtar->uname); if (bsdtar->gname) archive_entry_set_gname(entry, bsdtar->gname); /* * Exclude entries that are too old. */ st = archive_entry_stat(entry); if (bsdtar->newer_ctime_sec > 0) { if (st->st_ctime < bsdtar->newer_ctime_sec) continue; /* Too old, skip it. */ if (st->st_ctime == bsdtar->newer_ctime_sec && ARCHIVE_STAT_CTIME_NANOS(st) <= bsdtar->newer_ctime_nsec) continue; /* Too old, skip it. */ } if (bsdtar->newer_mtime_sec > 0) { if (st->st_mtime < bsdtar->newer_mtime_sec) continue; /* Too old, skip it. */ if (st->st_mtime == bsdtar->newer_mtime_sec && ARCHIVE_STAT_MTIME_NANOS(st) <= bsdtar->newer_mtime_nsec) continue; /* Too old, skip it. */ } /* * Note that pattern exclusions are checked before * pathname rewrites are handled. This gives more * control over exclusions, since rewrites always lose * information. (For example, consider a rewrite * s/foo[0-9]/foo/. If we check exclusions after the * rewrite, there would be no way to exclude foo1/bar * while allowing foo2/bar.) */ if (lafe_excluded(bsdtar->matching, archive_entry_pathname(entry))) continue; /* Excluded by a pattern test. */ if (mode == 't') { /* Perversely, gtar uses -O to mean "send to stderr" * when used with -t. */ out = bsdtar->option_stdout ? stderr : stdout; /* * TODO: Provide some reasonable way to * preview rewrites. gtar always displays * the unedited path in -t output, which means * you cannot easily preview rewrites. */ if (bsdtar->verbose < 2) safe_fprintf(out, "%s", archive_entry_pathname(entry)); else list_item_verbose(bsdtar, out, entry); fflush(out); r = archive_read_data_skip(a); if (r == ARCHIVE_WARN) { fprintf(out, "\n"); lafe_warnc(0, "%s", archive_error_string(a)); } if (r == ARCHIVE_RETRY) { fprintf(out, "\n"); lafe_warnc(0, "%s", archive_error_string(a)); } if (r == ARCHIVE_FATAL) { fprintf(out, "\n"); lafe_warnc(0, "%s", archive_error_string(a)); bsdtar->return_value = 1; break; } fprintf(out, "\n"); } else { /* Note: some rewrite failures prevent extraction. */ if (edit_pathname(bsdtar, entry)) continue; /* Excluded by a rewrite failure. */ if (bsdtar->option_interactive && !yes("extract '%s'", archive_entry_pathname(entry))) continue; /* * Format here is from SUSv2, including the * deferred '\n'. */ if (bsdtar->verbose) { safe_fprintf(stderr, "x %s", archive_entry_pathname(entry)); fflush(stderr); } // TODO siginfo_printinfo(bsdtar, 0); if (bsdtar->option_stdout) r = archive_read_data_into_fd(a, 1); else r = archive_read_extract(a, entry, bsdtar->extract_flags); if (r != ARCHIVE_OK) { if (!bsdtar->verbose) safe_fprintf(stderr, "%s", archive_entry_pathname(entry)); safe_fprintf(stderr, ": %s", archive_error_string(a)); if (!bsdtar->verbose) fprintf(stderr, "\n"); bsdtar->return_value = 1; } if (bsdtar->verbose) fprintf(stderr, "\n"); if (r == ARCHIVE_FATAL) break; } } r = archive_read_close(a); if (r != ARCHIVE_OK) lafe_warnc(0, "%s", archive_error_string(a)); if (r <= ARCHIVE_WARN) bsdtar->return_value = 1; if (bsdtar->verbose > 2) fprintf(stdout, "Archive Format: %s, Compression: %s\n", archive_format_name(a), archive_compression_name(a)); archive_read_finish(a); }
/* * Write user-specified files/dirs to opened archive. */ static void write_archive(struct archive *a, struct bsdtar *bsdtar) { const char *arg; struct archive_entry *entry, *sparse_entry; /* Choose a suitable copy buffer size */ bsdtar->buff_size = 64 * 1024; while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block) bsdtar->buff_size *= 2; /* Try to compensate for space we'll lose to alignment. */ bsdtar->buff_size += 16 * 1024; /* Allocate a buffer for file data. */ if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL) lafe_errc(1, 0, "cannot allocate memory"); if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) lafe_errc(1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, archive_format(a)); if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) lafe_errc(1, 0, "Cannot create read_disk object"); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL) archive_names_from_file(bsdtar, a); while (*bsdtar->argv) { arg = *bsdtar->argv; if (arg[0] == '-' && arg[1] == 'C') { arg += 2; if (*arg == '\0') { bsdtar->argv++; arg = *bsdtar->argv; if (arg == NULL) { lafe_warnc(0, "%s", "Missing argument for -C"); bsdtar->return_value = 1; goto cleanup; } if (*arg == '\0') { lafe_warnc(0, "Meaningless argument for -C: ''"); bsdtar->return_value = 1; goto cleanup; } } set_chdir(bsdtar, arg); } else { if (*arg != '/' && (arg[0] != '@' || arg[1] != '/')) do_chdir(bsdtar); /* Handle a deferred -C */ if (*arg == '@') { if (append_archive_filename(bsdtar, a, arg + 1) != 0) break; } else write_hierarchy(bsdtar, a, arg); } bsdtar->argv++; } entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); while (entry != NULL) { write_file(bsdtar, a, entry); archive_entry_free(entry); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); } if (archive_write_close(a)) { lafe_warnc(0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } cleanup: /* Free file data buffer. */ free(bsdtar->buff); archive_entry_linkresolver_free(bsdtar->resolver); bsdtar->resolver = NULL; archive_read_free(bsdtar->diskreader); bsdtar->diskreader = NULL; if (bsdtar->option_totals) { fprintf(stderr, "Total bytes written: %s\n", tar_i64toa(archive_position_compressed(a))); } archive_write_free(a); }
void addFilespec(FILE *fd, int squash_uids, int squash_perms) { unsigned long rmode, mode, uid, gid, major, minor, i; unsigned long start, increment, count, octmode, decmode; char *c, *dir, *name, *dname = NULL, *path = NULL, *path2 = NULL, *line = NULL; char type; size_t len; int argv, i2, overWrite = 0, lineno = 0; __u16 inodeType; while ( getline(&line, &len, fd) >= 0 ) { rmode = mode = uid = gid = major = minor = start = count = overWrite = 0; increment = 1; lineno++; if (( c = strchr(line, '#'))) *c = 0; if ( path ) { free( path ); path = NULL; } if ( path2 ) { free( path2 ); path2 = NULL; } argv = sscanf(line, "%" SCANF_PREFIX "s %c %ld %lu %lu %lu %lu %lu %lu %lu", SCANF_STRING(path), &type, &rmode, &uid, &gid, &major, &minor, &start, &increment, &count); if ( argv < 3 ) { if ( argv > 0 ) log_warning("device table[%d]: bad format for entry '%s' [skip]", lineno, path); continue; } i2 = 0; octmode = rmode; decmode = 0; while ( octmode != 0 ) { decmode = decmode + (octmode % 10) * pow(8, i2++); octmode = octmode / 10; } if ( squash_uids ) uid = gid = 0; mode = decmode; path2 = strdup( path ); name = basename( path ); dir = dirname( path2 ); if (( !strcmp(name, ".")) || ( !strcmp(name, "..")) || ( !strcmp(name, "/"))) { log_warning("device table[%d]: [skip]", lineno); continue; } log_action(ACT_CHDIR, dir, NULL, 0, 0, 0, 0, 0, 0, 0); if ( !do_chdir(dir)) { log_warning("device table[%d]: target directory '%s' for entry '%s' does not exist [skip]", lineno, dir, name); log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0); if ( !do_chdir("/")) log_error("[Filesystem error] cannot chdir to root"); continue; } if (( type != 'd' ) && ( type != 'f' ) && ( type != 'p' ) && ( type != 'c' ) && ( type != 'b' ) && ( type != 's')) { log_warning("device table[%d]: bad type '%c' for entry '%s' [skip]", lineno, type, name); continue; } if (squash_perms) { mode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO ); rmode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO); } if ( count > 0 ) { if ( dname ) { free( dname ); dname = NULL; } unsigned len; len = strlen(name) + 10; dname = malloc(len + 1); for ( i = start; i < count; i++ ) { snprintf(dname, len, "%s%lu", name, i); if (( overWrite = name_to_inode(dname))) inodeType = inode_mode(dname); if (( type == 'd' ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType))) log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), dname); else if (( type != 'd' ) && ( overWrite )) { if ( LINUX_S_ISDIR(inodeType)) log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), dname); if ((!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) && (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) && (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType))) log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].", log_cwd(), dname, inodeType); } switch ( type ) { case 'd': mode |= LINUX_S_IFDIR; log_action(ACT_MKDIR, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !overWrite ) if ( !do_mkdir(dname)) log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), dname); break; case 'c': case 'b': if ( type == 'c' ) mode |= LINUX_S_IFCHR; else mode |= LINUX_S_IFBLK; if ( overWrite ) { log_action(ACT_RM, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_rm(dname)) log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), dname); } log_action(ACT_MKNOD, dname, NULL, 0, 0, 0, type, major, minor + ((i * increment) - start), overWrite); if ( !do_mknod(dname, type, major, minor + ((i * increment) - start))) log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), dname); break; case 's': case 'p': if ( type == 's' ) mode |= LINUX_S_IFSOCK; else mode |= LINUX_S_IFIFO; if ( overWrite ) { log_action(ACT_RM, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_rm(dname)) log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), dname); } log_action(ACT_MKNOD, dname, NULL, 0, 0, 0, type, 0, 0, overWrite); if ( !do_mknod(dname, type, 0, 0)) log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), dname); break; } log_action(ACT_CHMOD, dname, NULL, rmode, 0, 0, 0, 0, 0, 0); if ( !do_chmod(dname, rmode)) log_error("[Filesystem error] cannot chmod %s/%s", log_cwd(), dname); log_action(ACT_CHOWN, dname, NULL, 0, uid, gid, 0, 0, 0, 0); if ( !do_chown(dname, uid, gid)) log_error("[Filesystem error] cannot chown %s/%s", log_cwd(), dname); } log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0); if ( !do_chdir("/")) log_error("[Filesystem error] cannot chdir to root"); free(dname); dname = NULL; } else { if (( overWrite = name_to_inode(name))) inodeType = inode_mode(name); if (( type == 'd' ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType))) log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), dname); else if ( type != 'd' ) { if (( overWrite ) && ( LINUX_S_ISDIR(inodeType))) log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), dname); if (( overWrite ) && (!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) && (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) && (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType))) log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].", log_cwd(), dname, inodeType); } switch ( type ) { case 'd': mode |= LINUX_S_IFDIR; log_action(ACT_MKDIR, name, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !overWrite ) if ( !do_mkdir(name)) log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), name); break; case 'c': case 'b': if ( type == 'c' ) mode |= LINUX_S_IFCHR; else mode |= LINUX_S_IFBLK; if ( overWrite ) { log_action(ACT_RM, name, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_rm(name)) log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), name); } log_action(ACT_MKNOD, name, NULL, 0, 0, 0, type, major, minor, overWrite); if ( !do_mknod(name, type, major, minor)) log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), name); break; case 's': case 'p': if ( type == 's' ) mode |= LINUX_S_IFSOCK; else mode |= LINUX_S_IFIFO; if ( overWrite ) { log_action(ACT_RM, name, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_rm(name)) log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), name); } log_action(ACT_MKNOD, name, NULL, 0, 0, 0, type, 0, 0, overWrite); if ( !do_mknod(name, type, 0, 0)) log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), name); break; } log_action(ACT_CHMOD, name, NULL, rmode, 0, 0, 0, 0, 0, 0); if ( !do_chmod(name, rmode)) log_error("[Filesystem error] cannot chmod %s/%s", log_cwd(), name); log_action(ACT_CHOWN, name, NULL, 0, uid, gid, 0, 0, 0, 0); if ( !do_chown(name, uid, gid)) log_error("[Filesystem error] cannot chown %s/%s", log_cwd(), name); log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0); if ( !do_chdir("/")) log_error("[Filesystem error] cannot chdir to root"); } } if ( line ) { free( line ); line = NULL; } if ( path ) { free( path ); path = NULL; } if ( path2 ) { free( path2 ); path2 = NULL; } }
/* * Write user-specified files/dirs to opened archive. */ static void write_archive(struct archive *a, struct bsdtar *bsdtar) { const char *arg; struct archive_entry *entry, *sparse_entry; /* We want to catch SIGINFO and SIGUSR1. */ siginfo_init(bsdtar); /* Allocate a buffer for file data. */ if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL) bsdtar_errc(bsdtar, 1, 0, "cannot allocate memory"); if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver"); archive_entry_linkresolver_set_strategy(bsdtar->resolver, archive_format(a)); if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) bsdtar_errc(bsdtar, 1, 0, "Cannot create read_disk object"); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL) archive_names_from_file(bsdtar, a); while (*bsdtar->argv) { arg = *bsdtar->argv; if (arg[0] == '-' && arg[1] == 'C') { arg += 2; if (*arg == '\0') { bsdtar->argv++; arg = *bsdtar->argv; if (arg == NULL) { bsdtar_warnc(bsdtar, 1, 0, "Missing argument for -C"); bsdtar->return_value = 1; goto cleanup; } } set_chdir(bsdtar, arg); } else { if (*arg != '/' && (arg[0] != '@' || arg[1] != '/')) do_chdir(bsdtar); /* Handle a deferred -C */ if (*arg == '@') { if (append_archive_filename(bsdtar, a, arg + 1) != 0) break; } else #if defined(_WIN32) && !defined(__CYGWIN__) write_hierarchy_win(bsdtar, a, arg, write_hierarchy); #else write_hierarchy(bsdtar, a, arg); #endif } bsdtar->argv++; } entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); while (entry != NULL) { write_entry_backend(bsdtar, a, entry); archive_entry_free(entry); entry = NULL; archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); } if (archive_write_close(a)) { bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a)); bsdtar->return_value = 1; } cleanup: /* Free file data buffer. */ free(bsdtar->buff); archive_entry_linkresolver_free(bsdtar->resolver); bsdtar->resolver = NULL; archive_read_finish(bsdtar->diskreader); bsdtar->diskreader = NULL; if (bsdtar->option_totals) { fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n", (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a)); } archive_write_finish(a); /* Restore old SIGINFO + SIGUSR1 handlers. */ siginfo_done(bsdtar); }
void addPath(const char *path, int squash_uids, int squash_perms) { size_t len; char *full_name = NULL, *lnk = NULL; struct dirent *file = NULL; DIR *direc = NULL; struct stat st; int overWrite; __u16 inodeType; direc = opendir(path); if ( !direc ) log_error("[Local fs opendir] Cannot open directory %s", path); while (( file = readdir(direc)) != NULL ) { if (( !strcmp(file->d_name, "." )) || ( !strcmp(file->d_name, ".." ))) continue; len = strlen(path) + strlen( file->d_name ) + 3; if ( full_name ) { free( full_name ); full_name = NULL; } full_name = (char*)malloc(len + 2); if ( !full_name ) log_error("[Local fs stat] Memory allocation error ( full_name --> %s/%s )", path, file->d_name); memset(full_name, 0, len + 2); snprintf(full_name, len, "%s/%s", path, file->d_name); lstat(full_name, &st); mode_t fmt = st.st_mode & S_IFMT; if ( squash_uids ) st.st_uid = st.st_gid = 0; if ( squash_perms ) st.st_mode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO ); overWrite = name_to_inode( file->d_name ); if ( st.st_nlink > 1 ) { if (( lnk = linklist_add(st.st_dev, st.st_ino, full_name + modPath_path_len))) { if ( overWrite ) { log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_rm(file->d_name)) log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name); } log_action(ACT_HARDLINK, file->d_name, lnk, 0, 0, 0, 0, 0, 0, overWrite); if (!do_hardlink(&st, lnk, file->d_name)) log_error("[Filesystem error] cannot hardlink %s --> %s", file->d_name, lnk); continue; } } if ( overWrite ) inodeType = inode_mode( file->d_name ); if (( fmt == S_IFDIR ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType))) log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), file->d_name); else if (( fmt != S_IFDIR) && ( overWrite )) { if ( LINUX_S_ISDIR(inodeType)) log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), file->d_name); if ((!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) && (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) && (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType))) log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].", log_cwd(), file->d_name); } switch ( fmt ) { case S_IFDIR: // Directory log_action(ACT_MKDIR, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !overWrite ) if ( !do_mkdir( &st, file->d_name )) log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), file->d_name); log_action(ACT_CHMODE, file->d_name, NULL, st.st_mode, 0, 0, 0, 0, 0, overWrite); if ( !do_chmode(file->d_name, st.st_mode)) log_error("[Filesystem error] Failed to chmode 0x%x for directory %s/%s", st.st_mode, log_cwd(), file->d_name); log_action(ACT_CHOWN, file->d_name, NULL, 0, st.st_uid, st.st_gid, 0, 0, 0, 0); if ( !do_chown(file->d_name, st.st_uid, st.st_gid)) log_error("[Filesystem error] Failed to chown %ld, %ld for directory %s/%s", st.st_uid, st.st_gid, log_cwd(), file->d_name); log_action(ACT_CHDIR, file->d_name, NULL, 0, 0, 0, 0, 0, 0, 0); if ( !do_chdir( file->d_name )) log_error("[Filesystem error] cannot chdir to newly created %s/%s", log_cwd(), file->d_name); addPath(full_name, squash_uids, squash_perms); log_action(ACT_CHDIR, "..", NULL, 0, 0, 0, 0, 0, 0, 0); if ( !do_chdir("..")) log_error("[Filesystem error] cannot chdir to parent directory"); break; case S_IFREG: // Regular file if ( overWrite ) { log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_rm(file->d_name)) log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name); } log_action(ACT_WRITE, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_write(full_name, file->d_name)) log_error("[Filesystem error] cannot write %s/%s", log_cwd(), file->d_name); break; case S_IFLNK: // Symbolic link lnk = (char*)malloc(MAX_PATHSIZE + 2); if ( !lnk ) log_error("[symlink] Memory allocation error (lnk)"); int len = readlink(full_name, lnk, MAX_PATHSIZE); if ( len == -1 ) { free(lnk); log_error("[Local filesystem error] Cannot read destination for link %s/%s", log_cwd(), file->d_name); } else lnk[len] = '\0'; if ( overWrite ) { log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_rm(file->d_name)) log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name); } log_action(ACT_SYMLINK, file->d_name, lnk, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_symlink(&st, lnk, file->d_name)) log_error("[Filesystem error] cannot symlink %s/%s --> %s", log_cwd(), file->d_name, lnk); free(lnk); break; case S_IFBLK: // Block device node case S_IFCHR: // Character device node case S_IFSOCK: // socket case S_IFIFO: // fifo if ( overWrite ) { log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite); if ( !do_rm(file->d_name)) log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name); } char nodetype = ( fmt == S_IFBLK ? 'b' : ( fmt == S_IFCHR ? 'c' : ( fmt == S_IFSOCK ? 's' : 'p' ))); unsigned long major = 0, minor = 0; if (( nodetype == 'b' ) || ( nodetype == 'c' )) { major = (long)major(st.st_rdev); minor = (long)minor(st.st_rdev); } log_action(ACT_MKNOD, file->d_name, NULL, 0, 0, 0, nodetype, major, minor, overWrite); if ( !do_mknod(file->d_name, nodetype, major, minor)) log_error("[Filesystem error] cannot mknod %c %ld,%ld %s/%s", log_cwd(), nodetype, major, minor, log_cwd(), file->d_name); break; } if ( fmt != S_IFDIR ) { // Not dir ? log_action(ACT_CHMODE, file->d_name, NULL, st.st_mode, 0, 0, 0, 0, 0, overWrite); if ( !do_chmode(file->d_name, st.st_mode)) log_error("[Filesystem error] Failed to chmode 0x%x for file %s/%s", st.st_mode, log_cwd(), file->d_name); log_action(ACT_CHOWN, file->d_name, NULL, 0, st.st_uid, st.st_gid, 0, 0, 0, 0); if ( !do_chown(file->d_name, st.st_uid, st.st_gid)) log_error("[Filesystem error] Failed to chown %ld, %ld for file %s/%s", st.st_uid, st.st_gid, log_cwd(), file->d_name); } if ( full_name ) { free( full_name ); full_name = NULL; } } closedir(direc); }
int main(int argc, char** argv) { int c, i, mypid; int opt_depth = 1; int opt_mknod = 0; static struct option long_opt[] = { {"depth", 1, 0, 'd' }, {"help", 0, 0, 'h' }, {"mknod", 0, 0, 'm' }, {"output", 1, 0, 'o' }, {"trace", 1, 0, 't' }, {"verbose", 0, 0, 'v' }, {0,0,0,0} }; char *outputfilename = NULL; char *base_pathname; char pathname[PATH_MAX]; char mark_buf[PATH_MAX + 50]; char mycwd[PATH_MAX]; char *pname = argv[0]; while ((c = getopt_long(argc, argv, "d:mhvo:", long_opt, NULL)) != -1) { switch (c) { case 'd': opt_depth = atoi(optarg); if ((opt_depth == 0) || (opt_depth > 1100)) usage(pname); break; case 'm': opt_mknod = 1; break; case 't': opt_trace = 1; break; case 'v': opt_verbose = 1; break; case 'o': outputfilename = optarg; break; case 'h': case '?': case ':': default: usage(pname); break; } } if (optind != (argc - 1)) usage(pname); base_pathname = argv[optind]; mypid = getpid(); if (!getcwd(&mycwd[0], sizeof(mycwd))) { fprintf(stderr, "%s: unable to getcwd()\n", pname); exit(1); } printf("%s(pid=%d) depth=%d mknod=%d, basepathname=%s, trace=%d\n", pname, mypid, opt_depth, opt_mknod, base_pathname, opt_trace); if (outputfilename) printf("outputfilename=%s\n", outputfilename); if (opt_trace) { ltrace_start(); ltrace_clear(); snprintf(mark_buf, PATH_MAX, "Initialize - mkdir %s; chdir %s", base_pathname, base_pathname); ltrace_mark(2, mark_buf); } if (do_mkdir(base_pathname)!=0) exit(1); if (do_chdir(base_pathname)!=0) exit(1); /* Create directory tree with depth level of subdirectories */ if (opt_trace) { snprintf(mark_buf, PATH_MAX, "Create Directory Tree (depth %d)", opt_depth); ltrace_mark(2, mark_buf); } for (i = 0; i < opt_depth; i++) { snprintf(pathname, sizeof(pathname), "%d", i + 1); if (i == (opt_depth - 1)) { /* Last Iteration */ if (opt_trace) { snprintf(mark_buf, PATH_MAX, "Tree Leaf (%d) %s/stat", i, (opt_mknod ? "mknod" : "mkdir")); ltrace_mark(3, mark_buf); } if (opt_mknod) do_mknod(pathname); else do_mkdir(pathname); /* Now stat it */ do_stat(pathname); } else { /* Not Leaf */ if (opt_trace) { snprintf(mark_buf, sizeof(mark_buf), "Tree Level (%d) mkdir/stat/chdir", i); ltrace_mark(3, mark_buf); } do_mkdir(pathname); do_stat(pathname); do_chdir(pathname); } } /* Stat through directory tree with fullpaths */ if (opt_trace) { snprintf(mark_buf, PATH_MAX, "Walk Directory Tree"); ltrace_mark(2, mark_buf); } do_chdir(base_pathname); strncpy(pathname, base_pathname, sizeof(pathname)); c = strlen(base_pathname); for (i = 0; i < opt_depth; i++) { c += snprintf(pathname + c, sizeof(pathname) - c, "/%d", i+1); if (opt_trace) { snprintf(mark_buf, PATH_MAX, "stat %s", pathname); ltrace_mark(2, mark_buf); } do_stat(pathname); } if (opt_trace && outputfilename) { ltrace_write_file(outputfilename); ltrace_add_processnames(outputfilename); ltrace_stop(); } do_chdir(base_pathname); printf("%s (pid=%d) done.\n", pname, mypid); return 0; }