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.6 2002/06/23 09:30:14 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 74 attrib_clear(&a); 75 a.flags = buffer_get_int(b); 76 if (a.flags & SSH2_FILEXFER_ATTR_SIZE) 77 a.size = buffer_get_int64(b); 78 if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { 79 a.uid = buffer_get_int(b); 80 a.gid = buffer_get_int(b); 81 } 82 if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 83 a.perm = buffer_get_int(b); 84 if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 85 a.atime = buffer_get_int(b); 86 a.mtime = buffer_get_int(b); 87 } 88 /* vendor-specific extensions */ 89 if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) { 90 char *type, *data; 91 int i, count; 92 93 count = buffer_get_int(b); 94 for (i = 0; i < count; i++) { 95 type = buffer_get_string(b, NULL); 96 data = buffer_get_string(b, NULL); 97 debug3("Got file attribute \"%s\"", type); 98 xfree(type); 99 xfree(data); 100 } 101 } 102 return &a; 103 } 104 105 /* Encode attributes to buffer */ 106 void 107 encode_attrib(Buffer *b, Attrib *a) 108 { 109 buffer_put_int(b, a->flags); 110 if (a->flags & SSH2_FILEXFER_ATTR_SIZE) 111 buffer_put_int64(b, a->size); 112 if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { 113 buffer_put_int(b, a->uid); 114 buffer_put_int(b, a->gid); 115 } 116 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 117 buffer_put_int(b, a->perm); 118 if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 119 buffer_put_int(b, a->atime); 120 buffer_put_int(b, a->mtime); 121 } 122 } 123 124 /* Convert from SSH2_FX_ status to text error message */ 125 const char * 126 fx2txt(int status) 127 { 128 switch (status) { 129 case SSH2_FX_OK: 130 return("No error"); 131 case SSH2_FX_EOF: 132 return("End of file"); 133 case SSH2_FX_NO_SUCH_FILE: 134 return("No such file or directory"); 135 case SSH2_FX_PERMISSION_DENIED: 136 return("Permission denied"); 137 case SSH2_FX_FAILURE: 138 return("Failure"); 139 case SSH2_FX_BAD_MESSAGE: 140 return("Bad message"); 141 case SSH2_FX_NO_CONNECTION: 142 return("No connection"); 143 case SSH2_FX_CONNECTION_LOST: 144 return("Connection lost"); 145 case SSH2_FX_OP_UNSUPPORTED: 146 return("Operation unsupported"); 147 default: 148 return("Unknown status"); 149 } 150 /* NOTREACHED */ 151 } 152