home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / E-zine / Magazines / crh / freebsd / rootkit / ls / print.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-05-27  |  7.4 KB  |  298 lines

  1. /*
  2.  * Copyright (c) 1989, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Michael Fischbein.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  *
  36.  *    $Id: print.c,v 1.8 1996/01/20 10:31:14 mpp Exp $
  37.  */
  38.  
  39. #ifndef lint
  40. static char sccsid[] = "@(#)print.c    8.4 (Berkeley) 4/17/94";
  41. #endif /* not lint */
  42.  
  43. #include <sys/param.h>
  44. #include <sys/stat.h>
  45.  
  46. #include <err.h>
  47. #include <errno.h>
  48. #include <fts.h>
  49. #include <grp.h>
  50. #include <pwd.h>
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <string.h>
  54. #include <time.h>
  55. #include <unistd.h>
  56.  
  57. #include "ls.h"
  58. #include "extern.h"
  59.  
  60. static int    printaname __P((FTSENT *, u_long, u_long));
  61. static void    printlink __P((FTSENT *));
  62. static void    printtime __P((time_t));
  63. static int    printtype __P((u_int));
  64.  
  65. #define    IS_NOPRINT(p)    ((p)->fts_number == NO_PRINT)
  66.  
  67. void
  68. printscol(dp)
  69.     DISPLAY *dp;
  70. {
  71.     FTSENT *p;
  72.  
  73.     for (p = dp->list; p; p = p->fts_link) {
  74.         if (IS_NOPRINT(p))
  75.             continue;
  76.         (void)printaname(p, dp->s_inode, dp->s_block);
  77.         (void)putchar('\n');
  78.     }
  79. }
  80.  
  81. void
  82. printlong(dp)
  83.     DISPLAY *dp;
  84. {
  85.     struct stat *sp;
  86.     FTSENT *p;
  87.     NAMES *np;
  88.     char buf[20];
  89.  
  90.     if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
  91.         (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
  92.  
  93.     for (p = dp->list; p; p = p->fts_link) {
  94.         if (IS_NOPRINT(p))
  95.             continue;
  96.         sp = p->fts_statp;
  97.         if (f_inode)
  98.             (void)printf("%*lu ", dp->s_inode, sp->st_ino);
  99.         if (f_size)
  100.             (void)printf("%*qd ",
  101.                 dp->s_block, howmany(sp->st_blocks, blocksize));
  102.         (void)strmode(sp->st_mode, buf);
  103.         np = p->fts_pointer;
  104.         (void)printf("%s %*u %-*s  %-*s  ", buf, dp->s_nlink,
  105.             sp->st_nlink, dp->s_user, np->user, dp->s_group,
  106.             np->group);
  107.         if (f_flags)
  108.             (void)printf("%-*s ", dp->s_flags, np->flags);
  109.         if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
  110.             if (minor(sp->st_rdev) > 255)
  111.                 (void)printf("%3d, 0x%08x ",
  112.                     major(sp->st_rdev), minor(sp->st_rdev));
  113.             else
  114.                 (void)printf("%3d, %3d ",
  115.                     major(sp->st_rdev), minor(sp->st_rdev));
  116.         else if (dp->bcfile)
  117.             (void)printf("%*s%*qd ",
  118.                 8 - dp->s_size, "", dp->s_size, sp->st_size);
  119.         else
  120.             (void)printf("%*qd ", dp->s_size, sp->st_size);
  121.         if (f_accesstime)
  122.             printtime(sp->st_atime);
  123.         else if (f_statustime)
  124.             printtime(sp->st_ctime);
  125.         else
  126.             printtime(sp->st_mtime);
  127.         (void)printf("%s", p->fts_name);
  128.         if (f_type)
  129.             (void)printtype(sp->st_mode);
  130.         if (S_ISLNK(sp->st_mode))
  131.             printlink(p);
  132.         (void)putchar('\n');
  133.     }
  134. }
  135.  
  136. #define    TAB    8
  137.  
  138. void
  139. printcol(dp)
  140.     DISPLAY *dp;
  141. {
  142.     extern int termwidth;
  143.     static FTSENT **array;
  144.     static int lastentries = -1;
  145.     FTSENT *p;
  146.     int base, chcnt, cnt, col, colwidth, num;
  147.     int endcol, numcols, numrows, row;
  148.  
  149.     /*
  150.      * Have to do random access in the linked list -- build a table
  151.      * of pointers.
  152.      */
  153.     if (dp->entries > lastentries) {
  154.         lastentries = dp->entries;
  155.         if ((array =
  156.             realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
  157.             warn(NULL);
  158.             printscol(dp);
  159.         }
  160.     }
  161.     for (p = dp->list, num = 0; p; p = p->fts_link)
  162.         if (p->fts_number != NO_PRINT)
  163.             array[num++] = p;
  164.  
  165.     colwidth = dp->maxlen;
  166.     if (f_inode)
  167.         colwidth += dp->s_inode + 1;
  168.     if (f_size)
  169.         colwidth += dp->s_block + 1;
  170.     if (f_type)
  171.         colwidth += 1;
  172.  
  173.     colwidth = (colwidth + TAB) & ~(TAB - 1);
  174.     if (termwidth < 2 * colwidth) {
  175.         printscol(dp);
  176.         return;
  177.     }
  178.  
  179.     numcols = termwidth / colwidth;
  180.     numrows = num / numcols;
  181.     if (num % numcols)
  182.         ++numrows;
  183.  
  184.     if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
  185.         (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
  186.     for (row = 0; row < numrows; ++row) {
  187.         endcol = colwidth;
  188.         for (base = row, chcnt = col = 0; col < numcols; ++col) {
  189.             chcnt += printaname(array[base], dp->s_inode,
  190.                 dp->s_block);
  191.             if ((base += numrows) >= num)
  192.                 break;
  193.             while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) <= endcol){
  194.                 (void)putchar('\t');
  195.                 chcnt = cnt;
  196.             }
  197.             endcol += colwidth;
  198.         }
  199.         (void)putchar('\n');
  200.     }
  201. }
  202.  
  203. /*
  204.  * print [inode] [size] name
  205.  * return # of characters printed, no trailing characters.
  206.  */
  207. static int
  208. printaname(p, inodefield, sizefield)
  209.     FTSENT *p;
  210.     u_long sizefield, inodefield;
  211. {
  212.     struct stat *sp;
  213.     int chcnt;
  214.  
  215.     sp = p->fts_statp;
  216.     chcnt = 0;
  217.     if (f_inode)
  218.         chcnt += printf("%*lu ", (int)inodefield, sp->st_ino);
  219.     if (f_size)
  220.         chcnt += printf("%*qd ",
  221.             (int)sizefield, howmany(sp->st_blocks, blocksize));
  222.     chcnt += printf("%s", p->fts_name);
  223.     if (f_type)
  224.         chcnt += printtype(sp->st_mode);
  225.     return (chcnt);
  226. }
  227.  
  228. static void
  229. printtime(ftime)
  230.     time_t ftime;
  231. {
  232.     int i;
  233.     char longstring[80];
  234.  
  235.     strftime(longstring, sizeof(longstring), "%c", localtime(&ftime));
  236.     for (i = 4; i < 11; ++i)
  237.         (void)putchar(longstring[i]);
  238.  
  239. #define    SIXMONTHS    ((365 / 2) * 86400)
  240.     if (f_sectime)
  241.         for (i = 11; i < 24; i++)
  242.             (void)putchar(longstring[i]);
  243.     else if (ftime + SIXMONTHS > time(NULL))
  244.         for (i = 11; i < 16; ++i)
  245.             (void)putchar(longstring[i]);
  246.     else {
  247.         (void)putchar(' ');
  248.         for (i = 20; i < 24; ++i)
  249.             (void)putchar(longstring[i]);
  250.     }
  251.     (void)putchar(' ');
  252. }
  253.  
  254. static int
  255. printtype(mode)
  256.     u_int mode;
  257. {
  258.     switch (mode & S_IFMT) {
  259.     case S_IFDIR:
  260.         (void)putchar('/');
  261.         return (1);
  262.     case S_IFIFO:
  263.         (void)putchar('|');
  264.         return (1);
  265.     case S_IFLNK:
  266.         (void)putchar('@');
  267.         return (1);
  268.     case S_IFSOCK:
  269.         (void)putchar('=');
  270.         return (1);
  271.     }
  272.     if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
  273.         (void)putchar('*');
  274.         return (1);
  275.     }
  276.     return (0);
  277. }
  278.  
  279. static void
  280. printlink(p)
  281.     FTSENT *p;
  282. {
  283.     int lnklen;
  284.     char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
  285.  
  286.     if (p->fts_level == FTS_ROOTLEVEL)
  287.         (void)snprintf(name, sizeof(name), "%s", p->fts_name);
  288.     else
  289.         (void)snprintf(name, sizeof(name),
  290.             "%s/%s", p->fts_parent->fts_accpath, p->fts_name);
  291.     if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
  292.         (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
  293.         return;
  294.     }
  295.     path[lnklen] = '\0';
  296.     (void)printf(" -> %s", path);
  297. }
  298.