1 /* 2 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Damien Miller. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "includes.h" 27 RCSID("$OpenBSD: sftp-common.c,v 1.2 2001/02/06 23:50:10 markus Exp $"); 28 29 #include "buffer.h" 30 #include "bufaux.h" 31 #include "getput.h" 32 #include "log.h" 33 #include "xmalloc.h" 34 35 #include "sftp.h" 36 #include "sftp-common.h" 37 38 void 39 attrib_clear(Attrib *a) 40 { 41 a->flags = 0; 42 a->size = 0; 43 a->uid = 0; 44 a->gid = 0; 45 a->perm = 0; 46 a->atime = 0; 47 a->mtime = 0; 48 } 49 50 void 51 stat_to_attrib(struct stat *st, Attrib *a) 52 { 53 attrib_clear(a); 54 a->flags = 0; 55 a->flags |= SSH2_FILEXFER_ATTR_SIZE; 56 a->size = st->st_size; 57 a->flags |= SSH2_FILEXFER_ATTR_UIDGID; 58 a->uid = st->st_uid; 59 a->gid = st->st_gid; 60 a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; 61 a->perm = st->st_mode; 62 a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME; 63 a->atime = st->st_atime; 64 a->mtime = st->st_mtime; 65 } 66 67 Attrib * 68 decode_attrib(Buffer *b) 69 { 70 static Attrib a; 71 attrib_clear(&a); 72 a.flags = buffer_get_int(b); 73 if (a.flags & SSH2_FILEXFER_ATTR_SIZE) 74 a.size = buffer_get_int64(b); 75 if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { 76 a.uid = buffer_get_int(b); 77 a.gid = buffer_get_int(b); 78 } 79 if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 80 a.perm = buffer_get_int(b); 81 if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 82 a.atime = buffer_get_int(b); 83 a.mtime = buffer_get_int(b); 84 } 85 /* vendor-specific extensions */ 86 if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) { 87 char *type, *data; 88 int i, count; 89 count = buffer_get_int(b); 90 for (i = 0; i < count; i++) { 91 type = buffer_get_string(b, NULL); 92 data = buffer_get_string(b, NULL); 93 debug3("Got file attribute \"%s\"", type); 94 xfree(type); 95 xfree(data); 96 } 97 } 98 return &a; 99 } 100 101 void 102 encode_attrib(Buffer *b, Attrib *a) 103 { 104 buffer_put_int(b, a->flags); 105 if (a->flags & SSH2_FILEXFER_ATTR_SIZE) 106 buffer_put_int64(b, a->size); 107 if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { 108 buffer_put_int(b, a->uid); 109 buffer_put_int(b, a->gid); 110 } 111 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 112 buffer_put_int(b, a->perm); 113 if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 114 buffer_put_int(b, a->atime); 115 buffer_put_int(b, a->mtime); 116 } 117 } 118 119 const char * 120 fx2txt(int status) 121 { 122 switch (status) { 123 case SSH2_FX_OK: 124 return("No error"); 125 case SSH2_FX_EOF: 126 return("End of file"); 127 case SSH2_FX_NO_SUCH_FILE: 128 return("No such file or directory"); 129 case SSH2_FX_PERMISSION_DENIED: 130 return("Permission denied"); 131 case SSH2_FX_FAILURE: 132 return("Failure"); 133 case SSH2_FX_BAD_MESSAGE: 134 return("Bad message"); 135 case SSH2_FX_NO_CONNECTION: 136 return("No connection"); 137 case SSH2_FX_CONNECTION_LOST: 138 return("Connection lost"); 139 case SSH2_FX_OP_UNSUPPORTED: 140 return("Operation unsupported"); 141 default: 142 return("Unknown status"); 143 }; 144 /* NOTREACHED */ 145 } 146 147