# last --- high speed line count and last n line print of file # ehs 6/80, modified 1/29/81; 5/3/81; 5/19/81 include ARGUMENT_DEFS integer open, mapfd, isatty, gfnarg, mktemp, getlin long_int last file_des fd, funit integer path (MAXPATH), lne_cnt, is_temp integer i, j, lne (MAXLINE), state (4) long_int sze logical print_text, print_count ARG_DECL string usage "Usage: last [-t ] [ -c] [-l<#>] [-v] [-n<#> | -n | {}]" ARG_DEFAULT_INT(l, 20) PARSE_COMMAND_LINE ("lvtcn"s, usage) if (ARG_PRESENT(l)) lne_cnt = ARG_VALUE(l) else lne_cnt = 20 print_count = ARG_PRESENT(c) print_text = ((~ARG_PRESENT(c)) | ARG_PRESENT(t)) state(1) = 1 repeat { is_temp = NO if (gfnarg (path, state) == EOF) stop else { fd = open (path, READ) if (fd == ERR) call cant (path) } if (isatty (fd) == YES) { j = mktemp (READWRITE) call fcopy (fd, j) fd = j is_temp = YES } call rewind (fd) call flush$ (fd) funit = mapfd (fd) if (funit == ERR) call error ('error in mapfd.') sze = last (funit, lne_cnt) if (sze < 0) { call print (ERROUT, "*s: "s, path) call error ('error in "last".'s) } if (print_count) { call print (STDOUT, "*6l"s, sze) if (ARG_PRESENT(v)) call print (STDOUT, " lines | *s"s, path) call print (STDOUT, "*n"s) } if (ARG_PRESENT(v) & ~print_count) call print (STDOUT, " *s*n"p, path) if (print_text) { if (lne_cnt > 0) call fcopy (fd, STDOUT) else { call rewind (fd) for (j = 1; j <= -lne_cnt; j +=1) { if (getlin (lne, fd, MAXLINE) == EOF) break call putlin (lne, STDOUT) } } } if (is_temp == YES) call rmtemp (fd) } end