1d059297112922cabb0c674840589be8db821fd9aAdam Langley/* $OpenBSD: sftp-common.c,v 1.28 2015/01/20 23:14:00 deraadt Exp $ */ 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 2001 Markus Friedl. All rights reserved. 4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 2001 Damien Miller. All rights reserved. 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Redistribution and use in source and binary forms, with or without 7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * modification, are permitted provided that the following conditions 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * are met: 9bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 1. Redistributions of source code must retain the above copyright 10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer. 11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 2. Redistributions in binary form must reproduce the above copyright 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer in the 13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * documentation and/or other materials provided with the distribution. 14bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 28bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 29d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <sys/param.h> /* MAX */ 30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h> 31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/stat.h> 32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <grp.h> 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <pwd.h> 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdio.h> 36d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <stdlib.h> 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <string.h> 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <time.h> 39bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdarg.h> 40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_UTIL_H 41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <util.h> 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 43bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 44bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "xmalloc.h" 45d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "ssherr.h" 46d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "sshbuf.h" 47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "log.h" 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "sftp.h" 50bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "sftp-common.h" 51bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 52bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Clear contents of attributes structure */ 53bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanattrib_clear(Attrib *a) 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->flags = 0; 57bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->size = 0; 58bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->uid = 0; 59bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->gid = 0; 60bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->perm = 0; 61bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->atime = 0; 62bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->mtime = 0; 63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 65bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Convert from struct stat to filexfer attribs */ 66bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstat_to_attrib(const struct stat *st, Attrib *a) 68bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 69bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman attrib_clear(a); 70bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->flags = 0; 71bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->flags |= SSH2_FILEXFER_ATTR_SIZE; 72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->size = st->st_size; 73bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->flags |= SSH2_FILEXFER_ATTR_UIDGID; 74bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->uid = st->st_uid; 75bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->gid = st->st_gid; 76bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; 77bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->perm = st->st_mode; 78bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME; 79bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->atime = st->st_atime; 80bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman a->mtime = st->st_mtime; 81bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 82bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 83bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Convert from filexfer attribs to struct stat */ 84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 85bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanattrib_to_stat(const Attrib *a, struct stat *st) 86bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 87bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman memset(st, 0, sizeof(*st)); 88bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 89bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (a->flags & SSH2_FILEXFER_ATTR_SIZE) 90bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman st->st_size = a->size; 91bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { 92bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman st->st_uid = a->uid; 93bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman st->st_gid = a->gid; 94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 95bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 96bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman st->st_mode = a->perm; 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 98bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman st->st_atime = a->atime; 99bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman st->st_mtime = a->mtime; 100bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 103bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Decode attributes in buffer */ 104d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 105d059297112922cabb0c674840589be8db821fd9aAdam Langleydecode_attrib(struct sshbuf *b, Attrib *a) 106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 107d059297112922cabb0c674840589be8db821fd9aAdam Langley int r; 108d059297112922cabb0c674840589be8db821fd9aAdam Langley 109d059297112922cabb0c674840589be8db821fd9aAdam Langley attrib_clear(a); 110d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_get_u32(b, &a->flags)) != 0) 111d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 112d059297112922cabb0c674840589be8db821fd9aAdam Langley if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { 113d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_get_u64(b, &a->size)) != 0) 114d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 115d059297112922cabb0c674840589be8db821fd9aAdam Langley } 116d059297112922cabb0c674840589be8db821fd9aAdam Langley if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { 117d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_get_u32(b, &a->uid)) != 0 || 118d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_get_u32(b, &a->gid)) != 0) 119d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 120d059297112922cabb0c674840589be8db821fd9aAdam Langley } 121d059297112922cabb0c674840589be8db821fd9aAdam Langley if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { 122d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_get_u32(b, &a->perm)) != 0) 123d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 124d059297112922cabb0c674840589be8db821fd9aAdam Langley } 125d059297112922cabb0c674840589be8db821fd9aAdam Langley if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 126d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_get_u32(b, &a->atime)) != 0 || 127d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_get_u32(b, &a->mtime)) != 0) 128d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 129bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 130bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* vendor-specific extensions */ 131d059297112922cabb0c674840589be8db821fd9aAdam Langley if (a->flags & SSH2_FILEXFER_ATTR_EXTENDED) { 132d059297112922cabb0c674840589be8db821fd9aAdam Langley char *type; 133d059297112922cabb0c674840589be8db821fd9aAdam Langley u_char *data; 134d059297112922cabb0c674840589be8db821fd9aAdam Langley size_t dlen; 135d059297112922cabb0c674840589be8db821fd9aAdam Langley u_int i, count; 136bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 137d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_get_u32(b, &count)) != 0) 138d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: buffer error: %s", __func__, ssh_err(r)); 139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < count; i++) { 140d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_get_cstring(b, &type, NULL)) != 0 || 141d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_get_string(b, &data, &dlen)) != 0) 142d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 143d059297112922cabb0c674840589be8db821fd9aAdam Langley debug3("Got file attribute \"%.100s\" len %zu", 144d059297112922cabb0c674840589be8db821fd9aAdam Langley type, dlen); 145d059297112922cabb0c674840589be8db821fd9aAdam Langley free(type); 146d059297112922cabb0c674840589be8db821fd9aAdam Langley free(data); 147bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 148bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 149d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 150bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 151bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 152bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Encode attributes to buffer */ 153d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 154d059297112922cabb0c674840589be8db821fd9aAdam Langleyencode_attrib(struct sshbuf *b, const Attrib *a) 155bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 156d059297112922cabb0c674840589be8db821fd9aAdam Langley int r; 157d059297112922cabb0c674840589be8db821fd9aAdam Langley 158d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_put_u32(b, a->flags)) != 0) 159d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 160d059297112922cabb0c674840589be8db821fd9aAdam Langley if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { 161d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_put_u64(b, a->size)) != 0) 162d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 163d059297112922cabb0c674840589be8db821fd9aAdam Langley } 164bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { 165d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_put_u32(b, a->uid)) != 0 || 166d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_u32(b, a->gid)) != 0) 167d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 168d059297112922cabb0c674840589be8db821fd9aAdam Langley } 169d059297112922cabb0c674840589be8db821fd9aAdam Langley if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { 170d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_put_u32(b, a->perm)) != 0) 171d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 172bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 173bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { 174d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_put_u32(b, a->atime)) != 0 || 175d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_u32(b, a->mtime)) != 0) 176d059297112922cabb0c674840589be8db821fd9aAdam Langley return r; 177bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 178d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 179bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 180bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 181bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Convert from SSH2_FX_ status to text error message */ 182bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanconst char * 183bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanfx2txt(int status) 184bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman switch (status) { 186bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case SSH2_FX_OK: 187bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("No error"); 188bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case SSH2_FX_EOF: 189bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("End of file"); 190bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case SSH2_FX_NO_SUCH_FILE: 191bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("No such file or directory"); 192bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case SSH2_FX_PERMISSION_DENIED: 193bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("Permission denied"); 194bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case SSH2_FX_FAILURE: 195bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("Failure"); 196bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case SSH2_FX_BAD_MESSAGE: 197bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("Bad message"); 198bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case SSH2_FX_NO_CONNECTION: 199bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("No connection"); 200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case SSH2_FX_CONNECTION_LOST: 201bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("Connection lost"); 202bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman case SSH2_FX_OP_UNSUPPORTED: 203bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("Operation unsupported"); 204bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman default: 205bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return("Unknown status"); 206bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 207bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* NOTREACHED */ 208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 209bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 210bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 211bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh 212bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 213bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanchar * 214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanls_file(const char *name, const struct stat *st, int remote, int si_units) 215bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 216bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int ulen, glen, sz = 0; 217bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct tm *ltime = localtime(&st->st_mtime); 218bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *user, *group; 219bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; 220bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char sbuf[FMT_SCALED_STRSIZE]; 221d059297112922cabb0c674840589be8db821fd9aAdam Langley time_t now; 222bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 223bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strmode(st->st_mode, mode); 224bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!remote) { 225bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman user = user_from_uid(st->st_uid, 0); 226bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 227bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid); 228bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman user = ubuf; 229bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 230bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!remote) { 231bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman group = group_from_gid(st->st_gid, 0); 232bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 233bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid); 234bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman group = gbuf; 235bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 236bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (ltime != NULL) { 237d059297112922cabb0c674840589be8db821fd9aAdam Langley now = time(NULL); 238d059297112922cabb0c674840589be8db821fd9aAdam Langley if (now - (365*24*60*60)/2 < st->st_mtime && 239d059297112922cabb0c674840589be8db821fd9aAdam Langley now >= st->st_mtime) 240bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman sz = strftime(tbuf, sizeof tbuf, "%b %e %H:%M", ltime); 241bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 242bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman sz = strftime(tbuf, sizeof tbuf, "%b %e %Y", ltime); 243bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 244bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (sz == 0) 245bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman tbuf[0] = '\0'; 246bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ulen = MAX(strlen(user), 8); 247bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman glen = MAX(strlen(group), 8); 248bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (si_units) { 249bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fmt_scaled((long long)st->st_size, sbuf); 250bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8s %s %s", mode, 251bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (u_int)st->st_nlink, ulen, user, glen, group, 252bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman sbuf, tbuf, name); 253bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 254bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, 255bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (u_int)st->st_nlink, ulen, user, glen, group, 256bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (unsigned long long)st->st_size, tbuf, name); 257bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 258bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return xstrdup(buf); 259bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 260