715 lines
22 KiB
C
715 lines
22 KiB
C
/* epics/share/src/util $Id$
|
||
* Author: Roger A. Cole
|
||
* Date: mm-dd-yy
|
||
*
|
||
* Experimental Physics and Industrial Control System (EPICS)
|
||
*
|
||
* Copyright 1991, the Regents of the University of California,
|
||
* and the University of Chicago Board of Governors.
|
||
*
|
||
* This software was produced under U.S. Government contracts:
|
||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||
*
|
||
* Initial development by:
|
||
* The Controls and Automation Group (AT-8)
|
||
* Ground Test Accelerator
|
||
* Accelerator Technology Division
|
||
* Los Alamos National Laboratory
|
||
*
|
||
* Co-developed with
|
||
* The Controls and Computing Group
|
||
* Accelerator Systems Division
|
||
* Advanced Photon Source
|
||
* Argonne National Laboratory
|
||
*
|
||
* Modification Log:
|
||
* -----------------
|
||
* 1.1 07/12/89 rac initial version
|
||
* 1.2 09/15/89 rac allow multiple input files; change
|
||
* the calling sequence so -o specifies
|
||
* output file; print non-printing chars
|
||
* as <code>.
|
||
* 1.3 11/02/89 rac change printing of <; allow default
|
||
* input from stdin. If first line on page
|
||
* is FF, don't print empty page.
|
||
* 1.4 11/03/89 rac fix bug in input from stdin.
|
||
* 1.5 12/04/89 rac handle long lines without truncation
|
||
* 1.6 02/11/90 rac handle module name and subr name in heading;
|
||
* put page number in footing.
|
||
* 1.7 skipped
|
||
* 1.8 08/31/90 rac handle /subhead text--- divider lines
|
||
* 1.9 09/17/90 rac fix long line bug; allow more pages
|
||
* 1.10 07-28-91 rac installed in EPICS
|
||
* 1.11 07-28-91 rac add -w option for page width
|
||
*
|
||
*/
|
||
/*+/mod***********************************************************************
|
||
* TITLE racPrint - filter for printing
|
||
*
|
||
* SYNOPSIS
|
||
* racPrint [-l lm] [-o output] [-t tab] [-P point] [-w width] input ...
|
||
*
|
||
* lm is the number of columns for left margin; default 0.
|
||
* tab is the tab width, in columns; default 8.
|
||
* input is an ascii file; several may be specified; if none
|
||
* is specified, stdin is used.
|
||
* output is an ascii file containing the input file broken
|
||
* into pages, with pages in reverse order;
|
||
* default is stdout.
|
||
* point is a point size for PostScript printers
|
||
* width is page width, in characters
|
||
*
|
||
* DESCRIPTION
|
||
* The input file is broken into pages and written in reverse page
|
||
* order to the output file. The following processing is done:
|
||
* o a 3 line heading is written, containing time and date, file
|
||
* path, file name, modification date, and subroutien name is
|
||
* printed
|
||
* o a 3 line footing containing file number and page number is
|
||
* printed
|
||
* o a left margin of 8 columns is added, plus an additional 7
|
||
* columns for line numbering. (If -l is specified, it
|
||
* controls the left margin.)
|
||
* o tabs are expanded
|
||
* o form-feed characters are honored
|
||
* o long lines are folded
|
||
* o non-printing characters are printed as <code>, where
|
||
* code is the hexadecimal code for the character. Where
|
||
* a < occurs, it is printed as a <; hopefully, the context
|
||
* will avoid confusion with <code>.
|
||
* EXAMPLE
|
||
* % racPrint source.c | lpr
|
||
*
|
||
* BUGS
|
||
* o should guard against printing binary files
|
||
* o files which exactly fill the last page result in an extra, blank
|
||
* page being printed.
|
||
* o Doesn't print info following ^L if <cr> doesn't follow ^L
|
||
*
|
||
*-*/
|
||
/*-----------------------------------------------------------------------------
|
||
* APOLOGY: I offer my humble apologies to whomever comes across this code--
|
||
* it was my first program in C, and it shows it. R. Cole
|
||
*----------------------------------------------------------------------------*/
|
||
|
||
/* WISH LIST:
|
||
* - generate a 'table of contents' from names from divider lines
|
||
* - generate table of contents for file names and extractable entities
|
||
* - add a -help switch
|
||
* - handle the backspace character
|
||
* - handle "pre-formatted" files, such as man pages output
|
||
* - handle extremely long path names, or at least check for overflow
|
||
* - allow a `-H heading' option to provide a meaningful heading when
|
||
* input is from stdin
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <ctype.h>
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
#include <time.h>
|
||
|
||
#define MAXCHAR 95 /* max characters per line */
|
||
#define MAXLINE 66 /* max lines per page */
|
||
#define MAXPAGE 500 /* max pages at a time */
|
||
#define MAXTOC 10 /* max table of contents pages */
|
||
#define lineBufDim 10000 /* dimension for input line and ovf buffers */
|
||
|
||
#define STRCAT_CHK(str,sub_str) strcat_chk(str,sizeof str,sub_str)
|
||
|
||
typedef struct
|
||
{ int page_no; /* page number */
|
||
int nlines; /* number of lines on this page */
|
||
char lines[MAXLINE][MAXCHAR+1]; /* lines of the page */
|
||
} PAGE;
|
||
|
||
|
||
struct FILE_INF
|
||
{ FILE *ptr; /* file pointer from 'fopen' */
|
||
char path[80]; /* pathname to file */
|
||
char date_mod[30]; /* time and date last modified */
|
||
short line_no; /* line number in file */
|
||
char name[20]; /* file name */
|
||
char subr[30]; /* subroutine name from subr heading */
|
||
int fd; /* file descriptor for use in 'stat' call */
|
||
};
|
||
|
||
char date[40]; /* date and time */
|
||
char header[80]; /* heading line */
|
||
int page_no; /* number of current page within file */
|
||
int file_no = 0; /* file number being processed */
|
||
int npages = 0; /* number of pages */
|
||
PAGE pages[MAXPAGE]; /* pages from file */
|
||
int pages_sub = 0; /* subscript into pages structure */
|
||
PAGE toc[MAXTOC]; /* table of contents */
|
||
int toc_sub = 0; /* subscript into toc structure */
|
||
|
||
int left_margin = 0; /* width of left margin in output */
|
||
int line_numbering = 1; /* flag to number lines in output */
|
||
int page_width = 80; /* page width, in characters */
|
||
int point_size = 0; /* PostScript point size if non-zero */
|
||
int tab_width = 8; /* columns per 'tab stop' */
|
||
char overflow[lineBufDim]; /* overflow record buffer */
|
||
int overflow_flag = 0; /* overflow record buffer in use */
|
||
|
||
|
||
/*+*****************************************************************
|
||
* NAME main - racPrint main program
|
||
*
|
||
*-*/
|
||
main(argc, argv)
|
||
int argc; /* number of command line args */
|
||
char *argv[]; /* command line args */
|
||
{
|
||
void get_time_and_date(); /* get time and date string */
|
||
int i; /* temp for loops */
|
||
struct FILE_INF in_file; /* input file */
|
||
struct FILE_INF out_file; /* output file */
|
||
|
||
char line[MAXCHAR+1]; /* line of file */
|
||
int get_next_page(); /* get a page from the file */
|
||
|
||
get_time_and_date(date);
|
||
|
||
/* -------------------------------------------------------------
|
||
* get the option arguments from the command line
|
||
* -------------------------------------------------------------*/
|
||
|
||
get_option_args(argc, argv, &out_file);
|
||
|
||
/* -------------------------------------------------------------
|
||
* get the input file names from the command line, processing each
|
||
* in turn.
|
||
* -------------------------------------------------------------*/
|
||
|
||
while (get_input_file(argc, argv, &in_file) != NULL) {
|
||
|
||
/* -------------------------------------------------------------
|
||
* Read pages from input file. If 'buffer' becomes full, print
|
||
* the accumulated pages in reverse order.
|
||
* -------------------------------------------------------------*/
|
||
|
||
in_file.line_no = 0;
|
||
while (get_next_page(&in_file) != EOF) {
|
||
if (pages_sub == MAXPAGE) { /* dump and start fresh */
|
||
for (i=pages_sub-1; i>=0; i--)
|
||
print_page(&out_file,i);
|
||
pages_sub = 0;
|
||
}
|
||
}
|
||
if (in_file.ptr != stdin) /* don't close stdin */
|
||
fclose(in_file.ptr);
|
||
}
|
||
|
||
for (i=pages_sub-1; i>=0; i--) {
|
||
print_page(&out_file,i);
|
||
}
|
||
|
||
print_banner_page(&in_file,&out_file);
|
||
|
||
/* flush and close files */
|
||
fflush(out_file.ptr);
|
||
fclose(out_file.ptr);
|
||
|
||
exit(0);
|
||
}
|
||
|
||
/*+/subr************************************************************
|
||
* NAME print_banner_page - write a banner page to the output file
|
||
*
|
||
*-*/
|
||
print_banner_page(p_in_file,p_out_file)
|
||
struct FILE_INF *p_in_file; /* pointer to input file */
|
||
struct FILE_INF *p_out_file; /* pointer to output file */
|
||
{
|
||
char banner[80]; /* temp for banner line */
|
||
char *env; /* pointer to string from getenv */
|
||
char *getenv(); /* get environment variables */
|
||
int i; /* temp for loops */
|
||
|
||
for (i=0; i<79; i++)
|
||
banner[i] = '/';
|
||
banner[79] = '\0';
|
||
|
||
env = getenv("LOGNAME");
|
||
|
||
for (i=0; i<MAXLINE-1; i++) {
|
||
if (i<10)
|
||
fprintf(p_out_file->ptr,
|
||
"%s\n",banner);
|
||
else if (i==15)
|
||
fprintf(p_out_file->ptr,
|
||
"////////// For: %s\n",env);
|
||
else if (i==17)
|
||
fprintf(p_out_file->ptr,
|
||
"////////// Date: %s\n",date);
|
||
else
|
||
fprintf(p_out_file->ptr,
|
||
"////////// \n");
|
||
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
/*+/subr************************************************************
|
||
* NAME print_page - write a page to the output file
|
||
*
|
||
*-*/
|
||
print_page(p_out_file,page_number)
|
||
struct FILE_INF *p_out_file; /* pointer to file */
|
||
int page_number; /* page number to print 0-n */
|
||
{
|
||
int i; /* temp for loops */
|
||
|
||
for (i=0; i<pages[page_number].nlines; i++)
|
||
fputs(pages[page_number].lines[i],p_out_file->ptr);
|
||
|
||
return;
|
||
}
|
||
|
||
/*+/subr************************************************************
|
||
* NAME line_store - store a line into a page
|
||
*
|
||
* DESCRIPTION
|
||
* The record is stored into the line buffer, expanding tabs.
|
||
*
|
||
* If the record isn't an overflow record, left margin and
|
||
* record number are added to the line buffer. If the
|
||
* record is too long to fit in the line buffer, the overflow
|
||
* flag is set and the excess characters are copied into the
|
||
* overflow record.
|
||
*
|
||
* If the record is an overflow record, the left margin and
|
||
* padding for the record number field are added to the line
|
||
* buffer. If the record is too long to fit in the line buffer,
|
||
* the overflow flag and overflow record will be handled as above.
|
||
*
|
||
* RETURNS
|
||
* 0 if no form-feed encountered
|
||
* 1 if form-feed encountered and line printed
|
||
* 2 if form-feed encountered and no line printed
|
||
*
|
||
*-*/
|
||
line_store (line, rec, line_no)
|
||
char line[]; /* line to receive record, with tabs
|
||
expanded and left margin set */
|
||
char rec[]; /* record to store */
|
||
int line_no; /* line number to attach; if zero,
|
||
no line number will appear. */
|
||
{
|
||
char c; /* temp for character */
|
||
int ff=0; /* form feed encountered flag */
|
||
char hex_code[3]; /* temp for hex code for char */
|
||
int l_col=0; /* column index in line */
|
||
int lmar; /* left margin to store actual record */
|
||
int r_col=0; /* column index in record */
|
||
|
||
/* -------------------------------------------------------------
|
||
* If the first thing on a line is a ^L (i.e., ff), then don't
|
||
* do anything; just exit with `ff' indicated.
|
||
* -------------------------------------------------------------*/
|
||
if (rec[0] == '\f') {
|
||
ff = 2;
|
||
return ff;
|
||
}
|
||
|
||
while (l_col < left_margin)
|
||
line[l_col++] = ' '; /* blank fill left margin */
|
||
|
||
if (!overflow_flag) {
|
||
if (line_no > 0) { /* 'print' the line number */
|
||
sprintf (&line[l_col], "%.5d", line_no);
|
||
l_col += 5;
|
||
line[l_col++] = ' ';
|
||
line[l_col++] = ' ';
|
||
}
|
||
}
|
||
else {
|
||
sprintf(&line[l_col], " ");
|
||
l_col += 5;
|
||
line[l_col++] = ' ';
|
||
line[l_col++] = ' ';
|
||
}
|
||
|
||
/* -------------------------------------------------------------
|
||
* Move the record into the line buffer, expanding tabs. If record is
|
||
* too long, the overflow is invoked. Line buffer will always be
|
||
* terminated with \n\0. Non-printing characters will be shown as
|
||
* <hh>, where hh is the hex code for the character. Where < occurs
|
||
* in the text, it will be shown as itself.
|
||
* -------------------------------------------------------------*/
|
||
#define store_c(c) \
|
||
if (l_col < page_width-1)\
|
||
line[l_col++] = c;\
|
||
else\
|
||
line[lmar-2] = '*';
|
||
|
||
overflow_flag = 0; /* reset overflow flag */
|
||
lmar = l_col; /* save this to make tab expansion 'sane' */
|
||
while ((c=rec[r_col++]) != NULL && !overflow_flag) {
|
||
if (l_col < page_width-2) {
|
||
switch (c) {
|
||
case '\t':
|
||
line[l_col++] = ' ';
|
||
while (l_col < page_width-1 &&
|
||
((l_col-lmar) % tab_width) != 0)
|
||
line[l_col++] = ' ';
|
||
break;
|
||
case '\f':
|
||
ff = 1;
|
||
break;
|
||
case '\n':
|
||
break;
|
||
case '<':
|
||
store_c(c);
|
||
break;
|
||
default:
|
||
if (isprint(c))
|
||
line[l_col++] = c;
|
||
else {
|
||
store_c('<');
|
||
sprintf(hex_code,"%02.2X",c);
|
||
store_c(hex_code[0]);
|
||
store_c(hex_code[1]);
|
||
store_c('>');
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
else {
|
||
r_col--;
|
||
strcpy(overflow, &rec[r_col]);
|
||
overflow_flag = 1;
|
||
}
|
||
}
|
||
|
||
line[l_col++] = '\n';
|
||
line[l_col++] = '\0';
|
||
|
||
return ff;
|
||
}
|
||
|
||
/*+/subr************************************************************
|
||
* NAME get_next_page - format the next page for printing
|
||
*
|
||
* DESCRIPTION
|
||
*
|
||
* RETURNS
|
||
*
|
||
* SEE ALSO
|
||
*
|
||
* EXAMPLE
|
||
*
|
||
*-*/
|
||
int get_next_page(p_in_file)
|
||
struct FILE_INF *p_in_file; /* pointer to input file */
|
||
{
|
||
char buf_in[lineBufDim];/* input buffer */
|
||
int buf_in_len; /* length of input line */
|
||
int col = 0; /* temp for column in line */
|
||
int eof = 0; /* end-of-file flag */
|
||
int ff; /* form feed flag */
|
||
int line = 0; /* temp for line in page */
|
||
|
||
|
||
line = 3;
|
||
|
||
/* -------------------------------------------------------------
|
||
* read the lines from the file for one page, leaving room for 'footing'
|
||
* If the overflow flag is set, input line is taken from overflow
|
||
* buffer instead of file.
|
||
* -------------------------------------------------------------*/
|
||
while (line < MAXLINE-3 && eof == 0) {
|
||
if (overflow_flag) {
|
||
strcpy(buf_in, overflow);
|
||
}
|
||
else if (fgets(buf_in, lineBufDim, p_in_file->ptr) != NULL ) {
|
||
p_in_file->line_no++;
|
||
}
|
||
else
|
||
eof = EOF; /* no more to read */
|
||
|
||
if (!eof) {
|
||
if (strncmp(buf_in, "* NAME", 6) == 0) {
|
||
sscanf(&buf_in[6], "%29s", p_in_file->subr);
|
||
}
|
||
else if (strncmp(buf_in, "/*/subhead ", 11) == 0) {
|
||
int i;
|
||
int c;
|
||
i = 0;
|
||
while (i< 29 && (c=buf_in[11+i])!='-')
|
||
p_in_file->subr[i++] = c;
|
||
p_in_file->subr[i] = '\0';
|
||
|
||
}
|
||
ff = line_store(pages[pages_sub].lines[line++], buf_in,
|
||
line_numbering ? p_in_file->line_no : 0);
|
||
if (ff == 2 && line == 4) { /* FF on first line of page */
|
||
line--; /* throw away the FF; already new page */
|
||
}
|
||
else if (ff) { /* if FF encountered, pad rest of page */
|
||
if (ff == 2) /* if no line printed, reset line_no */
|
||
line--;
|
||
while (line < MAXLINE-3)
|
||
pages[pages_sub].lines[line++][0] = '\n';
|
||
}
|
||
}
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------
|
||
* set up the footing
|
||
*---------------------------------------------------------------------------*/
|
||
for(; line<MAXLINE-2; line++)
|
||
strcpy(pages[pages_sub].lines[line],"\n");
|
||
if (line < MAXLINE-1) {
|
||
for (col=0; col<(page_width-12)/2; col++)
|
||
pages[pages_sub].lines[line][col] = ' ';
|
||
sprintf(&(pages[pages_sub].lines[line][col]),
|
||
"Page %d-%d\n", file_no, page_no);
|
||
line++;
|
||
}
|
||
if (line < MAXLINE) {
|
||
strcpy(pages[pages_sub].lines[line],"\n");
|
||
line++;
|
||
}
|
||
|
||
pages[pages_sub].nlines = line;
|
||
|
||
/* -------------------------------------------------------------
|
||
* set up the header; if input is from stdin, suppress path and
|
||
* modification date for file.
|
||
* -------------------------------------------------------------*/
|
||
|
||
line = 0; /* line 0 has time, date, mod. date, file name */
|
||
col = 0;
|
||
while (col<left_margin) /* put left margin into line */
|
||
pages[pages_sub].lines[line][col++] = ' ';
|
||
sprintf(&pages[pages_sub].lines[line][col],"%s %s %s",
|
||
date,
|
||
(p_in_file->date_mod[0] != '\0') ? "last modified:" : " ",
|
||
p_in_file->date_mod);
|
||
for (col=strlen(pages[pages_sub].lines[line]);
|
||
col<page_width-2-strlen(p_in_file->name); col++)
|
||
pages[pages_sub].lines[line][col] = ' ';
|
||
sprintf(&(pages[pages_sub].lines[line][page_width-2-strlen(p_in_file->name)]),
|
||
"%s\n", p_in_file->name);
|
||
|
||
line = 1; /* line 1 has path and subroutine name */
|
||
col = 0;
|
||
while (col<left_margin) /* put left margin into line */
|
||
pages[pages_sub].lines[line][col++] = ' ';
|
||
sprintf(&pages[pages_sub].lines[line][col],"%s",
|
||
p_in_file->path);
|
||
for (col=strlen(pages[pages_sub].lines[line]);
|
||
col<page_width-2-strlen(p_in_file->subr); col++)
|
||
pages[pages_sub].lines[line][col] = ' ';
|
||
sprintf(&(pages[pages_sub].lines[line][page_width-2-strlen(p_in_file->subr)]),
|
||
"%s\n", p_in_file->subr);
|
||
|
||
line++; /* line 2 is blank */
|
||
strcpy(pages[pages_sub].lines[line],"\n");
|
||
|
||
pages[pages_sub].page_no = ++npages;
|
||
pages_sub++;
|
||
page_no++;
|
||
|
||
return eof;
|
||
|
||
}
|
||
|
||
/*+/subr************************************************************
|
||
* NAME get_option_args - get option args from command line
|
||
*
|
||
* DESCRIPTION
|
||
* Gets the command line options, except for input file. If
|
||
* an error is encountered, exit(1) is done.
|
||
*
|
||
*-*/
|
||
get_option_args(argc, argv, p_out_file)
|
||
int argc; /* number of command line args */
|
||
char *argv[]; /* command line args */
|
||
struct FILE_INF *p_out_file; /* pointer to output file */
|
||
{
|
||
int c; /* option letter */
|
||
int errflg = 0; /* error flag for options */
|
||
int i; /* temp for string length */
|
||
extern char *optarg; /* argument for an option */
|
||
extern int optind; /* index in argv of next option */
|
||
|
||
/* -------------------------------------------------------------
|
||
* Get any options from the command line and process them. If the
|
||
* output file is specified, open it; abort if can't open it.
|
||
* -------------------------------------------------------------*/
|
||
|
||
p_out_file->ptr = stdout; /* default for output is stdout */
|
||
while ((c = getopt (argc, argv, "l:t:o:P:w:")) != -1) {
|
||
switch(c) {
|
||
case'l':
|
||
left_margin = atoi(optarg); /* -l left_margin */
|
||
case't':
|
||
tab_width = atoi(optarg); /* -t tab_width */
|
||
break;
|
||
case'o':
|
||
if ((p_out_file->ptr = fopen (optarg, "w")) == NULL) {
|
||
fprintf(stderr, "racPrint: can't open %s\n", optarg);
|
||
exit(1);
|
||
}
|
||
break;
|
||
case'P':
|
||
point_size = atoi(optarg); /* -P PostScript point_size */
|
||
break;
|
||
case'w':
|
||
page_width = atoi(optarg); /* -w page_width */
|
||
if (page_width > MAXCHAR)
|
||
page_width = MAXCHAR;
|
||
break;
|
||
case'?':
|
||
errflg++;
|
||
}
|
||
}
|
||
|
||
if (errflg)
|
||
usage();
|
||
|
||
return;
|
||
}
|
||
usage()
|
||
{
|
||
fprintf(stderr,
|
||
"Usage: racPrint [-l l_mar] [-t tabwid] [-o out_file]\
|
||
[-w width] [-P point] input_file\n");
|
||
exit(2);
|
||
}
|
||
|
||
/*+/subr************************************************************
|
||
* NAME get_input_file - get next input file from command line
|
||
*
|
||
* DESCRIPTION
|
||
* Gets the next input file argument from the command line. If
|
||
* an error is encountered, exit(1) is done.
|
||
*
|
||
* RETURNS
|
||
* 0 if no input file arg found
|
||
* 1 if there is an input file
|
||
*
|
||
*-*/
|
||
get_input_file(argc, argv, p_in_file)
|
||
int argc; /* number of command line args */
|
||
char *argv[]; /* command line args */
|
||
struct FILE_INF *p_in_file; /* pointer to input file */
|
||
{
|
||
char *ctime(); /* convert 'time_t' to 'ascii' */
|
||
char *getenv(); /* get environment variable value */
|
||
int i; /* temp for string length */
|
||
extern char *optarg; /* argument for an option */
|
||
extern int optind; /* index in argv of next option */
|
||
struct stat p_fstat; /* pointer to status buffer */
|
||
char *p_ftime; /* pointer to date and time of last mod */
|
||
|
||
/* -------------------------------------------------------------
|
||
* Set up pointers and do the opens for the next input file.
|
||
* The file descriptor for the file is also captured and stored.
|
||
* -------------------------------------------------------------*/
|
||
|
||
if (optind>=argc && file_no==0) {
|
||
p_in_file->ptr = stdin;
|
||
strcpy(p_in_file->name, "stdin");
|
||
strcpy(p_in_file->path, " ");
|
||
p_in_file->date_mod[0] = '\0';
|
||
|
||
page_no=1;
|
||
file_no++;
|
||
strcpy(p_in_file->subr, " ");
|
||
return(1);
|
||
}
|
||
else if (optind<argc) {
|
||
if ((p_in_file->ptr = fopen(argv[optind], "r")) == NULL) {
|
||
fprintf(stderr, "racPrint: can't open %s\n", argv[optind]);
|
||
exit(1);
|
||
}
|
||
strcpy(p_in_file->name,argv[optind]);
|
||
strcpy(p_in_file->path,getenv("PWD")); /* get working directory */
|
||
STRCAT_CHK(p_in_file->path,"/"); /* append /filename to it */
|
||
STRCAT_CHK(p_in_file->path,p_in_file->name);
|
||
p_in_file->fd = fileno(p_in_file->ptr); /* get file descriptor */
|
||
i = fstat(p_in_file->fd,&p_fstat); /* get file stat info */
|
||
p_ftime = ctime(&p_fstat.st_mtime); /* convert to ascii \n\0 */
|
||
p_ftime[strlen(p_ftime)-1] = '\0'; /* remove the \n */
|
||
strcpy(p_in_file->date_mod,p_ftime); /* date last modified */
|
||
|
||
optind++;
|
||
|
||
page_no=1;
|
||
file_no++;
|
||
strcpy(p_in_file->subr, " ");
|
||
return(1);
|
||
}
|
||
else
|
||
return(0);
|
||
}
|
||
|
||
/*+/subr************************************************************
|
||
* NAME strcat_chk - concatenate strings, checking bounds
|
||
*
|
||
* DESCRIPTION
|
||
* The sub_string is concatenated to the end of string. If
|
||
* string isn't large enough, only the part of sub_string which
|
||
* will fit is concatenated. Strings are \0 terminated.
|
||
*
|
||
*-*/
|
||
strcat_chk (string, size_of_string, sub_string)
|
||
char string[]; /* 'master' string */
|
||
int size_of_string; /* declared length of string */
|
||
char sub_string[]; /* substring to concatenate */
|
||
{
|
||
int i;
|
||
|
||
i = 0;
|
||
while (string[i] && i<size_of_string) /* find the \0 on string */
|
||
i++;
|
||
|
||
if (i<size_of_string) { /* see if there's room for more */
|
||
while (i<size_of_string-1 && *sub_string) /* untill full or \0 */
|
||
string[i++] = *sub_string++;
|
||
string[i] = '\0'; /* put in null following last char */
|
||
}
|
||
return;
|
||
}
|
||
|
||
|
||
/*+/subr************************************************************
|
||
* get_time_and_date - get time and date ascii string
|
||
*
|
||
* DESCRIPTION
|
||
* The date and time are returned in the following format:
|
||
* hh:mm Mon dd yyyy\0
|
||
* At least 18 character positions must be available.
|
||
*
|
||
* RETURNS
|
||
* none
|
||
*
|
||
*-*/
|
||
void
|
||
get_time_and_date(mytime)
|
||
char mytime[]; /* time and date as ascii string */
|
||
{
|
||
char *ptime;
|
||
char *ctime();
|
||
long timeofday;
|
||
|
||
time(&timeofday);
|
||
|
||
ptime = ctime(&timeofday);
|
||
|
||
strncpy(&mytime[0],&ptime[11],5);
|
||
mytime[5]=' ';
|
||
strncpy(&mytime[6],&ptime[4],6);
|
||
mytime[12]=' ';
|
||
strncpy(&mytime[13],&ptime[20],4);
|
||
mytime[17]='\0';
|
||
|
||
return;
|
||
}
|