/* Copyright (c) 1979 Regents of the University of California */
* ls - list file or directory
* Modified by Bill Joy UCB May/August 1977
* This version of ls is designed for graphic terminals and to
* list directories with lots of files in them compactly.
* It supports three variants for listings:
* 3) Old one per line format.
* Columnar output is the default.
* If, however, the standard output is not a teletype, the default
* With columnar output, the items are sorted down the columns.
* We use columns only for a directory we are interpreting.
* Thus, in particular, we do not use columns for
* This version of ls also prints non-printing characters as '?' if
* the standard output is a teletype.
* Flags relating to these and other new features are:
* -m force stream output.
* -1 force one entry per line, e.g. to a teletype
* -q force non-printings to be '?'s, e.g. to a file
* -c force columnar output, e.g. into a file
* -n like -l, but user/group id's in decimal rather than
* looking in /etc/passwd to save time
int aflg
, dflg
, lflg
, sflg
, tflg
, uflg
, iflg
, fflg
, gflg
, cflg
;
int Aflg
, nflg
, qflg
, across
;
struct lbuf
*flist
[NFILES
];
struct lbuf
**lastp
= flist
;
struct lbuf
**firstp
= flist
;
register struct lbuf
*ep
, **ep1
;
register struct lbuf
**slastp
;
year
= lb
.lmtime
- 6L*30L*24L*60L*60L; /* 6 months ago */
qflg
= gtty(1, buff
) == 0;
* If the standard output is not a teletype,
* then we default to one-per-line format
* otherwise decide between stream and
* columnar based on our name.
for (cp
= argv
[0]; cp
[0] && cp
[1]; cp
++)
* Name ends in l => stream
* ... if doesn't end in l or s ==> columns sorted across
if (--argc
> 0 && *argv
[1] == '-') {
while (*++*argv
) switch (**argv
) {
* c - force columnar output
* m - force stream output
* q - force ?'s in output
* 1 - force 1/line in output
* n - don't look in password file
for (i
=0; i
< argc
; i
++) {
if ((ep
= gstat(*++argv
, 1))==NULL
)
qsort(firstp
, lastp
- firstp
, sizeof *lastp
, compar
);
for (epp
=firstp
; epp
<slastp
; epp
++) {
if (ep
->ltype
=='d' && dflg
==0 || fflg
) {
printf("\n%s:\n", ep
->ln
.namep
);
qsort(slastp
,lastp
- slastp
,sizeof *lastp
,compar
);
printf("total %D", tblocks
);
register struct lbuf
**slp
, **lp
;
int ncols
, nrows
, row
, col
;
register struct lbuf
**ep
;
if (ncols
== 1 || cflg
== 0) {
for (ep
= slp
; ep
< lp
; ep
++)
for (ep = slp; ep < lp; ep++)
nrows
= (lp
- slp
- 1) / ncols
+ 1;
for (row
= 0; row
< nrows
; row
++) {
col
= row
== 0 && statreq
;
for (; col
< ncols
; col
++) {
ep
= slp
+ (nrows
* col
) + row
;
outcol
= (outcol
+ 8) &~ 7;
if (qflg
&& (c
< ' ' || c
>= 0177))
if (outcol
+ colwidth
+ 2 > 80) {
if ((outcol
/ colwidth
+ 2) * colwidth
> 80) {
} while (outcol
% colwidth
);
while((c
=fgetc(pwdf
)) != '\n') {
int m1
[] { 1, S_IREAD
>>0, 'r', '-' };
int m2
[] { 1, S_IWRITE
>>0, 'w', '-' };
int m3
[] { 2, S_ISUID
, 's', S_IEXEC
>>0, 'x', '-' };
int m4
[] { 1, S_IREAD
>>3, 'r', '-' };
int m5
[] { 1, S_IWRITE
>>3, 'w', '-' };
int m6
[] { 2, S_ISGID
, 's', S_IEXEC
>>3, 'x', '-' };
int m7
[] { 1, S_IREAD
>>6, 'r', '-' };
int m8
[] { 1, S_IWRITE
>>6, 'w', '-' };
int m9
[] { 2, S_ISVTX
, 't', S_IEXEC
>>6, 'x', '-' };
int *m
[] { m1
, m2
, m3
, m4
, m5
, m6
, m7
, m8
, m9
};
for (mp
= &m
[0]; mp
< &m
[sizeof(m
)/sizeof(m
[0])];)
while (--n
>=0 && (flags
&*pairp
++)==0)
static struct direct dentry
;
register struct lbuf
*ep
;
if ((dirf
= fopen(dir
, "r")) == NULL
) {
printf("%s unreadable\n", dir
);
if (fread(&dentry
, sizeof(dentry
), 1, dirf
) != 1)
aflg
==0 && dentry
.d_name
[0]=='.' && (
|| dentry
.d_name
[1]=='.' && dentry
.d_name
[2]=='\0'))
ep
= gstat(makename(dir
, dentry
.d_name
), 0);
ep
->ln
.lname
[j
] = dentry
.d_name
[j
];
register struct lbuf
*rep
;
rep
= (struct lbuf
*)malloc(sizeof(struct lbuf
));
fprintf(stderr
, "ls: out of memory\n");
if (lastp
>= &flist
[NFILES
]) {
fprintf(stderr
, "ls: too many files\n");
if (stat(file
, &statb
)<0) {
printf("%s not found\n", file
);
rep
->lnum
= statb
.st_ino
;
rep
->lsize
= statb
.st_size
;
switch(statb
.st_mode
&S_IFMT
) {
rep
->lsize
= statb
.st_rdev
;
rep
->lsize
= statb
.st_rdev
;
rep
->lflags
= statb
.st_mode
& ~S_IFMT
;
rep
->luid
= statb
.st_uid
;
rep
->lgid
= statb
.st_gid
;
rep
->lnl
= statb
.st_nlink
;
rep
->lmtime
= statb
.st_atime
;
rep
->lmtime
= statb
.st_ctime
;
rep
->lmtime
= statb
.st_mtime
;
tblocks
=+ nblock(statb
.st_size
);
struct lbuf
**pp1
, **pp2
;
register struct lbuf
*p1
, *p2
;
if (p1
->lflags
&ISARG
&& p1
->ltype
=='d') {
if (!(p2
->lflags
&ISARG
&& p2
->ltype
=='d'))
if (p2
->lflags
&ISARG
&& p2
->ltype
=='d')
if(p2
->lmtime
== p1
->lmtime
)
if(p2
->lmtime
> p1
->lmtime
)
return(rflg
* strcmp(p1
->lflags
&ISARG
? p1
->ln
.namep
: p1
->ln
.lname
,
p2
->lflags
&ISARG
? p2
->ln
.namep
: p2
->ln
.lname
));
struct { char dminor
, dmajor
;};
printf("%D ", nblock(p
->lsize
));
printf("%4D ", nblock(p
->lsize
));
if (nflg
== 0 && getname(t
, tbuf
)==0)
if (p
->ltype
=='b' || p
->ltype
=='c')
printf("%3d,%3d", major((int)p
->lsize
), minor((int)p
->lsize
));
printf("%7ld", p
->lsize
);
printf(" %-7.7s %-4.4s ", cp
+4, cp
+20); else
printf(" %-12.12s ", cp
+4);
printf("%s", p
->ln
.namep
);
printf("%.14s", p
->ln
.lname
);
_strout(count
, string
, adjust
, file
, fillch
)
register struct _iobuf
*file
;
if (*string
=='-' && fillch
=='0') {
pputchar(*string
++, file
); count
--;
while (--adjust
>=0) pputchar(fillch
, file
);
while (--count
>=0) pputchar(*string
++, file
);
while (--adjust
>=0) pputchar(fillch
, file
);