Update tail, tar, tee, time, touch, tr, tsort, tty, uniq, w, wc, whereis, who.
This commit is contained in:
259
src/cmd/tail.c
259
src/cmd/tail.c
@@ -17,13 +17,15 @@
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef pdp11
|
||||
#define LBIN 16385
|
||||
@@ -31,189 +33,201 @@
|
||||
#define LBIN 32769
|
||||
#endif
|
||||
|
||||
#undef BUFSIZ
|
||||
#define BUFSIZ 8192
|
||||
#undef BUFSIZ
|
||||
#define BUFSIZ 8192
|
||||
|
||||
struct stat statb;
|
||||
struct stat statb;
|
||||
int follow;
|
||||
int piped;
|
||||
char bin[LBIN];
|
||||
int errno;
|
||||
|
||||
main(argc,argv)
|
||||
char **argv;
|
||||
static void fexit(void);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
long n,di;
|
||||
register i,j,k;
|
||||
char *arg;
|
||||
int partial,bylines,bkwds,fromend,lastnl;
|
||||
long n, di;
|
||||
int i, j, k;
|
||||
char *arg;
|
||||
int partial, bylines, bkwds, fromend, lastnl;
|
||||
char *p;
|
||||
|
||||
arg = argv[1];
|
||||
if(argc<=1 || *arg!='-'&&*arg!='+') {
|
||||
if (argc <= 1 || *arg != '-' && *arg != '+') {
|
||||
arg = "-10l";
|
||||
argc++;
|
||||
argv--;
|
||||
}
|
||||
fromend = *arg=='-';
|
||||
fromend = *arg == '-';
|
||||
arg++;
|
||||
if (isdigit(*arg)) {
|
||||
n = 0;
|
||||
while(isdigit(*arg))
|
||||
n = n*10 + *arg++ - '0';
|
||||
while (isdigit(*arg))
|
||||
n = n * 10 + *arg++ - '0';
|
||||
} else
|
||||
n = -1;
|
||||
if(!fromend&&n>0)
|
||||
if (!fromend && n > 0)
|
||||
n--;
|
||||
if(argc>2) {
|
||||
if (argc > 2) {
|
||||
(void)close(0);
|
||||
if(open(argv[2],0)!=0) {
|
||||
if (open(argv[2], 0) != 0) {
|
||||
perror(argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
(void)lseek(0,(off_t)0,L_INCR);
|
||||
piped = errno==ESPIPE;
|
||||
bylines = -1; bkwds = 0;
|
||||
while(*arg)
|
||||
switch(*arg++) {
|
||||
|
||||
case 'b':
|
||||
if (n == -1) n = 1;
|
||||
n <<= 9;
|
||||
if(bylines!=-1) goto errcom;
|
||||
bylines=0;
|
||||
break;
|
||||
case 'c':
|
||||
if(bylines!=-1) goto errcom;
|
||||
bylines=0;
|
||||
break;
|
||||
case 'f':
|
||||
follow = 1;
|
||||
break;
|
||||
case 'r':
|
||||
if(n==-1) n = LBIN;
|
||||
bkwds = 1; fromend = 1; bylines = 1;
|
||||
break;
|
||||
case 'l':
|
||||
if(bylines!=-1) goto errcom;
|
||||
(void)lseek(0, (off_t)0, L_INCR);
|
||||
piped = errno == ESPIPE;
|
||||
bylines = -1;
|
||||
bkwds = 0;
|
||||
while (*arg)
|
||||
switch (*arg++) {
|
||||
case 'b':
|
||||
if (n == -1)
|
||||
n = 1;
|
||||
n <<= 9;
|
||||
if (bylines != -1)
|
||||
goto errcom;
|
||||
bylines = 0;
|
||||
break;
|
||||
case 'c':
|
||||
if (bylines != -1)
|
||||
goto errcom;
|
||||
bylines = 0;
|
||||
break;
|
||||
case 'f':
|
||||
follow = 1;
|
||||
break;
|
||||
case 'r':
|
||||
if (n == -1)
|
||||
n = LBIN;
|
||||
bkwds = 1;
|
||||
fromend = 1;
|
||||
bylines = 1;
|
||||
break;
|
||||
case 'l':
|
||||
if (bylines != -1)
|
||||
goto errcom;
|
||||
bylines = 1;
|
||||
break;
|
||||
default:
|
||||
goto errcom;
|
||||
}
|
||||
if (n == -1)
|
||||
n = 10;
|
||||
if (bylines == -1)
|
||||
bylines = 1;
|
||||
break;
|
||||
default:
|
||||
goto errcom;
|
||||
}
|
||||
if (n==-1) n = 10;
|
||||
if(bylines==-1) bylines = 1;
|
||||
if(bkwds) follow=0;
|
||||
if(fromend)
|
||||
if (bkwds)
|
||||
follow = 0;
|
||||
if (fromend)
|
||||
goto keep;
|
||||
|
||||
/*seek from beginning */
|
||||
/*seek from beginning */
|
||||
|
||||
if(bylines) {
|
||||
if (bylines) {
|
||||
j = 0;
|
||||
while(n-->0) {
|
||||
while (n-- > 0) {
|
||||
do {
|
||||
if(j--<=0) {
|
||||
if (j-- <= 0) {
|
||||
p = bin;
|
||||
j = read(0,p,BUFSIZ);
|
||||
if(j--<=0)
|
||||
j = read(0, p, BUFSIZ);
|
||||
if (j-- <= 0)
|
||||
fexit();
|
||||
}
|
||||
} while(*p++ != '\n');
|
||||
} while (*p++ != '\n');
|
||||
}
|
||||
(void)write(1,p,j);
|
||||
} else if(n>0) {
|
||||
if(!piped)
|
||||
(void)fstat(0,&statb);
|
||||
if(piped||(statb.st_mode&S_IFMT)==S_IFCHR)
|
||||
while(n>0) {
|
||||
i = n>BUFSIZ?BUFSIZ:n;
|
||||
i = read(0,bin,i);
|
||||
if(i<=0)
|
||||
(void)write(1, p, j);
|
||||
} else if (n > 0) {
|
||||
if (!piped)
|
||||
(void)fstat(0, &statb);
|
||||
if (piped || (statb.st_mode & S_IFMT) == S_IFCHR)
|
||||
while (n > 0) {
|
||||
i = n > BUFSIZ ? BUFSIZ : n;
|
||||
i = read(0, bin, i);
|
||||
if (i <= 0)
|
||||
fexit();
|
||||
n -= i;
|
||||
}
|
||||
else
|
||||
(void)lseek(0,(off_t)n,L_SET);
|
||||
(void)lseek(0, (off_t)n, L_SET);
|
||||
}
|
||||
copy:
|
||||
while((i=read(0,bin,BUFSIZ))>0)
|
||||
(void)write(1,bin,i);
|
||||
while ((i = read(0, bin, BUFSIZ)) > 0)
|
||||
(void)write(1, bin, i);
|
||||
fexit();
|
||||
|
||||
/*seek from end*/
|
||||
/*seek from end*/
|
||||
|
||||
keep:
|
||||
if(n <= 0)
|
||||
if (n <= 0)
|
||||
fexit();
|
||||
if(!piped) {
|
||||
(void)fstat(0,&statb);
|
||||
if (!piped) {
|
||||
(void)fstat(0, &statb);
|
||||
/* If by lines, back up 1 buffer: else back up as needed */
|
||||
di = bylines?LBIN-1:n;
|
||||
if(statb.st_size > di)
|
||||
(void)lseek(0,(off_t)-di,L_XTND);
|
||||
if(!bylines)
|
||||
di = bylines ? LBIN - 1 : n;
|
||||
if (statb.st_size > di)
|
||||
(void)lseek(0, (off_t)-di, L_XTND);
|
||||
if (!bylines)
|
||||
goto copy;
|
||||
}
|
||||
partial = 1;
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
i = 0;
|
||||
do {
|
||||
j = read(0,&bin[i],LBIN-i);
|
||||
if(j<=0)
|
||||
j = read(0, &bin[i], LBIN - i);
|
||||
if (j <= 0)
|
||||
goto brka;
|
||||
i += j;
|
||||
} while(i<LBIN);
|
||||
} while (i < LBIN);
|
||||
partial = 0;
|
||||
}
|
||||
brka:
|
||||
if(!bylines) {
|
||||
k =
|
||||
n<=i ? i-n:
|
||||
partial ? 0:
|
||||
n>=LBIN ? i+1:
|
||||
i-n+LBIN;
|
||||
if (!bylines) {
|
||||
k = n <= i ? i - n : partial ? 0 : n >= LBIN ? i + 1 : i - n + LBIN;
|
||||
k--;
|
||||
} else {
|
||||
if(bkwds && bin[i==0?LBIN-1:i-1]!='\n'){ /* force trailing newline */
|
||||
bin[i]='\n';
|
||||
if(++i>=LBIN) {i = 0; partial = 0;}
|
||||
if (bkwds && bin[i == 0 ? LBIN - 1 : i - 1] != '\n') { /* force trailing newline */
|
||||
bin[i] = '\n';
|
||||
if (++i >= LBIN) {
|
||||
i = 0;
|
||||
partial = 0;
|
||||
}
|
||||
}
|
||||
k = i;
|
||||
j = 0;
|
||||
do {
|
||||
lastnl = k;
|
||||
do {
|
||||
if(--k<0) {
|
||||
if(partial) {
|
||||
if(bkwds)
|
||||
(void)write(1,bin,lastnl+1);
|
||||
if (--k < 0) {
|
||||
if (partial) {
|
||||
if (bkwds)
|
||||
(void)write(1, bin, lastnl + 1);
|
||||
goto brkb;
|
||||
}
|
||||
k = LBIN -1;
|
||||
k = LBIN - 1;
|
||||
}
|
||||
} while(bin[k]!='\n'&&k!=i);
|
||||
if(bkwds && j>0){
|
||||
if(k<lastnl) (void)write(1,&bin[k+1],lastnl-k);
|
||||
} while (bin[k] != '\n' && k != i);
|
||||
if (bkwds && j > 0) {
|
||||
if (k < lastnl)
|
||||
(void)write(1, &bin[k + 1], lastnl - k);
|
||||
else {
|
||||
(void)write(1,&bin[k+1],LBIN-k-1);
|
||||
(void)write(1,bin,lastnl+1);
|
||||
(void)write(1, &bin[k + 1], LBIN - k - 1);
|
||||
(void)write(1, bin, lastnl + 1);
|
||||
}
|
||||
}
|
||||
} while(j++<n&&k!=i);
|
||||
} while (j++ < n && k != i);
|
||||
brkb:
|
||||
if(bkwds) exit(0);
|
||||
if(k==i) do {
|
||||
if(++k>=LBIN)
|
||||
k = 0;
|
||||
} while(bin[k]!='\n'&&k!=i);
|
||||
if (bkwds)
|
||||
exit(0);
|
||||
if (k == i)
|
||||
do {
|
||||
if (++k >= LBIN)
|
||||
k = 0;
|
||||
} while (bin[k] != '\n' && k != i);
|
||||
}
|
||||
if(k<i)
|
||||
(void)write(1,&bin[k+1],i-k-1);
|
||||
if (k < i)
|
||||
(void)write(1, &bin[k + 1], i - k - 1);
|
||||
else {
|
||||
(void)write(1,&bin[k+1],LBIN-k-1);
|
||||
(void)write(1,bin,i);
|
||||
(void)write(1, &bin[k + 1], LBIN - k - 1);
|
||||
(void)write(1, bin, i);
|
||||
}
|
||||
fexit();
|
||||
errcom:
|
||||
@@ -221,12 +235,15 @@ errcom:
|
||||
exit(2);
|
||||
}
|
||||
|
||||
fexit()
|
||||
{ register int n;
|
||||
if (!follow || piped) exit(0);
|
||||
for (;;)
|
||||
{ sleep(1);
|
||||
while ((n = read (0, bin, BUFSIZ)) > 0)
|
||||
(void)write (1, bin, n);
|
||||
void fexit()
|
||||
{
|
||||
int n;
|
||||
|
||||
if (!follow || piped)
|
||||
exit(0);
|
||||
for (;;) {
|
||||
sleep(1);
|
||||
while ((n = read(0, bin, BUFSIZ)) > 0)
|
||||
(void)write(1, bin, n);
|
||||
}
|
||||
}
|
||||
|
||||
575
src/cmd/tar.c
575
src/cmd/tar.c
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* tee-- pipe fitting
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define BUFSIZ 8192
|
||||
#define BUFSIZ 8192
|
||||
|
||||
int openf[20] = { 1 };
|
||||
int n = 1;
|
||||
@@ -15,23 +17,23 @@ int t = 0;
|
||||
int aflag;
|
||||
|
||||
char in[BUFSIZ];
|
||||
|
||||
char out[BUFSIZ];
|
||||
|
||||
putstr(s)
|
||||
char *s;
|
||||
static void stash(int p);
|
||||
|
||||
void putstr(char *s)
|
||||
{
|
||||
while(*s)
|
||||
write(2,s++,1);
|
||||
while (*s)
|
||||
write(2, s++, 1);
|
||||
}
|
||||
|
||||
main(argc,argv)
|
||||
char **argv;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int register r,w,p;
|
||||
int r, w, p;
|
||||
struct stat buf;
|
||||
while(argc>1&&argv[1][0]=='-') {
|
||||
switch(argv[1][1]) {
|
||||
|
||||
while (argc > 1 && argv[1][0] == '-') {
|
||||
switch (argv[1][1]) {
|
||||
case 'a':
|
||||
aflag++;
|
||||
break;
|
||||
@@ -42,20 +44,20 @@ char **argv;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
fstat(1,&buf);
|
||||
t = (buf.st_mode&S_IFMT)==S_IFCHR;
|
||||
if(lseek(1,0L,1)==-1&&errno==ESPIPE)
|
||||
fstat(1, &buf);
|
||||
t = (buf.st_mode & S_IFMT) == S_IFCHR;
|
||||
if (lseek(1, 0L, 1) == -1 && errno == ESPIPE)
|
||||
t++;
|
||||
while(argc-->1) {
|
||||
if(aflag) {
|
||||
openf[n] = open(argv[1],1);
|
||||
if(openf[n] < 0)
|
||||
openf[n] = creat(argv[1],0666);
|
||||
lseek(openf[n++],0L,2);
|
||||
while (argc-- > 1) {
|
||||
if (aflag) {
|
||||
openf[n] = open(argv[1], 1);
|
||||
if (openf[n] < 0)
|
||||
openf[n] = creat(argv[1], 0666);
|
||||
lseek(openf[n++], 0L, 2);
|
||||
} else
|
||||
openf[n++] = creat(argv[1],0666);
|
||||
if(stat(argv[1],&buf)>=0) {
|
||||
if((buf.st_mode&S_IFMT)==S_IFCHR)
|
||||
openf[n++] = creat(argv[1], 0666);
|
||||
if (stat(argv[1], &buf) >= 0) {
|
||||
if ((buf.st_mode & S_IFMT) == S_IFCHR)
|
||||
t++;
|
||||
} else {
|
||||
putstr("tee: cannot open ");
|
||||
@@ -66,13 +68,14 @@ char **argv;
|
||||
argv++;
|
||||
}
|
||||
r = w = 0;
|
||||
for(;;) {
|
||||
for(p=0;p<BUFSIZ;) {
|
||||
if(r>=w) {
|
||||
if(t>0&&p>0) break;
|
||||
w = read(0,in,BUFSIZ);
|
||||
for (;;) {
|
||||
for (p = 0; p < BUFSIZ;) {
|
||||
if (r >= w) {
|
||||
if (t > 0 && p > 0)
|
||||
break;
|
||||
w = read(0, in, BUFSIZ);
|
||||
r = 0;
|
||||
if(w<=0) {
|
||||
if (w <= 0) {
|
||||
stash(p);
|
||||
exit(0);
|
||||
}
|
||||
@@ -83,13 +86,13 @@ char **argv;
|
||||
}
|
||||
}
|
||||
|
||||
stash(p)
|
||||
void stash(int p)
|
||||
{
|
||||
int k;
|
||||
int i;
|
||||
int d;
|
||||
d = t ? 16 : p;
|
||||
for(i=0; i<p; i+=d)
|
||||
for(k=0;k<n;k++)
|
||||
write(openf[k], out+i, d<p-i?d:p-i);
|
||||
for (i = 0; i < p; i += d)
|
||||
for (k = 0; k < n; k++)
|
||||
write(openf[k], out + i, d < p - i ? d : p - i);
|
||||
}
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
/*
|
||||
* time
|
||||
*/
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
void printt(char *s, struct timeval *tv)
|
||||
{
|
||||
fprintf(stderr, "%9ld.%01ld %s ", tv->tv_sec, tv->tv_usec / 100000, s);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int status;
|
||||
register int p;
|
||||
int p;
|
||||
struct timeval before, after;
|
||||
struct rusage ru;
|
||||
|
||||
if (argc<=1)
|
||||
if (argc <= 1)
|
||||
exit(0);
|
||||
gettimeofday(&before, 0);
|
||||
p = fork();
|
||||
@@ -35,7 +39,7 @@ main(argc, argv)
|
||||
while (wait3(&status, 0, &ru) != p)
|
||||
;
|
||||
gettimeofday(&after, 0);
|
||||
if ((status&0377) != 0)
|
||||
if ((status & 0377) != 0)
|
||||
fprintf(stderr, "Command terminated abnormally.\n");
|
||||
after.tv_sec -= before.tv_sec;
|
||||
after.tv_usec -= before.tv_usec;
|
||||
@@ -45,13 +49,5 @@ main(argc, argv)
|
||||
printt("user", &ru.ru_utime);
|
||||
printt("sys ", &ru.ru_stime);
|
||||
fprintf(stderr, "\n");
|
||||
exit (status>>8);
|
||||
}
|
||||
|
||||
printt(s, tv)
|
||||
char *s;
|
||||
struct timeval *tv;
|
||||
{
|
||||
|
||||
fprintf(stderr, "%9ld.%01ld %s ", tv->tv_sec, tv->tv_usec/100000, s);
|
||||
exit(status >> 8);
|
||||
}
|
||||
|
||||
@@ -6,19 +6,22 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
int dontcreate; /* set if -c option */
|
||||
int force; /* set if -f option */
|
||||
|
||||
char *whoami = "touch";
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
static void touch(char *filename);
|
||||
static void readwrite(char *filename, off_t size);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *argp;
|
||||
char *argp;
|
||||
|
||||
dontcreate = 0;
|
||||
force = 0;
|
||||
@@ -32,8 +35,7 @@ main(argc,argv)
|
||||
force = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: bad option -%c\n",
|
||||
whoami, *argp);
|
||||
fprintf(stderr, "%s: bad option -%c\n", whoami, *argp);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -43,40 +45,35 @@ main(argc,argv)
|
||||
}
|
||||
}
|
||||
|
||||
touch(filename)
|
||||
char *filename;
|
||||
void touch(char *filename)
|
||||
{
|
||||
struct stat statbuffer;
|
||||
|
||||
if (stat(filename,&statbuffer) == -1) {
|
||||
if (stat(filename, &statbuffer) == -1) {
|
||||
if (!dontcreate) {
|
||||
readwrite(filename,0L);
|
||||
readwrite(filename, 0L);
|
||||
} else {
|
||||
fprintf(stderr, "%s: %s: does not exist\n",
|
||||
whoami, filename);
|
||||
fprintf(stderr, "%s: %s: does not exist\n", whoami, filename);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((statbuffer.st_mode & S_IFMT) != S_IFREG) {
|
||||
fprintf(stderr, "%s: %s: can only touch regular files\n",
|
||||
whoami, filename);
|
||||
fprintf(stderr, "%s: %s: can only touch regular files\n", whoami, filename);
|
||||
return;
|
||||
}
|
||||
if (!access(filename,4|2)) {
|
||||
readwrite(filename,statbuffer.st_size);
|
||||
if (!access(filename, 4 | 2)) {
|
||||
readwrite(filename, statbuffer.st_size);
|
||||
return;
|
||||
}
|
||||
if (force) {
|
||||
if (chmod(filename,0666)) {
|
||||
fprintf(stderr, "%s: %s: couldn't chmod: ",
|
||||
whoami, filename);
|
||||
if (chmod(filename, 0666)) {
|
||||
fprintf(stderr, "%s: %s: couldn't chmod: ", whoami, filename);
|
||||
perror("");
|
||||
return;
|
||||
}
|
||||
readwrite(filename,statbuffer.st_size);
|
||||
if (chmod(filename,statbuffer.st_mode)) {
|
||||
fprintf(stderr, "%s: %s: couldn't chmod back: ",
|
||||
whoami, filename);
|
||||
readwrite(filename, statbuffer.st_size);
|
||||
if (chmod(filename, statbuffer.st_mode)) {
|
||||
fprintf(stderr, "%s: %s: couldn't chmod back: ", whoami, filename);
|
||||
perror("");
|
||||
return;
|
||||
}
|
||||
@@ -85,17 +82,15 @@ touch(filename)
|
||||
}
|
||||
}
|
||||
|
||||
readwrite(filename,size)
|
||||
char *filename;
|
||||
off_t size;
|
||||
void readwrite(char *filename, off_t size)
|
||||
{
|
||||
int filedescriptor;
|
||||
char first;
|
||||
char first;
|
||||
|
||||
if (size) {
|
||||
filedescriptor = open(filename,2);
|
||||
filedescriptor = open(filename, 2);
|
||||
if (filedescriptor == -1) {
|
||||
error:
|
||||
error:
|
||||
fprintf(stderr, "%s: %s: ", whoami, filename);
|
||||
perror("");
|
||||
return;
|
||||
@@ -103,14 +98,14 @@ error:
|
||||
if (read(filedescriptor, &first, 1) != 1) {
|
||||
goto error;
|
||||
}
|
||||
if (lseek(filedescriptor,0l,0) == -1) {
|
||||
if (lseek(filedescriptor, 0l, 0) == -1) {
|
||||
goto error;
|
||||
}
|
||||
if (write(filedescriptor, &first, 1) != 1) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
filedescriptor = creat(filename,0666);
|
||||
filedescriptor = creat(filename, 0666);
|
||||
if (filedescriptor == -1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
147
src/cmd/tr.c
147
src/cmd/tr.c
@@ -4,21 +4,27 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int dflag = 0;
|
||||
int sflag = 0;
|
||||
int dflag = 0;
|
||||
int sflag = 0;
|
||||
int cflag = 0;
|
||||
int save = 0;
|
||||
char code[256];
|
||||
char squeez[256];
|
||||
char vect[256];
|
||||
struct string { int last, max; char *p; } string1, string2;
|
||||
int save = 0;
|
||||
char code[256];
|
||||
char squeez[256];
|
||||
char vect[256];
|
||||
|
||||
main(argc,argv)
|
||||
char **argv;
|
||||
struct string {
|
||||
int last, max;
|
||||
char *p;
|
||||
} string1, string2;
|
||||
|
||||
static int next(struct string *s);
|
||||
static int nextc(struct string *s);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
register i;
|
||||
int i;
|
||||
int j;
|
||||
register c, d;
|
||||
int c, d;
|
||||
char *compl;
|
||||
int lastd;
|
||||
|
||||
@@ -26,11 +32,11 @@ char **argv;
|
||||
string1.max = string2.max = 0;
|
||||
string1.p = string2.p = "";
|
||||
|
||||
if(--argc>0) {
|
||||
if (--argc > 0) {
|
||||
argv++;
|
||||
if(*argv[0]=='-'&&argv[0][1]!=0) {
|
||||
while(*++argv[0])
|
||||
switch(*argv[0]) {
|
||||
if (*argv[0] == '-' && argv[0][1] != 0) {
|
||||
while (*++argv[0])
|
||||
switch (*argv[0]) {
|
||||
case 'c':
|
||||
cflag++;
|
||||
continue;
|
||||
@@ -45,95 +51,106 @@ char **argv;
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
if(argc>0) string1.p = argv[0];
|
||||
if(argc>1) string2.p = argv[1];
|
||||
for(i=0; i<256; i++)
|
||||
if (argc > 0)
|
||||
string1.p = argv[0];
|
||||
if (argc > 1)
|
||||
string2.p = argv[1];
|
||||
for (i = 0; i < 256; i++)
|
||||
code[i] = vect[i] = 0;
|
||||
if(cflag) {
|
||||
while(c = next(&string1))
|
||||
vect[c&0377] = 1;
|
||||
if (cflag) {
|
||||
while ((c = next(&string1)))
|
||||
vect[c & 0377] = 1;
|
||||
j = 0;
|
||||
for(i=1; i<256; i++)
|
||||
if(vect[i]==0) vect[j++] = i;
|
||||
for (i = 1; i < 256; i++)
|
||||
if (vect[i] == 0)
|
||||
vect[j++] = i;
|
||||
vect[j] = 0;
|
||||
compl = vect;
|
||||
}
|
||||
for(i=0; i<256; i++)
|
||||
for (i = 0; i < 256; i++)
|
||||
squeez[i] = 0;
|
||||
lastd = 0;
|
||||
for(;;){
|
||||
if(cflag) c = *compl++;
|
||||
else c = next(&string1);
|
||||
if(c==0) break;
|
||||
for (;;) {
|
||||
if (cflag)
|
||||
c = *compl ++;
|
||||
else
|
||||
c = next(&string1);
|
||||
if (c == 0)
|
||||
break;
|
||||
d = next(&string2);
|
||||
if(d==0) d = lastd;
|
||||
else lastd = d;
|
||||
squeez[d&0377] = 1;
|
||||
code[c&0377] = dflag?1:d;
|
||||
if (d == 0)
|
||||
d = lastd;
|
||||
else
|
||||
lastd = d;
|
||||
squeez[d & 0377] = 1;
|
||||
code[c & 0377] = dflag ? 1 : d;
|
||||
}
|
||||
while(d = next(&string2))
|
||||
squeez[d&0377] = 1;
|
||||
while ((d = next(&string2)))
|
||||
squeez[d & 0377] = 1;
|
||||
squeez[0] = 1;
|
||||
for(i=0;i<256;i++) {
|
||||
if(code[i]==0) code[i] = i;
|
||||
else if(dflag) code[i] = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (code[i] == 0)
|
||||
code[i] = i;
|
||||
else if (dflag)
|
||||
code[i] = 0;
|
||||
}
|
||||
|
||||
clearerr(stdout);
|
||||
while((c=getc(stdin)) != EOF ) {
|
||||
if(c == 0) continue;
|
||||
if(c = code[c&0377]&0377)
|
||||
if(!sflag || c!=save || !squeez[c&0377]) {
|
||||
while ((c = getc(stdin)) != EOF) {
|
||||
if (c == 0)
|
||||
continue;
|
||||
if ((c = code[c & 0377] & 0377))
|
||||
if (!sflag || c != save || !squeez[c & 0377]) {
|
||||
putchar(save = c);
|
||||
if(ferror(stdout))
|
||||
if (ferror(stdout))
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
next(s)
|
||||
struct string *s;
|
||||
int next(struct string *s)
|
||||
{
|
||||
|
||||
again:
|
||||
if(s->max) {
|
||||
if(s->last++ < s->max)
|
||||
return(s->last);
|
||||
if (s->max) {
|
||||
if (s->last++ < s->max)
|
||||
return (s->last);
|
||||
s->max = s->last = 0;
|
||||
}
|
||||
if(s->last && *s->p=='-') {
|
||||
if (s->last && *s->p == '-') {
|
||||
nextc(s);
|
||||
s->max = nextc(s);
|
||||
if(s->max==0) {
|
||||
if (s->max == 0) {
|
||||
s->p--;
|
||||
return('-');
|
||||
return ('-');
|
||||
}
|
||||
if(s->max < s->last) {
|
||||
s->last = s->max-1;
|
||||
return('-');
|
||||
if (s->max < s->last) {
|
||||
s->last = s->max - 1;
|
||||
return ('-');
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
return(s->last = nextc(s));
|
||||
return (s->last = nextc(s));
|
||||
}
|
||||
|
||||
nextc(s)
|
||||
struct string *s;
|
||||
int nextc(struct string *s)
|
||||
{
|
||||
register c, i, n;
|
||||
int c, i, n;
|
||||
|
||||
c = *s->p++;
|
||||
if(c=='\\') {
|
||||
if (c == '\\') {
|
||||
i = n = 0;
|
||||
while(i<3 && (c = *s->p)>='0' && c<='7') {
|
||||
n = n*8 + c - '0';
|
||||
while (i < 3 && (c = *s->p) >= '0' && c <= '7') {
|
||||
n = n * 8 + c - '0';
|
||||
i++;
|
||||
s->p++;
|
||||
}
|
||||
if(i>0) c = n;
|
||||
else c = *s->p++;
|
||||
if (i > 0)
|
||||
c = n;
|
||||
else
|
||||
c = *s->p++;
|
||||
}
|
||||
if(c==0) *--s->p = 0;
|
||||
return(c&0377);
|
||||
if (c == 0)
|
||||
*--s->p = 0;
|
||||
return (c & 0377);
|
||||
}
|
||||
|
||||
183
src/cmd/tsort.c
183
src/cmd/tsort.c
@@ -13,9 +13,9 @@
|
||||
* make it easy to grow in natural order
|
||||
* states of the "live" field:
|
||||
*/
|
||||
#define DEAD 0 /* already printed*/
|
||||
#define LIVE 1 /* not yet printed*/
|
||||
#define VISITED 2 /*used only in findloop()*/
|
||||
#define DEAD 0 /* already printed*/
|
||||
#define LIVE 1 /* not yet printed*/
|
||||
#define VISITED 2 /*used only in findloop()*/
|
||||
|
||||
/* a predecessor list tells all the immediate
|
||||
* predecessors of a given node
|
||||
@@ -30,154 +30,158 @@ struct nodelist {
|
||||
struct predlist *inedges;
|
||||
char *name;
|
||||
int live;
|
||||
} firstnode = {NULL, NULL, NULL, DEAD};
|
||||
} firstnode = { NULL, NULL, NULL, DEAD };
|
||||
|
||||
struct nodelist *nindex();
|
||||
struct nodelist *findloop();
|
||||
struct nodelist *mark();
|
||||
char *empty = "";
|
||||
|
||||
static void error(char *s, char *t);
|
||||
static int present(struct nodelist *i, struct nodelist *j);
|
||||
static int anypred(struct nodelist *i);
|
||||
static int cmp(char *s, char *t);
|
||||
static void note(char *s, char *t);
|
||||
|
||||
/* the first for loop reads in the graph,
|
||||
* the second prints out the ordering
|
||||
*/
|
||||
main(argc,argv)
|
||||
char **argv;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
register struct predlist *t;
|
||||
struct predlist *t;
|
||||
FILE *input = stdin;
|
||||
register struct nodelist *i, *j;
|
||||
struct nodelist *i, *j;
|
||||
int x;
|
||||
char precedes[50], follows[50];
|
||||
if(argc>1) {
|
||||
input = fopen(argv[1],"r");
|
||||
if(input==NULL)
|
||||
|
||||
if (argc > 1) {
|
||||
input = fopen(argv[1], "r");
|
||||
if (input == NULL)
|
||||
error("cannot open ", argv[1]);
|
||||
}
|
||||
for(;;) {
|
||||
x = fscanf(input,"%s%s",precedes, follows);
|
||||
if(x==EOF)
|
||||
for (;;) {
|
||||
x = fscanf(input, "%s%s", precedes, follows);
|
||||
if (x == EOF)
|
||||
break;
|
||||
if(x!=2)
|
||||
error("odd data",empty);
|
||||
if (x != 2)
|
||||
error("odd data", empty);
|
||||
i = nindex(precedes);
|
||||
j = nindex(follows);
|
||||
if(i==j||present(i,j))
|
||||
if (i == j || present(i, j))
|
||||
continue;
|
||||
t = (struct predlist *)malloc(sizeof(struct predlist));
|
||||
t->nextpred = j->inedges;
|
||||
t->pred = i;
|
||||
j->inedges = t;
|
||||
}
|
||||
for(;;) {
|
||||
x = 0; /*anything LIVE on this sweep?*/
|
||||
for(i= &firstnode; i->nextnode!=NULL; i=i->nextnode) {
|
||||
if(i->live==LIVE) {
|
||||
for (;;) {
|
||||
x = 0; /*anything LIVE on this sweep?*/
|
||||
for (i = &firstnode; i->nextnode != NULL; i = i->nextnode) {
|
||||
if (i->live == LIVE) {
|
||||
x = 1;
|
||||
if(!anypred(i))
|
||||
if (!anypred(i))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(x==0)
|
||||
if (x == 0)
|
||||
break;
|
||||
if(i->nextnode==NULL)
|
||||
if (i->nextnode == NULL)
|
||||
i = findloop();
|
||||
printf("%s\n",i->name);
|
||||
printf("%s\n", i->name);
|
||||
i->live = DEAD;
|
||||
}
|
||||
}
|
||||
|
||||
/* is i present on j's predecessor list?
|
||||
*/
|
||||
present(i,j)
|
||||
struct nodelist *i, *j;
|
||||
int present(struct nodelist *i, struct nodelist *j)
|
||||
{
|
||||
register struct predlist *t;
|
||||
for(t=j->inedges; t!=NULL; t=t->nextpred)
|
||||
if(t->pred==i)
|
||||
return(1);
|
||||
return(0);
|
||||
struct predlist *t;
|
||||
|
||||
for (t = j->inedges; t != NULL; t = t->nextpred)
|
||||
if (t->pred == i)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* is there any live predecessor for i?
|
||||
*/
|
||||
anypred(i)
|
||||
struct nodelist *i;
|
||||
int anypred(struct nodelist *i)
|
||||
{
|
||||
register struct predlist *t;
|
||||
for(t=i->inedges; t!=NULL; t=t->nextpred)
|
||||
if(t->pred->live==LIVE)
|
||||
return(1);
|
||||
return(0);
|
||||
struct predlist *t;
|
||||
|
||||
for (t = i->inedges; t != NULL; t = t->nextpred)
|
||||
if (t->pred->live == LIVE)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* turn a string into a node pointer
|
||||
*/
|
||||
struct nodelist *
|
||||
nindex(s)
|
||||
register char *s;
|
||||
struct nodelist *nindex(char *s)
|
||||
{
|
||||
register struct nodelist *i;
|
||||
register char *t;
|
||||
for(i= &firstnode; i->nextnode!=NULL; i=i->nextnode)
|
||||
if(cmp(s,i->name))
|
||||
return(i);
|
||||
for(t=s; *t; t++) ;
|
||||
t = malloc((unsigned)(t+1-s));
|
||||
struct nodelist *i;
|
||||
char *t;
|
||||
|
||||
for (i = &firstnode; i->nextnode != NULL; i = i->nextnode)
|
||||
if (cmp(s, i->name))
|
||||
return (i);
|
||||
for (t = s; *t; t++)
|
||||
;
|
||||
t = malloc((unsigned)(t + 1 - s));
|
||||
i->nextnode = (struct nodelist *)malloc(sizeof(struct nodelist));
|
||||
if(i->nextnode==NULL||t==NULL)
|
||||
error("too many items",empty);
|
||||
if (i->nextnode == NULL || t == NULL)
|
||||
error("too many items", empty);
|
||||
i->name = t;
|
||||
i->live = LIVE;
|
||||
i->nextnode->nextnode = NULL;
|
||||
i->nextnode->inedges = NULL;
|
||||
i->nextnode->live = DEAD;
|
||||
while(*t++ = *s++);
|
||||
return(i);
|
||||
while ((*t++ = *s++))
|
||||
;
|
||||
return (i);
|
||||
}
|
||||
|
||||
cmp(s,t)
|
||||
register char *s, *t;
|
||||
int cmp(char *s, char *t)
|
||||
{
|
||||
while(*s==*t) {
|
||||
if(*s==0)
|
||||
return(1);
|
||||
while (*s == *t) {
|
||||
if (*s == 0)
|
||||
return (1);
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
error(s,t)
|
||||
char *s, *t;
|
||||
void error(char *s, char *t)
|
||||
{
|
||||
note(s,t);
|
||||
note(s, t);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
note(s,t)
|
||||
char *s,*t;
|
||||
void note(char *s, char *t)
|
||||
{
|
||||
fprintf(stderr,"tsort: %s%s\n",s,t);
|
||||
fprintf(stderr, "tsort: %s%s\n", s, t);
|
||||
}
|
||||
|
||||
/* given that there is a cycle, find some
|
||||
* node in it
|
||||
*/
|
||||
struct nodelist *
|
||||
findloop()
|
||||
struct nodelist *findloop()
|
||||
{
|
||||
register struct nodelist *i, *j;
|
||||
for(i= &firstnode; i->nextnode!=NULL; i=i->nextnode)
|
||||
if(i->live==LIVE)
|
||||
struct nodelist *i, *j;
|
||||
|
||||
for (i = &firstnode; i->nextnode != NULL; i = i->nextnode)
|
||||
if (i->live == LIVE)
|
||||
break;
|
||||
note("cycle in data",empty);
|
||||
note("cycle in data", empty);
|
||||
i = mark(i);
|
||||
if(i==NULL)
|
||||
error("program error",empty);
|
||||
for(j= &firstnode; j->nextnode!=NULL; j=j->nextnode)
|
||||
if(j->live==VISITED)
|
||||
if (i == NULL)
|
||||
error("program error", empty);
|
||||
for (j = &firstnode; j->nextnode != NULL; j = j->nextnode)
|
||||
if (j->live == VISITED)
|
||||
j->live = LIVE;
|
||||
return(i);
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* depth-first search of LIVE predecessors
|
||||
@@ -185,23 +189,22 @@ findloop()
|
||||
* VISITED is a temporary state recording the
|
||||
* visits of the search
|
||||
*/
|
||||
struct nodelist *
|
||||
mark(i)
|
||||
register struct nodelist *i;
|
||||
struct nodelist *mark(struct nodelist *i)
|
||||
{
|
||||
register struct nodelist *j;
|
||||
register struct predlist *t;
|
||||
if(i->live==DEAD)
|
||||
return(NULL);
|
||||
if(i->live==VISITED)
|
||||
return(i);
|
||||
struct nodelist *j;
|
||||
struct predlist *t;
|
||||
|
||||
if (i->live == DEAD)
|
||||
return (NULL);
|
||||
if (i->live == VISITED)
|
||||
return (i);
|
||||
i->live = VISITED;
|
||||
for(t=i->inedges; t!=NULL; t=t->nextpred) {
|
||||
for (t = i->inedges; t != NULL; t = t->nextpred) {
|
||||
j = mark(t->pred);
|
||||
if(j!=NULL) {
|
||||
note(i->name,empty);
|
||||
return(j);
|
||||
if (j != NULL) {
|
||||
note(i->name, empty);
|
||||
return (j);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
register char *p;
|
||||
char *p;
|
||||
|
||||
p = ttyname(0);
|
||||
if(argc==2 && !strcmp(argv[1], "-s"))
|
||||
if (argc == 2 && !strcmp(argv[1], "-s"))
|
||||
;
|
||||
else
|
||||
printf("%s\n", (p? p: "not a tty"));
|
||||
exit(p? 0: 1);
|
||||
printf("%s\n", (p ? p : "not a tty"));
|
||||
exit(p ? 0 : 1);
|
||||
}
|
||||
|
||||
100
src/cmd/uniq.c
100
src/cmd/uniq.c
@@ -1,33 +1,37 @@
|
||||
/*
|
||||
* Deal with duplicated lines in a file
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int fields;
|
||||
int letters;
|
||||
int linec;
|
||||
char mode;
|
||||
char mode;
|
||||
int uniq;
|
||||
char *skip();
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
static void printe(char *p, char *s);
|
||||
static int gline(char buf[]);
|
||||
static void pline(char buf[]);
|
||||
static int equal(char b1[], char b2[]);
|
||||
static char *skip(char *s);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
static char b1[1000], b2[1000];
|
||||
|
||||
while(argc > 1) {
|
||||
if(*argv[1] == '-') {
|
||||
while (argc > 1) {
|
||||
if (*argv[1] == '-') {
|
||||
if (isdigit(argv[1][1]))
|
||||
fields = atoi(&argv[1][1]);
|
||||
else mode = argv[1][1];
|
||||
else
|
||||
mode = argv[1][1];
|
||||
argc--;
|
||||
argv++;
|
||||
continue;
|
||||
}
|
||||
if(*argv[1] == '+') {
|
||||
if (*argv[1] == '+') {
|
||||
letters = atoi(&argv[1][1]);
|
||||
argc--;
|
||||
argv++;
|
||||
@@ -37,62 +41,59 @@ char *argv[];
|
||||
printe("cannot open %s\n", argv[1]);
|
||||
break;
|
||||
}
|
||||
if(argc > 2 && freopen(argv[2], "w", stdout) == NULL)
|
||||
if (argc > 2 && freopen(argv[2], "w", stdout) == NULL)
|
||||
printe("cannot create %s\n", argv[2]);
|
||||
|
||||
if(gline(b1))
|
||||
if (gline(b1))
|
||||
exit(0);
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
linec++;
|
||||
if(gline(b2)) {
|
||||
if (gline(b2)) {
|
||||
pline(b1);
|
||||
exit(0);
|
||||
}
|
||||
if(!equal(b1, b2)) {
|
||||
if (!equal(b1, b2)) {
|
||||
pline(b1);
|
||||
linec = 0;
|
||||
do {
|
||||
linec++;
|
||||
if(gline(b1)) {
|
||||
if (gline(b1)) {
|
||||
pline(b2);
|
||||
exit(0);
|
||||
}
|
||||
} while(equal(b1, b2));
|
||||
} while (equal(b1, b2));
|
||||
pline(b2);
|
||||
linec = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gline(buf)
|
||||
register char buf[];
|
||||
int gline(char buf[])
|
||||
{
|
||||
register c;
|
||||
int c;
|
||||
|
||||
while((c = getchar()) != '\n') {
|
||||
if(c == EOF)
|
||||
return(1);
|
||||
while ((c = getchar()) != '\n') {
|
||||
if (c == EOF)
|
||||
return (1);
|
||||
*buf++ = c;
|
||||
}
|
||||
*buf = 0;
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
pline(buf)
|
||||
register char buf[];
|
||||
void pline(char buf[])
|
||||
{
|
||||
|
||||
switch(mode) {
|
||||
|
||||
switch (mode) {
|
||||
case 'u':
|
||||
if(uniq) {
|
||||
if (uniq) {
|
||||
uniq = 0;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if(uniq) break;
|
||||
if (uniq)
|
||||
break;
|
||||
return;
|
||||
|
||||
case 'c':
|
||||
@@ -103,41 +104,38 @@ register char buf[];
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
equal(b1, b2)
|
||||
register char b1[], b2[];
|
||||
int equal(char b1[], char b2[])
|
||||
{
|
||||
register char c;
|
||||
char c;
|
||||
|
||||
b1 = skip(b1);
|
||||
b2 = skip(b2);
|
||||
while((c = *b1++) != 0)
|
||||
if(c != *b2++) return(0);
|
||||
if(*b2 != 0)
|
||||
return(0);
|
||||
while ((c = *b1++) != 0)
|
||||
if (c != *b2++)
|
||||
return (0);
|
||||
if (*b2 != 0)
|
||||
return (0);
|
||||
uniq++;
|
||||
return(1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
char *
|
||||
skip(s)
|
||||
register char *s;
|
||||
char *skip(char *s)
|
||||
{
|
||||
register nf, nl;
|
||||
int nf, nl;
|
||||
|
||||
nf = nl = 0;
|
||||
while(nf++ < fields) {
|
||||
while(*s == ' ' || *s == '\t')
|
||||
while (nf++ < fields) {
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
while( !(*s == ' ' || *s == '\t' || *s == 0) )
|
||||
while (!(*s == ' ' || *s == '\t' || *s == 0))
|
||||
s++;
|
||||
}
|
||||
while(nl++ < letters && *s != 0)
|
||||
s++;
|
||||
return(s);
|
||||
while (nl++ < letters && *s != 0)
|
||||
s++;
|
||||
return (s);
|
||||
}
|
||||
|
||||
printe(p,s)
|
||||
char *p,*s;
|
||||
void printe(char *p, char *s)
|
||||
{
|
||||
fprintf(stderr, p, s);
|
||||
exit(1);
|
||||
|
||||
391
src/cmd/w.c
391
src/cmd/w.c
@@ -6,83 +6,92 @@
|
||||
* This program is similar to the systat command on Tenex/Tops 10/20
|
||||
* It needs read permission on /dev/mem and /dev/swap.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <utmp.h>
|
||||
#include <paths.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/tty.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
|
||||
#define NMAX sizeof(utmp.ut_name)
|
||||
#define LMAX sizeof(utmp.ut_line)
|
||||
#define ARGWIDTH 33 /* # chars left on 80 col crt for args */
|
||||
#define ARGLIST 1024 /* amount of stack to examine for argument list */
|
||||
#define NMAX sizeof(utmp.ut_name)
|
||||
#define LMAX sizeof(utmp.ut_line)
|
||||
#define ARGWIDTH 33 /* # chars left on 80 col crt for args */
|
||||
#define ARGLIST 1024 /* amount of stack to examine for argument list */
|
||||
|
||||
struct smproc {
|
||||
long w_addr; /* address in file for args */
|
||||
short w_pid; /* proc.p_pid */
|
||||
int w_igintr; /* INTR+3*QUIT, 0=die, 1=ign, 2=catch */
|
||||
time_t w_time; /* CPU time used by this process */
|
||||
time_t w_ctime; /* CPU time used by children */
|
||||
dev_t w_tty; /* tty device of process */
|
||||
char w_comm[15]; /* user.u_comm, null terminated */
|
||||
char w_args[ARGWIDTH+1]; /* args if interesting process */
|
||||
} *pr;
|
||||
long w_addr; /* address in file for args */
|
||||
short w_pid; /* proc.p_pid */
|
||||
int w_igintr; /* INTR+3*QUIT, 0=die, 1=ign, 2=catch */
|
||||
time_t w_time; /* CPU time used by this process */
|
||||
time_t w_ctime; /* CPU time used by children */
|
||||
dev_t w_tty; /* tty device of process */
|
||||
char w_comm[15]; /* user.u_comm, null terminated */
|
||||
char w_args[ARGWIDTH + 1]; /* args if interesting process */
|
||||
} * pr;
|
||||
|
||||
FILE *ut;
|
||||
FILE *ut;
|
||||
int swmem;
|
||||
int swap; /* /dev/mem, mem, and swap */
|
||||
int swap; /* /dev/mem, mem, and swap */
|
||||
int file;
|
||||
dev_t tty;
|
||||
char doing[520]; /* process attached to terminal */
|
||||
time_t proctime; /* cpu time of process in doing */
|
||||
dev_t tty;
|
||||
char doing[520]; /* process attached to terminal */
|
||||
time_t proctime; /* cpu time of process in doing */
|
||||
unsigned avenrun[3];
|
||||
extern int errno, optind;
|
||||
|
||||
#define DIV60(t) ((t+30)/60) /* x/60 rounded */
|
||||
#define TTYEQ (tty == pr[i].w_tty)
|
||||
#define IGINT (1+3*1) /* ignoring both SIGINT & SIGQUIT */
|
||||
#define DIV60(t) ((t + 30) / 60) /* x/60 rounded */
|
||||
#define TTYEQ (tty == pr[i].w_tty)
|
||||
#define IGINT (1 + 3 * 1) /* ignoring both SIGINT & SIGQUIT */
|
||||
|
||||
char *getargs();
|
||||
char *getptr();
|
||||
|
||||
char *program;
|
||||
int header = 1; /* true if -h flag: don't print heading */
|
||||
int lflag = 1; /* true if -l flag: long style output */
|
||||
time_t idle; /* number of minutes user is idle */
|
||||
int nusers; /* number of users logged in now */
|
||||
char * sel_user; /* login of particular user selected */
|
||||
int wcmd = 1; /* running as the w command */
|
||||
time_t jobtime; /* total cpu time visible */
|
||||
time_t now; /* the current time of day */
|
||||
struct tm *nowt; /* current time as time struct */
|
||||
struct timeval boottime; /* time since last reboot */
|
||||
time_t uptime; /* elapsed time since */
|
||||
int np; /* number of processes currently active */
|
||||
struct utmp utmp;
|
||||
struct user up;
|
||||
char *program;
|
||||
int header = 1; /* true if -h flag: don't print heading */
|
||||
int lflag = 1; /* true if -l flag: long style output */
|
||||
time_t idle; /* number of minutes user is idle */
|
||||
int nusers; /* number of users logged in now */
|
||||
char *sel_user; /* login of particular user selected */
|
||||
int wcmd = 1; /* running as the w command */
|
||||
time_t jobtime; /* total cpu time visible */
|
||||
time_t now; /* the current time of day */
|
||||
struct tm *nowt; /* current time as time struct */
|
||||
struct timeval boottime; /* time since last reboot */
|
||||
time_t uptime; /* elapsed time since */
|
||||
int np; /* number of processes currently active */
|
||||
struct utmp utmp;
|
||||
struct user up;
|
||||
|
||||
struct addrmap {
|
||||
long b1, e1; long f1;
|
||||
long b2, e2; long f2;
|
||||
long b1, e1;
|
||||
long f1;
|
||||
long b2, e2;
|
||||
long f2;
|
||||
};
|
||||
struct addrmap datmap;
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
static void readpr(void);
|
||||
static void prtat(struct tm *p);
|
||||
static void gettty(void);
|
||||
static int findidle(void);
|
||||
static void putline(void);
|
||||
static void prttime(time_t tim, char *tail);
|
||||
static char *getargs(struct smproc *p);
|
||||
static char *getptr(char **adr);
|
||||
static int getbyte(char *adr);
|
||||
static int within(char *adr, long lbd, long ubd);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int days, hrs, mins;
|
||||
register int i;
|
||||
int i;
|
||||
char *cp;
|
||||
register int curpid, empty;
|
||||
size_t size;
|
||||
int curpid, empty;
|
||||
size_t size;
|
||||
int mib[2];
|
||||
|
||||
program = argv[0];
|
||||
@@ -91,34 +100,31 @@ main(argc, argv)
|
||||
if (*cp == 'u')
|
||||
wcmd = 0;
|
||||
|
||||
while ((i = getopt(argc, argv, "hlswu")) != EOF)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 'h':
|
||||
header = 0;
|
||||
break;
|
||||
case 'l':
|
||||
lflag++;
|
||||
break;
|
||||
case 's':
|
||||
lflag = 0;
|
||||
break;
|
||||
case 'u':
|
||||
wcmd = 0;
|
||||
break;
|
||||
case 'w':
|
||||
wcmd = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Usage: %s [-hlswu] [user]\n",
|
||||
program);
|
||||
exit(1);
|
||||
}
|
||||
while ((i = getopt(argc, argv, "hlswu")) != EOF) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
header = 0;
|
||||
break;
|
||||
case 'l':
|
||||
lflag++;
|
||||
break;
|
||||
case 's':
|
||||
lflag = 0;
|
||||
break;
|
||||
case 'u':
|
||||
wcmd = 0;
|
||||
break;
|
||||
case 'w':
|
||||
wcmd = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Usage: %s [-hlswu] [user]\n", program);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (*argv)
|
||||
if (*argv)
|
||||
sel_user = *argv;
|
||||
|
||||
if (wcmd)
|
||||
@@ -133,26 +139,25 @@ main(argc, argv)
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_BOOTTIME;
|
||||
size = sizeof (boottime);
|
||||
if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 &&
|
||||
boottime.tv_sec != 0) {
|
||||
size = sizeof(boottime);
|
||||
if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0) {
|
||||
uptime = now - boottime.tv_sec;
|
||||
days = uptime / (60L*60L*24L);
|
||||
uptime %= (60L*60L*24L);
|
||||
hrs = uptime / (60L*60L);
|
||||
uptime %= (60L*60L);
|
||||
days = uptime / (60L * 60L * 24L);
|
||||
uptime %= (60L * 60L * 24L);
|
||||
hrs = uptime / (60L * 60L);
|
||||
uptime %= (60L * 60L);
|
||||
mins = DIV60(uptime);
|
||||
|
||||
printf(" up");
|
||||
if (days > 0)
|
||||
printf(" %d day%s,", days, days>1?"s":"");
|
||||
printf(" %d day%s,", days, days > 1 ? "s" : "");
|
||||
if (hrs > 0 && mins > 0) {
|
||||
printf(" %2d:%02d,", hrs, mins);
|
||||
} else {
|
||||
if (hrs > 0)
|
||||
printf(" %d hr%s,", hrs, hrs>1?"s":"");
|
||||
printf(" %d hr%s,", hrs, hrs > 1 ? "s" : "");
|
||||
if (mins > 0)
|
||||
printf(" %d min%s,", mins, mins>1?"s":"");
|
||||
printf(" %d min%s,", mins, mins > 1 ? "s" : "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,17 +167,16 @@ main(argc, argv)
|
||||
nusers++;
|
||||
}
|
||||
rewind(ut);
|
||||
printf(" %d user%c", nusers, nusers > 1 ? 's' : '\0');
|
||||
printf(" %d user%c", nusers, nusers > 1 ? 's' : '\0');
|
||||
|
||||
if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) == -1)
|
||||
printf(", no load average information available\n");
|
||||
else {
|
||||
printf(", load averages:");
|
||||
for (i = 0; i < (sizeof(avenrun)/sizeof(avenrun[0])); i++) {
|
||||
for (i = 0; i < (sizeof(avenrun) / sizeof(avenrun[0])); i++) {
|
||||
if (i > 0)
|
||||
printf(",");
|
||||
printf(" %u.%02u", avenrun[i] / 100,
|
||||
avenrun[i] % 100);
|
||||
printf(" %u.%02u", avenrun[i] / 100, avenrun[i] % 100);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
@@ -181,24 +185,22 @@ main(argc, argv)
|
||||
|
||||
/* Headers for rest of output */
|
||||
if (lflag)
|
||||
printf("%-*.*s %-*.*s login@ idle JCPU PCPU what\n",
|
||||
NMAX, NMAX, "User", LMAX, LMAX, "tty");
|
||||
printf("%-*.*s %-*.*s login@ idle JCPU PCPU what\n", NMAX, NMAX, "User", LMAX,
|
||||
LMAX, "tty");
|
||||
else
|
||||
printf("%-*.*s tty idle what\n",
|
||||
NMAX, NMAX, "User");
|
||||
printf("%-*.*s tty idle what\n", NMAX, NMAX, "User");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
for (;;) { /* for each entry in utmp */
|
||||
for (;;) { /* for each entry in utmp */
|
||||
if (fread(&utmp, sizeof(utmp), 1, ut) == NULL) {
|
||||
fclose(ut);
|
||||
exit(0);
|
||||
}
|
||||
if (utmp.ut_name[0] == '\0')
|
||||
continue; /* that tty is free */
|
||||
continue; /* that tty is free */
|
||||
if (sel_user && strncmp(utmp.ut_name, sel_user, NMAX) != 0)
|
||||
continue; /* we wanted only somebody else */
|
||||
continue; /* we wanted only somebody else */
|
||||
|
||||
gettty();
|
||||
jobtime = 0;
|
||||
@@ -207,19 +209,19 @@ main(argc, argv)
|
||||
empty = 1;
|
||||
curpid = -1;
|
||||
idle = findidle();
|
||||
for (i=0; i<np; i++) { /* for each process on this tty */
|
||||
for (i = 0; i < np; i++) { /* for each process on this tty */
|
||||
if (!(TTYEQ))
|
||||
continue;
|
||||
jobtime += pr[i].w_time + pr[i].w_ctime;
|
||||
proctime += pr[i].w_time;
|
||||
if (empty && pr[i].w_igintr!=IGINT) {
|
||||
if (empty && pr[i].w_igintr != IGINT) {
|
||||
empty = 0;
|
||||
curpid = -1;
|
||||
}
|
||||
if(pr[i].w_pid>curpid && (pr[i].w_igintr!=IGINT || empty)){
|
||||
if (pr[i].w_pid > curpid && (pr[i].w_igintr != IGINT || empty)) {
|
||||
curpid = pr[i].w_pid;
|
||||
strcpy(doing, lflag ? pr[i].w_args : pr[i].w_comm);
|
||||
if (doing[0]==0 || doing[0]=='-' && doing[1]<=' ' || doing[0] == '?') {
|
||||
if (doing[0] == 0 || doing[0] == '-' && doing[1] <= ' ' || doing[0] == '?') {
|
||||
strcat(doing, " (");
|
||||
strcat(doing, pr[i].w_comm);
|
||||
strcat(doing, ")");
|
||||
@@ -231,7 +233,7 @@ main(argc, argv)
|
||||
}
|
||||
|
||||
/* figure out the major/minor device # pair for this tty */
|
||||
gettty()
|
||||
void gettty()
|
||||
{
|
||||
char ttybuf[20];
|
||||
struct stat statbuf;
|
||||
@@ -246,9 +248,8 @@ gettty()
|
||||
/*
|
||||
* putline: print out the accumulated line of info about one user.
|
||||
*/
|
||||
putline()
|
||||
void putline()
|
||||
{
|
||||
|
||||
/* print login name of the user */
|
||||
printf("%-*.*s ", NMAX, NMAX, utmp.ut_name);
|
||||
|
||||
@@ -258,7 +259,7 @@ putline()
|
||||
printf("%-*.*s", LMAX, LMAX, utmp.ut_line);
|
||||
else {
|
||||
/* short form: 2 chars, skipping 'tty' if there */
|
||||
if (utmp.ut_line[0]=='t' && utmp.ut_line[1]=='t' && utmp.ut_line[2]=='y')
|
||||
if (utmp.ut_line[0] == 't' && utmp.ut_line[1] == 't' && utmp.ut_line[2] == 'y')
|
||||
printf("%-2.2s", &utmp.ut_line[3]);
|
||||
else
|
||||
printf("%-2.2s", utmp.ut_line);
|
||||
@@ -269,22 +270,22 @@ putline()
|
||||
prtat(localtime(&utmp.ut_time));
|
||||
|
||||
/* print idle time */
|
||||
prttime(idle," ");
|
||||
prttime(idle, " ");
|
||||
|
||||
if (lflag) {
|
||||
/* print CPU time for all processes & children */
|
||||
prttime(DIV60(jobtime)," ");
|
||||
prttime(DIV60(jobtime), " ");
|
||||
/* print cpu time for interesting process */
|
||||
prttime(DIV60(proctime)," ");
|
||||
prttime(DIV60(proctime), " ");
|
||||
}
|
||||
|
||||
/* what user is doing, either command tail or args */
|
||||
printf(" %-.32s\n",doing);
|
||||
printf(" %-.32s\n", doing);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* find & return number of minutes current tty has been idle */
|
||||
findidle()
|
||||
int findidle()
|
||||
{
|
||||
struct stat stbuf;
|
||||
long lastaction, diff;
|
||||
@@ -297,8 +298,9 @@ findidle()
|
||||
lastaction = stbuf.st_atime;
|
||||
diff = now - lastaction;
|
||||
diff = DIV60(diff);
|
||||
if (diff < 0) diff = 0;
|
||||
return(diff);
|
||||
if (diff < 0)
|
||||
diff = 0;
|
||||
return (diff);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -306,21 +308,19 @@ findidle()
|
||||
* The character string tail is printed at the end, obvious
|
||||
* strings to pass are "", " ", or "am".
|
||||
*/
|
||||
prttime(tim, tail)
|
||||
time_t tim;
|
||||
char *tail;
|
||||
void prttime(time_t tim, char *tail)
|
||||
{
|
||||
register int didhrs = 0;
|
||||
int didhrs = 0;
|
||||
|
||||
if (tim >= 60) {
|
||||
printf("%3ld:", tim/60);
|
||||
printf("%3ld:", tim / 60);
|
||||
didhrs++;
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
tim %= 60;
|
||||
if (tim > 0 || didhrs) {
|
||||
printf(didhrs&&tim<10 ? "%02ld" : "%2ld", tim);
|
||||
printf(didhrs && tim < 10 ? "%02ld" : "%2ld", tim);
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
@@ -328,39 +328,38 @@ prttime(tim, tail)
|
||||
}
|
||||
|
||||
/* prtat prints a 12 hour time given a pointer to a time of day */
|
||||
prtat(p)
|
||||
register struct tm *p;
|
||||
void prtat(struct tm *p)
|
||||
{
|
||||
register int pm;
|
||||
int pm;
|
||||
time_t t;
|
||||
|
||||
t = p -> tm_hour;
|
||||
t = p->tm_hour;
|
||||
pm = (t > 11);
|
||||
if (t > 11)
|
||||
t -= 12;
|
||||
if (t == 0)
|
||||
t = 12;
|
||||
prttime(t*60 + p->tm_min, pm ? "pm" : "am");
|
||||
prttime(t * 60 + p->tm_min, pm ? "pm" : "am");
|
||||
}
|
||||
|
||||
/*
|
||||
* readpr finds and reads in the array pr, containing the interesting
|
||||
* parts of the proc and user tables for each live process.
|
||||
*/
|
||||
readpr()
|
||||
void readpr()
|
||||
{
|
||||
struct kinfo_proc *kp;
|
||||
register struct proc *p;
|
||||
register struct smproc *smp;
|
||||
struct kinfo_proc *kpt;
|
||||
struct kinfo_proc *kp;
|
||||
struct proc *p;
|
||||
struct smproc *smp;
|
||||
struct kinfo_proc *kpt;
|
||||
int pn, nproc;
|
||||
long addr, daddr, saddr;
|
||||
long txtsiz, datsiz, stksiz;
|
||||
int septxt;
|
||||
int mib[4], st;
|
||||
size_t size;
|
||||
size_t size;
|
||||
|
||||
if((swmem = open("/dev/mem", 0)) < 0) {
|
||||
if ((swmem = open("/dev/mem", 0)) < 0) {
|
||||
perror("/dev/mem");
|
||||
exit(1);
|
||||
}
|
||||
@@ -377,27 +376,25 @@ register struct smproc *smp;
|
||||
fprintf(stderr, "sysctl: %s \n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (size % sizeof (struct kinfo_proc) != 0) {
|
||||
fprintf(stderr, "proc size mismatch (%d total, %d chunks)\n",
|
||||
size, sizeof(struct kinfo_proc));
|
||||
if (size % sizeof(struct kinfo_proc) != 0) {
|
||||
fprintf(stderr, "proc size mismatch (%d total, %d chunks)\n", size,
|
||||
sizeof(struct kinfo_proc));
|
||||
exit(1);
|
||||
}
|
||||
kpt = (struct kinfo_proc *)malloc(size);
|
||||
if (kpt == (struct kinfo_proc *)NULL) {
|
||||
fprintf(stderr, "Not %d bytes of memory for proc table\n",
|
||||
size);
|
||||
fprintf(stderr, "Not %d bytes of memory for proc table\n", size);
|
||||
exit(1);
|
||||
}
|
||||
if (sysctl(mib, 4, kpt, &size, NULL, 0) == -1) {
|
||||
fprintf(stderr, "sysctl fetch of proc table failed: %s\n",
|
||||
strerror(errno));
|
||||
fprintf(stderr, "sysctl fetch of proc table failed: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nproc = size / sizeof (struct kinfo_proc);
|
||||
pr = (struct smproc *) malloc(nproc * sizeof(struct smproc));
|
||||
nproc = size / sizeof(struct kinfo_proc);
|
||||
pr = (struct smproc *)malloc(nproc * sizeof(struct smproc));
|
||||
if (pr == (struct smproc *)NULL) {
|
||||
fprintf(stderr,"Not enough memory for proc table\n");
|
||||
fprintf(stderr, "Not enough memory for proc table\n");
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
@@ -409,7 +406,7 @@ register struct smproc *smp;
|
||||
for (pn = 0; pn < nproc; kp++, pn++) {
|
||||
p = &kp->kp_proc;
|
||||
/* decide if it's an interesting process */
|
||||
if (p->p_stat==0 || p->p_stat==SZOMB || p->p_pgrp==0)
|
||||
if (p->p_stat == 0 || p->p_stat == SZOMB || p->p_pgrp == 0)
|
||||
continue;
|
||||
/* find & read in the user structure */
|
||||
if (p->p_flag & SLOAD) {
|
||||
@@ -434,7 +431,7 @@ register struct smproc *smp;
|
||||
datsiz = up.u_dsize;
|
||||
stksiz = up.u_ssize;
|
||||
datmap.b1 = txtsiz;
|
||||
datmap.e1 = datmap.b1+datsiz;
|
||||
datmap.e1 = datmap.b1 + datsiz;
|
||||
datmap.f1 = daddr;
|
||||
datmap.b2 = stackbas(stksiz);
|
||||
datmap.e2 = stacktop(stksiz);
|
||||
@@ -444,13 +441,13 @@ register struct smproc *smp;
|
||||
smp->w_addr = saddr + (long)p->p_ssize - ARGLIST;
|
||||
smp->w_pid = p->p_pid;
|
||||
smp->w_igintr = ((up.u_signal[SIGINT] == SIG_IGN) +
|
||||
2 * ((unsigned)up.u_signal[SIGINT] > (unsigned)SIG_IGN) +
|
||||
3 * (up.u_signal[SIGQUIT] == SIG_IGN)) +
|
||||
6 * ((unsigned)up.u_signal[SIGQUIT] > (unsigned)SIG_IGN);
|
||||
2 * ((unsigned)up.u_signal[SIGINT] > (unsigned)SIG_IGN) +
|
||||
3 * (up.u_signal[SIGQUIT] == SIG_IGN)) +
|
||||
6 * ((unsigned)up.u_signal[SIGQUIT] > (unsigned)SIG_IGN);
|
||||
smp->w_time = up.u_ru.ru_utime + up.u_ru.ru_stime;
|
||||
smp->w_ctime = up.u_cru.ru_utime + up.u_cru.ru_stime;
|
||||
smp->w_tty = up.u_ttyd;
|
||||
up.u_comm[14] = 0; /* Bug: This bombs next field. */
|
||||
up.u_comm[14] = 0; /* Bug: This bombs next field. */
|
||||
strcpy(smp->w_comm, up.u_comm);
|
||||
/*
|
||||
* Get args if there's a chance we'll print it.
|
||||
@@ -458,8 +455,9 @@ register struct smproc *smp;
|
||||
* Cant use strncpy: that crock blank pads.
|
||||
*/
|
||||
smp->w_args[0] = 0;
|
||||
strncat(smp->w_args,getargs(smp),ARGWIDTH);
|
||||
if (smp->w_args[0]==0 || smp->w_args[0]=='-' && smp->w_args[1]<=' ' || smp->w_args[0] == '?') {
|
||||
strncat(smp->w_args, getargs(smp), ARGWIDTH);
|
||||
if (smp->w_args[0] == 0 || smp->w_args[0] == '-' && smp->w_args[1] <= ' ' ||
|
||||
smp->w_args[0] == '?') {
|
||||
strcat(smp->w_args, " (");
|
||||
strcat(smp->w_args, smp->w_comm);
|
||||
strcat(smp->w_args, ")");
|
||||
@@ -474,31 +472,29 @@ register struct smproc *smp;
|
||||
* getargs: given a pointer to a proc structure, this looks at the swap area
|
||||
* and tries to reconstruct the arguments. This is straight out of ps.
|
||||
*/
|
||||
char *
|
||||
getargs(p)
|
||||
struct smproc *p;
|
||||
char *getargs(struct smproc *p)
|
||||
{
|
||||
int c, nbad;
|
||||
static char abuf[ARGLIST];
|
||||
register int *ip;
|
||||
register char *cp, *cp1;
|
||||
int *ip;
|
||||
char *cp, *cp1;
|
||||
char **ap;
|
||||
long addr;
|
||||
|
||||
addr = p->w_addr;
|
||||
|
||||
/* look for sh special */
|
||||
lseek(file, addr+ARGLIST-sizeof(char **), 0);
|
||||
lseek(file, addr + ARGLIST - sizeof(char **), 0);
|
||||
if (read(file, (char *)&ap, sizeof(char *)) != sizeof(char *))
|
||||
return(NULL);
|
||||
return (NULL);
|
||||
if (ap) {
|
||||
char *b = (char *) abuf;
|
||||
char *b = (char *)abuf;
|
||||
char *bp = b;
|
||||
while((cp=getptr(ap++)) && cp && (bp<b+ARGWIDTH) ) {
|
||||
while ((cp = getptr(ap++)) && cp && (bp < b + ARGWIDTH)) {
|
||||
nbad = 0;
|
||||
while((c=getbyte(cp++)) && (bp<b+ARGWIDTH)) {
|
||||
if (c<' ' || c>'~') {
|
||||
if (nbad++>3)
|
||||
while ((c = getbyte(cp++)) && (bp < b + ARGWIDTH)) {
|
||||
if (c < ' ' || c > '~') {
|
||||
if (nbad++ > 3)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
@@ -507,22 +503,22 @@ getargs(p)
|
||||
*bp++ = ' ';
|
||||
}
|
||||
*bp++ = 0;
|
||||
return(b);
|
||||
return (b);
|
||||
}
|
||||
|
||||
lseek(file, addr, 0);
|
||||
if (read(file, abuf, sizeof(abuf)) != sizeof(abuf))
|
||||
return((char *)1);
|
||||
for (ip = (int *) &abuf[ARGLIST]-2; ip > (int *) abuf;) {
|
||||
return ((char *)1);
|
||||
for (ip = (int *)&abuf[ARGLIST] - 2; ip > (int *)abuf;) {
|
||||
/* Look from top for -1 or 0 as terminator flag. */
|
||||
if (*--ip == -1 || *ip == 0) {
|
||||
cp = (char *)(ip+1);
|
||||
if (*cp==0)
|
||||
cp = (char *)(ip + 1);
|
||||
if (*cp == 0)
|
||||
cp++;
|
||||
nbad = 0; /* up to 5 funny chars as ?'s */
|
||||
nbad = 0; /* up to 5 funny chars as ?'s */
|
||||
for (cp1 = cp; cp1 < (char *)&abuf[ARGLIST]; cp1++) {
|
||||
c = *cp1&0177;
|
||||
if (c==0) /* nulls between args => spaces */
|
||||
c = *cp1 & 0177;
|
||||
if (c == 0) /* nulls between args => spaces */
|
||||
*cp1 = ' ';
|
||||
else if (c < ' ' || c > 0176) {
|
||||
if (++nbad >= 5) {
|
||||
@@ -530,64 +526,57 @@ getargs(p)
|
||||
break;
|
||||
}
|
||||
*cp1 = '?';
|
||||
} else if (c=='=') { /* Oops - found an
|
||||
* environment var, back
|
||||
* over & erase it. */
|
||||
} else if (c == '=') { /* Oops - found an
|
||||
* environment var, back
|
||||
* over & erase it. */
|
||||
*cp1 = 0;
|
||||
while (cp1>cp && *--cp1!=' ')
|
||||
while (cp1 > cp && *--cp1 != ' ')
|
||||
*cp1 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (*--cp1==' ') /* strip trailing spaces */
|
||||
while (*--cp1 == ' ') /* strip trailing spaces */
|
||||
*cp1 = 0;
|
||||
return(cp);
|
||||
return (cp);
|
||||
}
|
||||
}
|
||||
return (p->w_comm);
|
||||
}
|
||||
|
||||
char *
|
||||
getptr(adr)
|
||||
char **adr;
|
||||
char *getptr(char **adr)
|
||||
{
|
||||
char *ptr;
|
||||
register char *p, *pa;
|
||||
register i;
|
||||
char *p, *pa;
|
||||
int i;
|
||||
|
||||
ptr = 0;
|
||||
pa = (char *)adr;
|
||||
p = (char *)&ptr;
|
||||
for (i=0; i<sizeof(ptr); i++)
|
||||
for (i = 0; i < sizeof(ptr); i++)
|
||||
*p++ = getbyte(pa++);
|
||||
return(ptr);
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
getbyte(adr)
|
||||
char *adr;
|
||||
int getbyte(char *adr)
|
||||
{
|
||||
register struct addrmap *amap = &datmap;
|
||||
struct addrmap *amap = &datmap;
|
||||
char b;
|
||||
long saddr;
|
||||
|
||||
if(!within(adr, amap->b1, amap->e1)) {
|
||||
if(within(adr, amap->b2, amap->e2)) {
|
||||
if (!within(adr, amap->b1, amap->e1)) {
|
||||
if (within(adr, amap->b2, amap->e2)) {
|
||||
saddr = (unsigned)adr + amap->f2 - amap->b2;
|
||||
} else
|
||||
return(0);
|
||||
return (0);
|
||||
} else
|
||||
saddr = (unsigned)adr + amap->f1 - amap->b1;
|
||||
if(lseek(file, saddr, 0)==-1
|
||||
|| read(file, &b, 1)<1) {
|
||||
return(0);
|
||||
if (lseek(file, saddr, 0) == -1 || read(file, &b, 1) < 1) {
|
||||
return (0);
|
||||
}
|
||||
return((unsigned)b);
|
||||
return ((unsigned)b);
|
||||
}
|
||||
|
||||
|
||||
within(adr,lbd,ubd)
|
||||
char *adr;
|
||||
long lbd, ubd;
|
||||
int within(char *adr, long lbd, long ubd)
|
||||
{
|
||||
return((unsigned)adr>=lbd && (unsigned)adr<ubd);
|
||||
return ((unsigned)adr >= lbd && (unsigned)adr < ubd);
|
||||
}
|
||||
|
||||
71
src/cmd/wc.c
71
src/cmd/wc.c
@@ -8,22 +8,26 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
long linect, wordct, charct, pagect;
|
||||
long tlinect, twordct, tcharct, tpagect;
|
||||
char *wd = "lwc";
|
||||
long linect, wordct, charct, pagect;
|
||||
long tlinect, twordct, tcharct, tpagect;
|
||||
char *wd = "lwc";
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
static void wcp(char *wd, long charct, long wordct, long linect);
|
||||
static void ipr(long num);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, token;
|
||||
register FILE *fp;
|
||||
register int c;
|
||||
FILE *fp;
|
||||
int c;
|
||||
char *p;
|
||||
|
||||
while (argc > 1 && *argv[1] == '-') {
|
||||
switch (argv[1][1]) {
|
||||
case 'l': case 'w': case 'c':
|
||||
wd = argv[1]+1;
|
||||
case 'l':
|
||||
case 'w':
|
||||
case 'c':
|
||||
wd = argv[1] + 1;
|
||||
break;
|
||||
default:
|
||||
usage:
|
||||
@@ -37,7 +41,7 @@ char **argv;
|
||||
i = 1;
|
||||
fp = stdin;
|
||||
do {
|
||||
if(argc>1 && (fp=fopen(argv[i], "r")) == NULL) {
|
||||
if (argc > 1 && (fp = fopen(argv[i], "r")) == NULL) {
|
||||
perror(argv[i]);
|
||||
continue;
|
||||
}
|
||||
@@ -45,28 +49,27 @@ char **argv;
|
||||
wordct = 0;
|
||||
charct = 0;
|
||||
token = 0;
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
c = getc(fp);
|
||||
if (c == EOF)
|
||||
break;
|
||||
charct++;
|
||||
if(' '<c&&c<0177) {
|
||||
if(!token) {
|
||||
if (' ' < c && c < 0177) {
|
||||
if (!token) {
|
||||
wordct++;
|
||||
token++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(c=='\n') {
|
||||
if (c == '\n') {
|
||||
linect++;
|
||||
}
|
||||
else if(c!=' '&&c!='\t')
|
||||
} else if (c != ' ' && c != '\t')
|
||||
continue;
|
||||
token = 0;
|
||||
}
|
||||
/* print lines, words, chars */
|
||||
wcp(wd, charct, wordct, linect);
|
||||
if(argc>1) {
|
||||
if (argc > 1) {
|
||||
printf(" %s\n", argv[i]);
|
||||
} else
|
||||
printf("\n");
|
||||
@@ -74,36 +77,34 @@ char **argv;
|
||||
tlinect += linect;
|
||||
twordct += wordct;
|
||||
tcharct += charct;
|
||||
} while(++i<argc);
|
||||
if(argc > 2) {
|
||||
} while (++i < argc);
|
||||
if (argc > 2) {
|
||||
wcp(wd, tcharct, twordct, tlinect);
|
||||
printf(" total\n");
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
wcp(wd, charct, wordct, linect)
|
||||
register char *wd;
|
||||
long charct; long wordct; long linect;
|
||||
void wcp(char *wd, long charct, long wordct, long linect)
|
||||
{
|
||||
while (*wd) switch (*wd++) {
|
||||
case 'l':
|
||||
ipr(linect);
|
||||
break;
|
||||
while (*wd) {
|
||||
switch (*wd++) {
|
||||
case 'l':
|
||||
ipr(linect);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
ipr(wordct);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
ipr(charct);
|
||||
break;
|
||||
case 'w':
|
||||
ipr(wordct);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
ipr(charct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ipr(num)
|
||||
long num;
|
||||
void ipr(long num)
|
||||
{
|
||||
printf(" %7ld", num);
|
||||
}
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/dir.h>
|
||||
|
||||
static char *bindirs[] = {
|
||||
// clang-format off
|
||||
"/etc",
|
||||
"/bin",
|
||||
"/sbin",
|
||||
@@ -20,8 +21,10 @@ static char *bindirs[] = {
|
||||
"/local/bin",
|
||||
"/new",
|
||||
0
|
||||
// clang-format on
|
||||
};
|
||||
static char *mandirs[] = {
|
||||
// clang-format off
|
||||
"/man/man1",
|
||||
"/man/man2",
|
||||
"/man/man3",
|
||||
@@ -34,8 +37,10 @@ static char *mandirs[] = {
|
||||
"/man/mann",
|
||||
"/man/mano",
|
||||
0
|
||||
// clang-format on
|
||||
};
|
||||
static char *srcdirs[] = {
|
||||
static char *srcdirs[] = {
|
||||
// clang-format off
|
||||
"/src/bin",
|
||||
"/src/sbin",
|
||||
"/src/etc",
|
||||
@@ -51,88 +56,96 @@ static char *srcdirs[] = {
|
||||
"/src/lib/libc/net/inet",
|
||||
"/src/lib/libc/net/misc",
|
||||
0
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
char sflag = 1;
|
||||
char bflag = 1;
|
||||
char mflag = 1;
|
||||
char **Sflag;
|
||||
char sflag = 1;
|
||||
char bflag = 1;
|
||||
char mflag = 1;
|
||||
char **Sflag;
|
||||
int Scnt;
|
||||
char **Bflag;
|
||||
char **Bflag;
|
||||
int Bcnt;
|
||||
char **Mflag;
|
||||
char **Mflag;
|
||||
int Mcnt;
|
||||
char uflag;
|
||||
char uflag;
|
||||
|
||||
static void getlist(int *argcp, char ***argvp, char ***flagp, int *cntp);
|
||||
static void zerof(void);
|
||||
static void lookup(char *cp);
|
||||
static void looksrc(char *cp);
|
||||
static void lookbin(char *cp);
|
||||
static void lookman(char *cp);
|
||||
static void find(char **dirs, char *cp);
|
||||
static void findv(char **dirv, int dirc, char *cp);
|
||||
static void findin(char *dir, char *cp);
|
||||
static int itsit(char *cp, char *dp);
|
||||
|
||||
/*
|
||||
* whereis name
|
||||
* look for source, documentation and binaries
|
||||
*/
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
argc--, argv++;
|
||||
if (argc == 0) {
|
||||
usage:
|
||||
fprintf(stderr, "whereis [ -sbmu ] [ -SBM dir ... -f ] name...\n");
|
||||
exit(1);
|
||||
}
|
||||
do
|
||||
do {
|
||||
if (argv[0][0] == '-') {
|
||||
register char *cp = argv[0] + 1;
|
||||
while (*cp) switch (*cp++) {
|
||||
char *cp = argv[0] + 1;
|
||||
|
||||
case 'f':
|
||||
break;
|
||||
while (*cp) {
|
||||
switch (*cp++) {
|
||||
case 'f':
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
getlist(&argc, &argv, &Sflag, &Scnt);
|
||||
break;
|
||||
case 'S':
|
||||
getlist(&argc, &argv, &Sflag, &Scnt);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
getlist(&argc, &argv, &Bflag, &Bcnt);
|
||||
break;
|
||||
case 'B':
|
||||
getlist(&argc, &argv, &Bflag, &Bcnt);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
getlist(&argc, &argv, &Mflag, &Mcnt);
|
||||
break;
|
||||
case 'M':
|
||||
getlist(&argc, &argv, &Mflag, &Mcnt);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
zerof();
|
||||
sflag++;
|
||||
continue;
|
||||
case 's':
|
||||
zerof();
|
||||
sflag++;
|
||||
continue;
|
||||
|
||||
case 'u':
|
||||
uflag++;
|
||||
continue;
|
||||
case 'u':
|
||||
uflag++;
|
||||
continue;
|
||||
|
||||
case 'b':
|
||||
zerof();
|
||||
bflag++;
|
||||
continue;
|
||||
case 'b':
|
||||
zerof();
|
||||
bflag++;
|
||||
continue;
|
||||
|
||||
case 'm':
|
||||
zerof();
|
||||
mflag++;
|
||||
continue;
|
||||
case 'm':
|
||||
zerof();
|
||||
mflag++;
|
||||
continue;
|
||||
|
||||
default:
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
argv++;
|
||||
} else
|
||||
} else {
|
||||
lookup(*argv++);
|
||||
while (--argc > 0);
|
||||
}
|
||||
} while (--argc > 0);
|
||||
}
|
||||
|
||||
getlist(argcp, argvp, flagp, cntp)
|
||||
char ***argvp;
|
||||
int *argcp;
|
||||
char ***flagp;
|
||||
int *cntp;
|
||||
void getlist(int *argcp, char ***argvp, char ***flagp, int *cntp)
|
||||
{
|
||||
|
||||
(*argvp)++;
|
||||
*flagp = *argvp;
|
||||
*cntp = 0;
|
||||
@@ -142,21 +155,18 @@ getlist(argcp, argvp, flagp, cntp)
|
||||
(*argvp)--;
|
||||
}
|
||||
|
||||
|
||||
zerof()
|
||||
void zerof()
|
||||
{
|
||||
|
||||
if (sflag && bflag && mflag)
|
||||
sflag = bflag = mflag = 0;
|
||||
}
|
||||
|
||||
int count;
|
||||
int print;
|
||||
|
||||
|
||||
lookup(cp)
|
||||
register char *cp;
|
||||
void lookup(char *cp)
|
||||
{
|
||||
register char *dp;
|
||||
char *dp;
|
||||
|
||||
for (dp = cp; *dp; dp++)
|
||||
continue;
|
||||
@@ -204,8 +214,7 @@ again:
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
looksrc(cp)
|
||||
char *cp;
|
||||
void looksrc(char *cp)
|
||||
{
|
||||
if (Sflag == 0) {
|
||||
find(srcdirs, cp);
|
||||
@@ -213,8 +222,7 @@ looksrc(cp)
|
||||
findv(Sflag, Scnt, cp);
|
||||
}
|
||||
|
||||
lookbin(cp)
|
||||
char *cp;
|
||||
void lookbin(char *cp)
|
||||
{
|
||||
if (Bflag == 0)
|
||||
find(bindirs, cp);
|
||||
@@ -222,8 +230,7 @@ lookbin(cp)
|
||||
findv(Bflag, Bcnt, cp);
|
||||
}
|
||||
|
||||
lookman(cp)
|
||||
char *cp;
|
||||
void lookman(char *cp)
|
||||
{
|
||||
if (Mflag == 0) {
|
||||
find(mandirs, cp);
|
||||
@@ -231,27 +238,19 @@ lookman(cp)
|
||||
findv(Mflag, Mcnt, cp);
|
||||
}
|
||||
|
||||
findv(dirv, dirc, cp)
|
||||
char **dirv;
|
||||
int dirc;
|
||||
char *cp;
|
||||
void findv(char **dirv, int dirc, char *cp)
|
||||
{
|
||||
|
||||
while (dirc > 0)
|
||||
findin(*dirv++, cp), dirc--;
|
||||
}
|
||||
|
||||
find(dirs, cp)
|
||||
char **dirs;
|
||||
char *cp;
|
||||
void find(char **dirs, char *cp)
|
||||
{
|
||||
|
||||
while (*dirs)
|
||||
findin(*dirs++, cp);
|
||||
}
|
||||
|
||||
findin(dir, cp)
|
||||
char *dir, *cp;
|
||||
void findin(char *dir, char *cp)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct direct *dp;
|
||||
@@ -269,12 +268,11 @@ findin(dir, cp)
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
itsit(cp, dp)
|
||||
register char *cp, *dp;
|
||||
int itsit(char *cp, char *dp)
|
||||
{
|
||||
register int i = strlen(dp);
|
||||
int i = strlen(dp);
|
||||
|
||||
if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
|
||||
if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp + 2))
|
||||
return (1);
|
||||
while (*cp && *dp && *cp == *dp)
|
||||
cp++, dp++, i--;
|
||||
|
||||
@@ -3,41 +3,41 @@
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <utmp.h>
|
||||
#include <ctype.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/param.h> /* for MAXHOSTNAMELEN */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/param.h> /* for MAXHOSTNAMELEN */
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
|
||||
#define NMAX sizeof(utmp.ut_name)
|
||||
#define LMAX sizeof(utmp.ut_line)
|
||||
#define HMAX sizeof(utmp.ut_host)
|
||||
|
||||
struct utmp utmp;
|
||||
struct passwd *pw;
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
struct utmp utmp;
|
||||
struct passwd *pw;
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
static void putline(void);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
register char *tp, *s;
|
||||
register FILE *fi;
|
||||
char *tp, *s;
|
||||
FILE *fi;
|
||||
|
||||
s = _PATH_UTMP;
|
||||
if(argc == 2)
|
||||
if (argc == 2)
|
||||
s = argv[1];
|
||||
if (argc == 3) {
|
||||
tp = ttyname(0);
|
||||
if (tp)
|
||||
tp = rindex(tp, '/') + 1;
|
||||
else { /* no tty - use best guess from passwd file */
|
||||
else { /* no tty - use best guess from passwd file */
|
||||
pw = getpwuid(getuid());
|
||||
strncpy(utmp.ut_name, pw ? pw->pw_name : "?", NMAX);
|
||||
strcpy(utmp.ut_line, "tty??");
|
||||
@@ -52,7 +52,7 @@ main(argc, argv)
|
||||
}
|
||||
while (fread((char *)&utmp, sizeof(utmp), 1, fi) == 1) {
|
||||
if (argc == 3) {
|
||||
gethostname(hostname, sizeof (hostname));
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
if (strcmp(utmp.ut_line, tp))
|
||||
continue;
|
||||
printf("%s!", hostname);
|
||||
@@ -65,15 +65,13 @@ main(argc, argv)
|
||||
}
|
||||
}
|
||||
|
||||
putline()
|
||||
void putline()
|
||||
{
|
||||
register char *cbuf;
|
||||
char *cbuf;
|
||||
|
||||
printf("%-*.*s %-*.*s",
|
||||
NMAX, NMAX, utmp.ut_name,
|
||||
LMAX, LMAX, utmp.ut_line);
|
||||
printf("%-*.*s %-*.*s", NMAX, NMAX, utmp.ut_name, LMAX, LMAX, utmp.ut_line);
|
||||
cbuf = ctime(&utmp.ut_time);
|
||||
printf("%.12s", cbuf+4);
|
||||
printf("%.12s", cbuf + 4);
|
||||
if (utmp.ut_host[0])
|
||||
printf("\t(%.*s)", HMAX, utmp.ut_host);
|
||||
putchar('\n');
|
||||
|
||||
Reference in New Issue
Block a user