| 1 | /* |
| 2 | * psftp.h: interface between psftp.c / scp.c and each |
| 3 | * platform-specific SFTP module. |
| 4 | */ |
| 5 | |
| 6 | #include "int64.h" |
| 7 | |
| 8 | #ifndef PUTTY_PSFTP_H |
| 9 | #define PUTTY_PSFTP_H |
| 10 | |
| 11 | /* |
| 12 | * psftp_getcwd returns the local current directory. The returned |
| 13 | * string must be freed by the caller. |
| 14 | */ |
| 15 | char *psftp_getcwd(void); |
| 16 | |
| 17 | /* |
| 18 | * psftp_lcd changes the local current directory. The return value |
| 19 | * is NULL on success, or else an error message which must be freed |
| 20 | * by the caller. |
| 21 | */ |
| 22 | char *psftp_lcd(char *newdir); |
| 23 | |
| 24 | /* |
| 25 | * Retrieve file times on a local file. Must return two unsigned |
| 26 | * longs in POSIX time_t format. |
| 27 | */ |
| 28 | void get_file_times(char *filename, unsigned long *mtime, |
| 29 | unsigned long *atime); |
| 30 | |
| 31 | /* |
| 32 | * One iteration of the PSFTP event loop: wait for network data and |
| 33 | * process it, once. |
| 34 | */ |
| 35 | int ssh_sftp_loop_iteration(void); |
| 36 | |
| 37 | /* |
| 38 | * Read a command line for PSFTP from standard input. Caller must |
| 39 | * free. |
| 40 | * |
| 41 | * If `backend_required' is TRUE, should also listen for activity |
| 42 | * at the backend (rekeys, clientalives, unexpected closures etc) |
| 43 | * and respond as necessary, and if the backend closes it should |
| 44 | * treat this as a failure condition. If `backend_required' is |
| 45 | * FALSE, a back end is not (intentionally) active at all (e.g. |
| 46 | * psftp before an `open' command). |
| 47 | */ |
| 48 | char *ssh_sftp_get_cmdline(char *prompt, int backend_required); |
| 49 | |
| 50 | /* |
| 51 | * The main program in psftp.c. Called from main() in the platform- |
| 52 | * specific code, after doing any platform-specific initialisation. |
| 53 | */ |
| 54 | int psftp_main(int argc, char *argv[]); |
| 55 | |
| 56 | /* |
| 57 | * These functions are used by PSCP to transmit progress updates |
| 58 | * and error information to a GUI window managing it. This will |
| 59 | * probably only ever be supported on Windows, so these functions |
| 60 | * can safely be stubs on all other platforms. |
| 61 | */ |
| 62 | void gui_update_stats(char *name, unsigned long size, |
| 63 | int percentage, unsigned long elapsed, |
| 64 | unsigned long done, unsigned long eta, |
| 65 | unsigned long ratebs); |
| 66 | void gui_send_errcount(int list, int errs); |
| 67 | void gui_send_char(int is_stderr, int c); |
| 68 | void gui_enable(char *arg); |
| 69 | |
| 70 | /* |
| 71 | * It's likely that a given platform's implementation of file |
| 72 | * transfer utilities is going to want to do things with them that |
| 73 | * aren't present in stdio. Hence we supply an alternative |
| 74 | * abstraction for file access functions. |
| 75 | * |
| 76 | * This abstraction tells you the size and access times when you |
| 77 | * open an existing file (platforms may choose the meaning of the |
| 78 | * file times if it's not clear; whatever they choose will be what |
| 79 | * PSCP sends to the server as mtime and atime), and lets you set |
| 80 | * the times when saving a new file. |
| 81 | * |
| 82 | * On the other hand, the abstraction is pretty simple: it supports |
| 83 | * only opening a file and reading it, or creating a file and writing |
| 84 | * it. None of this read-and-write, seeking-back-and-forth stuff. |
| 85 | */ |
| 86 | typedef struct RFile RFile; |
| 87 | typedef struct WFile WFile; |
| 88 | /* Output params size, perms, mtime and atime can all be NULL if |
| 89 | * desired. perms will be -1 if the OS does not support POSIX permissions. */ |
| 90 | RFile *open_existing_file(char *name, uint64 *size, |
| 91 | unsigned long *mtime, unsigned long *atime, |
| 92 | long *perms); |
| 93 | WFile *open_existing_wfile(char *name, uint64 *size); |
| 94 | /* Returns <0 on error, 0 on eof, or number of bytes read, as usual */ |
| 95 | int read_from_file(RFile *f, void *buffer, int length); |
| 96 | /* Closes and frees the RFile */ |
| 97 | void close_rfile(RFile *f); |
| 98 | WFile *open_new_file(char *name, long perms); |
| 99 | /* Returns <0 on error, 0 on eof, or number of bytes written, as usual */ |
| 100 | int write_to_file(WFile *f, void *buffer, int length); |
| 101 | void set_file_times(WFile *f, unsigned long mtime, unsigned long atime); |
| 102 | /* Closes and frees the WFile */ |
| 103 | void close_wfile(WFile *f); |
| 104 | /* Seek offset bytes through file */ |
| 105 | enum { FROM_START, FROM_CURRENT, FROM_END }; |
| 106 | int seek_file(WFile *f, uint64 offset, int whence); |
| 107 | /* Get file position */ |
| 108 | uint64 get_file_posn(WFile *f); |
| 109 | /* |
| 110 | * Determine the type of a file: nonexistent, file, directory or |
| 111 | * weird. `weird' covers anything else - named pipes, Unix sockets, |
| 112 | * device files, fish, badgers, you name it. Things marked `weird' |
| 113 | * will be skipped over in recursive file transfers, so the only |
| 114 | * real reason for not lumping them in with `nonexistent' is that |
| 115 | * it allows a slightly more sane error message. |
| 116 | */ |
| 117 | enum { |
| 118 | FILE_TYPE_NONEXISTENT, FILE_TYPE_FILE, FILE_TYPE_DIRECTORY, FILE_TYPE_WEIRD |
| 119 | }; |
| 120 | int file_type(char *name); |
| 121 | |
| 122 | /* |
| 123 | * Read all the file names out of a directory. |
| 124 | */ |
| 125 | typedef struct DirHandle DirHandle; |
| 126 | DirHandle *open_directory(char *name); |
| 127 | /* The string returned from this will need freeing if not NULL */ |
| 128 | char *read_filename(DirHandle *dir); |
| 129 | void close_directory(DirHandle *dir); |
| 130 | |
| 131 | /* |
| 132 | * Test a filespec to see whether it's a local wildcard or not. |
| 133 | * Return values: |
| 134 | * |
| 135 | * - WCTYPE_WILDCARD (this is a wildcard). |
| 136 | * - WCTYPE_FILENAME (this is a single file name). |
| 137 | * - WCTYPE_NONEXISTENT (whichever it was, nothing of that name exists). |
| 138 | * |
| 139 | * Some platforms may choose not to support local wildcards when |
| 140 | * they come from the command line; in this case they simply never |
| 141 | * return WCTYPE_WILDCARD, but still test the file's existence. |
| 142 | * (However, all platforms will probably want to support wildcards |
| 143 | * inside the PSFTP CLI.) |
| 144 | */ |
| 145 | enum { |
| 146 | WCTYPE_NONEXISTENT, WCTYPE_FILENAME, WCTYPE_WILDCARD |
| 147 | }; |
| 148 | int test_wildcard(char *name, int cmdline); |
| 149 | |
| 150 | /* |
| 151 | * Actually return matching file names for a local wildcard. |
| 152 | */ |
| 153 | typedef struct WildcardMatcher WildcardMatcher; |
| 154 | WildcardMatcher *begin_wildcard_matching(char *name); |
| 155 | /* The string returned from this will need freeing if not NULL */ |
| 156 | char *wildcard_get_filename(WildcardMatcher *dir); |
| 157 | void finish_wildcard_matching(WildcardMatcher *dir); |
| 158 | |
| 159 | /* |
| 160 | * Vet a filename returned from the remote host, to ensure it isn't |
| 161 | * in some way malicious. The idea is that this function is applied |
| 162 | * to filenames returned from FXP_READDIR, which means we can panic |
| 163 | * if we see _anything_ resembling a directory separator. |
| 164 | * |
| 165 | * Returns TRUE if the filename is kosher, FALSE if dangerous. |
| 166 | */ |
| 167 | int vet_filename(char *name); |
| 168 | |
| 169 | /* |
| 170 | * Create a directory. Returns 0 on error, !=0 on success. |
| 171 | */ |
| 172 | int create_directory(char *name); |
| 173 | |
| 174 | /* |
| 175 | * Concatenate a directory name and a file name. The way this is |
| 176 | * done will depend on the OS. |
| 177 | */ |
| 178 | char *dir_file_cat(char *dir, char *file); |
| 179 | |
| 180 | #endif /* PUTTY_PSFTP_H */ |