home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1083 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  25.8 KB

  1. From: davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr)
  2. Newsgroups: alt.sources
  3. Subject: le, a versatile replacement for ls
  4. Message-ID: <2187@crdos1.crd.ge.COM>
  5. Date: 29 Mar 90 19:37:45 GMT
  6.  
  7.  
  8.   This was rejected for publication in comp.sources.misc for reasons I
  9. don't totally inderstand. Anyway it's a file listing program with a
  10. number of options to control what characteristics are displayed, and how
  11. they are displayed. For example, the date changed, modified, or accessed
  12. may be displayed, in human readable format or as yyyy-mm-dd hh:mm:ss so
  13. "sort" will put things in order.
  14.  
  15.   I like this because the dates don't change format as the file ages,
  16. while ls starts including the year after a while. Awk scripts which read
  17. the dates get complex quickly.
  18.  
  19.   Original by Peter DaSilva many years ago, changes and some
  20. documentation by me.
  21.  
  22. #!/bin/sh
  23. # shar:    Shell Archiver  (v1.27)
  24. #
  25. #    Run the following text with /bin/sh to create:
  26. #      le.doc
  27. #      le.1
  28. #      le.c
  29. #
  30. echo "x - extracting le.doc (Text)"
  31. sed 's/^X//' << 'SHAR_EOF' > le.doc &&
  32. XArticle 2687 (43 more) in net.sources:
  33. XFrom: peter@baylor.UUCP (Peter da Silva)
  34. XSubject: le.c
  35. XMessage-ID: <506@baylor.UUCP>
  36. XDate: 21 Aug 85 19:05:15 GMT
  37. XDate-Received: 28 Aug 85 08:22:21 GMT
  38. XDistribution: net
  39. XOrganization: The Power Elite, Houston, TX
  40. XLines: 82
  41. X
  42. Xle is an extended ls, designed to please all the people who want to get
  43. Xweird info on a file. It dumps reliable info in reliable positions, for
  44. Xexample it won't stick the major/minor device #s in the file size feild
  45. Xof the output. Let me see about the options...
  46. X
  47. X
  48. XWithout any flags it outputs the same info as ls...
  49. X
  50. X        Usage: le [-A|-N] [-diMmlUuGgrsatc] [-Ttab] [-Hh] [-D] [file]...
  51. X
  52. X        -d      Toggle 'dev' flag.
  53. X        -i      Toggle 'inode' flag.
  54. X        -m      Toggle 'mode' flag.
  55. X        -M      Toggle 'short mode' (octal mode) flag.
  56. X        -l      Toggle 'links' flag.
  57. X        -u      Toggle 'user' flag.
  58. X        -U      Toggle 'short user' (userid) flag.
  59. X        -g      Toggle 'group' flag.
  60. X        -G      Toggle 'short group' (groupid) flag.
  61. X        -r      Toggle 'rdev' flag.
  62. X        -s      Toggle 'size' flag.
  63. X    -k      Toggle 'ksize' flag.
  64. X        -a      Toggle 'atime' flag.
  65. X        -t      Toggle 'mtime' flag.
  66. X        -c      Toggle 'ctime' flag.
  67. X        -h      Print help and exit.
  68. X        -H      Force output of the header.
  69. X        -N      (None) Clear all flags.
  70. X        -A      (All) Set all flags.
  71. X        -D      Dont list directories (like ls -d).
  72. X        -Ttab   Use the string 'tab' to seperate feilds instead of space.
  73. X    -f      Format dates so they will sort in ascending order
  74. X
  75. X        The flags can be included in any order but having any of
  76. X[dimMluUgGrsatc] before [AN] is kind of useless, and having [Hh]
  77. Xbefore [dimMluUgGrsatc] can be misleading. You can intersperse
  78. Xoptions with files if you want to list different directories
  79. Xdifferently. I don't see any reason to do this but I also see no
  80. Xgood reason to prevent this (no, I don't use getopt).
  81. X
  82. XAs an example: here is 'ls -al' compared with 'le'
  83. X
  84. XNote that feild 7 varies between a time and a year, and that 4 varies
  85. Xbetween a size and a device #... while this is more useful for humans
  86. Xit's kind of hard on awk... le isn't a replacement for 'ls', just for
  87. Xls in shell scripts so you can keep awk and relatives happy.
  88. X
  89. X% ls -al /dev
  90. Xtotal 4
  91. Xc-w--w--w- 2 root      5,  0 Aug 21 13:46 aux1
  92. Xc-w--w--w- 2 root      5,  1 May 20 09:50 aux2
  93. Xcrw--w--w- 1 root      0,  8 Aug 20 13:52 console
  94. X...
  95. Xcrw-rw-rw- 1 root      1, 23 Aug 18  1982 hsix7
  96. Xcrw------- 1 root      2,  1 Aug 20 13:52 kmem
  97. X-rw-rw-r-- 1 root       1635 Jul 11 17:39 lp
  98. Xc-w--w--w- 2 root      5,  0 Aug 21 13:46 lp1
  99. Xc-w--w--w- 2 root      5,  1 May 20 09:50 lp2
  100. X...
  101. Xcrw--w--w- 1 root      0, 15 Jul 23 15:38 tty7
  102. X% le /dev
  103. Xdrwxr-xr-x   2 root        928  11 Jul 85 16:40  /dev/.
  104. Xdrwxr-xr-x  11 root        368  20 Aug 85 13:52  /dev/..
  105. Xc-w--w--w-   2 root          0  21 Aug 85 13:46  /dev/aux1
  106. Xc-w--w--w-   2 root          0  20 May 85  9:50  /dev/aux2
  107. Xcrw--w--w-   1 root          0  20 Aug 85 13:52  /dev/console
  108. X...
  109. Xcrw-rw-rw-   1 root          0  18 Aug 82 11:11  /dev/hsix7
  110. Xcrw-------   1 root          0  20 Aug 85 13:52  /dev/kmem
  111. X-rw-rw-r--   1 root       1635  11 Jul 85 17:39  /dev/lp
  112. Xc-w--w--w-   2 root          0  21 Aug 85 13:46  /dev/lp1
  113. Xc-w--w--w-   2 root          0  20 May 85  9:50  /dev/lp2
  114. X...
  115. Xcrw--w--w-   1 root          0  23 Jul 85 15:38  /dev/tty7
  116. X
  117. XThere is a problem: le expands control characters to '^X', which may cause
  118. Xproblems in some cases... le -N is thus not exactly the equivalent of ls -A.
  119. XThis code can be easily changed if this proves a problem. Don't ask me why
  120. X/dev/lp is a regular file, I didn't create it... :-> Time to go do some sa-type
  121. Xstuff.
  122. X-- 
  123. X        Peter (Made in Australia) da Silva
  124. X                UUCP: ...!shell!neuro1!{hyd-ptd,baylor,datafac}!peter
  125. X                MCI: PDASILVA; CIS: 70216,1076
  126. X________________________________________________________________
  127. X
  128. XNotes from bill davidsen:
  129. X
  130. XThe original version had one flag which toggled having the headers on
  131. Xand print the header after the options were evaluated, and another which
  132. Xforced the header out when parsed, sometimes before other options
  133. Xmodified the display format. Now -H prints the headers after all options
  134. Xare evaluated.
  135. X
  136. XI wanted to be able to sort the information on time modified, accessed,
  137. Xetc, so I added the -f option to output the date in yyyy-mm-dd format,
  138. Xsuch as 1988-12-08, so that 'sort' will correctly sort the output, and
  139. Xmy little database program will find things by date.
  140. X
  141. XI added -h as help, because I can't remember the more obscure options of
  142. Xthe program, I frequently don't have a manual handy, and at the time I
  143. Xadded help there was no man page and I may not find time to write one.
  144. SHAR_EOF
  145. chmod 0644 le.doc || echo "restore of le.doc fails"
  146. echo "x - extracting le.1 (Text)"
  147. sed 's/^X//' << 'SHAR_EOF' > le.1 &&
  148. X'\" @(#)skeleton    3.3 - 12/21/83
  149. X'\" [c][e][t] (only if preprocessing by cw, eqn, and/or tbl required)
  150. X.TH LE 1 local
  151. X'\" Heading: name(sect)    center (paren)    name(sect)
  152. X.SH NAME
  153. Xle - display directory infomation with format control
  154. X.SH SYNOPSIS
  155. Xle [-A|-N] [-diMmlUuGgrsatc] [-Ttab] [-Hh] [-D] [file]...
  156. X.SH DESCRIPTION
  157. X.B le
  158. XGives much the same information as 'ls' but does so with full user
  159. Xcontrol. ls makes format changes, such as having the year in the date
  160. Xsometimes, or putting the major and minor device numbers in place of
  161. Xfile size. These are excelent choices for humans, but they confuse
  162. X\fIsed\fR and \fIawk\fR.
  163. X\fBle\fR allows the user full control of the output contents, including
  164. Xheaders. All fields have the same format and width for all items.
  165. X.SS Options
  166. XOptions are parsed left to right, which allows options which affect the
  167. Xentire format to be modified by specifying exceptions, rather than by
  168. Xlisting all of the defaults individually.
  169. X.ne 10
  170. X.SS "Options affecting more than one field
  171. X.TS
  172. Xtab(@);
  173. Xlbw(.5i) l.
  174. X-A@T{
  175. XDisplay \fIall\fR information on this file. This will produce a report
  176. Xwider than 80 columns.
  177. XT}
  178. X
  179. X-N@T{
  180. XDisplay only the filename. Additional information may be added by use of
  181. Xfollowing options.
  182. XT}
  183. X
  184. X-h@Generate a help listing of options
  185. X
  186. X-f@T{
  187. XChange date format for sorting. The default format for dates is
  188. X.tr ~
  189. Xdd~mmm~yy, for human readability. The \fB-f\fR changes this to
  190. Xyyyy-mm-dd, which allows sorting by \fIsort\fR or other programs using
  191. Xan alphabetic or numeric sort.
  192. XT}
  193. X
  194. X-D@T{
  195. XDon't expand directories. Information is printed about the directory,
  196. Xrather than the contents of it.
  197. XT}
  198. X
  199. X-Tx@Separate fields by \fIx\fR instead of blanks.
  200. X
  201. X-H@Output a header describing the contents of each field.
  202. X.TE
  203. X.sp
  204. X.ne 10
  205. X.SS "Options which toggle the display of selected information
  206. X.TS
  207. Xtab(@);
  208. Xlbw(.5i) l.
  209. X-m@T{
  210. Xcontrols the display of mode information in alphabetic format, such as
  211. X"drwx--x--x" which is produced by "ls~-l".
  212. XT}
  213. X
  214. X-M@T{
  215. Xcontrols the display of "short mode" information, shown as an octal
  216. Xvalue such as is given by listing the contents of a \fItar\fR or
  217. X\fIcpio\fR dump on most systems.
  218. XT}
  219. X
  220. X-l@controls the display of the number of links to the inode.
  221. X
  222. X-i@controls display of the inode number.
  223. X
  224. X-d@T{
  225. Xcontrols display of the inode device. This is the major and minor device
  226. Xnumbers for the device on which the inode is stored.
  227. XT}
  228. X
  229. X-r@T{
  230. Xcontrols the display of the major and minor device numbers of cataloged
  231. Xdevices. This will be the same information displayed in place of the
  232. Xsize by "ls~-l".
  233. XT}
  234. X
  235. X-u@controls display of the UID by name.
  236. X
  237. X-U@controls the display of the UID by number.
  238. X
  239. X-g@controls the display of the GID by name.
  240. X
  241. X-G@controls the display of the GID by number.
  242. X
  243. X-s@controls display of the filesize in bytes.
  244. X
  245. X-k@controls display of the filesize in k.
  246. X
  247. X-a@controls display of the date last accessed.
  248. X
  249. X-c@controls display of the date the inode was last modified.
  250. X
  251. X-t@controls display of the date the file was last modofied.
  252. X.TE
  253. X.ne 15
  254. X.SH EXAMPLES
  255. X.nf
  256. X.in +.5i
  257. X\" change to constant width font or use .cs
  258. X.ft CW
  259. X$ le -Hr
  260. X   Rdev Long mode  Lnx User       Size  Modify time      File name
  261. X  2,224 drwxr-xr-x   3 bin        2688   9 Nov 88 14:52  /dev/.
  262. X  2,232 drwxr-xr-x  17 bin         496  29 Nov 88  8:36  /dev/..
  263. X103, 73 drwxrwxrwx   2 root        592  10 Sep 87 14:49  /dev/EXOS
  264. X  8,  0 crw-r--r--   1 root          0   5 Dec 88 18:18  /dev/clock
  265. X  7,  0 crw-r--r--   1 sysinfo       0  30 May 86 17:52  /dev/cmos
  266. X  0,  0 crw-rw-rw-   1 root          0   8 Dec 88  9:45  /dev/console
  267. X  1, 47 brw-------   1 sysinfo       0   4 Mar 88 18:51  /dev/d1057all
  268. X  1,119 brw-r--r--   1 root          0  30 May 86 19:12  /dev/dh1d
  269. X.ft R
  270. X.in -.5i
  271. X.fi
  272. X.SH WARNINGS
  273. XThere may be special device types which \fBle\fR will not handle. In
  274. Xthis case the device type will be shown as a "?" in the mode.
  275. X.SH FILES
  276. X.SH SEE ALSO
  277. Xls.
  278. X.SH DIAGNOSTICS
  279. XVery large directories may produce a diagnostic as internal table
  280. Xoverflow.
  281. X.SH LIMITATIONS
  282. X.SH AUTHOR
  283. XPeter da Silva (peter@baylor.uucp), changes and man page by Bill
  284. XDavidsen (davidsen@crdos1.uucp).
  285. SHAR_EOF
  286. chmod 0666 le.1 || echo "restore of le.1 fails"
  287. echo "x - extracting le.c (Text)"
  288. sed 's/^X//' << 'SHAR_EOF' > le.c &&
  289. X/* LE.C - enhanced version of ls
  290. X
  291. X   From net.sources 28 Aug 1985, by Peter da Silva (peter@baylor.uucp).
  292. X   
  293. X   Modifications by bill davidsen (davidsen@crdos1.uucp) 3/28/90.
  294. X*/
  295. X
  296. Xstatic char *SCCSid = "@(#)le.c v1.8 - 3/29/90";
  297. X
  298. X#include <stdio.h>
  299. X#include <sys/types.h>
  300. X#include <sys/stat.h>
  301. X#include <sys/dir.h>
  302. X#include <pwd.h>
  303. X#include <grp.h>
  304. X#include <time.h>
  305. X#ifdef    M_XENIX
  306. X#include <sys/sysmacros.h>
  307. X#endif
  308. X
  309. X#define D_DEV   01
  310. X#define D_INO   02
  311. X#define D_MODE  04
  312. X#define D_LINKS 010
  313. X#define D_UID   020
  314. X#define D_GID   040
  315. X#define D_RDEV  0100
  316. X#define D_SIZE  0200
  317. X#define D_ATIME 0400
  318. X#define D_MTIME 01000
  319. X#define D_CTIME 02000
  320. X
  321. X#define D_SMODE 04000
  322. X#define D_SUID  010000
  323. X#define D_SGID  020000
  324. X#define D_KSIZE 040000
  325. X
  326. X#define FALSE 0
  327. X#define TRUE 1
  328. X
  329. X#define MAXENTS 512
  330. X#define MAXID 64
  331. X
  332. Xstruct entry {
  333. X        struct direct e_dir;
  334. X        char filler;
  335. X        struct stat e_stat;
  336. X} entries[MAXENTS];
  337. Xint nentries;
  338. X
  339. Xchar *errname;
  340. Xextern int errno;
  341. Xint xerrno;
  342. Xchar *tab=" ";
  343. Xlong maxsize;
  344. Xchar sizstr[2][10] = {"%6lu%s","%6s%s"};
  345. Xint dohead=0, dodir=1;
  346. Xint flags = D_MODE|D_LINKS|D_UID|D_SIZE|D_MTIME;
  347. Xint datefmt = 0;
  348. X
  349. Xchar *emesg[3]={
  350. X        "No such error",
  351. X#define TOO_MANY 1
  352. X        "Too many directory entries",
  353. X        0
  354. X};
  355. X
  356. Xgetdir(dir)
  357. Xchar *dir;
  358. X{
  359. X        int     entcmp();
  360. X        char *nameof();
  361. X        FILE *fp;
  362. X        int valid;
  363. X
  364. X        if(!(fp = fopen(dir, "r"))) {
  365. X                errname=dir;
  366. X                return FALSE;
  367. X        }
  368. X
  369. X        maxsize=0L;
  370. X        for(nentries=0;
  371. X            nentries<MAXENTS &&
  372. X              fread((char *)&entries[nentries].e_dir,
  373. X                    sizeof entries[nentries].e_dir, 1, fp)>0;
  374. X            nentries += valid) {
  375. X                if(valid=entries[nentries].e_dir.d_ino?1:0) {
  376. X                        entries[nentries].filler=0;
  377. X                        if(stat(nameof(entries[nentries].e_dir.d_name, dir),
  378. X                                &entries[nentries].e_stat
  379. X                               )==-1
  380. X                          ) {
  381. X                                fclose(fp);
  382. X                                errname=nameof(entries[nentries].e_dir.d_name,
  383. X                                                dir);
  384. X                                return FALSE;
  385. X                        }
  386. X                        if(entries[nentries].e_stat.st_size>maxsize)
  387. X                                maxsize=entries[nentries].e_stat.st_size;
  388. X                }
  389. X        }
  390. X
  391. X        if(nentries>=MAXENTS) {
  392. X                errno=0;
  393. X                xerrno=TOO_MANY;
  394. X                errname=dir;
  395. X                return FALSE;
  396. X        }
  397. X
  398. X        fclose(fp);
  399. X
  400. X        qsort(entries, nentries, sizeof(struct entry), entcmp);
  401. X
  402. X        setsize(maxsize);
  403. X
  404. X        return TRUE;
  405. X}
  406. X
  407. Xsetsize(size)
  408. Xlong size;
  409. X{
  410. X        char tmp[32];
  411. X        int siz;
  412. X        sprintf(tmp, "%lu", size);
  413. X        siz=strlen(tmp);
  414. X        if(siz<6) siz=6;
  415. X        sprintf(sizstr[0], "%%%dlu%%s", siz);
  416. X        sprintf(sizstr[1], "%%%ds%%s", siz);
  417. X        if(dohead) {
  418. X                header();
  419. X                dohead=0;
  420. X        }
  421. X}
  422. X
  423. Xchar *
  424. Xnameof(name, dir)
  425. Xchar *name, *dir;
  426. X{
  427. X        char nambuf[BUFSIZ];
  428. X
  429. X        if(!dir[0])
  430. X                return name;
  431. X        if(dir[0]=='.' && !dir[1])
  432. X                return name;
  433. X        else if(dir[0]=='/' && !dir[1]) {
  434. X                sprintf(nambuf, "/%s", name);
  435. X                return nambuf;
  436. X        } else {
  437. X                sprintf(nambuf, "%s/%s", dir, name);
  438. X                return nambuf;
  439. X        }
  440. X}
  441. X
  442. Xpname(name)
  443. Xchar *name;
  444. X{
  445. X        int len = 0;
  446. X
  447. X        for(;*name; name++)
  448. X                if(*name<' ') { printf("^%c", *name+'@'); len+=2; }
  449. X                else if(*name=='\177') { printf("^?"); len+=2; }
  450. X                else if(*name>'\177') { printf("\\%03o", *name); len += 4; }
  451. X                else { putchar(*name); len++; }
  452. X        return len;
  453. X}
  454. X
  455. Xentcmp(e1, e2)
  456. Xstruct entry *e1, *e2;
  457. X{
  458. X        return strcmp(e1->e_dir.d_name, e2->e_dir.d_name);
  459. X}
  460. X
  461. Xfdump(dir)
  462. Xchar *dir;
  463. X{
  464. X        struct stat sbuf;
  465. X
  466. X        if(stat(dir, &sbuf)==-1) {
  467. X                errname=dir;
  468. X                return FALSE;
  469. X        } else
  470. X                if(dodir && (sbuf.st_mode&S_IFMT)==S_IFDIR) {
  471. X                        if(getdir(dir))
  472. X                                return dump(dir);
  473. X                        else
  474. X                                return FALSE;
  475. X                } else {
  476. X                        setsize(sbuf.st_size);
  477. X                        statout(dir, &sbuf, ".");
  478. X                        return TRUE;
  479. X                }
  480. X}
  481. X
  482. Xdump(dir)
  483. Xchar *dir;
  484. X{
  485. X        int i, j;
  486. X        int chars;
  487. X
  488. X        if(flags==0) {
  489. X                for(i=0; i<=nentries/5; i++) {
  490. X                        chars = 0;
  491. X                        for(j=0; j<5; j++) {
  492. X                                if(i+j*nentries/5<nentries)
  493. X                                        chars +=
  494. X                                        pname(entries[i+j*nentries/5].e_dir.d_name);
  495. X                                if(chars<8) { putchar('\t'); chars=8; }
  496. X                                if(chars<16) { putchar('\t'); chars=16; }
  497. X                                else { putchar(' '); chars++; }
  498. X                                chars %= 16;
  499. X                        }
  500. X                        putchar('\n');
  501. X                }
  502. X        }
  503. X        else for(i=0; i<nentries; i++)
  504. X                statout(entries[i].e_dir.d_name,
  505. X                        &entries[i].e_stat, dir);
  506. X        return TRUE;
  507. X}
  508. X
  509. Xstatout(name, sbuf, dir)
  510. Xchar *name;
  511. Xstruct stat *sbuf;
  512. Xchar *dir;
  513. X{
  514. X        char *u_name(), *g_name();
  515. X
  516. X        if(flags&D_DEV)
  517. X                printf("%3d,%3d%s",
  518. X                        major(sbuf->st_dev),
  519. X                        minor(sbuf->st_dev),
  520. X                        tab);
  521. X        if(flags&D_RDEV)
  522. X                printf("%3d,%3d%s",
  523. X                        major(sbuf->st_rdev),
  524. X                        minor(sbuf->st_rdev),
  525. X                        tab);
  526. X        if(flags&D_INO)
  527. X                printf("%5u%s", sbuf->st_ino, tab);
  528. X        if(flags&D_SMODE)
  529. X                printf("%6o%s", sbuf->st_mode, tab);
  530. X        if(flags&D_MODE) {
  531. X                int mode = sbuf->st_mode;
  532. X                if((mode&S_IFMT)==S_IFCHR) putchar('c');
  533. X                else if((mode&S_IFMT)==S_IFBLK) putchar('b');
  534. X                else if((mode&S_IFMT)==S_IFDIR) putchar('d');
  535. X                else if((mode&S_IFMT)==S_IFREG) putchar('-');
  536. X                else if((mode&S_IFMT)==S_IFIFO) putchar('p');
  537. X                else putchar('?');
  538. X                triad((mode>>6)&7, mode&S_ISUID, 's');
  539. X                triad((mode>>3)&7, mode&S_ISGID, 's');
  540. X                triad(mode&7, mode&S_ISVTX, 't');
  541. X                printf("%s", tab);
  542. X        }
  543. X        if(flags&D_LINKS)
  544. X                printf("%3u%s", sbuf->st_nlink, tab);
  545. X        if(flags&D_SUID)
  546. X                printf("%3d%s", sbuf->st_uid, tab);
  547. X        if(flags&D_UID)
  548. X                printf("%-8s%s", u_name(sbuf->st_uid), tab);
  549. X        if(flags&D_SGID)
  550. X                printf("%3d%s", sbuf->st_gid, tab);
  551. X        if(flags&D_GID)
  552. X                printf("%-8s%s", g_name(sbuf->st_gid), tab);
  553. X        if(flags&D_SIZE)
  554. X                printf(sizstr[0], sbuf->st_size, tab);
  555. X        if(flags&D_KSIZE)
  556. X                printf("%6dk%s", (int)(sbuf->st_size)/1024, tab);
  557. X        if((flags&~(D_ATIME|D_MTIME|D_CTIME)) &&
  558. X           (flags&(D_ATIME|D_MTIME|D_CTIME))) putchar(' ');
  559. X        if(flags&D_ATIME)
  560. X                printime(&sbuf->st_atime);
  561. X        if(flags&D_MTIME)
  562. X                printime(&sbuf->st_mtime);
  563. X        if(flags&D_CTIME)
  564. X                printime(&sbuf->st_ctime);
  565. X        pname(nameof(name, dir));
  566. X        putchar('\n');
  567. X}
  568. X
  569. Xstruct idtab {
  570. X        int id_id;
  571. X        char id_name[10];
  572. X} u_list[MAXID], g_list[MAXID];
  573. Xint u_ptr=0, g_ptr=0;
  574. X
  575. Xchar *
  576. Xu_name(uid)
  577. Xint uid;
  578. X{
  579. X        int i;
  580. X        struct passwd *pwptr, *getpwuid();
  581. X
  582. X        for(i=0; i<u_ptr; i++)
  583. X                if(u_list[i].id_id==uid)
  584. X                        return u_list[i].id_name;
  585. X
  586. X        u_list[u_ptr].id_id=uid;
  587. X
  588. X        if(pwptr=getpwuid(uid)) {
  589. X                for(i=0; pwptr->pw_name[i]>' '; i++)
  590. X                        u_list[u_ptr].id_name[i]=pwptr->pw_name[i];
  591. X                u_list[u_ptr].id_name[i]=0;
  592. X        } else
  593. X                sprintf(u_list[u_ptr].id_name, "%d", uid);
  594. X
  595. X        return u_list[u_ptr++].id_name;
  596. X}
  597. X
  598. Xchar *
  599. Xg_name(gid)
  600. Xint gid;
  601. X{
  602. X        int i;
  603. X        struct group *grptr, *getgrgid();
  604. X
  605. X        for(i=0; i<g_ptr; i++)
  606. X                if(g_list[i].id_id==gid)
  607. X                        return g_list[i].id_name;
  608. X
  609. X        g_list[g_ptr].id_id=gid;
  610. X
  611. X        if(grptr=getgrgid(gid)) {
  612. X                for(i=0; grptr->gr_name[i]>' '; i++)
  613. X                        g_list[g_ptr].id_name[i]=grptr->gr_name[i];
  614. X                g_list[g_ptr].id_name[i]=0;
  615. X        } else
  616. X                sprintf(g_list[g_ptr].id_name, "%d", gid);
  617. X
  618. X        return g_list[g_ptr++].id_name;
  619. X}
  620. X
  621. Xprintime(clock)
  622. Xlong *clock;
  623. X{
  624. X        struct tm *tmbuf, *localtime();
  625. X        static char *months[12]= {
  626. X                "Jan","Feb","Mar","Apr","May","Jun",
  627. X                "Jul","Aug","Sep","Oct","Nov","Dec"
  628. X        };
  629. X
  630. X        tmbuf=localtime(clock);
  631. X    if (datefmt) {
  632. X        printf("%4d-%02d-%02d %02d:%02d %s",
  633. X            tmbuf->tm_year+1900,
  634. X            tmbuf->tm_mon+1,
  635. X            tmbuf->tm_mday,
  636. X                tmbuf->tm_hour,
  637. X                tmbuf->tm_min,
  638. X                tab);
  639. X    }
  640. X    else {
  641. X        printf("%2d %3s %02d %2d:%02d %s",
  642. X                tmbuf->tm_mday,
  643. X                months[tmbuf->tm_mon],
  644. X                tmbuf->tm_year,
  645. X                tmbuf->tm_hour,
  646. X                tmbuf->tm_min,
  647. X                tab);
  648. X    }
  649. X}
  650. X
  651. Xheader()
  652. X{
  653. X        if(flags&D_DEV)
  654. X                printf("%7s%s", "IDev", tab);
  655. X        if(flags&D_RDEV)
  656. X                printf("%7s%s", "Rdev", tab);
  657. X        if(flags&D_INO)
  658. X                printf("%5s%s", "Inode", tab);
  659. X        if(flags&D_SMODE)
  660. X                printf("%6s%s", "Mode", tab);
  661. X        if(flags&D_MODE)
  662. X                printf("%-10s%s", "Long mode", tab);
  663. X        if(flags&D_LINKS)
  664. X                printf("%3s%s", "Lnx", tab);
  665. X        if(flags&D_SUID)
  666. X                printf("%3s%s", "UID", tab);
  667. X        if(flags&D_UID)
  668. X                printf("%-8s%s", "User", tab);
  669. X        if(flags&D_SGID)
  670. X                printf("%3s%s", "GID", tab);
  671. X        if(flags&D_GID)
  672. X                printf("%-8s%s", "Group", tab);
  673. X        if(flags&D_SIZE)
  674. X                printf(sizstr[1], "Size", tab);
  675. X        if(flags&D_KSIZE)
  676. X                printf("  Size %s", tab);
  677. X        if((flags&~(D_ATIME|D_MTIME|D_CTIME)) &&
  678. X           (flags&(D_ATIME|D_MTIME|D_CTIME))) putchar(' ');
  679. X        if(flags&D_ATIME)
  680. X                printf("%-*s%s", datefmt+16, "Access time", tab);
  681. X        if(flags&D_MTIME)
  682. X                printf("%-*s%s", datefmt+16, "Modify time", tab);
  683. X        if(flags&D_CTIME)
  684. X                printf("%-*s%s", datefmt+16, "Inode time", tab);
  685. X        if(flags)
  686. X                printf("%s\n", "File name");
  687. X}
  688. X
  689. Xtriad(bits, special, code)
  690. Xint bits, special;
  691. Xchar code;
  692. X{
  693. X        if(bits&4) putchar('r');
  694. X        else putchar('-');
  695. X
  696. X        if(bits&2) putchar('w');
  697. X        else putchar('-');
  698. X
  699. X        if(special) putchar(code);
  700. X        else if(bits&1) putchar('x');
  701. X        else putchar('-');
  702. X}
  703. X
  704. Xmain(ac, av)
  705. Xint ac;
  706. Xchar **av;
  707. X{
  708. X        int i, j;
  709. X        int exit_status = 0;
  710. X        int filed=0;
  711. X
  712. X        for(i=1; i<ac; i++) {
  713. X                if(av[i][0]=='-')
  714. X                        for(j=1; av[i][j]; j++)
  715. X                                switch(av[i][j]) {
  716. X                                        case 'T':
  717. X                                                if(av[i][j+1])
  718. X                                                        tab = &av[i][++j];
  719. X                                                else
  720. X                                                        tab = &av[++i][j=0];
  721. X                                                while(av[i][j]) j++;
  722. X                                                j--;
  723. X                                                break;
  724. X                                        case 'N': flags = 0; break;
  725. X                                        case 'A': flags = -1; break;
  726. X                                        case 'D': dodir=!dodir; break;
  727. X                                        case 'd': flags ^= D_DEV; break;
  728. X                                        case 'i': flags ^= D_INO; break;
  729. X                                        case 'm': flags ^= D_MODE; break;
  730. X                                        case 'M': flags ^= D_SMODE; break;
  731. X                                        case 'l': flags ^= D_LINKS; break;
  732. X                                        case 'u': flags ^= D_UID; break;
  733. X                                        case 'U': flags ^= D_SUID; break;
  734. X                                        case 'g': flags ^= D_GID; break;
  735. X                                        case 'G': flags ^= D_SGID; break;
  736. X                                        case 'r': flags ^= D_RDEV; break;
  737. X                                        case 's': flags ^= D_SIZE; break;
  738. X                                        case 'k': flags ^= D_KSIZE; break;
  739. X                                        case 'a': flags ^= D_ATIME; break;
  740. X                                        case 't': flags ^= D_MTIME; break;
  741. X                                        case 'c': flags ^= D_CTIME; break;
  742. X                    case 'f': datefmt = 1; break;
  743. X                                        case 'H': dohead = 1; break;
  744. X                                        default: printf("unknown option %c\n", av[i][j]);
  745. X                    case 'h': helpuser(); exit(0);
  746. X                                }
  747. X                else {
  748. X                        filed=1;
  749. X                        if(!fdump(av[i])) {
  750. X                                fperror(av[0], errname);
  751. X                                exit_status=errno?errno:(-xerrno);
  752. X                        }
  753. X                }
  754. X        }
  755. X        if(!filed)
  756. X                if(!fdump(".")) {
  757. X                        fperror(av[0], errname);
  758. X                        exit_status=errno;
  759. X                }
  760. X
  761. X        if(dohead) header();
  762. X        exit(exit_status);
  763. X}
  764. X
  765. Xfperror(prog, file)
  766. Xchar *prog, *file;
  767. X{
  768. X        fprintf(stderr, "%s -- ", prog);
  769. X        if(errno)
  770. X                perror(file);
  771. X        else
  772. X                fprintf(stderr, "%s: %s\n", file, emesg[xerrno]);
  773. X}
  774. X
  775. Xhelpuser() {
  776. X    int n;
  777. X
  778. X    static char *helpit[] = {
  779. X        "",
  780. X    "Usage: le [-A|-N] [-diMmlUuGgrsatc] [-Ttab] [-Hh] [-D] [file]...",
  781. X    "",
  782. X        "-d  Toggle 'dev' flag.            -r  Toggle 'rdev' flag.",
  783. X        "-i  Toggle 'inode' flag.          -s  Toggle 'size' flag.",
  784. X        "-m  Toggle 'mode' flag.           -k  Toggle 'ksize' flag.",
  785. X        "-M  Toggle 'short mode' flag.     -a  Toggle 'atime' flag.",
  786. X        "-l  Toggle 'links' flag.          -t  Toggle 'mtime' flag.",
  787. X        "-u  Toggle 'user' flag.           -c  Toggle 'ctime' flag.",
  788. X        "-U  Toggle 'short user' flag.     -f  format dates yyyy-mm-dd",
  789. X        "-g  Toggle 'group' flag.              to facilitate sorting",
  790. X        "-G  Toggle 'short group' flag.",
  791. X    "",
  792. X    "-H  Force output of the header.",
  793. X        "-N  (None) Clear all flags.",
  794. X        "-A  (All) Set all flags.",
  795. X        "-D  Dont list directories (like ls -d).",
  796. X        "-Ttab   Use the string 'tab' to seperate fields instead of space.",
  797. X    "",
  798. X    "Options are evaluated *left to right!*",
  799. X    NULL
  800. X    };
  801. X
  802. X    for (n=0; helpit[n] != NULL; n++)
  803. X        printf("\t%s\n", helpit[n]);
  804. X}
  805. SHAR_EOF
  806. chmod 0444 le.c || echo "restore of le.c fails"
  807. exit 0
  808. -- 
  809. bill davidsen    (davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen)
  810.             "Stupidity, like virtue, is its own reward" -me
  811.