1: /* $Header$ */
   2: 
   3: /*
   4:  * Author: Peter J. Nicklin
   5:  */
   6: 
   7: /*
   8:  * xppath() expands project pathname ppathname into regular pathname. Both
   9:  * the pathname type labels and description are ignored for efficiency.
  10:  * Returns -1 on error, otherwise zero.
  11:  */
  12: #include <pwd.h>
  13: #include <stdio.h>
  14: #include <sys/types.h>
  15: #include <sys/stat.h>
  16: #include "null.h"
  17: #include "path.h"
  18: #include "pdb.h"
  19: #include "pld.h"
  20: #include "system.h"
  21: #include "yesno.h"
  22: /*
  23:  * pathname states
  24:  */
  25: #define START   0001
  26: #define HDIR    0002
  27: #define PDIR1   0004
  28: #define PDIR2   0010
  29: #define DIR1    0020
  30: #define DIR2    0040
  31: #define EOP 0100
  32: #define ERROR   0200
  33: /*
  34:  * pathname errors
  35:  */
  36: #define E_UNKNOWN   0
  37: #define E_SYNTAX    1
  38: #define E_NOTPDIR   2
  39: #define E_NOTDIR    3
  40: 
  41: extern int errno;
  42: extern int sys_nerr;
  43: extern char *sys_errlist[];
  44: extern char PDBERR[];           /* project link dir error message */
  45: 
  46: static char *pp;            /* project pathname pointer */
  47: static char *perrlist[] =
  48:     {
  49:     "unknown error",
  50:     "pathname syntax error",
  51:     "no such project directory",
  52:     "no such file, directory, or project",
  53:     };
  54: 
  55: char *PATHERR;              /* current pathname error condition */
  56: int PPDEBUG = NO;           /* project pathname debug flag */
  57: 
  58: xppath(ppathname, pb)
  59:     char *ppathname;        /* project pathname */
  60:     register PATH *pb;      /* pathname struct pointer */
  61: {
  62:     register char *p;       /* regular pathname pointer */
  63:     register short pstat;       /* pathname state */
  64:     char *getcwp();         /* get current project pathname */
  65:     char *gethdir();        /* get home directory pathname */
  66:     char *hdir;         /* home directory pointer */
  67:     char *mkalias();        /* construct alias from pathname */
  68:     char *optpath();        /* optimize pathname */
  69:     char *pathcat();        /* pathname concatenation */
  70:     char *pbgetstring();        /* get specified string field */
  71:     char *pdir;         /* project directory pathname */
  72:     char pplex();           /* pathname lexical analyzer */
  73:     char *strcpy();         /* string copy */
  74:     char *strpcpy();        /* copy string to pathname */
  75:     char token[PATHSIZE];       /* receiving token */
  76:     int closepdb();         /* close database */
  77:     int pbfndflag();        /* find flag field */
  78:     int pfndent();          /* find and load database entry */
  79:     int strlen();           /* string length */
  80:     PDB *openpdb();         /* open database */
  81:     PDB *pdbp;          /* database stream */
  82:     struct passwd *getpwdir();  /* get password file entry for dir */
  83:     struct stat stbuf;      /* file state buffer */
  84: 
  85:     PATHERR = perrlist[E_UNKNOWN];
  86:     pstat = START;
  87:     pp = ppathname;
  88:     pb->p_mode = P_IFREG;
  89:     pb->p_alias = optpath(strcpy(pb->p_buf, mkalias(ppathname)));
  90:     p = pb->p_path = pb->p_buf + strlen(pb->p_buf) + 1;
  91:     *pb->p_project = '\0';
  92: 
  93:     while (pstat != EOP)
  94:         {
  95:         switch (pplex(token))
  96:             {
  97:             case _HDIRC:    /* user's home directory */
  98:                 if (pstat == START)
  99:                     {
 100:                     if ((hdir = gethdir(token+1)) != NULL)
 101:                         {
 102:                         p = strpcpy(p, hdir);
 103:                         strcpy(pb->p_project, pb->p_path);
 104:                         pb->p_mode = P_IFHOME;
 105:                         pstat = HDIR;
 106:                         break;
 107:                         }
 108:                     }
 109:                 PATHERR = perrlist[E_SYNTAX];
 110:                 pstat = ERROR;
 111:                 break;
 112:             case _PPSC: /* project pathname separator char */
 113:                 if ((pstat&(START|HDIR|PDIR2)) == 0)
 114:                     {
 115:                     if ((pstat&DIR1) != 0)
 116:                         PATHERR = perrlist[E_SYNTAX];
 117:                     else
 118:                         PATHERR = perrlist[E_NOTDIR];
 119:                     pstat = ERROR;
 120:                     break;
 121:                     }
 122:                 if (pstat == START)
 123:                     {
 124:                     pb->p_mode = P_IFHOME;
 125:                     p = strpcpy(p, gethdir((char *) NULL));
 126:                     strcpy(pb->p_project, pb->p_path);
 127:                     }
 128:                 p = strpcpy(p, PATHSEP);
 129:                 pstat = PDIR1;
 130:                 break;
 131:             case _PSC:  /* pathname separator character */
 132:                 if ((pstat&(START|HDIR|PDIR2|DIR2)) == 0)
 133:                     {
 134:                     PATHERR = perrlist[E_SYNTAX];
 135:                     pstat = ERROR;
 136:                     break;
 137:                     }
 138:                 if (pstat == START && (pdir = getcwp()) != NULL)
 139:                     strcpy(pb->p_project, pdir);
 140:                 p = strpcpy(p, PATHSEP);
 141:                 pstat = DIR1;
 142:                 break;
 143:             case '\0':
 144:                 *p = '\0';
 145:                 pstat = EOP;
 146:                 break;
 147:             default:
 148:                 /* project dir, regular dir, or file */
 149:                 if ((pstat&(START|PDIR1|DIR1)) == 0)
 150:                     {
 151:                     PATHERR = perrlist[E_SYNTAX];
 152:                     pstat = ERROR;
 153:                     break;
 154:                     }
 155:                 if (pstat == DIR1)
 156:                     {
 157:             regdir:     p = strpcpy(p, token);
 158:                     pb->p_mode = P_IFREG;
 159:                     pstat = DIR2;
 160:                     break;
 161:                     }
 162:                 /* initialize pathname */
 163:                 if (pstat == START)
 164:                     {
 165:                     if ((pdir = getcwp()) == NULL)
 166:                         goto regdir;
 167:                     strcpy(pb->p_project, pdir);
 168:                     }
 169:                 else    {
 170:                     pdir = pb->p_path;
 171:                     }
 172:                 if ((pdbp = openpdb(PLDNAME, pdir, "r")) == NULL)
 173:                     {
 174:                     PATHERR = PDBERR;
 175:                     pstat = ERROR;
 176:                     break;
 177:                     }
 178:                 /* project directory? */
 179:                 if (pfndent(token, pdbp) == NO)
 180:                     {
 181:                     closepdb(pdbp);
 182:                     if ((pstat&PDIR1) != 0)
 183:                         {/* project dir must follow ^ */
 184:                         PATHERR = perrlist[E_NOTPDIR];
 185:                         pstat = ERROR;
 186:                         break;
 187:                         }
 188:                     goto regdir;
 189:                     }
 190:                 if (pstat == START)
 191:                     {
 192:                     p = strpcpy(p, pdir);
 193:                     p = strpcpy(p, PATHSEP);
 194:                     }
 195:                 if (pbfndflag(PROOTDIR) == YES)
 196:                     {
 197:                     pb->p_mode = P_IFPROOT;
 198:                     pstat = PDIR2;
 199:                     }
 200:                 else    {
 201:                     pb->p_mode = P_IFPDIR;
 202:                     pstat = DIR2;
 203:                     }
 204:                 /* is new pathname absolute? */
 205:                 if (*pbgetstring(PDIRPATH, p) == _RDIRC)
 206:                     p = strpcpy(pb->p_path, p);
 207:                 else while (*p != '\0') p++;
 208:                 closepdb(pdbp);
 209:                 if (pb->p_mode == P_IFPROOT)
 210:                     strcpy(pb->p_project, pb->p_path);
 211:                 break;
 212:             }
 213:         if (pstat == ERROR)
 214:             {
 215:             *p = '\0';
 216:             break;
 217:             }
 218:         }
 219:     if (pstat != ERROR)
 220:         {
 221:         optpath(pb->p_path);
 222:         optpath(pb->p_project);
 223:         if (stat(pb->p_path, &stbuf) == 0)
 224:             {
 225:             /*
 226: 			 * a regular dir may be a root project directory
 227: 			 * specified as ~user, but expanded by the shell.
 228: 			 */
 229:             if (pb->p_mode == P_IFREG &&
 230:                (stbuf.st_mode&S_IFMT) == S_IFDIR)
 231:                 {
 232:                 char pathbuf[PATHSIZE];
 233: 
 234:                 pathcat(pathbuf, pb->p_path, PLDNAME);
 235:                 if (FILEXIST(pathbuf) &&
 236:                     getpwdir(pb->p_path) != NULL)
 237:                     {
 238:                     strcpy(pb->p_project, pb->p_path);
 239:                     pb->p_mode = P_IFHOME;
 240:                     }
 241:                 }
 242:             pb->p_mode |= (unsigned long) stbuf.st_mode;
 243:             }
 244:         else    {
 245:             if(errno < sys_nerr)
 246:                 PATHERR = sys_errlist[errno];
 247:             if (pb->p_mode == P_IFREG)
 248:                 pb->p_mode = P_IFNEW;
 249:             else    {   /* a project directory must exist */
 250:                 pstat = ERROR;
 251:                 }
 252:             }
 253:         pb->p_type = pb->p_path + strlen(pb->p_path) + 1;
 254:         pb->p_desc = pb->p_type + 1;
 255:         *pb->p_type = *pb->p_desc = '\0';
 256:         }
 257:     if (PPDEBUG == YES)
 258:         warn("%s --> %s", ppathname, pb->p_path);
 259:     return((pstat == ERROR) ? -1 : 0);
 260: }
 261: 
 262: 
 263: 
 264: /*
 265:  * pplex() gets next token. Returns first character of token.
 266:  */
 267: static char
 268: pplex(token)
 269:     register char *token;       /* receiving token */
 270: {
 271:     register char *rpp;     /* project pathname pointer */
 272:     char t;             /* 1st token character */
 273: 
 274:     rpp = pp;
 275:     t = *rpp;
 276:     switch (t)
 277:         {
 278:         case _PPSC:
 279:             *token++ = *rpp++;
 280:             while (*rpp == _PPSC) rpp++;
 281:             break;
 282:         case _PSC:
 283:             *token++ = *rpp++;
 284:             while (*rpp == _PSC) rpp++;
 285:             break;
 286:         case '\0':
 287:             break;
 288:         default:
 289:             while (*rpp != _PPSC && *rpp != _PSC && *rpp != '\0')
 290:                 *token++ = *rpp++;
 291:             break;
 292:         }
 293:     *token = '\0';
 294:     pp = rpp;
 295:     return(t);
 296: }
 297: 
 298: 
 299: 
 300: /*
 301:  * patherr() prints the error message PATHERR to stderr stream and
 302:  * returns constant 1.
 303:  */
 304: patherr(mesg)
 305:     char *mesg;         /* error message */
 306: {
 307:     int strlen();           /* string length */
 308: 
 309:     if (strlen(mesg) > 0)
 310:         warn("%s: %s", mesg, PATHERR);
 311:     else
 312:         warn("%s", PATHERR);
 313:     return(1);
 314: }

Defined functions

patherr defined in line 304; used 1 times
pplex defined in line 267; used 2 times

Defined variables

PATHERR defined in line 55; used 13 times
PPDEBUG defined in line 56; used 1 times
perrlist defined in line 47; used 7 times
pp defined in line 46; used 3 times

Defined macros

DIR1 defined in line 29; used 4 times
DIR2 defined in line 30; used 3 times
EOP defined in line 31; used 2 times
ERROR defined in line 32; used 10 times
E_NOTDIR defined in line 39; used 1 times
E_NOTPDIR defined in line 38; used 1 times
E_SYNTAX defined in line 37; used 4 times
E_UNKNOWN defined in line 36; used 1 times
  • in line 85
HDIR defined in line 26; used 3 times
PDIR1 defined in line 27; used 3 times
PDIR2 defined in line 28; used 3 times
START defined in line 25; used 9 times
Last modified: 1985-07-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1309
Valid CSS Valid XHTML 1.0 Strict