X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/61e9624802b421b3087730b8dbb768af2021dc6d..04b061c4f010dc56e46211f948a5ae8d9d22b2fb:/sftp-common.c diff --git a/sftp-common.c b/sftp-common.c index aed9b339..7ebadcc5 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -1,3 +1,4 @@ +/* $OpenBSD: sftp-common.c,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. @@ -24,17 +25,26 @@ */ #include "includes.h" -RCSID("$OpenBSD: sftp-common.c,v 1.1 2001/02/04 11:11:54 djm Exp $"); +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "xmalloc.h" #include "buffer.h" -#include "bufaux.h" -#include "getput.h" #include "log.h" -#include "xmalloc.h" #include "sftp.h" #include "sftp-common.h" +/* Clear contents of attributes structure */ void attrib_clear(Attrib *a) { @@ -47,8 +57,9 @@ attrib_clear(Attrib *a) a->mtime = 0; } +/* Convert from struct stat to filexfer attribs */ void -stat_to_attrib(struct stat *st, Attrib *a) +stat_to_attrib(const struct stat *st, Attrib *a) { attrib_clear(a); a->flags = 0; @@ -64,10 +75,32 @@ stat_to_attrib(struct stat *st, Attrib *a) a->mtime = st->st_mtime; } +/* Convert from filexfer attribs to struct stat */ +void +attrib_to_stat(const Attrib *a, struct stat *st) +{ + memset(st, 0, sizeof(*st)); + + if (a->flags & SSH2_FILEXFER_ATTR_SIZE) + st->st_size = a->size; + if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { + st->st_uid = a->uid; + st->st_gid = a->gid; + } + if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) + st->st_mode = a->perm; + if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { + st->st_atime = a->atime; + st->st_mtime = a->mtime; + } +} + +/* Decode attributes in buffer */ Attrib * decode_attrib(Buffer *b) { static Attrib a; + attrib_clear(&a); a.flags = buffer_get_int(b); if (a.flags & SSH2_FILEXFER_ATTR_SIZE) @@ -86,6 +119,7 @@ decode_attrib(Buffer *b) if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) { char *type, *data; int i, count; + count = buffer_get_int(b); for (i = 0; i < count; i++) { type = buffer_get_string(b, NULL); @@ -98,8 +132,9 @@ decode_attrib(Buffer *b) return &a; } +/* Encode attributes to buffer */ void -encode_attrib(Buffer *b, Attrib *a) +encode_attrib(Buffer *b, const Attrib *a) { buffer_put_int(b, a->flags); if (a->flags & SSH2_FILEXFER_ATTR_SIZE) @@ -116,18 +151,19 @@ encode_attrib(Buffer *b, Attrib *a) } } +/* Convert from SSH2_FX_ status to text error message */ const char * fx2txt(int status) { switch (status) { case SSH2_FX_OK: - return("No Error"); + return("No error"); case SSH2_FX_EOF: - return("End of File"); + return("End of file"); case SSH2_FX_NO_SUCH_FILE: - return("No Such File"); + return("No such file or directory"); case SSH2_FX_PERMISSION_DENIED: - return("Permission Denied"); + return("Permission denied"); case SSH2_FX_FAILURE: return("Failure"); case SSH2_FX_BAD_MESSAGE: @@ -140,7 +176,48 @@ fx2txt(int status) return("Operation unsupported"); default: return("Unknown status"); - }; + } /* NOTREACHED */ } +/* + * drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh + */ +char * +ls_file(const char *name, const struct stat *st, int remote) +{ + int ulen, glen, sz = 0; + struct passwd *pw; + struct group *gr; + struct tm *ltime = localtime(&st->st_mtime); + char *user, *group; + char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; + + strmode(st->st_mode, mode); + if (!remote && (pw = getpwuid(st->st_uid)) != NULL) { + user = pw->pw_name; + } else { + snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid); + user = ubuf; + } + if (!remote && (gr = getgrgid(st->st_gid)) != NULL) { + group = gr->gr_name; + } else { + snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid); + group = gbuf; + } + if (ltime != NULL) { + if (time(NULL) - st->st_mtime < (365*24*60*60)/2) + sz = strftime(tbuf, sizeof tbuf, "%b %e %H:%M", ltime); + else + sz = strftime(tbuf, sizeof tbuf, "%b %e %Y", ltime); + } + if (sz == 0) + tbuf[0] = '\0'; + ulen = MAX(strlen(user), 8); + glen = MAX(strlen(group), 8); + snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, + (u_int)st->st_nlink, ulen, user, glen, group, + (unsigned long long)st->st_size, tbuf, name); + return xstrdup(buf); +}