LCOV - code coverage report
Current view: top level - openssh-6.6p1 - sftp-common.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 83 107 77.6 %
Date: 2014-08-01 Functions: 7 7 100.0 %
Branches: 31 56 55.4 %

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

Generated by: LCOV version 1.9