void cmd_rmdir(const char *name) { const smbftpd_valid_share_t *share; char *real_path; real_path = smbftpd_get_realpath(smbftpd_session.valid_shares, name, FLAG_CHECK_WRITABLE | FLAG_NO_FOLLOW_LINK); if (NULL == real_path) { reply_fs2client(550, "%s: Permission denied.", name); return; } if (smbftpd_session.mode == MODE_SMB) { share = smbftpd_get_share_by_path(smbftpd_session.valid_shares, real_path); if (!share || share->disable_modify) { reply_noformat(550, "Remove directory denied."); return; } } LOGCMD("rmdir", name); if (rmdir(real_path) < 0) reply_fs2client(550, "%s: %s.", name, strerror(errno)); else reply_noformat(250, "RMD command successful."); }
void cmd_delete(const char *path) { const smbftpd_valid_share_t *share; struct stat st; char *real_path; real_path = smbftpd_get_realpath(smbftpd_session.valid_shares, path, FLAG_NO_FOLLOW_LINK | FLAG_CHECK_WRITABLE); if (NULL == real_path) { reply_fs2client(550, "%s: permission denied.", path); return; } if (smbftpd_session.mode == MODE_SMB) { share = smbftpd_get_share_by_path(smbftpd_session.valid_shares, real_path); if (!share || share->disable_modify) { reply_noformat(550, "Delete file denied."); return; } } LOGCMD("delete", path); if (lstat(real_path, &st) < 0) { reply_fs2client(550, "%s: %s.", path, strerror(errno)); return; } if (S_ISDIR(st.st_mode)) { if (rmdir(real_path) < 0) { reply_fs2client(550, "%s: %s.", path, strerror(errno)); return; } goto done; } if (unlink(real_path) < 0) { reply_fs2client(550, "%s: %s.", path, strerror(errno)); return; } done: reply_noformat(250, "DELE command successful."); }
void store (const char *name, const char *mode, int unique) { FILE *fout, *din; struct stat st; int (*closefunc) (FILE *); if (unique && stat (name, &st) == 0) { const char *name_unique = gunique (name); if (name_unique) name = name_unique; else { LOGCMD (*mode == 'w' ? "put" : "append", name); return; } } if (restart_point) mode = "r+"; fout = fopen (name, mode); closefunc = fclose; if (fout == NULL) { perror_reply (553, name); LOGCMD (*mode == 'w' ? "put" : "append", name); return; } byte_count = -1; if (restart_point) { if (type == TYPE_A) { off_t i, n; int c; n = restart_point; i = 0; while (i++ < n) { c = getc (fout); if (c == EOF) { perror_reply (550, name); goto done; } if (c == '\n') i++; } /* We must do this seek to "current" position because we are changing from reading to writing. */ if (fseek (fout, 0L, SEEK_CUR) < 0) { perror_reply (550, name); goto done; } } else if (lseek (fileno (fout), restart_point, SEEK_SET) < 0) { perror_reply (550, name); goto done; } } din = dataconn (name, (off_t) - 1, "r"); if (din == NULL) goto done; if (receive_data (din, fout) == 0) { if (unique) reply (226, "Transfer complete (unique file name:%s).", name); else reply (226, "Transfer complete."); } fclose (din); data = -1; pdata = -1; done: LOGBYTES (*mode == 'w' ? "put" : "append", name, byte_count); (*closefunc) (fout); }
void retrieve (const char *cmd, const char *name) { FILE *fin, *dout; struct stat st; int (*closefunc) (FILE *); size_t buffer_size = 0; if (cmd == 0) { fin = fopen (name, "r"), closefunc = fclose; st.st_size = 0; } else { char line[BUFSIZ]; snprintf (line, sizeof line, cmd, name); name = line; fin = ftpd_popen (line, "r"), closefunc = ftpd_pclose; st.st_size = -1; buffer_size = BUFSIZ; } if (fin == NULL) { if (errno != 0) { perror_reply (550, name); if (cmd == 0) { LOGCMD ("get", name); } } return; } byte_count = -1; if (cmd == 0 && (fstat (fileno (fin), &st) < 0 || !S_ISREG (st.st_mode))) { reply (550, "%s: not a plain file.", name); goto done; } if (restart_point) { if (type == TYPE_A) { off_t i, n; int c; n = restart_point; i = 0; while (i++ < n) { c = getc (fin); if (c == EOF) { perror_reply (550, name); goto done; } if (c == '\n') i++; } } else if (lseek (fileno (fin), restart_point, SEEK_SET) < 0) { perror_reply (550, name); goto done; } } dout = dataconn (name, st.st_size, "w"); if (dout == NULL) goto done; send_data (fin, dout, buffer_size); fclose (dout); data = -1; pdata = -1; done: if (cmd == 0) LOGBYTES ("get", name, byte_count); (*closefunc) (fin); }