sftp-common.c revision 1.3
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" 27RCSID("$OpenBSD: sftp-common.c,v 1.3 2001/06/26 17:27:24 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/* Clear contents of attributes structure */ 39void 40attrib_clear(Attrib *a) 41{ 42 a->flags = 0; 43 a->size = 0; 44 a->uid = 0; 45 a->gid = 0; 46 a->perm = 0; 47 a->atime = 0; 48 a->mtime = 0; 49} 50 51/* Convert from struct stat to filexfer attribs */ 52void 53stat_to_attrib(struct stat *st, Attrib *a) 54{ 55 attrib_clear(a); 56 a->flags = 0; 57 a->flags |= SSH2_FILEXFER_ATTR_SIZE; 58 a->size = st->st_size; 59 a->flags |= SSH2_FILEXFER_ATTR_UIDGID; 60 a->uid = st->st_uid; 61 a->gid = st->st_gid; 62 a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; 63 a->perm = st->st_mode; 64 a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME; 65 a->atime = st->st_atime; 66 a->mtime = st->st_mtime; 67} 68 69/* Decode attributes in buffer */ 70Attrib * 71decode_attrib(Buffer *b) 72{ 73 static Attrib a; 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 count = buffer_get_int(b); 93 for (i = 0; i < count; i++) { 94 type = buffer_get_string(b, NULL); 95 data = buffer_get_string(b, NULL); 96 debug3("Got file attribute \"%s\"", type); 97 xfree(type); 98 xfree(data); 99 } 100 } 101 return &a; 102} 103 104/* Encode attributes to buffer */ 105void 106encode_attrib(Buffer *b, Attrib *a) 107{ 108 buffer_put_int(b, a->flags); 109 if (a->flags & SSH2_FILEXFER_ATTR_SIZE) 110 buffer_put_int64(b, a->size); 111 if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { 112 buffer_put_int(b, a->uid); 113 buffer_put_int(b, a->gid); 114 } 115 if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 116 buffer_put_int(b, a->perm); 117 if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 118 buffer_put_int(b, a->atime); 119 buffer_put_int(b, a->mtime); 120 } 121} 122 123/* Convert from SSH2_FX_ status to text error message */ 124const char * 125fx2txt(int status) 126{ 127 switch (status) { 128 case SSH2_FX_OK: 129 return("No error"); 130 case SSH2_FX_EOF: 131 return("End of file"); 132 case SSH2_FX_NO_SUCH_FILE: 133 return("No such file or directory"); 134 case SSH2_FX_PERMISSION_DENIED: 135 return("Permission denied"); 136 case SSH2_FX_FAILURE: 137 return("Failure"); 138 case SSH2_FX_BAD_MESSAGE: 139 return("Bad message"); 140 case SSH2_FX_NO_CONNECTION: 141 return("No connection"); 142 case SSH2_FX_CONNECTION_LOST: 143 return("Connection lost"); 144 case SSH2_FX_OP_UNSUPPORTED: 145 return("Operation unsupported"); 146 default: 147 return("Unknown status"); 148 }; 149 /* NOTREACHED */ 150} 151