|
|
BSD 4.3
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSD/contrib/spms/src/bin/ppd/ppd.c,v 1.1.1.1 2018/04/24 16:12:55 root Exp $";
/*
* ppd - list project directories
*
* Author: Peter J. Nicklin
*/
#include <stdio.h>
#include "getarg.h"
#include "macro.h"
#include "null.h"
#include "path.h"
#include "pdb.h"
#include "pdtyp.h"
#include "pld.h"
#include "slslist.h"
#include "spms.h"
#include "yesno.h"
#define MAXLINE 80 /* maximum output line size */
#define TABSIZE 8 /* default tab width */
#define MINIMUM_GAP 2 /* minimum space between items */
/*
* Information request definitions
*/
#define ABSOLUTE_PATH_INFO 1 /* list absolute pathnames */
#define ALIAS_INFO 2 /* list aliases + absolute pathnames */
#define DESCRIPTION_INFO 3 /* list directory descriptions */
#define REGULAR_INFO 4 /* list project directory aliases */
#define TYPE_LABEL_INFO 5 /* list type labels */
char *PGN = "ppd"; /* program name */
int INFORMATION = REGULAR_INFO; /* type of information to be printed */
int LIST_ALL_ENTRIES = NO; /* print "..." && "...." ? */
int LIST_PLD_CONTENTS = YES; /* list project link dir contents */
int MARK_PROJECT_ROOT = 0; /* append project root dirs with `^' */
int ONE_ENTRY_PER_LINE = 0; /* print 1 project directory/line */
int PRINT_HEADING = YES; /* print headings for projects */
int RECURSIVE = 0; /* recursively print projects */
PDTYP PDIRTYP; /* project directory type labels list */
main(argc, argv)
int argc;
char **argv;
{
extern int PPDEBUG; /* project pathname debug flag */
char *cwp; /* current working project */
char *getcwp(); /* get current working project */
char *slsappend(); /* append key+string */
int pdtolist(); /* add project directories to pdlist */
int pdtparse(); /* parse boolean type label expr */
int qsort(); /* quicker sort */
int readpath(); /* read project or regular pathname */
int status = 0; /* exit status */
int strpcmp(); /* compare pointed-to strings */
PATH pathbuf; /* pathname struct buffer */
SLSBLK *pblk; /* project list block */
SLSLIST *pdlist; /* project directory list */
SLSLIST *plist; /* project list */
SLSLIST *slsinit(); /* initialize key+string list */
void printlist(); /* print project directory list */
void slsrm(); /* remove key+string list */
{
register char *s; /* option pointer */
while (--argc > 0 && **++argv == '-')
{
for (s = argv[0]+1; *s != '\0'; s++)
switch (*s)
{
case '1':
ONE_ENTRY_PER_LINE++;
break;
case 'D':
PPDEBUG = YES;
break;
case 'T':
if (pdtparse(GETARG(s), &PDIRTYP) == NO)
status = 1;
goto endfor;
case 'a':
LIST_ALL_ENTRIES = YES;
break;
case 'd':
INFORMATION = DESCRIPTION_INFO;
ONE_ENTRY_PER_LINE++;
break;
case 'l':
INFORMATION = ABSOLUTE_PATH_INFO;
ONE_ENTRY_PER_LINE++;
break;
case 'm':
MARK_PROJECT_ROOT++;
break;
case 'n':
INFORMATION = ALIAS_INFO;
ONE_ENTRY_PER_LINE++;
break;
case 'p':
LIST_PLD_CONTENTS = NO;
break;
case 'q':
PRINT_HEADING = NO;
break;
case 'r':
RECURSIVE++;
break;
case 't':
INFORMATION = TYPE_LABEL_INFO;
ONE_ENTRY_PER_LINE++;
break;
default:
warn("bad option -%c", *s);
status = 1;
goto endfor;
}
endfor: continue;
}
}
if (status == 1)
fatal("usage: ppd [-1adlmnpqrt] [-T typexpr] [pdirname ...]");
if (argc < 1)
{
if ((cwp = getcwp()) == NULL)
fatal("no project environment");
status |= listproject("", cwp);
exit(status);
}
pdlist = slsinit();
plist = slsinit();
qsort((char *) argv, argc, sizeof(char *), strpcmp);
for (; argc > 0; argc--, argv++)
if (readpath(*argv, &pathbuf) == -1)
{
patherr(*argv);
status = 1;
}
else switch (pathbuf.p_mode & P_IFMT)
{
case P_IFNEW:
case P_IFREG:
warn("%s: no such project or project directory", *argv);
status = 1;
break;
case P_IFHOME:
case P_IFPROOT:
if (LIST_PLD_CONTENTS == YES)
{
if (slsappend(*argv, pathbuf.p_path,
plist) == NULL)
exit(1);
}
else {
status |= pdtolist(*argv, &pathbuf, pdlist);
}
break;
case P_IFPDIR:
status |= pdtolist(*argv, &pathbuf, pdlist);
break;
}
/* don't bother to print heading if single project request */
if (RECURSIVE == 0 && SLSNUM(pdlist) == 0 && SLSNUM(plist) == 1)
PRINT_HEADING = NO;
/* print discrete project directories */
printlist("", pdlist);
slsrm(CNULL, pdlist);
/* print projects */
for (pblk = plist->head; pblk != NULL; pblk = pblk->next)
status |= listproject(pblk->key, pblk->string);
exit(status);
}
/*
* getpdesc() gets a project description. Returns constant 1 if error,
* otherwise 0.
*/
getpdesc(desc, pathname)
char *desc; /* description receiving buffer */
char *pathname; /* project link directory pathname */
{
char *pbgetstring(); /* get specified string field */
int closepdb(); /* close database */
int errpdb(); /* print database error message */
int pfndent(); /* find and load database entry */
PDB *pldp; /* project link directory stream */
PDB *openpdb(); /* open database */
*desc = '\0';
if ((pldp = openpdb(PLDNAME, pathname, "r")) == NULL)
return(errpdb((PDB *) NULL));
if (pfndent(CURPROJECT, pldp) == YES)
pbgetstring(PDIRDESC, desc);
return(closepdb(pldp));
}
/*
* getptype() gets project root directory types. Returns constant 1 if error,
* otherwise 0.
*/
getptype(type, pathname)
char *type; /* type receiving buffer */
char *pathname; /* project link directory pathname */
{
char *pbgetstring(); /* get specified string field */
int closepdb(); /* close database */
int errpdb(); /* print database error message */
int pfndent(); /* find and load database entry */
PDB *pldp; /* project link directory stream */
PDB *openpdb(); /* open database */
*type = '\0';
if ((pldp = openpdb(PLDNAME, pathname, "r")) == NULL)
return(errpdb((PDB *) NULL));
if (pfndent(CURPROJECT, pldp) == YES)
pbgetstring(PDIRTYPE, type);
return(closepdb(pldp));
}
/*
* ksprint() prints a list of key+string pairs (one pair per line).
*/
void
ksprint(colwidth, pdlist)
int colwidth; /* maximum column width */
SLSLIST *pdlist; /* project directory list */
{
register char *kp; /* key pointer */
register char *tp; /* type label pointer */
register int cw; /* column width */
SLSBLK *curblk; /* current list block */
for (curblk = pdlist->head; curblk != NULL; curblk = curblk->next)
{
for (cw=colwidth, kp=curblk->key; *kp != '\0' && cw-- > 0; kp++)
putchar(*kp);
if (cw > 0 && *curblk->string != '\0')
for(; cw > 0; cw -= TABSIZE)
putchar('\t');
if (INFORMATION == TYPE_LABEL_INFO)
{
for (tp = curblk->string; *tp != '\0'; tp++)
if (*tp == _PDTSC)
{
putchar(',');
putchar(' ');
}
else {
putchar(*tp);
}
putchar('\n');
}
else {
puts(curblk->string);
}
}
}
/*
* listproject() lists a project link directory.
*/
listproject(ppathname, pathname)
char *ppathname; /* project pathname */
char *pathname; /* regular pathname */
{
register char *alias; /* alias buffer pointer */
register char *path; /* path buffer pointer */
char aliasbuf[ALIASSIZE+1]; /* alias marking buffer */
char descbuf[DIRDESCSIZE]; /* project root directory description */
char *kp; /* key pointer */
char pathbuf[PATHSIZE+1]; /* regular pathname marking buffer */
char ppathbuf[PPATHSIZE]; /* project path concatenation buffer */
char *ppathcat(); /* project pathname concatenation */
char *slsappend(); /* append key+string */
char *strcat(); /* string concatenation */
char *strcpy(); /* string copy */
char typebuf[TYPBUFSIZE]; /* project root directory types */
int closepdb(); /* close database */
int errpdb(); /* print database error message */
int getpdesc(); /* get project description */
int getptype(); /* get project root directory types */
int pdtmatch(); /* match project dir type label expr */
int slssort(); /* sort key+string list */
int status = 0; /* return status */
int strcmp(); /* string comparison */
PATH *pd; /* pathname struct pointer */
PATH *readpld(); /* read project link directory entry */
PDB *openpdb(); /* open database */
PDB *pldp; /* project link directory stream */
SLSBLK *pblk; /* project list block */
SLSLIST *pdlist; /* project directory list */
SLSLIST *plist; /* project list */
SLSLIST *slsinit(); /* initialize key+string list */
void printlist(); /* print project directory list */
void slsrm(); /* remove key+string list */
pdlist = slsinit();
plist = slsinit();
/* read PLDNAME project link directory */
if ((pldp = openpdb(PLDNAME, pathname, "r")) == NULL)
return(errpdb((PDB *) NULL));
while ((pd = readpld(pldp)) != NULL)
{
alias = pd->p_alias;
path = pd->p_path;
if (EQUAL(alias, PARENTPROJECT))
{
if (LIST_ALL_ENTRIES == NO)
continue;
}
else if (EQUAL(alias, CURPROJECT))
{
if (PDIRTYP.pfxsize == 0 && LIST_ALL_ENTRIES == NO)
continue;
}
else if (RECURSIVE && pd->p_mode == P_IFPROOT)
if (slsappend(alias, path, plist) == NULL)
exit(1);
if (PDIRTYP.pfxsize != 0 && pdtmatch(&PDIRTYP,pd->p_type) == NO)
continue;
if (MARK_PROJECT_ROOT)
if (pd->p_mode == P_IFPROOT)
if (INFORMATION == ABSOLUTE_PATH_INFO)
{
path = strcpy(pathbuf, path);
strcat(path, ROOTPROJECT);
}
else {
alias = strcpy(aliasbuf, alias);
strcat(alias, ROOTPROJECT);
}
switch (INFORMATION)
{
case REGULAR_INFO:
kp = slsappend(alias, "", pdlist);
break;
case ABSOLUTE_PATH_INFO:
kp = slsappend(path, "", pdlist);
break;
case ALIAS_INFO:
kp = slsappend(alias, path, pdlist);
break;
case TYPE_LABEL_INFO:
if (pd->p_mode == P_IFPDIR)
{
kp=slsappend(alias, pd->p_type, pdlist);
}
else {
status |= getptype(typebuf, path);
kp=slsappend(alias, typebuf, pdlist);
}
break;
case DESCRIPTION_INFO:
if (pd->p_mode == P_IFPDIR)
{
kp=slsappend(alias, pd->p_desc, pdlist);
}
else {
status |= getpdesc(descbuf, path);
kp=slsappend(alias, descbuf, pdlist);
}
break;
}
if (kp == NULL)
exit(1);
}
status |= closepdb(pldp);
/* sort and print project directories */
if (slssort(strcmp, pdlist) == NO)
exit(1);
printlist(ppathname, pdlist);
slsrm(CNULL, pdlist);
/* if RECURSIVE, list subprojects */
if (RECURSIVE)
{
if (slssort(strcmp, plist) == NO)
exit(1);
for (pblk = plist->head; pblk != NULL; pblk = pblk->next)
{
ppathcat(ppathbuf, ppathname, pblk->key);
status |= listproject(ppathbuf, pblk->string);
}
}
slsrm(CNULL, plist);
return(status);
}
/*
* pdtolist() adds project (root) directories to pdlist. Returns
* constant 1 if error, otherwise 0.
*/
pdtolist(ppathname, pb, pdlist)
char *ppathname; /* project pathname */
PATH *pb; /* pathname struct buffer */
SLSLIST *pdlist; /* project directory list */
{
char *kp; /* key pointer */
char *slsappend(); /* append key+string */
char *strcat(); /* string concatenation */
int status = 0; /* return status */
unsigned long pathtyp; /* type of pathname */
pathtyp = pb->p_mode & P_IFMT;
if (MARK_PROJECT_ROOT)
if (pathtyp == P_IFHOME || pathtyp == P_IFPROOT)
if (INFORMATION == ABSOLUTE_PATH_INFO)
strcat(pb->p_path, ROOTPROJECT);
else
strcat(ppathname, ROOTPROJECT);
switch (INFORMATION)
{
case REGULAR_INFO:
kp = slsappend(ppathname, "", pdlist);
break;
case ABSOLUTE_PATH_INFO:
kp = slsappend(pb->p_path, "", pdlist);
break;
case ALIAS_INFO:
kp = slsappend(ppathname, pb->p_path, pdlist);
break;
case TYPE_LABEL_INFO:
kp = slsappend(ppathname, pb->p_type, pdlist);
break;
case DESCRIPTION_INFO:
kp = slsappend(ppathname, pb->p_desc, pdlist);
break;
}
if (kp == NULL)
exit(1);
return(status);
}
/*
* printlist() prints out a list of project directories.
*/
void
printlist(ppathname, pdlist)
char *ppathname; /* project pathname */
SLSLIST *pdlist; /* project directory list */
{
static int have_printed; /* has printing already been done? */
int colwidth; /* maximum column width */
int ncol; /* number of columns */
void ksprint(); /* print list of key+string pairs */
void slsprint(); /* print key+string list (key only) */
colwidth = pdlist->maxkey + MINIMUM_GAP;
if (colwidth % TABSIZE) colwidth = TABSIZE * (colwidth/TABSIZE + 1);
if (*ppathname != '\0' && PRINT_HEADING == YES)
printf((have_printed) ? "\n%s:\n" : "%s:\n", ppathname);
if (INFORMATION == REGULAR_INFO || INFORMATION == ABSOLUTE_PATH_INFO)
if (ONE_ENTRY_PER_LINE)
slsprint(1, colwidth, YES, stdout, pdlist);
else {
ncol = MAXLINE / colwidth;
slsprint(ncol, colwidth, YES, stdout, pdlist);
}
else
ksprint(colwidth, pdlist);
if (SLSNUM(pdlist) > 0)
have_printed = 1;
}
/*
* strpcmp() compares strings stored in a pointer array. Returns whatever
* strcmp() returns.
*/
strpcmp(p1, p2)
char **p1, **p2; /* string pointers */
{
int strcmp(); /* string comparison */
return(strcmp(*p1, *p2));
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.