Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

277 lines
5.5 KiB

/*** scan - display header info
*
* This program prints out synopses of the headers of documents in
* a DH folder.
*
* Usage:
* scan [-q] [-p pattern] ... doclist ...
*/
#include <stdio.h>
#include "dh.h"
/* Extern Functions */
extern int atoi();
extern int exit();
extern int fprintf();
extern int free();
extern int printf();
extern char *strrchr();
extern int strlen();
extern int strncmp();
extern char *strtok();
extern char toupper();
/* Static Functions */
static void header();
static void scan();
static void usage();
static int pattmatch();
/* Globals */
static int silentflg = 0;
#define NPATS 50
static struct {
char *pat;
int len;
} pats[NPATS];
static int pindx = 0;
/*** main - parse options, arguments
*
* We call 'getopt()' to parse the '-' style options
* and then examine the remaining arguments, if any.
* In this case, no remaining arguments means the user
* omitted something; he has to specify at least one
* document list.
* We dole the real work out to 'scan()' via 'map()'.
*
* Entry: argc = count of command line arguments
* argv = ptr to arry of ptr to cmd line args
*
* Return: none
*/
void main(argc, argv)
int argc;
char **argv;
{
extern int getopt();
extern char *optarg;
extern int optind;
int c, donework;
char *cp;
donework = 0;
while ((c = getopt(argc, argv, "qp:")) != EOF )
switch(c) {
case 'q':
silentflg = 1;
break;
case 'p':
if ( pindx >= NPATS ) {
fprintf(stderr, "scan: too many patterns.\n");
exit(1);
}
pats[pindx].pat = optarg;
pats[pindx].len = 0;
if ( (cp = strrchr(optarg, ':')) != NULL ) {
pats[pindx].len = atoi(cp+1);
*cp = '\0';
}
pindx += 1;
break;
case '?':
default:
usage();
exit(1);
}
if ( optind == argc ) {
usage();
exit(1);
}
if ( pindx == 0 ) {
/* no patterns specified, use defaults */
pats[pindx].pat = "From$";
pats[pindx++].len = 8;
pats[pindx].pat = "Subject$";
pats[pindx++].len = 0;
}
for( ; optind < argc; optind++) {
map(header, scan, null, argv[optind]);
}
exit(0);
}
/*** usage - print out a helpful message
*
* We print a standard XENIX style usage message on
* stderr.
*
* Entry: none
* Return: none
*/
static void usage()
{
fprintf(stderr,
"usage: scan [-q] [-p pattern:length] ... doclist ...\n");
}
/*** header - print a header
*
* Header is called as a result of the call to 'map()'
* in 'main()'. It is called once for each folder
* that is specified in a doclist given to 'main()'
* as an argument.
*
* We print an informative header, unless the
* user specified the silence option.
* Note that we arrange to have the output
* corresponding to each doclist SEPARATED by
* newlines; no newlines are printed if only
* one argument is given.
* Likewise, no newlines if we are told to be quiet.
*
* Column headers are printed iff all columns but the last
* have fixed widths.
*
* Entry: fh = handle to folder to print header for
* Return: none
*/
static void header(fh)
Fhandle fh;
{
static int needblank = 0;
int i, len;
if ( silentflg )
return;
if ( needblank )
printf("\n");
else
needblank = 1;
printf("%s:\n", getname(fh));
for ( i = 0; i < pindx - 1; i += 1)
if ( pats[i].len == 0 )
return;
printf("Id ");
for ( i = 0; i < pindx; i += 1 ) {
len = pats[i].len;
if ( len == 0 )
len = strlen(pats[i].pat);
printf(" %-*.*s", len, len, pats[i].pat);
}
printf("\n");
}
/*** scan - print info from headers of documents
*
* scan is called as a result of the call to 'map()'
* in 'main()'. It is called once for each document
* that was specified by some doclist given as an argument
* to main.
*
* 'scan()'s responsibility is to print out some of the
* info contained in the header of the specified document.
* Note that the document may not exist; in this case, we do
* nothing.
*
* Entry: fh = handle to folder containing document
* did = document id to print info for.
* Return: none
*/
static void scan(fh, did)
Fhandle fh;
Docid did;
{
char *hp, *wp, *tp;
Dhandle dh;
static char *lines[NPATS];
int i, len;
if ( ( dh = getdoc(fh, DOC_SPEC, did )) == ERROR )
return;
for ( i = 0; i < pindx; i += 1 )
lines[i] = NULL;
hp = gethdr(dh);
for ( wp = strtok(hp, "\n"); wp != NULL; wp = strtok(NULL, "\n") ) {
for ( i = 0; i < pindx; i += 1 ) {
if (pattmatch(pats[i].pat, wp, strlen(pats[i].pat))==0)
continue;
wp += strlen(pats[i].pat);
while ( *wp == ' ' || *wp == '\t' || *wp == ':' )
wp += 1;
lines[i] = wp;
break;
}
}
printf("%-5d", did);
for ( i = 0; i < pindx; i += 1 ) {
if ( lines[i] == NULL )
lines[i] = "None";
len = pats[i].len;
if ( len == 0 )
len = strlen(lines[i]);
printf(" %-*.*s", len, len, lines[i]);
}
printf("\n");
free(hp);
putdoc(dh);
}
/*** pattmatch - match a header line against a pattern, report if found
*
* pattmatch reports on whether target "lead matches" pattern.
* The match is:
* (1) Left anchored.
* (2) Case insensitive.
* (3) The following special characters are allowed
* $ - Name end = ' ' or ':' or '\t'
* ? - Anything
*
* Currently no way to escape $ or ?
*
* ENTRY pattern - string containing pattern to match against
* target - string we test for match with pattern
* length - number of characters to compare
*
* RETURN 0 = no match
* 1 = match
*
*/
static int pattmatch(pattern, target, length)
char *pattern;
char *target;
int length;
{
int i;
for (i = 0; i < length; ++i,++pattern,++target) {
if (toupper(*pattern) == toupper(*target))
continue;
if ((*pattern == '$') &&
( (*target==' ') || (*target==':') || (*target=='\t') ))
continue;
if (*pattern == '?')
continue;
return 0;
}
return 1;
}