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.5 2001/12/02 02:08:32 deraadt Exp $"); 28 29 #include "buffer.h" 30 #include "bufaux.h" 31 #include "log.h" 32 #include "xmalloc.h" 33 34 #include "sftp.h" 35 #include "sftp-common.h" 36 37 /* Clear contents of attributes structure */ 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 /* Convert from struct stat to filexfer attribs */ 51 void 52 stat_to_attrib(struct stat *st, Attrib *a) 53 { 54 attrib_clear(a); 55 a->flags = 0; 56 a->flags |= SSH2_FILEXFER_ATTR_SIZE; 57 a->size = st->st_size; 58 a->flags |= SSH2_FILEXFER_ATTR_UIDGID; 59 a->uid = st->st_uid; 60 a->gid = st->st_gid; 61 a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; 62 a->perm = st->st_mode; 63 a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME; 64 a->atime = st->st_atime; 65 a->mtime = st->st_mtime; 66 } 67 68 /* Decode attributes in buffer */ 69 Attrib * 70 decode_attrib(Buffer *b) 71 { 72 static Attrib a; 73 attrib_clear(&a); 74 a.flags = buffer_get_int(b); 75 if (a.flags & SSH2_FILEXFER_ATTR_SIZE) 76 a.size = buffer_get_int64(b); 77 if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { 78 a.uid = buffer_get_int(b); 79 a.gid = buffer_get_int(b); 80 } 81 if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 82 a.perm = buffer_get_int(b); 83 if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 84 a.atime = buffer_get_int(b); 85 a.mtime = buffer_get_int(b); 86 } 87 /* vendor-specific extensions */ 88 if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) { 89 char *type, *data; 90 int i, count; 91 count = buffer_get_int(b); 92 for (i = 0; i < count; i++) { 93 type = buffer_get_string(b, NULL); 94 data = buffer_get_string(b, NULL); 95 debug3("Got file attribute \"%s\"", type); 96 xfree(type); 97 xfree(data); 98 } 99 } 100 return &a; 101 } 102 103 /* Encode attributes to buffer */ 104 void 105 encode_attrib(Buffer *b, Attrib *a) 106 { 107 buffer_put_int(b, a->flags); 108 if (a->flags & SSH2_FILEXFER_ATTR_SIZE) 109 buffer_put_int64(b, a->size); 110 if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { 111 buffer_put_int(b, a->uid); 112 buffer_put_int(b, a->gid); 113 } 114 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 115 buffer_put_int(b, a->perm); 116 if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 117 buffer_put_int(b, a->atime); 118 buffer_put_int(b, a->mtime); 119 } 120 } 121 122 /* Convert from SSH2_FX_ status to text error message */ 123 const char * 124 fx2txt(int status) 125 { 126 switch (status) { 127 case SSH2_FX_OK: 128 return("No error"); 129 case SSH2_FX_EOF: 130 return("End of file"); 131 case SSH2_FX_NO_SUCH_FILE: 132 return("No such file or directory"); 133 case SSH2_FX_PERMISSION_DENIED: 134 return("Permission denied"); 135 case SSH2_FX_FAILURE: 136 return("Failure"); 137 case SSH2_FX_BAD_MESSAGE: 138 return("Bad message"); 139 case SSH2_FX_NO_CONNECTION: 140 return("No connection"); 141 case SSH2_FX_CONNECTION_LOST: 142 return("Connection lost"); 143 case SSH2_FX_OP_UNSUPPORTED: 144 return("Operation unsupported"); 145 default: 146 return("Unknown status"); 147 } 148 /* NOTREACHED */ 149 } 150