int rmdir_test() { int ret = 0; printf("rmdir_test: Start\n"); /* * Remove existing directory (=NEW_DIR_PATH_1) * which was created within mkdir_test */ printf("\tbegin: Remove existing directory(%s)\n", NEW_DIR_PATH_1); if((ret = do_rmdir(NEW_DIR_PATH_1)) != 0){ goto out; } printf("\tend: Success\n"); /* * Remove non-existing directory */ printf("\tbegin: Remove non-existing directory(%s)\n", DUMMY_DIR_PATH_1); ret = do_rmdir(DUMMY_DIR_PATH_1); switch(ret){ case 0: printf("\tnon existing directory was removed!\n"); ret = 1; goto out; case ENOENT: break; default: printf("\terror is not ENOENT, but %s\n", strerror(ret)); } ret = 0; printf("\tend: Success\n"); /* * Remove non-empty directory */ printf("\tbegin: Remove non-empty directory(%s)\n", NEW_DIR_PATH_2); ret = do_rmdir(NEW_DIR_PATH_2); switch(ret){ case 0: printf("\tnon-empty directory was removed!\n"); ret = 1; goto out; case ENOTEMPTY: break; default: printf("\terror is not ENOTEMPTY, but %s\n", strerror(ret)); } ret = 0; printf("\tend: Success\n"); out: if (ret) { printf("\tend: Failed\n"); } printf("rmdir_test: Finish\n"); return ret; }
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); }
/* simple backup creates a backup with a suffix in the same directory */ static int make_simple_backup(const char *fname) { int rename_errno; const char *fnamebak = get_backup_name(fname); if (!fnamebak) return 0; while (1) { if (do_rename(fname, fnamebak) == 0) { if (verbose > 1) { rprintf(FINFO, "backed up %s to %s\n", fname, fnamebak); } break; } /* cygwin (at least version b19) reports EINVAL */ if (errno == ENOENT || errno == EINVAL) break; rename_errno = errno; if (errno == EISDIR && do_rmdir(fnamebak) == 0) continue; if (errno == ENOTDIR && do_unlink(fnamebak) == 0) continue; rsyserr(FERROR, rename_errno, "rename %s to backup %s", fname, fnamebak); errno = rename_errno; return 0; } return 1; }
/** * Process the next incoming request * * @return status response */ status_t process_req() { msg_t *msg = malloc(sizeof(msg_t)); resp_t *resp = NULL; if (!EREADDATA(*msg)) { debug("Disconnected!\n"); return DISCON; } msg->buf[sizeof(msg->buf)-1] = '\0'; switch (msg->type) { case MKDIR: resp = do_mkdir(msg); break; case LIST: resp = do_list(msg); break; case PUT: resp = do_put(msg); break; case GET: resp = do_get(msg); break; case RM: resp = do_rm(msg); break; case RMDIR: resp = do_rmdir(msg); break; case QUIT: return EXIT; default: return ERR; } if (!resp) return ERR; ESENDDATA(*resp); if (last) free(last); last = (char *)resp; return OK; }
static int sys_rmdir(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_rmdir(path); kfree(path); if (err < 0) { curthr->kt_errno = -err; return -1; } else return err; }
int main (int argc, char **argv) { int exit = 0; char *buffer = g_new (char, 1024) ; GIOChannel *ioc; guint watch_id = 0; GOptionContext *ctx = NULL; GError *error = NULL; /* default to interactive on a terminal */ interactive = isatty (0); ctx = g_option_context_new("test-vfs"); g_option_context_add_main_entries(ctx, options, NULL); if (!g_option_context_parse(ctx, &argc, &argv, &error)) { g_printerr("main: %s\n", error->message); g_error_free(error); g_option_context_free(ctx); return 1; } g_option_context_free(ctx); files = g_hash_table_new (g_str_hash, g_str_equal); if (noninteractive) interactive = FALSE; if (interactive) vfserr = stderr; else vfserr = stdout; if (!mate_vfs_init ()) { fprintf (vfserr, "Cannot initialize mate-vfs.\n"); return 1; } mate_vfs_module_callback_push (MATE_VFS_MODULE_CALLBACK_AUTHENTICATION, authentication_callback, NULL, NULL); if (argc == 1) cur_dir = g_get_current_dir (); else cur_dir = g_strdup(argv[1]); if (cur_dir && !G_IS_DIR_SEPARATOR (cur_dir [strlen (cur_dir) - 1])) cur_dir = g_strconcat (cur_dir, G_DIR_SEPARATOR_S, NULL); if (interactive == TRUE) { main_loop = g_main_loop_new (NULL, TRUE); ioc = g_io_channel_unix_new (0 /* stdin */); g_io_channel_set_encoding (ioc, NULL, NULL); g_io_channel_set_buffered (ioc, FALSE); watch_id = g_io_add_watch (ioc, G_IO_IN | G_IO_HUP | G_IO_ERR, callback, buffer); g_io_channel_unref (ioc); } while (!exit) { char *ptr; if (interactive) { fprintf (stdout,"\n%s > ", cur_dir); fflush (stdout); strcpy (buffer, ""); g_main_loop_run (main_loop); } else { /* In non-interactive mode we just do this evil * thingie */ buffer[0] = '\0'; fgets (buffer, 1023, stdin); if (!buffer [0]) { exit = 1; continue; } } if (!buffer || buffer [0] == '#') continue; arg_data = g_strsplit (g_strchomp (buffer), delim, -1); arg_cur = 0; if ((!arg_data || !arg_data[0]) && interactive) continue; if (!interactive) printf ("Command : '%s'\n", arg_data [0]); ptr = arg_data[arg_cur++]; if (!ptr) continue; if (g_ascii_strcasecmp (ptr, "ls") == 0) do_ls (); else if (g_ascii_strcasecmp (ptr, "cd") == 0) do_cd (); else if (g_ascii_strcasecmp (ptr, "dump") == 0) do_dump (); else if (g_ascii_strcasecmp (ptr, "type") == 0 || g_ascii_strcasecmp (ptr, "cat") == 0) do_cat (); else if (g_ascii_strcasecmp (ptr, "cp") == 0) do_cp (); else if (g_ascii_strcasecmp (ptr, "rm") == 0) do_rm (); else if (g_ascii_strcasecmp (ptr, "mkdir") == 0) do_mkdir (); else if (g_ascii_strcasecmp (ptr, "rmdir") == 0) do_rmdir (); else if (g_ascii_strcasecmp (ptr, "mv") == 0) do_mv (); else if (g_ascii_strcasecmp (ptr, "info") == 0 || g_ascii_strcasecmp (ptr, "stat") == 0) do_info (); else if (g_ascii_strcasecmp (ptr, "findtrash") == 0) do_findtrash (); else if (g_ascii_strcasecmp (ptr, "ssl") == 0) do_ssl (); else if (g_ascii_strcasecmp (ptr, "sync") == 0) fprintf (vfserr, "a shell is like a boat, it lists or syncs (RMS)\n"); else if (g_ascii_strcasecmp (ptr,"help") == 0 || g_ascii_strcasecmp (ptr,"?") == 0 || g_ascii_strcasecmp (ptr,"info") == 0 || g_ascii_strcasecmp (ptr,"man") == 0) list_commands (); else if (g_ascii_strcasecmp (ptr,"exit") == 0 || g_ascii_strcasecmp (ptr,"quit") == 0 || g_ascii_strcasecmp (ptr,"q") == 0 || g_ascii_strcasecmp (ptr,"bye") == 0) exit = 1; /* File ops */ else if (g_ascii_strcasecmp (ptr, "open") == 0) do_open (); else if (g_ascii_strcasecmp (ptr, "create") == 0) do_create (); else if (g_ascii_strcasecmp (ptr, "close") == 0) do_close (); else if (g_ascii_strcasecmp (ptr, "handleinfo") == 0) do_handleinfo (); else if (g_ascii_strcasecmp (ptr, "read") == 0) do_read (); else if (g_ascii_strcasecmp (ptr, "seek") == 0) do_seek (); else fprintf (vfserr, "Unknown command '%s'", ptr); g_strfreev (arg_data); arg_data = NULL; } if (interactive) { g_source_remove (watch_id); g_main_loop_unref (main_loop); main_loop = NULL; } g_free (buffer); g_free (cur_dir); close_files (); 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; }
/* Delete a file or directory. If DEL_RECURSE is set in the flags, this will * delete recursively. * * Note that fbuf must point to a MAXPATHLEN buffer if the mode indicates it's * a directory! (The buffer is used for recursion, but returned unchanged.) */ enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) { enum delret ret; char *what; int ok; if (DEBUG_GTE(DEL, 2)) { rprintf(FINFO, "delete_item(%s) mode=%o flags=%d\n", fbuf, (int)mode, (int)flags); } if (flags & DEL_NO_UID_WRITE) do_chmod(fbuf, mode | S_IWUSR); if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) { /* This only happens on the first call to delete_item() since * delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */ ignore_perishable = 1; /* If DEL_RECURSE is not set, this just reports emptiness. */ ret = delete_dir_contents(fbuf, flags); ignore_perishable = 0; if (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT) goto check_ret; /* OK: try to delete the directory. */ } if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && stats.deleted_files >= max_delete) { skipped_deletes++; return DR_AT_LIMIT; } if (S_ISDIR(mode)) { what = "rmdir"; ok = do_rmdir(fbuf) == 0; } else { if (make_backups > 0 && !(flags & DEL_FOR_BACKUP) && (backup_dir || !is_backup_file(fbuf))) { what = "make_backup"; ok = make_backup(fbuf, True); if (ok == 2) { what = "unlink"; ok = robust_unlink(fbuf) == 0; } } else { what = "unlink"; ok = robust_unlink(fbuf) == 0; } } if (ok) { if (!(flags & DEL_MAKE_ROOM)) { log_delete(fbuf, mode); stats.deleted_files++; if (S_ISREG(mode)) { /* Nothing more to count */ } else if (S_ISDIR(mode)) stats.deleted_dirs++; #ifdef SUPPORT_LINKS else if (S_ISLNK(mode)) stats.deleted_symlinks++; #endif else if (IS_DEVICE(mode)) stats.deleted_symlinks++; else stats.deleted_specials++; } ret = DR_SUCCESS; } else { if (S_ISDIR(mode) && errno == ENOTEMPTY) { rprintf(FINFO, "cannot delete non-empty directory: %s\n", fbuf); ret = DR_NOT_EMPTY; } else if (errno != ENOENT) { rsyserr(FERROR, errno, "delete_file: %s(%s) failed", what, fbuf); ret = DR_FAILURE; } else ret = DR_SUCCESS; } check_ret: if (ret != DR_SUCCESS && flags & DEL_MAKE_ROOM) { const char *desc; switch (flags & DEL_MAKE_ROOM) { case DEL_FOR_FILE: desc = "regular file"; break; case DEL_FOR_DIR: desc = "directory"; break; case DEL_FOR_SYMLINK: desc = "symlink"; break; case DEL_FOR_DEVICE: desc = "device file"; break; case DEL_FOR_SPECIAL: desc = "special file"; break; default: exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */ } rprintf(FERROR_XFER, "could not make way for %s %s: %s\n", flags & DEL_FOR_BACKUP ? "backup" : "new", desc, fbuf); } return ret; }
static int parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int err_abort) { char *path1, *path2, *tmp; int pflag, lflag, iflag, cmdnum, i; unsigned long n_arg; Attrib a, *aa; char path_buf[MAXPATHLEN]; int err = 0; glob_t g; path1 = path2 = NULL; cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg, &path1, &path2); if (iflag != 0) err_abort = 0; memset(&g, 0, sizeof(g)); /* Perform command */ switch (cmdnum) { case 0: /* Blank line */ break; case -1: /* Unrecognized command */ err = -1; break; case I_GET: err = process_get(conn, path1, path2, *pwd, pflag); break; case I_PUT: err = process_put(conn, path1, path2, *pwd, pflag); break; case I_RENAME: path1 = make_absolute(path1, *pwd); path2 = make_absolute(path2, *pwd); err = do_rename(conn, path1, path2); break; case I_SYMLINK: path2 = make_absolute(path2, *pwd); err = do_symlink(conn, path1, path2); break; case I_RM: path1 = make_absolute(path1, *pwd); remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); for (i = 0; g.gl_pathv[i] && !interrupted; i++) { printf("Removing %s\n", g.gl_pathv[i]); err = do_rm(conn, g.gl_pathv[i]); if (err != 0 && err_abort) break; } break; case I_MKDIR: path1 = make_absolute(path1, *pwd); attrib_clear(&a); a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; a.perm = 0777; err = do_mkdir(conn, path1, &a); break; case I_RMDIR: path1 = make_absolute(path1, *pwd); err = do_rmdir(conn, path1); break; case I_CHDIR: path1 = make_absolute(path1, *pwd); if ((tmp = do_realpath(conn, path1)) == NULL) { err = 1; break; } if ((aa = do_stat(conn, tmp, 0)) == NULL) { xfree(tmp); err = 1; break; } if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) { error("Can't change directory: Can't check target"); xfree(tmp); err = 1; break; } if (!S_ISDIR(aa->perm)) { error("Can't change directory: \"%s\" is not " "a directory", tmp); xfree(tmp); err = 1; break; } xfree(*pwd); *pwd = tmp; break; case I_LS: if (!path1) { do_globbed_ls(conn, *pwd, *pwd, lflag); break; } /* Strip pwd off beginning of non-absolute paths */ tmp = NULL; if (*path1 != '/') tmp = *pwd; path1 = make_absolute(path1, *pwd); err = do_globbed_ls(conn, path1, tmp, lflag); break; case I_LCHDIR: if (chdir(path1) == -1) { error("Couldn't change local directory to " "\"%s\": %s", path1, strerror(errno)); err = 1; } break; case I_LMKDIR: if (mkdir(path1, 0777) == -1) { error("Couldn't create local directory " "\"%s\": %s", path1, strerror(errno)); err = 1; } break; case I_LLS: local_do_ls(cmd); break; case I_SHELL: local_do_shell(cmd); break; case I_LUMASK: umask(n_arg); printf("Local umask: %03lo\n", n_arg); break; case I_CHMOD: path1 = make_absolute(path1, *pwd); attrib_clear(&a); a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; a.perm = n_arg; remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); for (i = 0; g.gl_pathv[i] && !interrupted; i++) { printf("Changing mode on %s\n", g.gl_pathv[i]); err = do_setstat(conn, g.gl_pathv[i], &a); if (err != 0 && err_abort) break; } break; case I_CHOWN: case I_CHGRP: path1 = make_absolute(path1, *pwd); remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); for (i = 0; g.gl_pathv[i] && !interrupted; i++) { if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) { if (err != 0 && err_abort) break; else continue; } if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { error("Can't get current ownership of " "remote file \"%s\"", g.gl_pathv[i]); if (err != 0 && err_abort) break; else continue; } aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; if (cmdnum == I_CHOWN) { printf("Changing owner on %s\n", g.gl_pathv[i]); aa->uid = n_arg; } else { printf("Changing group on %s\n", g.gl_pathv[i]); aa->gid = n_arg; } err = do_setstat(conn, g.gl_pathv[i], aa); if (err != 0 && err_abort) break; } break; case I_PWD: printf("Remote working directory: %s\n", *pwd); break; case I_LPWD: if (!getcwd(path_buf, sizeof(path_buf))) { error("Couldn't get local cwd: %s", strerror(errno)); err = -1; break; } printf("Local working directory: %s\n", path_buf); break; case I_QUIT: /* Processed below */ break; case I_HELP: help(); break; case I_VERSION: printf("SFTP protocol version %u\n", sftp_proto_version(conn)); break; case I_PROGRESS: showprogress = !showprogress; if (showprogress) printf("Progress meter enabled\n"); else printf("Progress meter disabled\n"); break; default: fatal("%d is not implemented", cmdnum); } if (g.gl_pathc) globfree(&g); if (path1) xfree(path1); if (path2) xfree(path2); /* If an unignored error occurs in batch mode we should abort. */ if (err_abort && err != 0) return (-1); else if (cmdnum == I_QUIT) return (1); return (0); }
/* If we have a --backup-dir, then we get here from make_backup(). * We will move the file to be deleted into a parallel directory tree. */ static int keep_backup(const char *fname) { stat_x sx; struct file_struct *file; char *buf; int save_preserve_xattrs = preserve_xattrs; int kept = 0; int ret_code; /* return if no file to keep */ if (x_lstat(fname, &sx.st, NULL) < 0) return 1; #ifdef SUPPORT_ACLS sx.acc_acl = sx.def_acl = NULL; #endif #ifdef SUPPORT_XATTRS sx.xattr = NULL; #endif if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) return 1; /* the file could have disappeared */ if (!(buf = get_backup_name(fname))) { unmake_file(file); #ifdef SUPPORT_ACLS uncache_tmp_acls(); #endif #ifdef SUPPORT_XATTRS uncache_tmp_xattrs(); #endif return 0; } #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { get_acl(fname, &sx); cache_tmp_acl(file, &sx); free_acl(&sx); } #endif #ifdef SUPPORT_XATTRS if (preserve_xattrs) { get_xattr(fname, &sx); cache_tmp_xattr(file, &sx); free_xattr(&sx); } #endif /* Check to see if this is a device file, or link */ if ((am_root && preserve_devices && IS_DEVICE(file->mode)) || (preserve_specials && IS_SPECIAL(file->mode))) { int save_errno; do_unlink(buf); if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0) { save_errno = errno ? errno : EINVAL; /* 0 paranoia */ if (errno == ENOENT && make_bak_dir(buf) == 0) { if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0) save_errno = errno ? errno : save_errno; else save_errno = 0; } if (save_errno) { rsyserr(FERROR, save_errno, "mknod %s failed", full_fname(buf)); } } else save_errno = 0; if (verbose > 2 && save_errno == 0) { rprintf(FINFO, "make_backup: DEVICE %s successful.\n", fname); } kept = 1; do_unlink(fname); } if (!kept && S_ISDIR(file->mode)) { /* make an empty directory */ if (do_mkdir(buf, file->mode) < 0) { int save_errno = errno ? errno : EINVAL; /* 0 paranoia */ if (errno == ENOENT && make_bak_dir(buf) == 0) { if (do_mkdir(buf, file->mode) < 0) save_errno = errno ? errno : save_errno; else save_errno = 0; } if (save_errno) { rsyserr(FINFO, save_errno, "mkdir %s failed", full_fname(buf)); } } ret_code = do_rmdir(fname); if (verbose > 2) { rprintf(FINFO, "make_backup: RMDIR %s returns %i\n", full_fname(fname), ret_code); } kept = 1; } #ifdef SUPPORT_LINKS if (!kept && preserve_links && S_ISLNK(file->mode)) { const char *sl = F_SYMLINK(file); if (safe_symlinks && unsafe_symlink(sl, fname)) { if (verbose) { rprintf(FINFO, "ignoring unsafe symlink %s -> %s\n", full_fname(buf), sl); } kept = 1; } else { do_unlink(buf); if (do_symlink(sl, buf) < 0) { int save_errno = errno ? errno : EINVAL; /* 0 paranoia */ if (errno == ENOENT && make_bak_dir(buf) == 0) { if (do_symlink(sl, buf) < 0) save_errno = errno ? errno : save_errno; else save_errno = 0; } if (save_errno) { rsyserr(FERROR, save_errno, "link %s -> \"%s\"", full_fname(buf), sl); } } do_unlink(fname); kept = 1; } } #endif if (!kept && !S_ISREG(file->mode)) { rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname); unmake_file(file); #ifdef SUPPORT_ACLS uncache_tmp_acls(); #endif #ifdef SUPPORT_XATTRS uncache_tmp_xattrs(); #endif return 1; } /* move to keep tree if a file */ if (!kept) { if (robust_move(fname, buf) != 0) { rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"", full_fname(fname), buf); } else if (sx.st.st_nlink > 1) { /* If someone has hard-linked the file into the backup * dir, rename() might return success but do nothing! */ robust_unlink(fname); /* Just in case... */ } } preserve_xattrs = 0; set_file_attrs(buf, file, NULL, fname, 0); preserve_xattrs = save_preserve_xattrs; unmake_file(file); #ifdef SUPPORT_ACLS uncache_tmp_acls(); #endif #ifdef SUPPORT_XATTRS uncache_tmp_xattrs(); #endif if (verbose > 1) { rprintf(FINFO, "backed up %s to %s\n", fname, buf); } return 1; }
void rmdir_main(void) { char **s; for (s=toys.optargs; *s; s++) do_rmdir(*s); }
/* if we have a backup_dir, then we get here from make_backup(). We will move the file to be deleted into a parallel directory tree */ static int keep_backup(char *fname) { static int initialised; char keep_name [MAXPATHLEN]; STRUCT_STAT st; struct file_struct *file; int kept=0; int ret_code; if (!initialised) { if (backup_dir[strlen(backup_dir) - 1] == '/') backup_dir[strlen(backup_dir) - 1] = 0; if (verbose > 0) rprintf (FINFO, "backup_dir is %s\n", backup_dir); initialised = 1; } /* return if no file to keep */ #if SUPPORT_LINKS if (do_lstat (fname, &st)) return 1; #else if (do_stat (fname, &st)) return 1; #endif file = make_file(-1, fname, NULL, 1); /* the file could have disappeared */ if (!file) return 1; /* make a complete pathname for backup file */ if (strlen(backup_dir) + strlen(fname) + (suffix_specified ? strlen(backup_suffix) : 0) > (MAXPATHLEN - 1)) { rprintf (FERROR, "keep_backup filename too long\n"); return 0; } if (suffix_specified) { snprintf(keep_name, sizeof (keep_name), "%s/%s%s", backup_dir, fname, backup_suffix); } else { snprintf(keep_name, sizeof (keep_name), "%s/%s", backup_dir, fname); } #ifdef HAVE_MKNOD /* Check to see if this is a device file, or link */ if(IS_DEVICE(file->mode)) { if(am_root && preserve_devices) { make_bak_dir(fname,backup_dir); if(do_mknod(keep_name,file->mode,file->rdev)!=0) { rprintf(FERROR,"mknod %s : %s\n",keep_name,strerror(errno)); } else { if(verbose>2) rprintf(FINFO,"make_backup : DEVICE %s successful.\n",fname); }; }; kept=1; do_unlink(fname); }; #endif if(!kept && S_ISDIR(file->mode)) { /* make an empty directory */ make_bak_dir(fname,backup_dir); do_mkdir(keep_name,file->mode); ret_code=do_rmdir(fname); if(verbose>2) rprintf(FINFO,"make_backup : RMDIR %s returns %i\n",fname,ret_code); kept=1; }; #if SUPPORT_LINKS if(!kept && preserve_links && S_ISLNK(file->mode)) { extern int safe_symlinks; if (safe_symlinks && unsafe_symlink(file->link, keep_name)) { if (verbose) { rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n", keep_name,file->link); } kept=1; } make_bak_dir(fname,backup_dir); if(do_symlink(file->link,keep_name) != 0) { rprintf(FERROR,"link %s -> %s : %s\n",keep_name,file->link,strerror(errno)); }; do_unlink(fname); kept=1; }; #endif if(!kept && preserve_hard_links && check_hard_link(file)) { if(verbose > 1) rprintf(FINFO,"%s is a hard link\n",f_name(file)); }; if(!kept && !S_ISREG(file->mode)) { rprintf(FINFO,"make_bak: skipping non-regular file %s\n",fname); } /* move to keep tree if a file */ if(!kept) { if (!robust_move (fname, keep_name)) rprintf(FERROR, "keep_backup failed %s -> %s : %s\n", fname, keep_name, strerror(errno)); }; set_perms (keep_name, file, NULL, 0); free_file (file); free (file); if (verbose > 1) rprintf (FINFO, "keep_backup %s -> %s\n", fname, keep_name); return 1; } /* keep_backup */
void runProcess( Proc *proc, pid_t pgid, int fg, int inputFile, int outputFile, int errorFile) { // wrzucenie procesu do grupy procesow i danie przekazanie grupy terminalowu jezeli jest to stosowne // utowrzenie grupy lub dolaczenie do juz istniejacej pid_t pid = getpid(); if( pgid == 0 ) pgid = pid; setpgid(pid, pgid); // jesli w foreground to oddajemy terminal dla grupy procesow if(fg == 1) { tcsetpgrp( shellTerminal, pgid ); } struct sigaction act; act.sa_handler = SIG_DFL; /* set up signal handler */ act.sa_flags = 0; // kiedy shell przejmuje kontrole, powinien ignorowac ponizsze sygnaly, zeby samemu sie przypadkowo nie killnac sigaction(SIGINT, &act, NULL); // powrot do ustawien domyslnych (przez nasz shell te sygnaly byly ignorowane) sigaction(SIGINT, &act, NULL); sigaction(SIGQUIT, &act, NULL); sigaction(SIGCHLD, &act, NULL); sigaction(SIGTSTP, &act, NULL); sigaction(SIGTTIN, &act, NULL); sigaction(SIGTTOU, &act, NULL); // ustawienie standardowego I/O dla nowego procesu // jesli wyjscia sa inne niz standardowe to zamieniamy je - przekierowanie wyjscia if(inputFile != STDIN_FILENO) { dup2(inputFile, STDIN_FILENO); close(inputFile); } if(outputFile != STDOUT_FILENO) { dup2(outputFile, STDOUT_FILENO); close(outputFile); } if(errorFile != STDERR_FILENO) { dup2(errorFile, STDERR_FILENO); close(errorFile); } if(strcmp(proc->argv[0], "pwd") == 0) { do_pwd(); } else if(strcmp(proc->argv[0], "cd") == 0) { do_cd(proc->argv[1]); } else if(strcmp(proc->argv[0], "ls") == 0) { do_ls(proc->argv[1]); } else if(strcmp(proc->argv[0], "mkdir") == 0) { do_mkdir(proc->argv[1]); } else if(strcmp(proc->argv[0], "rmdir") == 0) { do_rmdir(proc->argv[1]); } else if(strcmp(proc->argv[0], "touch") == 0) { do_touch(proc->argv[1]); } else if(strcmp(proc->argv[0], "rm") == 0) { do_rm(proc->argv[1]); } else if(strcmp(proc->argv[0], "cp") == 0) { do_cp(proc->argv[1], proc->argv[2]); } else if(strcmp(proc->argv[0], "echo") == 0) { do_echo(proc->argv[1]); } else run(proc->argv[0], proc->argv); //execvp(proc->argv[0], proc->argv); // nie powinien wykonac exit'a przy poprawnym wykonaniu //exit(-1); }
//when exiting this function, dirPtr should be the directory from which you started int do_rmdir(char * name, char * size) { if (debug) printf("%s\n", __func__); //Reject request to delete directory .. or . if(strcmp(name, "..") == 0 || strcmp(name, ".") == 0) { printf("Move up a level to remove directory.\n"); return -1; } //Reject request to delete root directory if(strcmp(name, dirPtr->dirName) == 0 && dirPtr->prevDir == NULL) { printf("Cannot delete root directory.\n"); return -1; } if(dirPtr->firstSub != NULL) { if(strcmp(name, dirPtr->firstSub->dirName) == 0) dirPtr = dirPtr->firstSub; else { dirPtr = dirPtr->firstSub; while(dirPtr->nextSub != NULL) { dirPtr = dirPtr->nextSub; if(strcmp(name, dirPtr->dirName) == 0) { break; } } if(strcmp(name, dirPtr->dirName) != 0) { printf("Subdirectory %s does not exist in current directory.\n", name); dirPtr = dirPtr->prevDir; return -1; } } } else { printf("Subdirectory %s does not exist in current directory.\n", name); return -1; } //at this point, we are in the directory to be deleted //base case, no subdirectories in directory to be deleted if(dirPtr->firstSub == NULL) { dirPtr = dirPtr->prevDir; if(strcmp(name, dirPtr->firstSub->dirName) == 0) { //do temp directory stuff //release block dirPtr->firstSub = dirPtr->firstSub->nextSub; //printf("Deleting %s in 1\n", name); return 0; } else { dirPtr = dirPtr->firstSub; while(dirPtr->nextSub != NULL) { if(strcmp(name, dirPtr->nextSub->dirName) == 0) { //do temp directory stuff //release block dirPtr->nextSub = dirPtr->nextSub->nextSub; dirPtr = dirPtr->prevDir; //printf("Deleting %s in 2\n", name); return 0; } dirPtr = dirPtr->nextSub; } } } //second case, if there are at least two subdirectories while(dirPtr->firstSub->nextSub != NULL) { do_rmdir(dirPtr->firstSub->nextSub->dirName, 0); } //last case, only one subdirectory do_rmdir(dirPtr->firstSub->dirName, 0); dirPtr = dirPtr->prevDir; do_rmdir(name, 0); return 0; }
/* * delete a file or directory. If force_delet is set then delete * recursively */ int delete_file(char *fname) { DIR *d; struct dirent *di; char buf[MAXPATHLEN]; extern int force_delete; STRUCT_STAT st; int ret; extern int recurse; if (robust_unlink(fname) == 0 || errno == ENOENT) return 0; #if SUPPORT_LINKS ret = do_lstat(fname, &st); #else ret = do_stat(fname, &st); #endif if (ret) { rprintf(FERROR,"stat(%s) : %s\n", fname, strerror(errno)); return -1; } if (!S_ISDIR(st.st_mode)) { rprintf(FERROR,"unlink(%s) : %s\n", fname, strerror(errno)); return -1; } if (do_rmdir(fname) == 0 || errno == ENOENT) return 0; if (!force_delete || !recurse || (errno != ENOTEMPTY && errno != EEXIST)) { rprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno)); return -1; } /* now we do a recsursive delete on the directory ... */ d = opendir(fname); if (!d) { rprintf(FERROR,"opendir(%s): %s\n", fname,strerror(errno)); return -1; } for (di=readdir(d); di; di=readdir(d)) { char *dname = d_name(di); if (strcmp(dname,".")==0 || strcmp(dname,"..")==0) continue; slprintf(buf, sizeof(buf), "%s/%s", fname, dname); if (verbose > 0) rprintf(FINFO,"deleting %s\n", buf); if (delete_file(buf) != 0) { closedir(d); return -1; } } closedir(d); if (do_rmdir(fname) != 0) { rprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno)); return -1; } return 0; }
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; }
/* If we have a --backup-dir, then we get here from make_backup(). * We will move the file to be deleted into a parallel directory tree. */ static int keep_backup(const char *fname) { STRUCT_STAT st; struct file_struct *file; char *buf; int kept = 0; int ret_code; /* return if no file to keep */ if (do_lstat(fname, &st) < 0) return 1; if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) return 1; /* the file could have disappeared */ if (!(buf = get_backup_name(fname))) { unmake_file(file); return 0; } /* Check to see if this is a device file, or link */ if ((am_root && preserve_devices && IS_DEVICE(file->mode)) || (preserve_specials && IS_SPECIAL(file->mode))) { uint32 *devp = F_RDEV_P(file); dev_t rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); do_unlink(buf); if (do_mknod(buf, file->mode, rdev) < 0 && (errno != ENOENT || make_bak_dir(buf) < 0 || do_mknod(buf, file->mode, rdev) < 0)) { rsyserr(FERROR, errno, "mknod %s failed", full_fname(buf)); } else if (verbose > 2) { rprintf(FINFO, "make_backup: DEVICE %s successful.\n", fname); } kept = 1; do_unlink(fname); } if (!kept && S_ISDIR(file->mode)) { /* make an empty directory */ if (do_mkdir(buf, file->mode) < 0 && (errno != ENOENT || make_bak_dir(buf) < 0 || do_mkdir(buf, file->mode) < 0)) { rsyserr(FINFO, errno, "mkdir %s failed", full_fname(buf)); } ret_code = do_rmdir(fname); if (verbose > 2) { rprintf(FINFO, "make_backup: RMDIR %s returns %i\n", full_fname(fname), ret_code); } kept = 1; } #ifdef SUPPORT_LINKS if (!kept && preserve_links && S_ISLNK(file->mode)) { const char *sl = F_SYMLINK(file); if (safe_symlinks && unsafe_symlink(sl, buf)) { if (verbose) { rprintf(FINFO, "ignoring unsafe symlink %s -> %s\n", full_fname(buf), sl); } kept = 1; } else { do_unlink(buf); if (do_symlink(sl, buf) < 0 && (errno != ENOENT || make_bak_dir(buf) < 0 || do_symlink(sl, buf) < 0)) { rsyserr(FERROR, errno, "link %s -> \"%s\"", full_fname(buf), sl); } do_unlink(fname); kept = 1; } } #endif if (!kept && !S_ISREG(file->mode)) { rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname); unmake_file(file); return 1; } /* move to keep tree if a file */ if (!kept) { if (robust_move(fname, buf) != 0) { rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"", full_fname(fname), buf); } else if (st.st_nlink > 1) { /* If someone has hard-linked the file into the backup * dir, rename() might return success but do nothing! */ robust_unlink(fname); /* Just in case... */ } } set_file_attrs(buf, file, NULL, 0); unmake_file(file); if (verbose > 1) { rprintf(FINFO, "backed up %s to %s\n", fname, buf); } return 1; }