shapetools-1.4pl6.orig/ 40755 2013 145 0 6574031372 13054 5ustar dokoswtshapetools-1.4pl6.orig/src/ 40755 2013 145 0 5626416561 13647 5ustar dokoswtshapetools-1.4pl6.orig/src/atfs/ 40755 2013 145 0 5626415707 14605 5ustar dokoswtshapetools-1.4pl6.orig/src/atfs/afarchive.c100444 2013 145 107702 5614752357 17045 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afarchive.c -- read/write archives of attribute filesystem * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afarchive.c[7.1] Thu Aug 4 16:02:46 1994 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "afarchive.h" extern int af_errno; extern int nameConflict; EXPORT int af_suppressUdas = FALSE; LOCAL short arVersion; /*========================================================================== * afFirstItem, afNextItem -- isolate items in input line *==========================================================================*/ EXPORT char *afFirstItem (line) char *line; { register char *sptr; /* skip leading blank */ if ((sptr = strchr (&line[1], ' ')) == NULL) sptr = strchr (&line[1], '\n'); *sptr = '\0'; return (&line[1]); } EXPORT char *afNextItem (line) char *line; { register char *sptr, *finptr; sptr = &line[strlen(line)]+1; /* move to next entry */ if ((finptr = strchr (sptr, ' ')) == NULL) finptr = strchr (sptr, '\n'); *finptr = '\0'; return (sptr); } /*======================= rddata ====================================*/ LOCAL int af_rddata (file, dbuf, list) FILE *file; char *dbuf; Af_revlist *list; { register char *itemptr; char idstr[AF_IDSTRLEN+1], line[AF_LINESIZ]; register int i, maxindex; int gen, rev; register size_t size, dpos = 0; /* if there is a valid busy version */ if (list->af_list[0].af_class & AF_VALID) maxindex = list->af_nrevs; else maxindex = list->af_nrevs+1; idstr[AF_IDSTRLEN] = '\0'; /* skip busy version */ for (i=1; i < maxindex; i++) { fgets (idstr, AF_IDSTRLEN+1, file); if (strcmp (idstr, AF_NOTEID)) FATAL ("rddata", "wrong note-ID in datafile", AF_EINCONSIST, ERROR); fgets (line, AF_LINESIZ, file); itemptr = afFirstItem (line); gen = atoi (itemptr); itemptr = afNextItem (itemptr); rev = atoi (itemptr); itemptr = afNextItem (itemptr); size = (size_t) atoi (itemptr); if ((list->af_list[i].af_gen != gen) || (list->af_list[i].af_rev != rev)) FATAL ("rddata", "wrong version in datafile", AF_EINCONSIST, ERROR); /* read note */ list->af_list[i].af_notesize = size; if (size > 0) { fread (&(dbuf[dpos]), sizeof(char), (size_t) size, file); list->af_list[i].af_note = &(dbuf[dpos]); /* replace newline by nullbyte */ list->af_list[i].af_note[size-sizeof(char)] = '\0'; dpos = dpos+size; } else { /* skip newline */ fread (&(dbuf[dpos]), sizeof(char), (size_t) 1, file); list->af_list[i].af_note = NULL; } fgets (idstr, AF_IDSTRLEN+1, file); if (strcmp (idstr, AF_DATAID)) FATAL ("rddata", "wrong data-ID in datafile", AF_EINCONSIST, ERROR); fgets (line, AF_LINESIZ, file); itemptr = afFirstItem (line); gen = atoi (itemptr); itemptr = afNextItem (itemptr); rev = atoi (itemptr); itemptr = afNextItem (itemptr); itemptr = afNextItem (itemptr); size = (size_t) atoi (itemptr); if ((list->af_list[i].af_gen != gen) || (list->af_list[i].af_rev != rev)) FATAL ("rddata", "wrong version in datafile", AF_EINCONSIST, ERROR); /* read data */ if (size > 0) { fread (&(dbuf[dpos]), sizeof(char), (size_t) size, file); list->af_list[i].af_data = &(dbuf[dpos]); dpos = dpos+size; } else { list->af_list[i].af_data = NULL; } } return (AF_OK); } /* af_rddata */ /*========================================================================== * afReadData -- read notes and data section of archive file *==========================================================================*/ EXPORT int afReadData (list) Af_revlist *list; { register char *data; char idstr[AF_SEGSTRLEN+1], *archiveName, line[AF_LINESIZ]; register FILE *attrArchFile, *dataArchFile; /* if data are already loaded */ if ((list->af_extent & AF_DATA) == AF_DATA) return (AF_OK); /* set lock on old attr archive file -- tmp attr archive file *is* still locked */ archiveName = afArchiveName (list->af_arpath, AF_ATTRDIR, list->af_cattrs.af_globname, list->af_cattrs.af_globtype, AF_READ); if ((attrArchFile = afOpenLock (archiveName, AF_READ, list)) == NULL) return (ERROR); archiveName = afArchiveName (list->af_arpath, AF_DATADIR, list->af_cattrs.af_globname, list->af_cattrs.af_globtype, AF_READ); if ((dataArchFile = fopen (archiveName, "r")) == NULL) { afCloseUnlock (attrArchFile, AF_READ, list); FATAL ("ReadData", "", AF_ENOATFSFILE, ERROR); } idstr[AF_SEGSTRLEN] = '\0'; fgets (idstr, AF_SEGSTRLEN+1, dataArchFile); if (strncmp (idstr, AF_DATAHEADER, AF_SEGSTRLEN)) { fclose (dataArchFile); afCloseUnlock (attrArchFile, AF_READ, list); FATAL ("ReadData", "wrong header in datafile", AF_EINCONSIST, ERROR); } fgets (line, AF_LINESIZ, dataArchFile); arVersion = atoi (line); if (arVersion != AF_ARCURVERS) { fclose (dataArchFile); afCloseUnlock (attrArchFile, AF_READ, list); FATAL ("ReadData", "unknown archive format version", AF_EINCONSIST, ERROR); } /* if there are data */ if (list->af_datasize) { /* allocate memory for data */ if ((data = af_malloc (list, (unsigned) list->af_datasize * sizeof (char))) == NULL) { fclose (dataArchFile); afCloseUnlock (attrArchFile, AF_READ, list); return (ERROR); } if (af_rddata (dataArchFile, data, list) != AF_OK) { fclose (dataArchFile); afCloseUnlock (attrArchFile, AF_READ, list); return (ERROR); } } list->af_extent |= AF_DATA; fclose (dataArchFile); afCloseUnlock (attrArchFile, AF_READ, list); return (AF_OK); } /*======================= rdattrs ====================================*/ LOCAL int af_rdattrs (file, list, bibufptr) FILE *file; Af_revlist *list; struct stat *bibufptr; { register char *itemptr; char idstr[AF_IDSTRLEN+1], line[AF_LINESIZ]; register int i; int tmpMode; bool writeok; Af_user *user, *owner; /* skip idstring */ idstr[AF_IDSTRLEN] = '\0'; fgets (idstr, AF_IDSTRLEN+1, file); /* read constant attributes of busy version */ fgets (line, AF_LINESIZ, file); itemptr = afFirstItem (line); /* host - ignored ... */ itemptr = afNextItem (itemptr); /* path - ignored ... */ /* skip name and type */ itemptr = afNextItem (itemptr); /* name - ignored ... */ itemptr = afNextItem (itemptr); /* type - ignored ... */ itemptr = afNextItem (itemptr); /* variant (ignored) */ /* get owner of archive directory */ if ((owner = afArchiveOwner (list->af_arpath, &writeok, &list->af_owngid)) == NULL) FATAL ("rdattrs", "cannot get owner of archive", AF_EINTERNAL, ERROR); list->af_cattrs.af_ownname = af_entersym (owner->af_username); list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost); list->af_cattrs.af_owndomain = af_enterdomain (owner->af_userdomain); if (writeok) list->af_extent |= AF_UXWRITE; /* read owner from archive */ fgets (idstr, AF_IDSTRLEN+1, file); fgets (line, AF_LINESIZ, file); /* name, host and domain of owner */ /* plausibility of owner should be checked here */ fgets (idstr, AF_IDSTRLEN+1, file); fgets (line, AF_LINESIZ, file); /* predecessor of busy object */ itemptr = afFirstItem (line); list->af_list[0].af_predgen = atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[0].af_predrev = atoi (itemptr); fgets (idstr, AF_IDSTRLEN+1, file); fgets (line, AF_LINESIZ, file); /* locker */ itemptr = afFirstItem (line); if (strcmp (itemptr, AF_NOSTRING)) { list->af_list[0].af_lckname = af_entersym (itemptr); itemptr = afNextItem (itemptr); list->af_list[0].af_lckhost = af_enterhost (itemptr); itemptr = afNextItem (itemptr); list->af_list[0].af_lckdomain = af_enterdomain (itemptr); } else { list->af_list[0].af_lckname = NULL; itemptr = afNextItem (itemptr); list->af_list[0].af_lckhost = NULL; itemptr = afNextItem (itemptr); list->af_list[0].af_lckdomain = NULL; } itemptr = afNextItem (itemptr); list->af_list[0].af_ltime = (time_t)atoi(itemptr); /* initialize and attributes for busy version */ list->af_list[0].af_gen = AF_BUSYVERS; list->af_list[0].af_rev = AF_BUSYVERS; list->af_list[0].af_state = AF_BUSY; list->af_list[0].af_stime = AF_NOTIME; list->af_list[0].af_repr = AF_FILE; list->af_list[0].af_dsize = (size_t) 0; list->af_list[0].af_data = NULL; list->af_list[0].af_hashname = NULL; list->af_list[0].af_nrefs = 0; list->af_list[0].af_succgen = AF_NOVNUM; list->af_list[0].af_succrev = AF_NOVNUM; if (bibufptr->st_ino) { /* if there is a busy version */ list->af_list[0].af_class = AF_VALID; if ((user = af_afuser (bibufptr->st_uid)) == NULL) { af_wng ("rdattrs", "invalid userID in inode of busy file"); user = af_afuser ((uid_t) geteuid()); } list->af_list[0].af_auname = af_entersym (user->af_username); list->af_list[0].af_auhost = af_enterhost (user->af_userhost); list->af_list[0].af_audomain = af_enterdomain (user->af_userdomain); list->af_list[0].af_mode = bibufptr->st_mode; list->af_list[0].af_mtime = bibufptr->st_mtime; list->af_list[0].af_atime = bibufptr->st_atime; list->af_list[0].af_ctime = bibufptr->st_ctime; list->af_list[0].af_fsize = (size_t) bibufptr->st_size; } else { list->af_list[0].af_class = 0; list->af_list[0].af_auname = NULL; list->af_list[0].af_auhost = NULL; list->af_list[0].af_audomain = NULL; list->af_list[0].af_mode = AF_NOMODE; list->af_list[0].af_mtime = AF_NOTIME; list->af_list[0].af_atime = AF_NOTIME; list->af_list[0].af_ctime = AF_NOTIME; list->af_list[0].af_fsize = 0; } /* read list */ for (i=1; i < list->af_nrevs; i++) { /* do initializations */ list->af_list[i].af_class = AF_VALID; list->af_list[i].af_notesize = 0; list->af_list[i].af_note = NULL; list->af_list[i].af_data = NULL; list->af_list[0].af_nrefs = 0; list->af_list[i].af_hashname = NULL; /* enter name (set a pointer to the name-field of af_list[0]) */ /* skip position 0 */ if (i != 0) { list->af_list[i].af_name = list->af_list[0].af_name; list->af_list[i].af_type = list->af_list[0].af_type; } /* read revision ID */ fgets (idstr, AF_IDSTRLEN+1, file); if (strcmp (idstr, AF_REVID)) /* could be done for every field */ FATAL ("rdattrs", "wrong revision-ID in archive file", AF_EINCONSIST, ERROR); fgets (line, AF_LINESIZ, file); itemptr = afFirstItem (line); list->af_list[i].af_gen = atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_rev = atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_state = (short) atoi (itemptr); itemptr = afNextItem (itemptr); sscanf (itemptr, "%o", &tmpMode); list->af_list[i].af_mode = (mode_t) tmpMode; itemptr = afNextItem (itemptr); /* variant (ignored) */ /* read author*/ fgetc (file); /* skip tab */ fgets (idstr, AF_IDSTRLEN+1, file); fgets (line, AF_LINESIZ, file); /* predecessor of busy object */ itemptr = afFirstItem (line); list->af_list[i].af_auname = af_entersym (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_auhost = af_enterhost (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_audomain = af_enterdomain (itemptr); itemptr = afNextItem (itemptr); if (strcmp (itemptr, AF_NOSTRING)) { list->af_list[i].af_lckname = af_entersym (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_lckhost = af_enterhost (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_lckdomain = af_enterdomain (itemptr); } else { list->af_list[i].af_lckname = NULL; itemptr = afNextItem (itemptr); list->af_list[i].af_lckhost = NULL; itemptr = afNextItem (itemptr); list->af_list[i].af_lckdomain = NULL; } /* read dates */ fgetc (file); /* skip tab */ fgets (idstr, AF_IDSTRLEN+1, file); fgets (line, AF_LINESIZ, file); itemptr = afFirstItem (line); list->af_list[i].af_mtime = (time_t) atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_atime = (time_t) atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_ctime = (time_t) atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_stime = (time_t) atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_ltime = (time_t) atoi (itemptr); /* read kind of representation */ fgetc (file); /* skip tab */ fgets (idstr, AF_IDSTRLEN+1, file); fgets (line, AF_LINESIZ, file); itemptr = afFirstItem (line); list->af_list[i].af_repr = (short) atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_fsize = (size_t) atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_dsize = (size_t) atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_succgen = atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_succrev = atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_predgen = atoi (itemptr); itemptr = afNextItem (itemptr); list->af_list[i].af_predrev = atoi (itemptr); } if (!(bibufptr->st_ino)) /* if there is no busy version */ list->af_nrevs--; return (AF_OK); } /* af_rdattrs */ /*======================= rdudas ====================================*/ LOCAL int af_rdudas (file, list) FILE *file; Af_revlist *list; { char idstr[AF_IDSTRLEN+1], line[AF_LINESIZ]; register char *udabuf = NULL; char *itemptr; register int c, i, j, maxindex; int gen, rev; Af_key tmpkey; tmpkey.af_ldes = list; /* if there is a valid busy version */ if (list->af_list[0].af_class & AF_VALID) maxindex = list->af_nrevs; else maxindex = list->af_nrevs+1; getc (file); /* skip newline */ idstr[AF_IDSTRLEN] = '\0'; for (i=0; i < maxindex; i++) { fgets (idstr, AF_IDSTRLEN+1, file); if (strcmp (idstr, AF_UDAID)) FATAL ("rdudas", "wrong uda-ID in archive file", AF_EINCONSIST, ERROR); fgets (line, AF_LINESIZ, file); itemptr = afFirstItem (line); gen = atoi (itemptr); itemptr = afNextItem (itemptr); rev = atoi (itemptr); if ((list->af_list[i].af_gen != gen) || (list->af_list[i].af_rev != rev)) FATAL ("rdudas", "wrong version in archive file", AF_EINCONSIST, ERROR); /* build up hashlist and read user defined attributes */ tmpkey.af_lpos = i; afInitUdas (&tmpkey); if (i == 0) { /* initalize only once */ if ((udabuf = malloc ((unsigned) (AF_UDASEGSIZ * sizeof (char)))) == NULL) FAIL ("rdudas", "malloc", AF_ESYSERR, ERROR); } /* if there is *no* valid busy version, skip the user defined */ /* attributes for the busy version */ if ((i==0) && !(list->af_list[0].af_class & AF_VALID)) { while (TRUE) { if ((c = getc (file)) == '\0') { if ((c = getc (file)) == '\0') break; } } getc (file); /* skip trailing newline char */ continue; } j = 0; while (TRUE) { if ((udabuf[j] = getc (file)) == '\0') { if (j != 0) { tmpkey.af_lpos = i; afEnterUda (&tmpkey, udabuf); } /* a second nullbyte indicates the end of the list of udas */ if ((c = getc (file)) == '\0') break; udabuf[0] = c; j = 1; } else { j++; if ((j % AF_UDASEGSIZ) == 0) { /* if segment is full */ if ((udabuf = realloc (udabuf, (unsigned) ((j + AF_UDASEGSIZ) * sizeof (char)))) == NULL) FAIL ("rdudas", "realloc", AF_ESYSERR, ERROR); } } } getc (file); /* skip trailing newline char */ } free (udabuf); return (AF_OK); } /* af_rdudas */ /*========================================================================== * afReadAttrs -- read attributes from archive file *==========================================================================*/ EXPORT int afReadAttrs (list) Af_revlist *list; { char idstr[AF_SEGSTRLEN+1], line[AF_LINESIZ]; char *archiveName; register char *itemptr; register FILE *archfile; struct stat bibuf, aibuf; bool writeok; register Af_user *user, *owner; Af_key tmpkey; tmpkey.af_ldes = list; if (!list->af_arpath) { list->af_arpath = afArchivePath (list->af_cattrs.af_syspath); list->af_extent |= AF_ARCHIVE; } if ((list->af_cattrs.af_globtype == NULL) && (!strcmp (list->af_cattrs.af_globname, ".") || !strcmp (list->af_cattrs.af_globname, ".."))) archiveName = NULL; else archiveName = afArchiveName (list->af_arpath, AF_ATTRDIR, list->af_cattrs.af_globname, list->af_cattrs.af_globtype, AF_READ); /* if archive file has been modified */ if (stat (NOTNIL (archiveName), &aibuf) == -1) aibuf.st_mtime = (time_t) 0; if (list->af_lastmod != aibuf.st_mtime) { if (list->af_access > 0) { af_wng ("ReadAttrs", "archive file has changed"); list->af_access = 0; } afDetachList (list); /* invalidate data */ } /* if attributes are already loaded */ if ((list->af_extent & AF_ATTRS) == AF_ATTRS) { /* see if busy version has changed */ if (stat (list->af_busyfilename, &bibuf) == ERROR) { /* no busy version */ if (list->af_list[0].af_class & AF_VALID) { list->af_nrevs--; list->af_list[0].af_class &= ~AF_VALID; } } else { if (bibuf.st_ctime != list->af_list[0].af_ctime) { /* update busy version */ if (!(list->af_list[0].af_class & AF_VALID)) { list->af_nrevs++; tmpkey.af_lpos = 0; afInitUdas (&tmpkey); list->af_list[0].af_class = AF_VALID; } if ((user = af_afuser (bibuf.st_uid)) == NULL) { af_wng ("ReadAttrs", "invalid userID in inode of busy file"); user = af_afuser ((uid_t) geteuid()); } list->af_list[0].af_auname = af_entersym (user->af_username); list->af_list[0].af_auhost = af_enterhost (user->af_userhost); list->af_list[0].af_audomain = af_enterdomain (user->af_userdomain); list->af_list[0].af_mode = bibuf.st_mode; list->af_list[0].af_mtime = bibuf.st_mtime; list->af_list[0].af_atime = bibuf.st_atime; list->af_list[0].af_ctime = bibuf.st_ctime; list->af_list[0].af_fsize = (size_t) bibuf.st_size; } } return (AF_OK); } if (list->af_list) afDetachList (list); if (!list->af_busyfilename) { if ((list->af_busyfilename = af_gbusname (list->af_cattrs.af_syspath, list->af_cattrs.af_globname, list->af_cattrs.af_globtype)) == NULL) return (ERROR); } if (stat (list->af_busyfilename, &bibuf) == ERROR) bibuf.st_ino = 0; /* open archive with read lock */ if ((archiveName == NULL) || ((archfile = afOpenLock (archiveName, AF_READ, list)) == NULL)) { if (bibuf.st_ino == 0) /* no busy file */ { list->af_nrevs = 0; afDetachList (list); FAIL ("ReadAttrs", "", AF_ENOATFSFILE, ERROR); } list->af_nrevs = 1; list->af_listlen = AF_NEWREVS; list->af_extent |= AF_SEGMASK; list->af_datasize = 0; /* determine author of busy file */ if ((user = af_afuser (bibuf.st_uid)) == NULL) { af_wng ("ReadAttrs", "invalid userID in inode of busy file"); user = af_afuser ((uid_t)geteuid()); } /* if an archive-directory exists, get its owner */ if ((owner = afArchiveOwner (list->af_arpath, &writeok, &list->af_owngid)) == NULL) { list->af_cattrs.af_ownname = af_entersym (user->af_username); list->af_cattrs.af_ownhost = af_enterhost (user->af_userhost); list->af_cattrs.af_owndomain = af_enterdomain (user->af_userdomain); } else { list->af_cattrs.af_ownname = af_entersym (owner->af_username); list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost); list->af_cattrs.af_owndomain = af_enterdomain (owner->af_userdomain); } if (writeok) list->af_extent |= AF_UXWRITE; if ((list->af_list = (Af_vattrs *)af_malloc (list, (unsigned) (list->af_listlen * sizeof(Af_vattrs)))) == NULL) { return (ERROR); } memset ((char *)list->af_list, 0, list->af_listlen * sizeof (Af_vattrs)); /* init attrbuf for busy version (relevant attrs only) */ list->af_list[0].af_name = list->af_cattrs.af_globname; list->af_list[0].af_type = list->af_cattrs.af_globtype; list->af_list[0].af_gen = AF_BUSYVERS; list->af_list[0].af_rev = AF_BUSYVERS; list->af_list[0].af_state = AF_BUSY; list->af_list[0].af_class = AF_VALID; list->af_list[0].af_auname = af_entersym (user->af_username); list->af_list[0].af_auhost = af_enterhost (user->af_userhost); list->af_list[0].af_audomain = af_enterdomain (user->af_userdomain); list->af_list[0].af_mode = bibuf.st_mode; list->af_list[0].af_lckname = NULL; list->af_list[0].af_lckhost = NULL; list->af_list[0].af_lckdomain = NULL; list->af_list[0].af_mtime = bibuf.st_mtime; list->af_list[0].af_atime = bibuf.st_atime; list->af_list[0].af_ctime = bibuf.st_ctime; list->af_list[0].af_stime = AF_NOTIME; list->af_list[0].af_ltime = AF_NOTIME; list->af_list[0].af_notesize = 0; list->af_list[0].af_note = NULL; tmpkey.af_lpos = 0; afInitUdas (&tmpkey); list->af_list[0].af_repr = AF_FILE; list->af_list[0].af_fsize = (size_t) bibuf.st_size; list->af_list[0].af_dsize = 0; list->af_list[0].af_data = NULL; list->af_list[0].af_hashname = NULL; list->af_list[0].af_nrefs = 0; list->af_list[0].af_succgen = AF_NOVNUM; list->af_list[0].af_succrev = AF_NOVNUM; list->af_list[0].af_predgen = AF_NOVNUM; list->af_list[0].af_predrev = AF_NOVNUM; return (AF_OK); } /* record date of last modification */ list->af_lastmod = aibuf.st_mtime; /* archive file ? */ idstr[AF_SEGSTRLEN] = '\0'; fgets (idstr, AF_SEGSTRLEN+1, archfile); if (strncmp (idstr, AF_ARHEADER, AF_SEGSTRLEN)) { afCloseUnlock (archfile, AF_READ, list); FATAL ("ReadAttrs", "wrong header in archive file", AF_EINCONSIST, ERROR); } /* read header */ fgets (line, AF_LINESIZ, archfile); itemptr = afFirstItem (line); arVersion = atoi (itemptr); if (arVersion != AF_ARCURVERS) { afCloseUnlock (archfile, AF_READ, list); FATAL ("ReadAttrs", "unknown archive format version", AF_EINCONSIST, ERROR); } itemptr = afNextItem (itemptr); list->af_nrevs = atoi (itemptr); itemptr = afNextItem (itemptr); list->af_datasize = atoi (itemptr); /* alloc memory for revision list (plus space for new revs) */ list->af_listlen = list->af_nrevs + AF_NEWREVS; if ((list->af_list = (Af_vattrs *)af_malloc (list, (unsigned) (list->af_listlen * sizeof(Af_vattrs)))) == NULL) { afCloseUnlock (archfile, AF_READ, list); return (ERROR); } memset ((char *) list->af_list, 0, list->af_listlen * sizeof (Af_vattrs)); /* enter name and type */ list->af_list[0].af_name = list->af_cattrs.af_globname; list->af_list[0].af_type = list->af_cattrs.af_globtype; if (af_rdattrs (archfile, list, &bibuf) != AF_OK) { list->af_nrevs = 0; afDetachList (list); afCloseUnlock (archfile, AF_READ, list); return (ERROR); } if (!af_suppressUdas) { /* read id string for user defined attributes section*/ fgets (idstr, AF_SEGSTRLEN+1, archfile); if (strncmp (idstr, AF_UDASEG, AF_SEGSTRLEN)) { afCloseUnlock (archfile, AF_READ, list); FATAL ("ReadAttrs", "wrong udaseg-ID in archive file", AF_EINCONSIST,ERROR); } if (af_rdudas (archfile, list) != AF_OK) { list->af_nrevs = 0; afDetachList (list); afCloseUnlock (archfile, AF_READ, list); return (ERROR); } } list->af_extent |= AF_ATTRS; afCloseUnlock (archfile, AF_READ, list); return (AF_OK); } /* afReadAttrs */ /*========================================================================== * WriteArchive -- write archive file *==========================================================================*/ EXPORT int afWriteArchive (list) Af_revlist *list; { register int i, j, maxindex; register FILE *attrTmpFile, *dataTmpFile, *attrArchFile; int err; bool writeok; size_t siz; char *archiveName, *attrArchSym, *dataArchSym = NULL; char *attrTmpName, *dataTmpName = NULL, *ptrlist[AF_MAXUDAS+1], buf[BUFSIZ]; size_t datasize; Af_key tmpkey, *busyptr; Af_user *owner; struct stat ibuf; tmpkey.af_ldes = list; archiveName = afArchiveName (list->af_arpath, AF_ATTRDIR, list->af_cattrs.af_globname, list->af_cattrs.af_globtype, AF_WRITE); attrArchSym = af_entersym (archiveName); archiveName = afArchiveName (list->af_arpath, AF_DATADIR, list->af_cattrs.af_globname, list->af_cattrs.af_globtype, AF_WRITE); dataArchSym = af_entersym (archiveName); /* if AtFS directory was newly created by afArchiveName */ if ((owner = afArchiveOwner (list->af_arpath, &writeok, &list->af_owngid))) { list->af_cattrs.af_ownname = af_entersym (owner->af_username); list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost); list->af_cattrs.af_owndomain = af_enterdomain (owner->af_userdomain); if (writeok) list->af_extent |= AF_UXWRITE; } /* if all revisions have been removed */ if (list->af_nrevs == 0) { if ((attrArchFile = afOpenLock (attrArchSym, AF_WRITE, list)) == NULL) return (ERROR); disableSig (SIGINT); disableSig (SIGQUIT); unlink (attrArchSym); unlink (dataArchSym); enableSig(); afCloseUnlock (attrArchFile, AF_WRITE, list); return (AF_OK); } attrTmpName = af_gtmpname (list->af_arpath); af_regtmpfile (attrTmpName); /* open attrTmpFile */ if ((attrTmpFile = fopen (attrTmpName, "w")) == NULL) FAIL ("WriteArchive", "cannot open archive file for writing", AF_EMISC, ERROR); /* if there is no busy version - increase "nrevs" temporarily */ busyptr = af_gbuskey (list); if (!(VATTR(busyptr).af_class & AF_VALID)) list->af_nrevs++; /* write header */ fprintf (attrTmpFile, "%s %d %d %lu\n", AF_ARHEADER, AF_ARCURVERS, list->af_nrevs, list->af_datasize); /* write constant attributes */ fprintf (attrTmpFile, "%s %s %s %s %s %s\n", AF_NAMEID, list->af_cattrs.af_host, list->af_cattrs.af_syspath, list->af_list[0].af_name, NOTMT (list->af_list[0].af_type), AF_NOSTRING); /* former variant string */ /* write owner */ fprintf (attrTmpFile, "%s %s %s %s\n", AF_OWNID, list->af_cattrs.af_ownname, list->af_cattrs.af_ownhost, list->af_cattrs.af_owndomain); /* write predecessor and locker of busy version */ fprintf (attrTmpFile, "%s %d %d\n%s %s %s %s %ld\n", AF_PRDID, VATTR(busyptr).af_predgen, VATTR(busyptr).af_predrev, AF_LOCKID, NOTMT (VATTR(busyptr).af_lckname), NOTMT (VATTR(busyptr).af_lckhost), NOTMT (VATTR(busyptr).af_lckdomain), VATTR(busyptr).af_ltime); /* write list of version attributes */ maxindex = list->af_nrevs-1; for (i=1; i <= maxindex; i++) { /* skip deleted versions */ if (!(list->af_list[i].af_class & AF_VALID)) { if (++maxindex == list->af_listlen) { fclose (attrTmpFile); af_unregtmpfile (attrTmpName); unlink (attrTmpName); FATAL ("WriteArchive", "revision count", AF_EINCONSIST, ERROR); } continue; } /* write revision ID */ fprintf (attrTmpFile, "%s %d %d %d %o %s\n", AF_REVID, list->af_list[i].af_gen, list->af_list[i].af_rev, list->af_list[i].af_state, list->af_list[i].af_mode, AF_NOSTRING); /* former variant string */ /* write author */ fprintf (attrTmpFile, "\t%s %s %s %s %s %s %s\n", AF_AUTHORID, list->af_list[i].af_auname, list->af_list[i].af_auhost, list->af_list[i].af_audomain, NOTMT (list->af_list[i].af_lckname), NOTMT (list->af_list[i].af_lckhost), NOTMT (list->af_list[i].af_lckdomain)); /* write dates */ fprintf (attrTmpFile, "\t%s %ld %ld %ld %ld %ld\n", AF_DATEID, list->af_list[i].af_mtime, list->af_list[i].af_atime, list->af_list[i].af_ctime, list->af_list[i].af_stime, list->af_list[i].af_ltime); /* write kind of representation and tree connects */ fprintf (attrTmpFile, "\t%s %d %lu %lu %d %d %d %d\n", AF_REPRID, list->af_list[i].af_repr, list->af_list[i].af_fsize, list->af_list[i].af_dsize, list->af_list[i].af_succgen, list->af_list[i].af_succrev, list->af_list[i].af_predgen, list->af_list[i].af_predrev); } /* write user defined attributes */ fprintf (attrTmpFile, "%s\n", AF_UDASEG); maxindex = list->af_nrevs-1; for (i=0; i <= maxindex; i++) { /* skip deleted versions but not the busy version */ if (!(list->af_list[i].af_class & AF_VALID) && (list->af_list[i].af_state != AF_BUSY)) { maxindex++; continue; } fprintf (attrTmpFile, "%s %d %d\n", AF_UDAID, list->af_list[i].af_gen, list->af_list[i].af_rev); tmpkey.af_lpos = i; afListUdas (&tmpkey, ptrlist); j=0; while (ptrlist[j]) { fprintf (attrTmpFile, "%s%c", ptrlist[j++], '\0'); } if (j==0) /* if no user defined attribute has been written */ fputc ('\0', attrTmpFile); fputc ('\0', attrTmpFile); fputc ('\n', attrTmpFile); fflush (attrTmpFile); } if (fclose (attrTmpFile) < 0) { if (!(VATTR(busyptr).af_class & AF_VALID)) list->af_nrevs--; af_unregtmpfile (attrTmpName); unlink (attrTmpName); FAIL ("WriteArchive", "fclose", AF_ESYSERR, ERROR); } /* if data have been manipulated - write data file */ if ((list->af_extent & AF_DATA) == AF_DATA) { dataTmpName = af_gtmpname (list->af_arpath); af_regtmpfile (dataTmpName); /* open tmpfile for data */ if ((dataTmpFile = fopen (dataTmpName, "w")) == NULL) { if (!(VATTR(busyptr).af_class & AF_VALID)) list->af_nrevs--; af_unregtmpfile (attrTmpName); unlink (attrTmpName); FAIL ("WriteArchive", "fopen", AF_ESYSERR, ERROR); } /* write notes and data */ fprintf (dataTmpFile, "%s %d\n", AF_DATAHEADER, AF_ARCURVERS); maxindex = list->af_nrevs-1; for (i=1; i <= maxindex; i++) { /* skip deleted versions */ if (!(list->af_list[i].af_class & AF_VALID)) { maxindex++; continue; } fprintf (dataTmpFile, "%s %d %d %lu\n", AF_NOTEID, list->af_list[i].af_gen, list->af_list[i].af_rev, list->af_list[i].af_notesize); if (list->af_list[i].af_notesize > 1) { if (fwrite (list->af_list[i].af_note, sizeof(char), (size_t) list->af_list[i].af_notesize - sizeof(char), dataTmpFile) == 0) { if (!(VATTR(busyptr).af_class & AF_VALID)) list->af_nrevs--; fclose (dataTmpFile); af_unregtmpfile (dataTmpName); unlink (dataTmpName); af_unregtmpfile (attrTmpName); unlink (attrTmpName); FAIL ("WriteArchive", "fwrite", AF_ESYSERR, ERROR); } } fputc ('\n', dataTmpFile); if (list->af_list[i].af_repr == AF_CHUNK) datasize = list->af_list[i].af_fsize; else datasize = list->af_list[i].af_dsize; fprintf (dataTmpFile, "%s %d %d %d %lu\n", AF_DATAID, list->af_list[i].af_gen, list->af_list[i].af_rev, list->af_list[i].af_repr, datasize); if (datasize > 0) { if (fwrite (list->af_list[i].af_data, sizeof(char), (size_t) datasize, dataTmpFile) == 0) { if (!(VATTR(busyptr).af_class & AF_VALID)) list->af_nrevs--; fclose (dataTmpFile); af_unregtmpfile (dataTmpName); unlink (dataTmpName); af_unregtmpfile (attrTmpName); unlink (attrTmpName); FAIL ("WriteArchive", "fwrite", AF_ESYSERR, ERROR); } } } if (fclose (dataTmpFile) < 0) { if (!(VATTR(busyptr).af_class & AF_VALID)) list->af_nrevs--; af_unregtmpfile (dataTmpName); unlink (dataTmpName); FAIL ("WriteArchive", "fclose", AF_ESYSERR, ERROR); } } /* decrease "nrevs" again (see beginning of procedure */ if (!(VATTR(busyptr).af_class & AF_VALID)) list->af_nrevs--; /* check if temporary archive files can replace old archiche files */ /* -> if archive file was modified since last read */ if (stat (attrArchSym, &ibuf) == ERROR) { /* Ooops, lost it ? */ if (list->af_lastmod != (time_t) 0) { if ((list->af_extent & AF_DATA) == AF_DATA) { af_unregtmpfile (dataTmpName); unlink (dataTmpName); } af_unregtmpfile (attrTmpName); unlink (attrTmpName); FATAL ("WriteArchive", "archive file lost", AF_EINTERNAL, ERROR); } } else { /* if archive has changed since last read */ if (list->af_lastmod != ibuf.st_mtime) { if ((list->af_extent & AF_DATA) == AF_DATA) { af_unregtmpfile (dataTmpName); unlink (dataTmpName); } af_unregtmpfile (attrTmpName); unlink (attrTmpName); FAIL ("WriteArchive", "", AF_EARCHANGED, ERROR); } } if ((attrTmpFile = fopen (attrTmpName, "r")) == NULL) { if ((list->af_extent & AF_DATA) == AF_DATA) { af_unregtmpfile (dataTmpName); unlink (dataTmpName); } af_unregtmpfile (attrTmpName); unlink (attrTmpName); FATAL ("WriteArchive", "temporary archive file lost", AF_EINTERNAL, ERROR); } disableSig (SIGINT); disableSig (SIGQUIT); /* set lock on attr archive file and open (truncate) for writing */ if ((attrArchFile = afOpenLock (attrArchSym, AF_WRITE, list)) == NULL) { if ((list->af_extent & AF_DATA) == AF_DATA) { af_unregtmpfile (dataTmpName); unlink (dataTmpName); } af_unregtmpfile (attrTmpName); unlink (attrTmpName); return (ERROR); } /* attributes archive file is empty now ! */ /* copy contents of temporary file to archive file */ err = FALSE; while ((siz = fread (buf, sizeof(char), (size_t) BUFSIZ, attrTmpFile)) == BUFSIZ) { if (fwrite (buf, sizeof(char), (size_t) BUFSIZ, attrArchFile) != BUFSIZ) err = TRUE; } if ((fwrite (buf, sizeof(char), (size_t) siz, attrArchFile) != siz) || err) { char errMsg[PATH_MAX+256], *arBackupName; fclose (attrTmpFile); if ((list->af_extent & AF_DATA) == AF_DATA) { af_unregtmpfile (dataTmpName); unlink (dataTmpName); } /* preserve temporary file, as attributes file is empty yet */ arBackupName = af_entersym (afArchiveName (list->af_arpath, AF_ATTRBACKUPDIR, list->af_cattrs.af_globname, list->af_cattrs.af_globtype, AF_WRITE)); sprintf (errMsg, "Cannot write attributes archive file (fwrite failed) -- preserving temporary file as %s", arBackupName); unlink (arBackupName); if (link (attrTmpName, arBackupName) == ERROR) sprintf (errMsg, "Cannot write attributes archive file (fwrite failed) -- preserving temporary file as %s", attrTmpName); else unlink (attrTmpName); af_unregtmpfile (attrTmpName); enableSig(); FATAL ("WriteArchive", errMsg, AF_EMISC, ERROR); } fclose (attrTmpFile); af_unregtmpfile (attrTmpName); unlink (attrTmpName); /* if the data file has been written */ if ((list->af_extent & AF_DATA) == AF_DATA) { mode_t fileMode; af_unregtmpfile (dataTmpName); unlink (dataArchSym); if (link (dataTmpName, dataArchSym) == ERROR) { afCloseUnlock (attrArchFile, AF_WRITE, list); unlink (dataTmpName); enableSig(); FAIL ("WriteArchive", "link", AF_ESYSERR, ERROR); } chown (dataArchSym, geteuid(), list->af_owngid); if ((fileMode = afArchiveMode (list->af_arpath))) { fileMode &= ~(S_IXUSR|S_IXGRP|S_IXOTH|S_ISUID|S_ISGID); chmod (dataArchSym, fileMode); } unlink (dataTmpName); } enableSig(); afCloseUnlock (attrArchFile, AF_WRITE, list); /* update list descriptor */ if (stat (attrArchSym, &ibuf) != ERROR) list->af_lastmod = ibuf.st_mtime; return (AF_OK); } /* afWriteArchive */ shapetools-1.4pl6.orig/src/atfs/afarlock.c100444 2013 145 13043 5520500473 16633 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afarlock.c -- reader/writer locking on archive files * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afarlock.c[7.0] Sun Jan 23 16:05:51 1994 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" extern int errno; /* When this variable is set TRUE, no reader locking is performed */ EXPORT int af_noReadLock = FALSE; /*============================================== * afOpenLock -- open archive file and set lock *==============================================*/ EXPORT FILE *afOpenLock (fileName, mode, list) char *fileName; int mode; Af_revlist *list; { int fileDes, openMode, retries = 0; char modeStr[4]; mode_t fileMode; FILE *resultFile; #if defined(ATFS_OWN_LOCKING) char *lckName; struct stat lckIbuf; int lckFiledes; #else struct flock lockInfo; #endif if (mode == AF_WRITE) { openMode = O_WRONLY; #if !defined(ATFS_OWN_LOCKING) lockInfo.l_type = F_WRLCK; #endif strcpy (modeStr, "w+"); } else { openMode = O_RDONLY; #if !defined(ATFS_OWN_LOCKING) lockInfo.l_type = F_RDLCK; #endif strcpy (modeStr, "r"); if (af_noReadLock) { if ((resultFile = (fopen (fileName, modeStr))) == NULL) FAIL ("OpenLock", "fopen", AF_ESYSERR, NULL); return (resultFile); } } if ((fileDes = open (fileName, openMode)) < 0) { /* if file does not exist and shall be opened for writing, try to create it */ if ((mode == AF_WRITE) && (errno == ENOENT)) { if ((fileDes = creat (fileName, 0600)) < 0) FATAL ("OpenLock", "creat", AF_ESYSERR, NULL); chown (fileName, geteuid(), list->af_owngid); if ((fileMode = afArchiveMode (list->af_arpath))) { fileMode &= ~(S_IXUSR|S_IXGRP|S_IXOTH|S_ISUID|S_ISGID); chmod (fileName, fileMode); } } else FAIL ("OpenLock", "open", AF_ESYSERR, NULL); } #if defined(ATFS_OWN_LOCKING) /* build name for lock file */ if (list->af_extent & AF_CACHE) lckName = afCacheFileName (list->af_arpath, AF_CACHELCKNAME); else lckName = afArchiveName (list->af_arpath, AF_LOCKDIR, list->af_cattrs.af_globname, list->af_cattrs.af_globtype, AF_WRITE); retry: /* check if lock file exists */ if (stat (lckName, &lckIbuf) == ERROR) { if (mode == AF_WRITE) { /* no reader locking */ /* create lock file */ af_regtmpfile (lckName); if ((lckFiledes = creat (lckName, 0600)) < 0) FAIL ("OpenLock", "creat (lockfile)", AF_ESYSERR, NULL); close (lckFiledes); } } else { /* check if lock file is older than a 60 seconds */ if ((af_acttime() - lckIbuf.st_ctime) > 60) { /* remove old lock file and create new one */ af_wng ("WriteLock", "spurious lock file found -- removed."); if (unlink (lckName) == ERROR) FATAL ("OpenLock", "cannot unlink lock file", AF_EINTERNAL, NULL); if (mode == AF_WRITE) { /* no reader locking */ /* create new one */ af_regtmpfile (lckName); if ((lckFiledes = creat (lckName, 0600)) < 0) FAIL ("OpenLock", "creat (lockfile)", AF_ESYSERR, NULL); close (lckFiledes); } } else { /* retry */ if (retries == 3) FAIL ("OpenLock", "archive file is locked for writing", AF_EMISC, NULL); sleep (1); retries++; goto retry; } } #else lockInfo.l_whence = SEEK_SET; lockInfo.l_start = (off_t) 0; lockInfo.l_len = (off_t) 0; lockInfo.l_pid = getpid(); while (1) { if (fcntl (fileDes, F_SETLK, &lockInfo) != -1) break; if (retries++ == 10) FAIL ("OpenLock", "fcntl", AF_ESYSERR, NULL); sleep (1); } #endif if (mode == AF_WRITE) { /* reopen and truncate the file */ close (fileDes); if ((resultFile = fopen (fileName, modeStr)) == NULL) { FAIL ("OpenLock", "fopen", AF_ESYSERR, NULL); } return (resultFile); } /* else */ if ((resultFile = (fdopen (fileDes, modeStr))) == NULL) FAIL ("OpenLock", "fdopen", AF_ESYSERR, NULL); return (resultFile); } EXPORT int afCloseUnlock (fileDes, mode, list) FILE *fileDes; int mode; Af_revlist *list; { #if defined(ATFS_OWN_LOCKING) char *lckName; if (mode == AF_WRITE) { /* no reader locking */ if (list->af_extent & AF_CACHE) lckName = afCacheFileName (list->af_arpath, AF_CACHELCKNAME); else lckName = afArchiveName (list->af_arpath, AF_LOCKDIR, list->af_cattrs.af_globname, list->af_cattrs.af_globtype, AF_WRITE); if (unlink (lckName) == ERROR) FATAL ("afCloseUnlock", "cannot unlink lock file", AF_EINTERNAL, EOF); af_unregtmpfile (lckName); } #else struct flock lockInfo; if (af_noReadLock) { return (fclose (fileDes)); } lockInfo.l_type = F_UNLCK; lockInfo.l_whence = SEEK_SET; lockInfo.l_start = (off_t) 0; lockInfo.l_len = (off_t) 0; lockInfo.l_pid = (pid_t)0; if (fcntl (fileno(fileDes), F_SETLK, &lockInfo) == -1) FATAL ("CloseUnlock", "fcntl", AF_ESYSERR, EOF); #endif return (fclose (fileDes)); } shapetools-1.4pl6.orig/src/atfs/afattrs.c100444 2013 145 35226 5412541256 16530 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afattrs.c - reading and writing attributes * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afattrs.c[7.0] Fri Jun 25 14:31:41 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*=========================================================== * af_retattr -- return attribute in string representation *===========================================================*/ static char attrBuf[PATH_MAX]; EXPORT int af_isstdval (attrVal) char *attrVal; { return (attrBuf == attrVal); } EXPORT void af_freeattr (attrVal) char *attrVal; { if (attrVal != attrBuf) free (attrVal); } EXPORT void af_freeattrbuf (attrBuf) Af_attrs *attrBuf; { int i=0; while (attrBuf->af_udattrs[i]) free (attrBuf->af_udattrs[i++]); } EXPORT char *af_retattr (aso, attr) Af_key *aso; char *attr; { char *udattr, *entry, *valptr; if (afAccessAso (aso, AF_ATTRS)) FAIL ("retattr", "", AF_EINVKEY, NULL); if (!attr) FAIL ("retattr", "no attribute name given", AF_EMISC, NULL); attrBuf[0] = '\0'; if (!strncmp (attr, "af_", 3)) { /* presumably a standard attribute name */ char *aNamPtr = &attr[3]; if (!afAttrNameCmp (&AF_ATTHOST[3], aNamPtr)) { if (CATTR(aso).af_host) strcpy (attrBuf, CATTR(aso).af_host); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTSPATH[3], aNamPtr)) { if (CATTR(aso).af_syspath) strcpy (attrBuf, CATTR(aso).af_syspath); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTUNIXNAME[3], aNamPtr)) { strcpy (attrBuf, VATTR(aso).af_name); if (VATTR(aso).af_type) { strcat (attrBuf, "."); strcat (attrBuf, VATTR(aso).af_type); } return (attrBuf); } if (!afAttrNameCmp (&AF_ATTUNIXPATH[3], aNamPtr)) { strcpy (attrBuf, af_gbusname (CATTR(aso).af_syspath, VATTR(aso).af_name, VATTR(aso).af_type)); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTBOUND[3], aNamPtr)) { char tmpBuf[16]; strcpy (attrBuf, VATTR(aso).af_name); if (VATTR(aso).af_type) { strcat (attrBuf, "."); strcat (attrBuf, VATTR(aso).af_type); } if (VATTR(aso).af_gen == AF_BUSYVERS) strcat (attrBuf, "[busy]"); else { sprintf (tmpBuf, "[%d.%d]", VATTR(aso).af_gen, VATTR(aso).af_rev); strcat (attrBuf, tmpBuf); } return (attrBuf); } if (!afAttrNameCmp (&AF_ATTBOUNDPATH[3], aNamPtr)) { char tmpBuf[16]; strcpy (attrBuf, af_gbusname (CATTR(aso).af_syspath, VATTR(aso).af_name, VATTR(aso).af_type)); if (VATTR(aso).af_gen == AF_BUSYVERS) strcat (attrBuf, "[busy]"); else { sprintf (tmpBuf, "[%d.%d]", VATTR(aso).af_gen, VATTR(aso).af_rev); strcat (attrBuf, tmpBuf); } return (attrBuf); } if (!afAttrNameCmp (&AF_ATTNAME[3], aNamPtr)) { if (VATTR(aso).af_name) strcpy (attrBuf, VATTR(aso).af_name); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTTYPE[3], aNamPtr)) { if (VATTR(aso).af_type) strcpy (attrBuf, VATTR(aso).af_type); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTGEN[3], aNamPtr)) { if (VATTR(aso).af_gen == AF_BUSYVERS) strcpy (attrBuf, "busy"); else sprintf (attrBuf, "%d", VATTR(aso).af_gen); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTREV[3], aNamPtr)) { if (VATTR(aso).af_rev == AF_BUSYVERS) strcpy (attrBuf, "busy"); else sprintf (attrBuf, "%d", VATTR(aso).af_rev); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTVERSION[3], aNamPtr)) { if (VATTR(aso).af_gen == AF_BUSYVERS) strcpy (attrBuf, "busy"); else sprintf (attrBuf, "%d.%d", VATTR(aso).af_gen, VATTR(aso).af_rev); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTSTATE[3], aNamPtr)) { switch (VATTR(aso).af_state) { case AF_BUSY: strcpy (attrBuf, "busy"); break; case AF_SAVED: strcpy (attrBuf, "saved"); break; case AF_PROPOSED: strcpy (attrBuf, "proposed"); break; case AF_PUBLISHED: strcpy (attrBuf, "published"); break; case AF_ACCESSED: strcpy (attrBuf, "accessed"); break; case AF_FROZEN: strcpy (attrBuf, "frozen"); break; } return (attrBuf); } if (!afAttrNameCmp (&AF_ATTOWNER[3], aNamPtr)) { sprintf (attrBuf, "%s@%s", CATTR(aso).af_ownname, CATTR(aso).af_owndomain); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTAUTHOR[3], aNamPtr)) { sprintf (attrBuf, "%s@%s", VATTR(aso).af_auname, VATTR(aso).af_audomain); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTDSIZE[3], aNamPtr)) { if (VATTR(aso).af_repr == AF_DELTA) sprintf (attrBuf, "%lu", VATTR(aso).af_dsize); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTSIZE[3], aNamPtr)) { sprintf (attrBuf, "%lu", VATTR(aso).af_fsize); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTMODE[3], aNamPtr)) { sprintf (attrBuf, "%o", VATTR(aso).af_mode); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTLOCKER[3], aNamPtr)) { if (VATTR(aso).af_lckname) sprintf (attrBuf, "%s@%s", VATTR(aso).af_lckname, VATTR(aso).af_lckdomain); return (attrBuf); } if (!afAttrNameCmp (&AF_ATTMTIME[3], aNamPtr)) { strcpy (attrBuf, asctime (localtime (&VATTR(aso).af_mtime))); attrBuf[strlen(attrBuf)-1] = '\0'; return (attrBuf); } if (!afAttrNameCmp (&AF_ATTATIME[3], aNamPtr)) { strcpy (attrBuf, asctime (localtime (&VATTR(aso).af_atime))); attrBuf[strlen(attrBuf)-1] = '\0'; return (attrBuf); } if (!afAttrNameCmp (&AF_ATTCTIME[3], aNamPtr)) { strcpy (attrBuf, asctime (localtime (&VATTR(aso).af_ctime))); attrBuf[strlen(attrBuf)-1] = '\0'; return (attrBuf); } if (!afAttrNameCmp (&AF_ATTSTIME[3], aNamPtr)) { if (VATTR(aso).af_stime != AF_NOTIME) { strcpy (attrBuf, asctime (localtime (&VATTR(aso).af_stime))); attrBuf[strlen(attrBuf)-1] = '\0'; } return (attrBuf); } if (!afAttrNameCmp (&AF_ATTLTIME[3], aNamPtr)) { if (VATTR(aso).af_ltime != AF_NOTIME) { strcpy (attrBuf, asctime (localtime (&VATTR(aso).af_ltime))); attrBuf[strlen(attrBuf)-1] = '\0'; } return (attrBuf); } } /* assume user defined attribute */ if ((entry = afLookupUda (aso, attr)) == NULL) return (NULL); if ((valptr = strchr (entry, AF_UDANAMDEL))) { if ((udattr = malloc ((unsigned) strlen(valptr) + sizeof(char))) == NULL) FAIL ("rudattr", "malloc", AF_ESYSERR, NULL); /* replace delimiters by '\n' */ strcpy (udattr, valptr+1); valptr = udattr; while ((valptr = strchr (valptr, AF_UDAVALDEL))) *valptr = '\n'; return (udattr); } return (attrBuf); } /*============================================= * af_retnumattr -- return numeric attribute *=============================================*/ EXPORT int af_retnumattr (aso, attr) Af_key *aso; char *attr; { if (afAccessAso (aso, AF_ATTRS)) FAIL ("retnumattr", "", AF_EINVKEY, ERROR); if (!attr) FAIL ("retnumattr", "no attribute name given", AF_EMISC, 0); if (!afAttrNameCmp (AF_ATTGEN, attr)) return (VATTR(aso).af_gen); if (!afAttrNameCmp (AF_ATTREV, attr)) return (VATTR(aso).af_rev); if (!afAttrNameCmp (AF_ATTSTATE, attr)) return (VATTR(aso).af_state); if (!afAttrNameCmp (AF_ATTDSIZE, attr)) { if (VATTR(aso).af_repr != AF_DELTA) return (ERROR); return (VATTR(aso).af_dsize); } if (!afAttrNameCmp (AF_ATTSIZE, attr)) return (VATTR(aso).af_fsize); if (!afAttrNameCmp (AF_ATTMODE, attr)) return (VATTR(aso).af_mode); return (ERROR); } /*=========================================== * af_retuserattr -- return user attribute *===========================================*/ EXPORT Af_user *af_retuserattr (aso, attr) Af_key *aso; char *attr; { static Af_user userBuf; if (afAccessAso (aso, AF_ATTRS)) FAIL ("retuserattr", "", AF_EINVKEY, NULL); if (!attr) FAIL ("retuserattr", "empty attribute name", AF_EMISC, NULL); if (!afAttrNameCmp (AF_ATTOWNER, attr)) { strcpy (userBuf.af_username, CATTR(aso).af_ownname); strcpy (userBuf.af_userhost, CATTR(aso).af_ownhost); strcpy (userBuf.af_userdomain, CATTR(aso).af_owndomain); return (&userBuf); } if (!afAttrNameCmp (AF_ATTAUTHOR, attr)) { strcpy (userBuf.af_username, VATTR(aso).af_auname); strcpy (userBuf.af_userhost, VATTR(aso).af_auhost); strcpy (userBuf.af_userdomain, VATTR(aso).af_audomain); return (&userBuf); } if (!afAttrNameCmp (AF_ATTLOCKER, attr)) { if (VATTR(aso).af_lckname) { strcpy (userBuf.af_username, VATTR(aso).af_lckname); strcpy (userBuf.af_userhost, VATTR(aso).af_lckhost); strcpy (userBuf.af_userdomain, VATTR(aso).af_lckdomain); } else { userBuf.af_username[0] = '\0'; userBuf.af_userhost[0] = '\0'; userBuf.af_userdomain[0] = '\0'; } return (&userBuf); } return (NULL); } /*=========================================== * af_rettimeattr -- return time attribute *===========================================*/ EXPORT time_t af_rettimeattr (aso, attr) Af_key *aso; char *attr; { if (afAccessAso (aso, AF_ATTRS)) FAIL ("rettimeattr", "", AF_EINVKEY, AF_NOTIME); if (!attr) FAIL ("rettimeattr", "empty attribute name", AF_EMISC, 0); if (!afAttrNameCmp (AF_ATTMTIME, attr)) return (VATTR(aso).af_mtime); if (!afAttrNameCmp (AF_ATTATIME, attr)) return (VATTR(aso).af_atime); if (!afAttrNameCmp (AF_ATTCTIME, attr)) return (VATTR(aso).af_ctime); if (!afAttrNameCmp (AF_ATTSTIME, attr)) return (VATTR(aso).af_stime); if (!afAttrNameCmp (AF_ATTLTIME, attr)) return (VATTR(aso).af_ltime); return (AF_NOTIME); } /*=============================================== * af_setattr -- set user defined attribute *===============================================*/ EXPORT int af_setattr (key, mode, attr) Af_key *key; int mode; char *attr; { register char *udaptr, *tmpuda, *valptr; register int tail; if (afAccessAso (key, AF_ATTRS)) FAIL ("setattr", "", AF_EINVKEY, ERROR); if (!attr) FAIL ("setattr", "empty attribute name", AF_EMISC, 0); if ((VATTR(key).af_state == AF_FROZEN) && (mode == AF_REMOVE)) FAIL ("setattr", "", AF_EWRONGSTATE, ERROR); /* look for delimiter character in attribute string */ if (!attr || strchr (attr, AF_UDAVALDEL)) FAIL ("setattr", "illegal format of attribute string", AF_EMISC, ERROR); if (af_checkperm (key, AF_WORLD) == ERROR) return (ERROR); /* search entry */ udaptr = afLookupUda (key, attr); if (!udaptr && (mode == AF_REPLACE)) mode = AF_ADD; switch (mode) { case AF_ADD: if (udaptr) { /* build new entry and replace old one */ if (!(valptr = strchr (attr, AF_UDANAMDEL))) { /* no new value -- nothing to do */ break; } valptr += sizeof (char); if ((tmpuda = malloc ((unsigned) ((strlen (udaptr) + strlen (valptr) +2) * sizeof (char)))) == NULL) FAIL ("setattr", "malloc", AF_ESYSERR, ERROR); strcpy (tmpuda, udaptr); tail = strlen (tmpuda); tmpuda[tail] = AF_UDAVALDEL; tmpuda[tail+1] = '\0'; strcat (tmpuda, valptr); afReplUda (key, tmpuda); free (tmpuda); } else { /* add new entry */ if (VATTR(key).af_udanum == AF_MAXUDAS) FAIL ("setattr", "too many user defined attributes", AF_EMISC, ERROR); afEnterUda (key, attr); } break; case AF_REMOVE: if (udaptr == NULL) FAIL ("setattr", "", AF_ENOUDA, ERROR); afDelUda (key, udaptr); break; case AF_REPLACE: if (udaptr == NULL) FAIL ("setattr", "", AF_ENOUDA, ERROR); afReplUda (key, attr); break; default: FAIL ("setattr", "", AF_EMODE, ERROR); } if (afUpdateAso (key, AF_CHANGE) == ERROR) return (ERROR); return (AF_OK); } /*========================================= * af_allattrs -- return all attributes *=========================================*/ EXPORT int af_allattrs (key, attrbuf) Af_key *key; Af_attrs *attrbuf; { register int i; register char *valptr; char *udalist[AF_MAXUDAS+1]; if (afAccessAso (key, AF_ATTRS)) FAIL ("allattrs", "", AF_EINVKEY, ERROR); strcpy (attrbuf->af_host, CATTR(key).af_host); strcpy (attrbuf->af_name, VATTR(key).af_name); strcpy (attrbuf->af_type, NOTNIL(VATTR(key).af_type)); strcpy (attrbuf->af_syspath, CATTR(key).af_syspath); attrbuf->af_gen = VATTR(key).af_gen; attrbuf->af_rev = VATTR(key).af_rev; attrbuf->af_state = (int) VATTR(key).af_state; strcpy (attrbuf->af_owner.af_username, CATTR(key).af_ownname); strcpy (attrbuf->af_owner.af_userhost, CATTR(key).af_ownhost); strcpy (attrbuf->af_owner.af_userdomain, CATTR(key).af_owndomain); strcpy (attrbuf->af_author.af_username, VATTR(key).af_auname); strcpy (attrbuf->af_author.af_userhost, VATTR(key).af_auhost); strcpy (attrbuf->af_author.af_userdomain, VATTR(key).af_audomain); attrbuf->af_size = VATTR(key).af_fsize; attrbuf->af_mode = VATTR(key).af_mode; strcpy (attrbuf->af_locker.af_username, NOTNIL(VATTR(key).af_lckname)); strcpy (attrbuf->af_locker.af_userhost, NOTNIL(VATTR(key).af_lckhost)); strcpy (attrbuf->af_locker.af_userdomain, NOTNIL(VATTR(key).af_lckdomain)); attrbuf->af_mtime = VATTR(key).af_mtime; attrbuf->af_atime = VATTR(key).af_atime; attrbuf->af_ctime = VATTR(key).af_ctime; attrbuf->af_stime = VATTR(key).af_stime; attrbuf->af_ltime = VATTR(key).af_ltime; /* copy user defined attributes */ if (VATTR(key).af_udanum > 0) { afListUdas (key, udalist); i=0; while (udalist[i]) { if ((attrbuf->af_udattrs[i] = malloc (strlen(udalist[i]) + sizeof(char))) == NULL) FAIL ("allattrs", "malloc", AF_ESYSERR, ERROR); strcpy (attrbuf->af_udattrs[i], udalist[i]); /* replace delimiters by '\n' */ if ((valptr = strchr (attrbuf->af_udattrs[i], AF_UDANAMDEL))) { while ((valptr = strchr (valptr, AF_UDAVALDEL))) valptr[0] = '\n'; } i++; } attrbuf->af_udattrs[i] = NULL; /* finish list */ } else attrbuf->af_udattrs[0] = NULL; return (AF_OK); } shapetools-1.4pl6.orig/src/atfs/afcache.c100444 2013 145 27264 5423010307 16427 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afcache.c -- realize caching for archives in core * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afcache.c[7.0] Tue Jul 20 19:42:23 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "afarchive.h" extern int af_errno; /*========================================================================== * List of list-descriptors + hash table for faster access *==========================================================================*/ EXPORT Af_revlist *af_lists = NULL; /* base address of all list descriptors */ EXPORT Af_revlist *archFreelist = NULL; /* beginning of freelist */ EXPORT int af_listmem = 0; /* # of bytes used for list */ LOCAL int archtabSize; /*========================================================================= * Hash stuff *=========================================================================*/ LOCAL bool hashInit = FALSE; /* indicate if hashtable is yet initialized */ typedef struct AfArnt AfArchent; struct AfArnt { char *symbol; Af_revlist *list; AfArchent *next; }; LOCAL AfArchent *afArchhash; LOCAL char *hashSym; /*===================================================================== * afHasharch -- put archive into hashtable *=====================================================================*/ LOCAL int afHasharch (symbol, list) char *symbol; Af_revlist *list; { register int where; AfArchent *new, *curptr; where = afHashval (symbol, AF_MAXLISTS); if (!afArchhash[where].symbol) { /* entry is not used yet */ afArchhash[where].symbol = symbol; afArchhash[where].list = list; return (AF_OK); } else { /* hash collision! */ if ((new = (AfArchent *)malloc ((unsigned) sizeof (AfArchent))) == NULL) FAIL ("Hasharch", "malloc", AF_ESYSERR, ERROR); archtabSize += sizeof (AfArchent); new->symbol = symbol; new->list = list; new->next = NULL; curptr = &afArchhash[where]; while (curptr->next) curptr = curptr->next; curptr->next = new; return (AF_OK); } } /*===================================================================== * afLookuparch -- search archive in hashtable *=====================================================================*/ LOCAL Af_revlist *afLookuparch (symbol, path) char *symbol, *path; { int where; AfArchent *entry; /* lookup symbol */ where = afHashval (symbol, AF_MAXLISTS); if (afArchhash[where].symbol) { /* found something */ if ((afArchhash[where].symbol == symbol) && (afArchhash[where].list->af_cattrs.af_syspath == path)) return (afArchhash[where].list); else { entry = &afArchhash[where]; while (entry->next) { entry = entry->next; if ((entry->symbol == symbol) && (entry->list->af_cattrs.af_syspath == path)) return (entry->list); } } } /* nothing found */ return (NULL); } /*========================================================================= * afInitList *=========================================================================*/ EXPORT Af_revlist *afInitList (pathSym, nameSym, typeSym) char *pathSym, *nameSym, *typeSym; { register int i; register Af_revlist *list, *oldlist; /* init hashtable if this is not yet done */ if (!hashInit) { archtabSize = AF_MAXLISTS * sizeof (AfArchent); if ((afArchhash = (AfArchent *)malloc ((unsigned) archtabSize)) == NULL) FAIL ("InitList", "malloc", AF_ESYSERR, NULL); /* set hashlist all zeros */ memset ((char *)afArchhash, 0, archtabSize); hashInit = TRUE; } /* if list is already loaded */ if ((oldlist = afTestList (pathSym, nameSym, typeSym))) { oldlist->af_extent |= AF_LISTBUSY; if (afReadAttrs (oldlist) == ERROR) { oldlist->af_extent &= ~AF_LISTBUSY; return (NULL); } oldlist->af_extent &= ~AF_LISTBUSY; return (oldlist); } /* if there are no more descriptors available - allocate new space */ if (archFreelist == NULL) { if ((archFreelist = (Af_revlist *) malloc ((unsigned) (AF_LISTSEG * sizeof (Af_revlist)))) == NULL) FAIL ("InitList", "malloc(i)", AF_ESYSERR, NULL); archtabSize += AF_LISTSEG * sizeof (Af_revlist); /* build up new freelist */ for (i=1; iaf_next; memset ((char *)list, 0, sizeof (*list)); list->af_extent |= AF_LISTBUSY; list->af_mem = NULL; list->af_cattrs.af_host = af_gethostname (); list->af_cattrs.af_syspath = pathSym; list->af_cattrs.af_globname = nameSym; list->af_cattrs.af_globtype = typeSym; list->af_lastmod = (time_t) 0; if (afReadAttrs (list) == ERROR) { list->af_extent &= ~AF_LISTBUSY; list->af_next = archFreelist; archFreelist = list; return (NULL); } list->af_extent &= ~AF_LISTBUSY; /* add list to chain */ list->af_next = af_lists; af_lists = list; /* add list to hashtable */ afHasharch (hashSym, list); return (list); } /*========================================================================= * afInitObjCache *=========================================================================*/ LOCAL Af_revlist *objectCaches = NULL; EXPORT Af_revlist *afInitObjCache (pathSym) char *pathSym; { register int i; Af_revlist *list, *oldlist; Af_user *owner; bool writeOk; struct stat iBuf; /* check if path exists and is a directory */ if (stat (pathSym, &iBuf) == -1) { char msgBuf[PATH_MAX+64]; sprintf (msgBuf, "directory %s does not exist", pathSym); FAIL ("InitObjCache", msgBuf, AF_EMISC, NULL); } else if (!S_ISDIR (iBuf.st_mode)) { char msgBuf[PATH_MAX+64]; sprintf (msgBuf, "%s is not a directory", pathSym); FAIL ("InitObjCache", msgBuf, AF_EMISC, NULL); } /* init hashtable if it is not yet done */ if (!hashInit) { archtabSize = AF_MAXLISTS * sizeof (AfArchent); if ((afArchhash = (AfArchent *)malloc ((unsigned) archtabSize)) == NULL) FAIL ("InitObjCache", "malloc", AF_ESYSERR, NULL); /* set hashlist all zeros */ memset ((char *)afArchhash, 0, archtabSize); hashInit = TRUE; } /* if there are open archives check if desired archive is loaded yet */ if (objectCaches) { if ((oldlist = afLookuparch (pathSym, pathSym))) { oldlist->af_extent |= AF_LISTBUSY; if (afObjCacheRead (oldlist) == ERROR) { oldlist->af_extent &= ~AF_LISTBUSY; return (NULL); } oldlist->af_extent &= ~AF_LISTBUSY; return (oldlist); } } /* if there are no more descriptors available - allocate new space */ if (archFreelist == NULL) { if ((archFreelist = (Af_revlist *) malloc ((unsigned) (AF_LISTSEG * sizeof (Af_revlist)))) == NULL) FAIL ("InitObjCache", "malloc(i)", AF_ESYSERR, NULL); archtabSize += AF_LISTSEG * sizeof (Af_revlist); /* build up new freelist */ for (i=1; iaf_next; memset ((char *)list, 0, sizeof (*list)); list->af_arpath = afArchivePath (pathSym); if ((owner = afArchiveOwner (list->af_arpath, &writeOk, &list->af_owngid)) == NULL) { list->af_owngid = getegid(); owner = af_afuser ((uid_t) geteuid()); } list->af_lastmod = (time_t)0; list->af_busyfilename = NULL; list->af_datasize = 0; if (writeOk) list->af_extent |= (AF_CACHE | AF_LISTBUSY | AF_UXWRITE); else list->af_extent |= (AF_CACHE | AF_LISTBUSY); list->af_mem = NULL; list->af_cattrs.af_host = af_gethostname (); list->af_cattrs.af_syspath = pathSym; list->af_cattrs.af_ownname = af_entersym (owner->af_username); list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost); list->af_cattrs.af_owndomain = af_enterdomain (owner->af_userdomain); if (afObjCacheRead (list) == ERROR) { list->af_extent &= ~AF_LISTBUSY; list->af_next = archFreelist; archFreelist = list; return (NULL); } list->af_extent &= ~AF_LISTBUSY; /* add list to chain */ list->af_next = objectCaches; objectCaches = list; /* add list to hashtable */ afHasharch (pathSym, list); return (list); } /*========================================================================== * afTestList -- see if list is in core *==========================================================================*/ EXPORT Af_revlist *afTestList (pathSym, nameSym, typeSym) char *pathSym, *nameSym, *typeSym; { if (!hashInit) return (NULL); hashSym = af_gbusname (NULL, nameSym, typeSym); /* if there are open archives check if desired archive is loaded yet */ if (af_lists) return (afLookuparch (hashSym, pathSym)); return (NULL); } /*========================================================================== * afRefreshList -- re-read list (if necessary) *==========================================================================*/ EXPORT int afRefreshList (list, extent) Af_revlist *list; int extent; { int retcode = AF_OK; /* this shortcut is for sake of efficiency */ if ((list->af_access) && (extent == AF_ATTRS)) return (retcode); list->af_extent |= AF_LISTBUSY; /* if list is a derived object cache */ if ((list->af_extent & AF_CACHE) == AF_CACHE) retcode = afObjCacheRead (list); else { retcode = afReadAttrs (list); if (extent & AF_DATA) retcode = afReadData (list); } list->af_extent &= ~AF_LISTBUSY; return (retcode); } /*========================================================================== * afDetachList -- detach list data *==========================================================================*/ EXPORT int afDetachList (list) Af_revlist *list; { /* free all allocated memory */ af_frmemlist (list); list->af_listlen = 0; list->af_nrevs = 0; list->af_datasize = 0; list->af_extent &= ~AF_SEGMASK; list->af_list = NULL; return (AF_OK); } /*========================================================================== * afListSpace -- get space for new list *==========================================================================*/ EXPORT int afListSpace (size) int size; { register Af_revlist *listptr; if (af_listmem + size < AF_MAXMEM) return (AF_OK); /* search oldest unused revision list */ /* not yet implemented */ /* search first unused revision list and free memory */ listptr = af_lists; while (listptr) { if (!(listptr->af_extent & AF_LISTBUSY) && (listptr->af_access < 1) && (listptr->af_listlen > 0)) afDetachList (listptr); if (af_listmem + size < AF_MAXMEM) return (AF_OK); else listptr = listptr->af_next; } listptr = objectCaches; while (listptr) { if (!(listptr->af_extent & AF_LISTBUSY) && (listptr->af_access < 1) && (listptr->af_listlen > 0)) afDetachList (listptr); if (af_listmem + size < AF_MAXMEM) return (AF_OK); else listptr = listptr->af_next; } /* unable to free enough memory */ /* return (ERROR); ignore this */ return (AF_OK); } shapetools-1.4pl6.orig/src/atfs/afcompar.c100444 2013 145 26150 5412541216 16644 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afcompar.c -- attribute comparison routines * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afcompar.c[7.0] Fri Jun 25 14:31:46 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*================================================================ * af_cmpatime -- compare dates of last access *================================================================*/ EXPORT int af_cmpatime (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_atime - VATTR(key2).af_atime); } /*================================================================ * af_cmpauthor -- compare authors *================================================================*/ EXPORT int af_cmpauthor (key1, key2) Af_key *key1, *key2; { register int res; afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); if (!(res = strcmp (NOTNIL(VATTR(key1).af_auname), NOTNIL(VATTR(key2).af_auname)))) return (strcmp (NOTNIL(VATTR(key1).af_audomain), NOTNIL(VATTR(key2).af_audomain))); else return (res); } /*================================================================ * af_cmpctime -- compare dates of last status change *================================================================*/ EXPORT int af_cmpctime (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_ctime - VATTR(key2).af_ctime); } /*================================================================ * af_cmpgen -- compare generation numbers *================================================================*/ EXPORT int af_cmpgen (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_gen - VATTR(key2).af_gen); } /*================================================================ * af_cmphost -- compare hostnames *================================================================*/ EXPORT int af_cmphost (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (strcmp (CATTR(key1).af_host, CATTR(key2).af_host)); } /*================================================================ * af_cmpbound -- compare name, type, gen, rev *================================================================*/ EXPORT int af_cmpbound (key1, key2) Af_key *key1, *key2; { register int diff; afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); if (!(diff = strcmp (VATTR(key1).af_name, VATTR(key2).af_name)) && !(diff = strcmp (NOTNIL(VATTR(key1).af_type), NOTNIL(VATTR(key2).af_type))) && !(diff = VATTR(key1).af_gen - VATTR(key2).af_gen) && !(diff = VATTR(key1).af_rev - VATTR(key2).af_rev)) { return (0); } return (diff); } /*================================================================ * af_cmplocker -- compare lockers *================================================================*/ EXPORT int af_cmplocker (key1, key2) Af_key *key1, *key2; { register int res; afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); if (!(res = strcmp (NOTNIL(VATTR(key1).af_lckname), NOTNIL(VATTR(key2).af_lckname)))) return (strcmp (NOTNIL(VATTR(key1).af_lckdomain), NOTNIL(VATTR(key2).af_lckdomain))); else return (res); } /*================================================================ * af_cmpltime -- compare dates of last lock change *================================================================*/ EXPORT int af_cmpltime (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_ltime - VATTR(key2).af_ltime); } /*================================================================ * af_cmpmode -- compare protections *================================================================*/ EXPORT int af_cmpmode (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_mode - VATTR(key2).af_mode); } /*================================================================ * af_cmpmtime -- compare dates of last modification *================================================================*/ EXPORT int af_cmpmtime (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_mtime - VATTR(key2).af_mtime); } /*================================================================ * af_cmpname -- compare names *================================================================*/ EXPORT int af_cmpname (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (strcmp (VATTR(key1).af_name, VATTR(key2).af_name)); } /*================================================================ * af_cmpowner -- compare owners *================================================================*/ EXPORT int af_cmpowner (key1, key2) Af_key *key1, *key2; { register int res; afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); if (!(res = strcmp (CATTR(key1).af_ownname, CATTR(key2).af_ownname))) return (strcmp (CATTR(key1).af_owndomain, CATTR(key2).af_owndomain)); else return (res); } /*================================================================ * af_cmprev -- compare revision numbers *================================================================*/ EXPORT int af_cmprev (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_rev - VATTR(key2).af_rev); } /*================================================================ * af_cmpsize -- compare file size *================================================================*/ EXPORT int af_cmpsize (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_fsize - VATTR(key2).af_fsize); } /*================================================================ * af_cmpstate -- compare states *================================================================*/ EXPORT int af_cmpstate (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_state - VATTR(key2).af_state); } /*================================================================ * af_cmpsvtime -- compare dates of saving *================================================================*/ EXPORT int af_cmpsvtime (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (VATTR(key1).af_stime - VATTR(key2).af_stime); } /*================================================================ * af_cmpspath -- compare syspaths *================================================================*/ EXPORT int af_cmpspath (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (strcmp (CATTR(key1).af_syspath, CATTR(key2).af_syspath)); } /*================================================================ * af_cmptype -- compare types *================================================================*/ EXPORT int af_cmptype (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); return (strcmp (NOTNIL(VATTR(key1).af_type), NOTNIL(VATTR(key2).af_type))); } /*================================================================ * af_cmpversion -- compare version numbers (gen.rev) *================================================================*/ EXPORT int af_cmpversion (key1, key2) Af_key *key1, *key2; { afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); if (VATTR(key1).af_gen == VATTR(key2).af_gen) return (VATTR(key1).af_rev - VATTR(key2).af_rev); else return (VATTR(key1).af_gen - VATTR(key2).af_gen); } /*=============================================================== * af_cmpfuncts -- array of comparison functions *===============================================================*/ struct cmpfun { int (*func) (); }; EXPORT struct cmpfun af_cmpfuncts[] = { {af_cmpatime}, {af_cmpauthor}, {af_cmpbound}, {af_cmpctime}, {af_cmpgen}, {af_cmphost}, {af_cmplocker}, {af_cmpltime}, {af_cmpmode}, {af_cmpmtime}, {af_cmpname}, {af_cmpowner}, {af_cmprev}, {af_cmpsize}, {af_cmpstate}, {af_cmpsvtime}, {af_cmpspath}, {af_cmptype}, {af_cmpversion}, }; /*=============================================================== * af_attrlist -- list of attribute names * (in alphabetical order) *===============================================================*/ EXPORT char *af_attrlist[] = { AF_ATTATIME, AF_ATTAUTHOR, AF_ATTBOUND, AF_ATTCTIME, AF_ATTGEN, AF_ATTHOST, AF_ATTLOCKER, AF_ATTLTIME, AF_ATTMODE, AF_ATTMTIME, AF_ATTNAME, AF_ATTOWNER, AF_ATTREV, AF_ATTSIZE, AF_ATTSTATE, AF_ATTSTIME, AF_ATTSPATH, AF_ATTTYPE, AF_ATTVERSION, }; /*================================================================ * af_cmpuda -- compare user defined attributes *================================================================*/ EXPORT char af_udaname[AF_UDANAMLEN]; EXPORT int af_cmpuda (key1, key2) Af_key *key1, *key2; { register char *uda1, *uda2; char *vallist1, *vallist2; afAccessAso (key1, AF_ATTRS); afAccessAso (key2, AF_ATTRS); uda1 = afLookupUda (key1, af_udaname); uda2 = afLookupUda (key2, af_udaname); if (uda1 == NULL) { if (uda2 == NULL) return (0); /* equal */ else return (1); /* key1 is "greater" than key2 */ } else { if (uda2 == NULL) return (-1); /* key2 is "greater" than key1 */ } /* see if ther are values */ vallist1 = strchr (uda1, AF_UDANAMDEL); vallist2 = strchr (uda2, AF_UDANAMDEL); if (vallist1 == NULL) { if (vallist2 == NULL) return (0); /* equal */ else return (1); /* key1 is "greater" than key2 */ } else { if (vallist2 == NULL) return (-1); /* key2 is "greater" than key1 */ } /* compare values of user defined attributes */ /* this is a simple textual comparison up to now */ return (strcmp (vallist1, vallist2)); } shapetools-1.4pl6.orig/src/atfs/afdelta.c100444 2013 145 41724 5416551017 16464 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afdelta.c -- Delta processing * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afdelta.c[7.0] Wed Jul 7 19:05:08 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*==================================================================== * af_nodelta * * Store the busy version (busykey) without building a delta. * "nodelta" is necessary for saving the initial version (1.0) * or for storing versions without delta technique. * *====================================================================*/ EXPORT int af_nodelta (busykey, savekey) Af_key *busykey; Af_key *savekey; { register FILE *busyfile; VATTR(savekey).af_fsize = af_retfsize (busykey->af_ldes->af_busyfilename); VATTR(savekey).af_dsize = 0; VATTR(savekey).af_repr = AF_CHUNK; if ((VATTR(savekey).af_data = af_malloc (savekey->af_ldes, (unsigned) VATTR(savekey).af_fsize)) == NULL) return (ERROR); if ((busyfile = fopen (busykey->af_ldes->af_busyfilename, "r")) == NULL) FAIL ("nodelta", "fopen", AF_ESYSERR, ERROR); if (fread (VATTR(savekey).af_data, sizeof (char), (size_t) VATTR(savekey).af_fsize, busyfile) != VATTR(savekey).af_fsize) FAIL ("nodelta", "fread", AF_ESYSERR, ERROR); fclose (busyfile); savekey->af_ldes->af_datasize += VATTR(savekey).af_fsize; return (AF_OK); } /* af_nodelta */ /*==================================================================== * af_dodelta * * Build a delta between a busy version (busykey) and its preceeding * version (predkey) and store it as a new version (savekey). * If no busykey is given , build a null delta and store * it as new version. * The latter case is needed, if a version shall be stored with different * attributes but unchanged contents. * *====================================================================*/ EXPORT int af_dodelta (busykey, predkey, savekey) Af_key *busykey; Af_key *predkey; Af_key *savekey; { register char *delname; register FILE *busyfile, *delfile; if (busykey) { /* read in busyfile for delta processing */ VATTR(savekey).af_fsize = af_retfsize(busykey->af_ldes->af_busyfilename); if ((VATTR(savekey).af_data = af_malloc (savekey->af_ldes, (unsigned) VATTR(savekey).af_fsize)) == NULL) return (ERROR); if ((busyfile = fopen (busykey->af_ldes->af_busyfilename,"r")) == NULL) FAIL ("dodelta", "fopen", AF_ESYSERR, ERROR); if (fread (VATTR(savekey).af_data, sizeof (char), (size_t) VATTR(savekey).af_fsize, busyfile) != VATTR(savekey).af_fsize) FAIL ("dodelta", "fread", AF_ESYSERR, ERROR); fclose (busyfile); savekey->af_ldes->af_datasize += VATTR(savekey).af_fsize; VATTR(savekey).af_dsize = 0; VATTR(savekey).af_repr = AF_CHUNK; } else { /* produce null delta (new generation) */ VATTR(savekey).af_data = VATTR(predkey).af_data; VATTR(savekey).af_fsize = VATTR(predkey).af_fsize; VATTR(savekey).af_dsize = 0; VATTR(savekey).af_repr = AF_CHUNK; savekey->af_ldes->af_datasize += VATTR(savekey).af_fsize; } /* if version opens a new branch, no delta processing is necessary */ if ((predkey->af_ldes == NULL) || (VATTR(predkey).af_repr == AF_DELTA)) return (AF_OK); /* else do delta processing */ /* create filename for delta */ delname = af_gtmpname ("/tmp"); af_regtmpfile (delname); if (afMakeDelta (VATTR(savekey).af_data, VATTR(predkey).af_data, VATTR(savekey).af_fsize, VATTR(predkey).af_fsize, delname) == ERROR) FATAL ("dodelta", "", AF_EDELTA, ERROR); /* update predversion */ /* read deltafile if present */ if ((VATTR(predkey).af_dsize = af_retfsize (delname)) != (size_t)0) { if ((VATTR(predkey).af_dsize > VATTR(predkey).af_fsize) || (busykey == NULL)) if ((VATTR(predkey).af_data = af_malloc (predkey->af_ldes, (unsigned) VATTR(predkey).af_dsize)) == NULL) return (ERROR); if ((delfile = fopen (delname, "r")) == NULL) FAIL ("dodelta", "fopen", AF_ESYSERR, ERROR); if ((fread (VATTR(predkey).af_data, sizeof (char), (size_t) VATTR(predkey).af_dsize, delfile)) != VATTR(predkey).af_dsize) FAIL ("dodelta", "fread", AF_ESYSERR, ERROR); fclose (delfile); } else { VATTR(predkey).af_data = NULL; } /* remove tmp-file */ unlink (delname); af_unregtmpfile (delname); /* update list descriptor (file is replaced by delta) */ savekey->af_ldes->af_datasize -= VATTR(predkey).af_fsize; savekey->af_ldes->af_datasize += VATTR(predkey).af_dsize; VATTR(predkey).af_repr = AF_DELTA; VATTR(predkey).af_succgen = VATTR(savekey).af_gen; VATTR(predkey).af_succrev = VATTR(savekey).af_rev; return (AF_OK); } /* af_dodelta */ /*==================================================================== * af_undodelta * * The version pointed to by deltakey is supposed to be a (at least) * saved version represented by a chunk (AF_CHUNK) or a delta (AF_DELTA). * Passing a busy version causes an error (AF_NOVERS). * Filename has to be the name of an accessible UNIX-file, * where the rebuilt version will be stored. * The version pointed to by deltakey remains unchanged. * *====================================================================*/ EXPORT int af_undodelta (deltakey, filename) Af_key *deltakey; char *filename; { register Af_key *deltachain, *keyptr; char *tmpname, *data = NULL; register int i; size_t fsize; register FILE *tmpfile; /* this error should never occur */ if (VATTR(deltakey).af_repr == AF_FILE) FATAL ("undodelta", "wrong kind of representation", AF_EINTERNAL, ERROR); if ((deltachain = (Af_key *) malloc ((unsigned) (AF_SEGLEN * sizeof (Af_key)))) == NULL) FAIL ("undodelta", "malloc", AF_ESYSERR, ERROR); /* collect deltachain */ i = 0; deltachain[0] = *deltakey; keyptr = deltakey; while (VATTR(keyptr).af_repr == AF_DELTA) { i++; if ((i & AF_SEGLEN) == AF_SEGLEN) /* if segment is full */ if ((deltachain = (Af_key *) realloc ((char *) deltachain, (unsigned) ((i + AF_SEGLEN) * sizeof (Af_key)))) == NULL) FAIL ("undodelta", "realloc", AF_ESYSERR, ERROR); if (af_buildkey (deltakey->af_ldes, VATTR(keyptr).af_succgen, VATTR(keyptr).af_succrev, &(deltachain[i])) == ERROR) FATAL ("undodelta", "delta chain broken", AF_EINTERNAL, ERROR); keyptr = &(deltachain[i]); } if ((fsize = VATTR(keyptr).af_fsize) > 0) { if ((data = malloc ((unsigned) fsize)) == NULL) FAIL ("undodelta", "malloc", AF_ESYSERR, ERROR); memcpy (data, VATTR(keyptr).af_data, (size_t) fsize); } /* first step is done */ i--; /* process delta chain */ tmpname = af_gtmpname ("/tmp"); af_regtmpfile (tmpname); if (i < 0) { /* no delta chain */ if ((tmpfile = fopen (tmpname, "w")) == NULL) FAIL ("undodelta", "fopen", AF_ESYSERR, ERROR); if (fsize > 0) fwrite (data, (size_t) fsize, sizeof (char), tmpfile); fclose (tmpfile); } /* else */ for (; i >= 0; i--) { keyptr = &(deltachain[i]); if (afReconsData (data, VATTR(keyptr).af_data, fsize, VATTR(keyptr).af_dsize, tmpname) == ERROR) FATAL ("undodelta", "", AF_EDELTA, ERROR); if (i == 0) continue; /* increase performance */ if ((fsize = af_retfsize (tmpname)) > 0) { if (data) { if ((data = realloc (data, (unsigned)(fsize * sizeof (char)))) == NULL) FAIL ("undodelta", "realloc", AF_ESYSERR, ERROR); } else { if ((data = malloc ((unsigned)(fsize * sizeof (char)))) == NULL) FAIL ("undodelta", "realloc", AF_ESYSERR, ERROR); } if ((tmpfile = fopen (tmpname, "r")) == NULL) FAIL ("undodelta", "fopen", AF_ESYSERR, ERROR); fread (data, (size_t) fsize, sizeof (char), tmpfile); fclose (tmpfile); } else { if (data) free (data); data = NULL; } } free ((char *) deltachain); if (data) free (data); unlink (filename); if (link (tmpname, filename) == ERROR) { /* if link fails, try to copy file */ if (af_cpfile (tmpname, af_retfsize (tmpname), filename) == ERROR) FAIL ("undodelta", "link/copy", AF_ESYSERR, ERROR); } unlink (tmpname); af_unregtmpfile (tmpname); return (AF_OK); } /*==================================================================== * af_rmdelta * *====================================================================*/ EXPORT int af_rmdelta (deltakey) Af_key *deltakey; { register int i; int succsize, predsize; char *succdata, *preddata, *tmpname; register FILE *tmpfile; Af_key *deltachain, *keyptr = NULL, *predptr; /* deltachain shall hold all keys from the physical * predecessor to the end of the physical line of * descent (chunk). That is: * deltachain[0] = predecessor * deltachain[1] = deltakey * deltachain[2] = successor ... * ... deltachain[n] = chunk */ if ((deltachain = (Af_key *) malloc ((unsigned) (AF_SEGLEN * sizeof (Af_key)))) == NULL) FAIL ("rmdelta", "malloc", AF_ESYSERR, ERROR); /* update predecessor attributes of successor version */ if ((VATTR(deltakey).af_succgen != AF_NOVNUM) && (VATTR(deltakey).af_succrev != AF_NOVNUM)) { af_buildkey (deltakey->af_ldes, VATTR(deltakey).af_succgen, VATTR(deltakey).af_succrev, &(deltachain[2])); VATTR((&(deltachain[2]))).af_predgen = VATTR(deltakey).af_predgen; VATTR((&(deltachain[2]))).af_predrev = VATTR(deltakey).af_predrev; } /* *** new succ/pred chaining requires also search for other */ /* *** "successors". This is a bit "hacked" !!! */ for (i = 0; i < deltakey->af_ldes->af_listlen; i++) { if (!(deltakey->af_ldes->af_list[i].af_class & AF_VALID)) continue; if ((deltakey->af_ldes->af_list[i].af_predgen == VATTR(deltakey).af_gen) && (deltakey->af_ldes->af_list[i].af_predrev == VATTR(deltakey).af_rev)) { deltakey->af_ldes->af_list[i].af_predgen = AF_NOVNUM; deltakey->af_ldes->af_list[i].af_predrev = AF_NOVNUM; } } /* if deltakey points to the predecessor of the busy version, */ /* update busy version (should be optimized) */ /* works only, if busy version is at position 0 */ if ((deltakey->af_ldes->af_list[0].af_predgen == VATTR(deltakey).af_gen) && (deltakey->af_ldes->af_list[0].af_predrev == VATTR(deltakey).af_rev)) { deltakey->af_ldes->af_list[0].af_predgen = AF_NOVNUM; deltakey->af_ldes->af_list[0].af_predrev = AF_NOVNUM; } /* if deltakey points to first element in delta chain */ /* no delta processing is necessary */ /* *** delta chaining has been changed meanwhile. So this only */ /* *** applies to old archives and to the very first revision. */ if ((VATTR(deltakey).af_predgen == AF_NOVNUM) && (VATTR(deltakey).af_predrev == AF_NOVNUM)) return (AF_OK); /* else collect delta chain */ af_buildkey (deltakey->af_ldes, VATTR(deltakey).af_predgen, VATTR(deltakey).af_predrev, &(deltachain[0])); predptr = &(deltachain[0]); /* if predecessor's successor successor is different from own version */ /* number, we're at the starting pint of a branch -- no delta processing */ /* necessary. This applies to new style succ/pred chaining */ if ((VATTR(predptr).af_succgen != VATTR(deltakey).af_gen) || (VATTR(predptr).af_succgen != VATTR(deltakey).af_gen)) return (AF_OK); deltachain[1] = *deltakey; /* if deltakey points to chunk do nothing else */ if ((VATTR(deltakey).af_succgen == AF_NOVNUM) && (VATTR(deltakey).af_succrev == AF_NOVNUM)) { i = 1; } else { i = 2; keyptr = &(deltachain[2]); while (VATTR(keyptr).af_repr == AF_DELTA) { i++; if ((i & AF_SEGLEN) == AF_SEGLEN) /* if segment is full */ if ((deltachain = (Af_key *) realloc ((char *) deltachain, (unsigned) ((i+AF_SEGLEN) * sizeof(Af_key)))) == NULL) FAIL ("rmdelta", "realloc", AF_ESYSERR, ERROR); af_buildkey (deltakey->af_ldes, VATTR(keyptr).af_succgen, VATTR(keyptr).af_succrev, &(deltachain[i])); keyptr = &(deltachain[i]); } } tmpname = af_gtmpname ("/tmp"); af_regtmpfile (tmpname); /* if deltakey points to chunk, only the predecessor version has to */ /* be rebuilt */ if (i == 1) { /* generate chunk for predecessor */ if (afReconsData (VATTR(deltakey).af_data, VATTR(predptr).af_data, VATTR(deltakey).af_fsize, VATTR(predptr).af_dsize, tmpname) == ERROR) FATAL ("rmdelta", "", AF_EDELTA, ERROR); VATTR(predptr).af_repr = AF_CHUNK; /* update sizes in revision list descriptor and in attribute buffer */ deltakey->af_ldes->af_datasize -= VATTR(predptr).af_dsize; VATTR(predptr).af_dsize = 0; VATTR(predptr).af_fsize = af_retfsize (tmpname); deltakey->af_ldes->af_datasize += VATTR(predptr).af_fsize; /* if VATTR(predptr).af_data points to memory allocated by an own * af_malloc (and not in af_readdata), this memory segment remains * "unfreed" (This is a BUG !). */ if ((VATTR(predptr).af_data = af_malloc (predptr->af_ldes, (unsigned) (VATTR(predptr).af_fsize * sizeof(char)))) == NULL) return (ERROR); tmpfile = fopen (tmpname, "r"); fread (VATTR(predptr).af_data, (size_t) VATTR(predptr).af_fsize, sizeof (char), tmpfile); fclose (tmpfile); unlink (tmpname); af_unregtmpfile (tmpname); VATTR(predptr).af_succgen = AF_NOVNUM; VATTR(predptr).af_succrev = AF_NOVNUM; return (AF_OK); } /* else process delta chain and build pred and succ version */ succsize = VATTR(keyptr).af_fsize; if ((succdata = malloc ((unsigned) (VATTR(keyptr).af_fsize * sizeof (char)))) == NULL) FAIL ("rmdelta", "malloc", AF_ESYSERR, ERROR); memcpy (succdata, VATTR(keyptr).af_data, succsize); /* first step is done */ i--; /* first regenerate sucessor version and leave it in the buffer "succdata" */ for (; i >= 2; i--) { keyptr = &(deltachain[i]); if (afReconsData (succdata, VATTR(keyptr).af_data, (long) succsize, VATTR(keyptr).af_dsize, tmpname) == ERROR) FATAL ("rmdelta", "", AF_EDELTA, ERROR); succsize = af_retfsize (tmpname); if ((succdata = realloc (succdata, (unsigned) (succsize * sizeof(char)))) == NULL) FAIL ("rmdelta", "realloc", AF_ESYSERR, ERROR); tmpfile = fopen (tmpname, "r"); fread (succdata, (size_t)succsize, sizeof (char), tmpfile); fclose (tmpfile); } /* regenerate predecessor version in buffer "preddata" */ if (afReconsData (succdata, VATTR(deltakey).af_data, (long) succsize, VATTR(deltakey).af_dsize, tmpname) == ERROR) FATAL ("rmdelta", "", AF_EDELTA, ERROR); predsize = af_retfsize (tmpname); if ((preddata = malloc ((unsigned) (predsize * sizeof (char)))) == NULL) FAIL ("rmdelta", "malloc", AF_ESYSERR, ERROR); tmpfile = fopen (tmpname, "r"); fread (preddata, predsize, sizeof (char), tmpfile); fclose (tmpfile); if (afReconsData (preddata, VATTR((&(deltachain[0]))).af_data, (long) predsize, VATTR((&(deltachain[0]))).af_dsize, tmpname) == ERROR) FATAL ("rmdelta", "", AF_EDELTA, ERROR); predsize = af_retfsize (tmpname); if ((preddata = realloc (preddata, (unsigned) (predsize * sizeof (char)))) == NULL) FAIL ("rmdelta", "realloc", AF_ESYSERR, ERROR); tmpfile = fopen (tmpname, "r"); fread (preddata, predsize, sizeof (char), tmpfile); fclose (tmpfile); /* build new delta for predecessor version */ if (afMakeDelta (succdata, preddata, (long) succsize, (long) predsize, tmpname) == ERROR) FATAL ("rmdelta", "", AF_EDELTA, ERROR); /* update sizes in revision list descriptor and in attribute buffer */ deltakey->af_ldes->af_datasize -= VATTR(predptr).af_dsize; if ((VATTR(predptr).af_dsize = af_retfsize (tmpname)) != 0) { deltakey->af_ldes->af_datasize += VATTR(predptr).af_dsize; /* if VATTR(predptr).af_data points to memory allocated by an own * af_malloc (and not in af_readdata), this memory segment remains * "unfreed" (This is a BUG !). */ if ((VATTR(predptr).af_data = af_malloc (predptr->af_ldes, (unsigned) (VATTR(predptr).af_dsize*sizeof(char)))) == NULL) return (ERROR); tmpfile = fopen (tmpname, "r"); fread (VATTR(predptr).af_data, (size_t) VATTR(predptr).af_dsize, sizeof (char), tmpfile); fclose (tmpfile); } else { VATTR(predptr).af_data = NULL; } unlink (tmpname); af_unregtmpfile (tmpname); free (succdata); free (preddata); VATTR(predptr).af_succgen = VATTR((&(deltachain[2]))).af_gen; VATTR(predptr).af_succrev = VATTR((&(deltachain[2]))).af_rev; free ((char *) deltachain); return (AF_OK); } shapetools-1.4pl6.orig/src/atfs/afdeltaproc.c100444 2013 145 25634 5412541161 17345 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afdeltaproc.c -- generate and merge deltas * * by Andreas Lampen, TU-Berlin (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afdeltaproc.c[7.0] Fri Jun 25 14:31:51 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #define MV 0 #define AD 1 struct ed_cmd { int cmd; size_t length; }; #define TREESIZE 16129 #define SUFFSIZE 3 #define MINBLENG 18 #define MAXCMDLEN 32 struct indices { size_t idx; struct indices *next; }; struct suffixes { struct indices *next; struct indices *last; }; LOCAL size_t getCmd (strPtr, cmdPtr) char *strPtr; struct ed_cmd *cmdPtr; { size_t i=1; if (*strPtr == '\0') cmdPtr->cmd = MV; else cmdPtr->cmd = AD; cmdPtr->length = 0; while (strPtr[i]) { cmdPtr->length = cmdPtr->length << 3; cmdPtr->length |= ((strPtr[i++] - 48) & 07); } return (i+1); } LOCAL size_t getIndex (strPtr, indexPtr) char *strPtr; size_t *indexPtr; { size_t i=0; *indexPtr = 0; while (strPtr[i]) { *indexPtr = *indexPtr << 3; *indexPtr |= ((strPtr[i++] - 48) & 07); } if (i==0) i++; /* correction for zero value */ return (i+1); } LOCAL size_t putCmd (command, length, strPtr) int command; size_t length; char *strPtr; { size_t i=1, j=0; unsigned tmpLen; /* This should be "unsigned size_t" (and if * "size_t" were not a typedef, we could do just * that) */ char tmpStr[16]; switch (command) { case MV: strPtr[0] = '\0'; break; case AD: strPtr[0] = '\001'; break; default: strPtr[0] = '?'; } tmpLen = length; /* The compiler should warn about any narrowing */ while(tmpLen) { tmpStr[j++] = (tmpLen & 07) + 48; tmpLen >>= 3; /* The result would be implementation-defined * if "tmpLen" were negative */ } while (j) strPtr[i++] = tmpStr[--j]; if (!length) strPtr[i++] = '\0'; strPtr[i++] = '\0'; return (i); } LOCAL size_t putIndex (idx, strPtr) size_t idx; char *strPtr; { size_t i=0, j=0; unsigned tmpIdx; /* This should be "unsigned size_t" (and if * "size_t" were not a typedef, we could do just * that) */ char tmpStr[16]; tmpIdx = idx; /* The compiler should warn about any narrowing */ while(tmpIdx) { tmpStr[j++] = (tmpIdx & 07) + 48; tmpIdx >>= 3; /* The result would be implementation-defined * if "tmpIdx" were negative */ } while (j) strPtr[i++] = tmpStr[--j]; if (!idx) strPtr[i++] = '\0'; strPtr[i++] = '\0'; return (i); } /*=================================================================== * afConvertDelta -- convert Deltas * For sake of portability of archive files, numbers occuring * in deltas ("command", "length" and "idx") are stored in their * ASCII representation rather than binary. * *===================================================================*/ EXPORT char *afConvertDelta (deltaStr, deltaSize, newDeltaSize) char *deltaStr; size_t deltaSize, *newDeltaSize; { struct ed_cmd cmd; size_t idx; char *deltaPtr = deltaStr, *deltaEnd = deltaStr + deltaSize; char *newDelta, *newDeltaPtr; if (deltaSize < 16) deltaSize = 16; if ((newDelta = malloc ((unsigned) deltaSize*2)) == NULL) FAIL ("ConvertDelta", "malloc", AF_ESYSERR, NULL); newDeltaPtr = newDelta; /* newDeltaEnd = newDelta + deltaSize*2; */ while (deltaPtr < deltaEnd) { memcpy ((char *)&cmd, deltaPtr, sizeof (cmd)); deltaPtr += sizeof (cmd); newDeltaPtr += putCmd (cmd.cmd, cmd.length, newDeltaPtr); switch (cmd.cmd) { case MV: memcpy ((char*)&idx, deltaPtr, sizeof (idx)); deltaPtr += sizeof (idx); newDeltaPtr += putIndex (idx, newDeltaPtr); break; case AD: memcpy (newDeltaPtr, deltaPtr, (size_t) cmd.length); deltaPtr += cmd.length; newDeltaPtr += cmd.length; break; } } *newDeltaSize = newDeltaPtr - newDelta; return (newDelta); } /*=================================================================== * afReconsData -- reconstruct data from delta * *===================================================================*/ EXPORT int afReconsData (srcStr, deltaStr, srcSize, deltaSize, targetfn) char *srcStr, *deltaStr; size_t srcSize, deltaSize; char *targetfn; { FILE *ftarg; struct ed_cmd cmd; size_t idx; char *deltaPtr = deltaStr, *deltaEnd = deltaStr + deltaSize; if ((ftarg = fopen(targetfn, "w")) == NULL) return (ERROR); if (deltaSize == (size_t) 0) { if (srcSize > 0) fwrite (srcStr, sizeof(char), (size_t)srcSize, ftarg); fclose (ftarg); return (AF_OK); } while (deltaPtr < deltaEnd) { deltaPtr += getCmd (deltaPtr, &cmd); switch (cmd.cmd) { case MV: deltaPtr += getIndex (deltaPtr, &idx); fwrite (srcStr + idx, sizeof(char), (size_t)cmd.length, ftarg); break; case AD: fwrite (deltaPtr, sizeof(char), (size_t)cmd.length, ftarg); deltaPtr += cmd.length; break; default: fclose(ftarg); return (ERROR); } } fclose(ftarg); return(AF_OK); } /*=================================================================== * afMakeDelta -- generate delta * *===================================================================*/ LOCAL FILE *fdelta = NULL; /*============================ * manage suffix tree * *============================*/ LOCAL struct suffixes *suff_array = NULL; LOCAL struct indices *FreePtr; #define HASH(STRING,OFFSET)\ STRING[OFFSET] +\ (STRING[OFFSET + 4] << 1) +\ (STRING[OFFSET + 7] << 2) +\ (STRING[OFFSET + 11] << 3) +\ (STRING[OFFSET + 15] << 4) +\ (STRING[OFFSET + 17] << 5) LOCAL int build_suffix_tree (string, length) register char *string; size_t length; { register struct indices *current; register size_t i = 0; register int hash; struct indices *LargeMemPtr; suff_array = (struct suffixes *) malloc(TREESIZE * sizeof (struct suffixes)); if (suff_array == NULL) return (ERROR); memset ((char *)suff_array, 0, TREESIZE * sizeof(struct suffixes)); if ((LargeMemPtr = (struct indices *) calloc ((unsigned) length, sizeof (struct indices))) == 0) return (ERROR); FreePtr = LargeMemPtr; hash = abs (HASH (string, 0)); suff_array[hash].next = LargeMemPtr; LargeMemPtr++; suff_array[hash].last = suff_array[hash].next; suff_array[hash].next->idx = 0; suff_array[hash].next->next = NULL; for (i = 1; i < (length - (MINBLENG - 1)); i++) { hash = abs (HASH (string,i)); if (suff_array[hash].last) current = suff_array[hash].last->next = LargeMemPtr; else current = suff_array[hash].next = LargeMemPtr; LargeMemPtr++; current->idx = i; current->next = NULL; suff_array[hash].last = current; } return (AF_OK); } LOCAL void find_max_bm(t_str, s_str, targetSize, srcSize, t_offset, s_offset, leng) register char *t_str, *s_str; size_t targetSize, srcSize; size_t t_offset; size_t *s_offset, *leng; { register struct indices *current; register int i,j; register int hash; int off; int max; hash = abs (HASH (t_str, t_offset)); if (suff_array[hash].next == NULL) *leng = 0; else { max = 0; off = 0; current = suff_array[hash].next; while (current) { i = current->idx; j = t_offset; while ((i < srcSize) && (j < targetSize) && (t_str[j] == s_str[i])) { j++; i++; } if ((i - current->idx > max) && (t_str[t_offset] == s_str[current->idx]) && (t_str[t_offset + 1] == s_str[current->idx + 1])) { max = i - current->idx; off = current->idx; } current = current->next; if (current) { while (((t_offset + max) < targetSize) && ((current->idx + max) < srcSize) && (t_str[t_offset + max] != s_str[current->idx + max]) && (current->next)) current = current->next; } } *s_offset = off; if(max >= MINBLENG ) *leng = max; else *leng = 0; } return; } LOCAL void write_cmd (command, length, idx, targetString) int command; size_t length; size_t idx; char *targetString; { char cmdStr[MAXCMDLEN]; int cmdLength; cmdLength = putCmd (command, length, cmdStr); switch (command) { case MV: cmdLength += putIndex (idx, &cmdStr[cmdLength]); fwrite (cmdStr, sizeof(char), (size_t)cmdLength, fdelta); break; case AD: fwrite (cmdStr, sizeof(char), cmdLength, fdelta); fwrite (targetString+idx, sizeof(char), (size_t)length, fdelta); break; } } EXPORT int afMakeDelta (srcStr, targetStr, srcSize, targetSize, deltafn) char *srcStr, *targetStr; size_t srcSize, targetSize; char *deltafn; { register size_t trg_index = 0; size_t src_index, matchlength; register size_t nomtch_trg_index = 0, nomtchlength = 0; int nomatch = FALSE; fdelta = fopen (deltafn, "w"); /* if source and target are identical */ if (srcSize == targetSize) { if ((memcmp (srcStr, targetStr, (int) srcSize)) == 0) { fclose (fdelta); return (AF_OK); } } if ((srcSize <= MINBLENG) || (targetSize <= MINBLENG)) { write_cmd (AD, targetSize, (size_t)0, targetStr); fclose (fdelta); return(AF_OK); } if (build_suffix_tree (srcStr, srcSize) == ERROR) { fclose (fdelta); return(ERROR); } while (trg_index < (targetSize - (MINBLENG - 1))) { find_max_bm (targetStr, srcStr, targetSize, srcSize, trg_index, &src_index, &matchlength); if (matchlength > 0) { if (nomatch) { write_cmd (AD, nomtchlength, nomtch_trg_index, targetStr); nomtch_trg_index = 0; nomtchlength = 0; nomatch = FALSE; } write_cmd (MV, matchlength, src_index, targetStr); trg_index = trg_index + matchlength; } else { if (nomatch) nomtchlength++; else { nomatch = TRUE; nomtch_trg_index = trg_index; nomtchlength = 1; } trg_index++; if (trg_index >= targetSize) write_cmd (AD, nomtchlength, nomtch_trg_index, targetStr); } } if (trg_index <= (targetSize - 1)) { if (nomatch) write_cmd (AD, (nomtchlength + (targetSize - trg_index)), nomtch_trg_index, targetStr); else write_cmd (AD, (targetSize - trg_index), trg_index, targetStr); } fclose (fdelta); return(AF_OK); } shapetools-1.4pl6.orig/src/atfs/afenviron.c100444 2013 145 15735 5617455601 17063 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afenviron.c -- communication with the UNIX-Environment * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afenviron.c[7.1] Thu Aug 4 16:02:51 1994 andy@cs.tu-berlin.de frozen $ */ #include #include #include "atfs.h" #include "afarchive.h" /*======================================================================== * af_getuid - returns uid of user if from local host * AF_ERROR if user is unknown * AF_REMOTE if user is not local *========================================================================*/ EXPORT uid_t af_getuid (name, host, domain) char *name, *host, *domain; { struct passwd *pwent; if (name == NULL) /* in this case, name and host are null pointers */ return ((uid_t) ERROR); if (strcmp (af_getdomain(), NOTNIL(domain))) return ((uid_t) AF_REMOTE); if ((pwent = getpwnam (name)) == NULL) FATAL ("getuid", "cannot get user ID", AF_EINTERNAL, (uid_t) ERROR); return (pwent->pw_uid); } /*======================================================================== * af_getgid - returns gid of user if from local host * AF_ERROR if user is unknown * AF_REMOTE if user is not local *========================================================================*/ EXPORT gid_t af_getgid (name, host, domain) char *name, *host, *domain; { register struct passwd *pwent; if (name == NULL) /* in this case, name and host are null pointers */ return ((gid_t) ERROR); if (strcmp (af_getdomain(), NOTNIL(domain))) return ((gid_t) AF_REMOTE); if ((pwent = getpwnam (name)) == NULL) FATAL ("getgid", "cannot get group ID", AF_EINTERNAL, (gid_t) ERROR); return (pwent->pw_gid); } /*======================================================================== * af_afuser - returns name, host, and domain of caller *========================================================================*/ static uid_t calleruid; static Af_user caller; static bool initcaller = FALSE; #ifdef __STDC__ EXPORT Af_user *af_afuser (uid_t uid) #else EXPORT Af_user *af_afuser (uid) uid_t uid; #endif { static Af_user result; register struct passwd *pwent; if (!initcaller) /* if caller struct is not yet initialized */ { calleruid = geteuid(); if ((pwent = getpwuid (calleruid)) == NULL) FAIL ("getuser", "", AF_EINVUSER, NULL); strcpy (caller.af_username, pwent->pw_name); strcpy (caller.af_userhost, af_gethostname ()); strcpy (caller.af_userdomain, af_getdomain ()); initcaller = TRUE; } if (uid == calleruid) return (&caller); if ((pwent = getpwuid (uid)) == NULL) FAIL ("getuser", "", AF_EINVUSER, NULL); strcpy (result.af_username, pwent->pw_name); strcpy (result.af_userhost, af_gethostname ()); strcpy (result.af_userdomain, af_getdomain ()); return (&result); } /*==================================================================== * af_checkread -- see if AF-file is readable *====================================================================*/ EXPORT int af_checkread (key) Af_key *key; { uid_t uid, auuid, ownuid; if ((VATTR(key).af_mode & 0004) == 0004) /* readable for world */ return (AF_OK); if ((VATTR(key).af_mode & 0040) == 0040) /* readable for group */ { struct group *groupEntry; Af_user *myself; gid_t augid; int i=0; augid = af_getgid (VATTR(key).af_auname, VATTR(key).af_auhost, VATTR(key).af_audomain); /* check effective group id */ if (augid == getegid()) return (AF_OK); /* check supplementary groups */ if ((groupEntry = getgrgid (augid))) { /* if we find the author's group ... */ if ((myself = af_afuser (geteuid()))) { /* ... and my password entry ... */ while (groupEntry->gr_mem[i]) { /* ... then check if my name is in the group's members list */ if (!strcmp (myself->af_username, groupEntry->gr_mem[i++])) return (AF_OK); } } } } if ((VATTR(key).af_mode & 0400) == 0400) /* readable by owner */ { uid = geteuid(); auuid = af_getuid (VATTR(key).af_auname, VATTR(key).af_auhost, VATTR(key).af_audomain); ownuid = af_getuid (CATTR(key).af_ownname, CATTR(key).af_ownhost, CATTR(key).af_owndomain); if ((auuid == uid) || (ownuid == uid)) return (AF_OK); } return (ERROR); } /*==================================================================== * af_checkperm -- check access permissions for AF-file *====================================================================*/ EXPORT int af_checkperm (key, mode) Af_key *key; int mode; { uid_t uid = geteuid(), lockeruid; bool ok = FALSE; if (mode & AF_OWNER) { if (uid == af_getuid (CATTR(key).af_ownname, CATTR(key).af_ownhost, CATTR(key).af_owndomain)) ok = TRUE; } if (!ok && (mode & AF_LOCKHOLDER)) { if ((lockeruid = af_getuid (VATTR(key).af_lckname, VATTR(key).af_lckhost, VATTR(key).af_lckdomain)) == uid) ok = TRUE; else { /* if object is locked by someone else */ if (lockeruid != (uid_t) ERROR) goto exit; } } if (!ok && (mode & AF_AUTHOR)) { if (uid == af_getuid (VATTR(key).af_auname, VATTR(key).af_auhost, VATTR(key).af_audomain)) ok = TRUE; } if (!ok && (mode & AF_WORLD)) { ok = TRUE; } exit: /* if access is not ok, or AtFS subdir is not writable */ if (!ok) FAIL ("checkperm", "", AF_EACCES, ERROR); if (!(key->af_ldes->af_extent & AF_UXWRITE)) FAIL ("checkperm", "", AF_ENOATFSDIR, ERROR); return (AF_OK); } /*====================== * af_gethostname *======================*/ static char *hostSym = NULL; EXPORT char *af_gethostname () { char hostName[HOST_MAX]; if (!hostSym) { gethostname (hostName, HOST_MAX); hostSym = af_entersym (hostName); } return (hostSym); } /*====================== * af_getdomain *======================*/ static char *domainSym = NULL; EXPORT char *af_getdomain () { char domainName[DOMAIN_MAX+1]; if (domainSym) return (domainSym); getdomainname (domainName, DOMAIN_MAX); if (!domainName[0]) { domainSym = af_gethostname (); return (domainSym); } domainName[DOMAIN_MAX] = '\0'; if ((domainName[0] == '.') || (domainName[0] == '+')) domainSym = af_entersym (&domainName[1]); else domainSym = af_entersym (domainName); return (domainSym); } shapetools-1.4pl6.orig/src/atfs/aferror.c100444 2013 145 17235 5412541132 16515 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * aferror.c -- Error handling functions * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: aferror.c[7.0] Fri Jun 25 14:31:55 1993 andy@cs.tu-berlin.de frozen $ */ #include #include #ifdef SYSLOG #include #endif #include "atfs.h" static char logName[USER_MAX] = ""; /*========================================================================= * af_serr -- report error without writing error protocol *=========================================================================*/ extern int errno; extern char *sys_errlist[]; EXPORT int af_errno, af_nodiag = FALSE; EXPORT void af_serr (routine, called, errcd) char *routine; char *called; int errcd; { af_nodiag = TRUE; af_err (routine, called, errcd); af_nodiag = FALSE; } /*========================================================================= * af_err -- write error protocol *=========================================================================*/ static char diagstr[265]; /* for diagnistics of AF_EMISC */ static char *errors[] = { "", "", "", "permission denied", /* 3 */ "archive file has changed since last read", /* 4 */ "archive file is locked for writing", /* 5 */ "no additional space in binary pool", /* 6 */ "specified revision must not be a busy version", /* 7 */ "specified revision is a derived object", /* 8 */ "invalid key", /* 9 */ "invalid set", /* 10 */ "invalid user", /* 11 */ "bad version number", /* 12 */ "invalid location of archive", /* 13 */ "application exceeds memory limit", /* 14 */ "miscellaneous errors", /* 15 */ "invalid mode", /* 16 */ "AtFS subdirectory missing or not writable", /* 17 */ "key does not exist in set", /* 18 */ "invalid position in set", /* 19 */ "specified revision does not exist", /* 20 */ "specified object is no busy version", /* 21 */ "specified object is no derived object", /* 22 */ "version is not locked or locked by someone else", /* 23 */ "specified object is no regular file", /* 24 */ "specified object has no versions", /* 25 */ "user defined attribute does not exist", /* 26 */ "saved versions cannot be modified", /* 27 */ "invalid state transition", /* 28 */ "string too long", /* 29 */ "too many user defined attributes", /* 30 */ "wrong state", /* 31 */ "error during delta operation", /* 32 */ "Archive file inconsistent", /* 33 */ "internal error", /* 34 */ "no AtFS file", /* 35 */ "cannot build archive name (filename too long)", /* 36 */ }; EXPORT void af_err (routine, called, errcd) char *routine; char *called; int errcd; { char *prefix; #ifndef SYSLOG FILE *errfile; #endif if (af_nodiag) { af_errno = errcd; if (af_errno == AF_EMISC) strcpy (diagstr, called); return; /* do nothing */ } #ifdef SYSLOG if (!openlog ("AtFS", LOG_PID, LOG_LOCAL1)) { #else if ((errfile = fopen (AF_ERRLOG, "a")) == NULL) { #endif fprintf (stderr, "AtFS: cannot open Error-logfile\n"); return; } chmod (AF_ERRLOG, 0666); if (!(*logName)) { struct passwd *pwent; if ((pwent = getpwuid (geteuid()))) strcpy (logName, pwent->pw_name); else strcpy (logName, "--?--"); } if (isupper (routine[0])) prefix = "af"; else prefix = "af_"; #ifdef SYSLOG switch (errcd) { case AF_ESYSERR: syslog (LOG_ERR, "%s called %s%s: %s error in %s (%m)", logName, prefix, routine, errors [abs(errcd)], called); break; case AF_EINCONSIST: case AF_ENOATFSFILE: case AF_EINTERNAL: syslog (LOG_ERR, "%s called %s%s: %s (%s)", logName, prefix, routine, errors [abs(errcd)], called); break; case AF_EMISC: syslog (LOG_ERR, "%s called %s%s: %s ", logName, prefix, routine, called); strcpy (diagstr, called); break; default: syslog (LOG_ERR, "%s called %s%s: %s", logName, prefix, routine, errors [abs(errcd)]); } #else fprintf (errfile, "%s pid[%d] %s",af_gethostname(),getpid (), af_asctime ()); switch (errcd) { case AF_ESYSERR: fprintf (errfile, "\t%s called %s%s: %s error in %s\n", logName, prefix, routine, errors [abs(errcd)], called); break; case AF_EINCONSIST: case AF_ENOATFSFILE: case AF_EINTERNAL: fprintf (errfile, "\t%s called %s%s: %s (%s)\n", logName, prefix, routine, errors [abs(errcd)], called); break; case AF_EMISC: fprintf (errfile, "\t%s called %s%s: %s\n", logName, prefix, routine, called); strcpy (diagstr, called); break; default: fprintf (errfile, "\t%s called %s%s: %s\n", logName, prefix, routine, errors [abs(errcd)]); } #endif #ifdef SYSLOG closelog (); #else fclose (errfile); #endif af_errno = errcd; return; } /*========================================================================= * af_wng -- write warning to error protocol *=========================================================================*/ EXPORT void af_wng (routine, comment) char *routine, *comment; { char *prefix; #ifndef SYSLOG FILE *errfile; #endif #ifdef SYSLOG if (!openlog ("AtFS", LOG_PID, LOG_LOCAL1)) { #else if ((errfile = fopen (AF_ERRLOG, "a")) == NULL) { #endif fprintf (stderr, "AtFS: cannot open Error-logfile\n"); return; } chmod (AF_ERRLOG, 0666); if (!(*logName)) { struct passwd *pwent; if ((pwent = getpwuid (geteuid()))) strcpy (logName, pwent->pw_name); else strcpy (logName, "--?--"); } if (isupper (routine[0])) prefix = "af"; else prefix = "af_"; #ifdef SYSLOG syslog (LOG_ERR, "%s called %s%s: Warning - %s", logName, prefix, routine, comment); #else fprintf (errfile, "%s pid[%d] %s", af_gethostname(), getpid (), af_asctime ()); fprintf (errfile, "\t%s called %s%s: Warning - %s\n", logName, prefix, routine, comment); #endif #ifdef SYSLOG closelog (); #else fclose (errfile); #endif return; } /*========================================================================= * af_perror -- print AtFS-error message *=========================================================================*/ EXPORT void af_perror (string) char *string; { switch (af_errno) { case AF_ESYSERR: perror (string); break; case AF_EMISC: fprintf (stderr, "%s: %s\n", string, diagstr); break; default: fprintf (stderr, "%s: %s\n", string, errors [abs(af_errno)]); } } /*========================================================================= * af_errmsg -- print AtFS-error message *=========================================================================*/ EXPORT char *af_errmsg (string) char *string; { static char errMsg[256]; switch (af_errno) { case AF_ESYSERR: sprintf (errMsg, "%s: %s", string, sys_errlist[errno]); break; case AF_EMISC: sprintf (errMsg, "%s: %s", string, diagstr); break; default: sprintf (errMsg, "%s: %s", string, errors [abs(af_errno)]); } return (errMsg); } shapetools-1.4pl6.orig/src/atfs/affiles.c100444 2013 145 20012 5617463260 16465 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * affiles.c -- UNIX-files in AtFS * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: affiles.c[7.1] Thu Aug 4 16:02:54 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" extern int af_errno; /*================================================================ * af_access -- see if any version of named file exists *================================================================*/ EXPORT int af_access (path, name, type, mode) char *path, *name, *type; int mode; { char *uniqPath = af_uniqpath (af_entersym(path)); /* empty name argument */ if (!name || !(*name)) { if (type && *type) FAIL ("access", "cannot handle empty name and non-empty type", AF_EMISC, ERROR); name = "."; } /* too much hassle to handle this case */ if (!strcmp (name, "..") && (!type || !(*type))) FAIL ("access", "cannot handle name '..'", AF_EMISC, ERROR); /* when referring the current directory, busyname is just the pathname */ if (!strcmp (name, ".") && (!type || !(*type))) return (afTestAso (af_afpath (uniqPath), af_afname (uniqPath), af_aftype (uniqPath), mode)); else return (afTestAso (uniqPath, name, type, mode)); } /*================================================================ * af_crkey *================================================================*/ EXPORT int af_crkey (path, name, type, key) char *path; char *name, *type; Af_key *key; { char *busyname, *uniqpath = af_uniqpath (af_entersym(path)); FILE *busyfile; struct stat bibuf; /* empty name argument */ if (!name || !(*name)) { name = "."; if (type && *type) FAIL ("crkey", "cannot handle empty name and non-empty type", AF_EMISC, ERROR); name = "."; } /* too much hassle to handle this case */ if (!strcmp (name, "..") && (!type || !(*type))) FAIL ("crkey", "cannot handle name '..'", AF_EMISC, ERROR); /* when referring the current directory, busyname is just the pathname */ if (!strcmp (name, ".") && (!type || !(*type))) { busyname = uniqpath; uniqpath = af_afpath (busyname); name = af_afname (busyname); type = af_aftype (busyname); } else busyname = af_gbusname (uniqpath, name, type); /* if file does not exist -- create it */ if ((stat (busyname, &bibuf)) == ERROR) { if ((busyfile = fopen (busyname, "w")) == NULL) FAIL ("crkey", "fopen", AF_ESYSERR, ERROR); fclose (busyfile); stat (busyname, &bibuf); } /* select busy version if present */ if (afGetAso (uniqpath, name, type, AF_BUSYVERS, AF_BUSYVERS, key) == ERROR) return (ERROR); return (AF_OK); } /*================================================================ * af_open *================================================================*/ EXPORT FILE *af_open (key, mode) Af_key *key; char *mode; { FILE *file; char *tmpname; if (afAccessAso (key, AF_ATTRS)) FAIL ("open", "", AF_EINVKEY, NULL); /* if file is present as busy version */ if (VATTR(key).af_state == AF_BUSY) { if ((file = fopen (key->af_ldes->af_busyfilename, mode)) == NULL) FAIL ("open", "fopen", AF_ESYSERR, NULL); VATTR(key).af_atime = af_acttime (); return (file); } /* saved versions can be opened only for reading */ if (mode[0] != 'r') FAIL ("open", "", AF_ESAVED, NULL); /* see if file is readable */ if (af_checkread (key) == ERROR) FAIL ("open", "cannot read", AF_EACCES, NULL); /* build name for temporary file */ tmpname = af_gtmpname ("/tmp"); af_regtmpfile (tmpname); if (afBuildFile (key, tmpname) == ERROR) return (NULL); if ((file = fopen (tmpname, mode)) == NULL) FAIL ("open", "fopen", AF_ESYSERR, NULL); unlink (tmpname); /* this causes the tmp file to be removed on closing */ af_unregtmpfile (tmpname); /* do *not* set access date for sake of efficiency * VATTR(key).af_atime = af_acttime (); * * possibly the date of last access is *not* set properly * * instead of * afUpdateAso (key, 0); * * this should be * * if (afUpdateAso (key, 0) == ERROR) * * return (NULL); */ return (file); } /*================================================================ * af_establish *================================================================*/ EXPORT int af_establish (key, fileName) Af_key *key; char *fileName; { if (afAccessAso (key, AF_ATTRS)) FAIL ("establish", "", AF_EINVKEY, ERROR); /* see if file is readable */ if (af_checkread (key) == ERROR) FAIL ("establish", "cannot read", AF_EACCES, ERROR); /* if file is present as busy version */ if (VATTR(key).af_state == AF_BUSY) { if (af_cpfile (key->af_ldes->af_busyfilename, VATTR(key).af_fsize, fileName) == ERROR) return (ERROR); } if (afBuildFile (key, fileName) == ERROR) return (ERROR); /* do *not* set access date for sake of efficiency * VATTR(key).af_atime = af_acttime (); * * possibly the date of last access is *not* set properly * * instead of * afUpdateAso (key, 0); * * this should be * * if (afUpdateAso (key, 0) == ERROR) * * return (NULL); */ return (AF_OK); } /*================================================================ * af_close *================================================================*/ EXPORT int af_close (file) FILE *file; { return (fclose (file)); } /*================================================================ * af_rm *================================================================*/ EXPORT int af_rm (key) Af_key *key; { if (afAccessAso (key, AF_ATTRS)) FAIL ("rm", "", AF_EINVKEY, ERROR); /* if object is not locked (derived objects need not to be locked) */ if (VATTR(key).af_state != AF_DERIVED) { if (af_checkperm (key, AF_LOCKHOLDER) == ERROR) FAIL ("rm", "", AF_ENOTLOCKED, ERROR); } /* * if (VATTR(key).af_nrefs > 1) * af_wng ("rm", "deleted object has more than one reference"); */ if (afDeleteAso (key) == ERROR) return (ERROR); return (AF_OK); } /*================================================================ * af_restore *================================================================*/ EXPORT int af_restore (key, restkey) Af_key *key, *restkey; { char *busyname; if (afAccessAso (key, AF_ATTRS)) FAIL ("restore", "", AF_EINVKEY, ERROR); if (VATTR(key).af_state != AF_DERIVED) FAIL ("restore", "", AF_ENOTDERIVED, ERROR); /* see if file is readable */ if (af_checkread (key) == ERROR) FAIL ("restore", "cannot read cached file", AF_EACCES, ERROR); busyname = af_gbusname (CATTR(key).af_syspath, VATTR(key).af_name, VATTR(key).af_type); if (afBuildFile (key, busyname) == ERROR) return (ERROR); /* build key for restored file */ if (afGetAso (CATTR(key).af_syspath, VATTR(key).af_name, VATTR(key).af_type, AF_BUSYVERS, AF_BUSYVERS, restkey) == ERROR) FATAL ("restore", "cannot access restored file", AF_EINTERNAL, ERROR); /* restore user defined attributes from binary pool */ afDropUdas (restkey); afInitUdas (restkey); afCopyUdas (key, restkey); /* do *not* set access date for sake of efficiency * VATTR(key).af_atime = af_acttime (); * * possibly the date of last access is *not* set properly * * instead of * afUpdateAso (key, 0); * * this should be * * if (afUpdateAso (key, 0) == ERROR) * * return (NULL); */ afUpdateAso (restkey, 0); return (AF_OK); } shapetools-1.4pl6.orig/src/atfs/afkeys.c100444 2013 145 12164 5412541103 16331 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afkeys.c -- handle revision keys * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afkeys.c[7.0] Fri Jun 25 14:31:58 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*================================================================ * af_buildkey *================================================================*/ EXPORT int af_buildkey (list, gen, rev, key) Af_revlist *list; int gen; int rev; Af_key *key; /* out */ { register int i = list->af_listlen-1;; key->af_ldes = list; while (!(list->af_list[i].af_class & AF_VALID) || (list->af_list[i].af_gen != gen) || (list->af_list[i].af_rev != rev)) { i--; if (i == -1) FAIL ("buildkey", "", AF_ENOREV, ERROR); } key->af_lpos = i; return (AF_OK); } /*================================================================ * af_gbuskey *================================================================*/ EXPORT Af_key *af_gbuskey (list) Af_revlist *list; { static Af_key busykey; busykey.af_ldes = list; busykey.af_lpos = 0; return (&busykey); } /*================================================================ * af_glastkey *================================================================*/ EXPORT Af_key *af_glastkey (list) Af_revlist *list; { register int i = list->af_listlen-1; static Af_key lastkey; lastkey.af_ldes = list; while (!(list->af_list[i].af_class & AF_VALID)) { i--; if (i == 0) return (NULL); } lastkey.af_lpos = i; return (&lastkey); } /*================================================================ * af_glastgenkey *================================================================*/ EXPORT Af_key *af_glastgenkey (list, gen) Af_revlist *list; int gen; { register int i = list->af_listlen-1; static Af_key lastgenkey; lastgenkey.af_ldes = list; while (!(list->af_list[i].af_class & AF_VALID) || (list->af_list[i].af_gen != gen)) { i--; if (i == 0) return (NULL); } lastgenkey.af_lpos = i; return (&lastgenkey); } /*================================================================ * af_gfreepos -- search space for new list entry * preserve increasing order *================================================================*/ EXPORT int af_gfreepos (list) Af_revlist *list; { register int i = list->af_listlen-1; while (!(list->af_list[i].af_class & AF_VALID) && (i >= 0)) i--; if (i == list->af_listlen-1) return (ERROR); if (!(list->af_list[i].af_class & AF_VALID) && (i == 0)) return (0); return (i+1); } /*================================================================ * af_glastgenpos *================================================================*/ EXPORT int af_glastgenpos (list, gen) Af_revlist *list; int gen; { register int i = list->af_listlen-1; while (!(list->af_list[i].af_class & AF_VALID) || (list->af_list[i].af_gen != gen)) { i--; if (i == 0) return (ERROR); } return (i); } /*=================== * afIncreaseAccess *===================*/ EXPORT void afIncreaseAccess (key) Af_key *key; { (key->af_ldes)->af_access++; VATTR(key).af_nrefs++; #ifdef AFTRACE fprintf (stderr, "AF_TRACE (key): +++%s\n", af_retattr (key, AF_ATTBOUNDPATH)); #endif } /*=================== * afDecreaseAccess *===================*/ EXPORT void afDecreaseAccess (key) Af_key *key; { (key->af_ldes)->af_access--; VATTR(key).af_nrefs--; #ifdef AFTRACE fprintf (stderr, "AF_TRACE (key): ---%s\n", af_retattr (key, AF_ATTBOUNDPATH)); #endif } /*================================================================ * af_dropkey *================================================================*/ EXPORT int af_dropkey (key) Af_key *key; { if (afAccessAso (key, 0)) FAIL ("dropkey", "", AF_EINVKEY, ERROR); /* decrease reference count in corresponding archive and in attrbuf */ afDecreaseAccess (key); return (AF_OK); } /*================================================================ * af_dropall *================================================================*/ extern Af_revlist *af_lists; EXPORT int af_dropall () { Af_revlist *list; register int i; list = af_lists; while (list) { for (i=0; iaf_listlen; i++) list->af_list[i].af_nrefs = 0; list->af_access = 0; list = list->af_next; } #ifdef AFTRACE fprintf (stderr, "AF_TRACE (key): ----------- dropped all ------------\n"); #endif return (AF_OK); } shapetools-1.4pl6.orig/src/atfs/aflib.c100400 2013 145 5723 5412541060 16101 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * aflib.c -- Miscellaneous functions * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: aflib.c[7.0] Fri Jun 25 14:32:00 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*================================================================ * af_retfsize *================================================================*/ EXPORT size_t af_retfsize (file) char *file; { struct stat ibuf; if (stat (file, &ibuf) == -1) return ((size_t) 0); return (ibuf.st_size); } /* af_retfsize */ /*========================================================================= * af_cpfile -- copy files *=========================================================================*/ EXPORT int af_cpfile (source, size, dest) char *source; size_t size; char *dest; { char cont[BUFSIZ]; register int bufsiz = BUFSIZ; register FILE *sfile, *dfile; if ((sfile = fopen (source, "r")) == (FILE *)0) return (ERROR); if ((dfile = fopen (dest, "w")) == (FILE *) 0) { /* try to remove file */ unlink (dest); if ((dfile = fopen (dest, "w")) == (FILE *) 0) { fclose (sfile); return (ERROR); } } while (size > 0) { if (size >= BUFSIZ) size -= BUFSIZ; else { bufsiz = size; size = 0; } if (!fread (cont, sizeof(char), bufsiz, sfile)) { fclose (sfile); fclose (dfile); return (ERROR); } if (!fwrite (cont, sizeof(char), bufsiz, dfile)) { fclose (sfile); fclose (dfile); return (ERROR); } } fclose (sfile); fclose (dfile); return (AF_OK); } /*======================================================================== * af_bsearch -- do binary search on ordered list of strings * returns position (-1 if target not found) *========================================================================*/ EXPORT int af_bsearch (list, size, target) char **list; int size; char *target; { register int hi = size-1, lo=0, pos, res; pos = (hi+lo)/2; while (hi >= lo) { if ((res = strcmp (target, list[pos])) == 0) return (pos); else { if (res < 0) hi = pos - 1; else /* res > 0 */ lo = pos + 1; pos = (hi+lo)/2; } } /* the target string was not found */ return (ERROR); } shapetools-1.4pl6.orig/src/atfs/aflock.c100444 2013 145 10465 5412541043 16313 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * aflock.c -- Version locking * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: aflock.c[7.0] Fri Jun 25 14:32:02 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*================================================================ * af_lock *================================================================*/ EXPORT Af_user *af_lock (key, locker) Af_key *key; Af_user *locker; { int oldlockeruid, newlockeruid, calleruid; if (afAccessAso (key, AF_ATTRS)) FAIL ("lock", "", AF_EINVKEY, NULL); if (!S_ISREG (VATTR(key).af_mode)) FAIL ("lock", "", AF_ENOTREGULAR, NULL); if (VATTR(key).af_state == AF_DERIVED) FAIL ("lock", "", AF_EDERIVED, NULL); if (!locker->af_userhost[0]) strcpy (locker->af_userhost, af_gethostname()); if (!locker->af_userdomain[0]) strcpy (locker->af_userdomain, af_getdomain()); if ((newlockeruid = af_getuid (locker->af_username, locker->af_userhost, locker->af_userdomain)) == ERROR) FAIL ("lock", "invalid locker", AF_EMISC, NULL); calleruid = geteuid (); /* if caller == locker, everyone who has write access may set a lock, */ /* if the object is not locked by someone else */ /* else (caller != locker), only the owner may set a lock for someone else */ if (calleruid == newlockeruid) { if (af_checkperm (key, AF_WORLD) == ERROR) return (NULL); } else { if (af_checkperm (key, AF_OWNER) == ERROR) return (NULL); } /* if version is not locked or already locked by caller */ oldlockeruid = af_getuid (VATTR(key).af_lckname, VATTR(key).af_lckhost, VATTR(key).af_lckdomain); if ((oldlockeruid == (uid_t) ERROR) || (oldlockeruid == calleruid)) { VATTR(key).af_lckname = af_entersym (locker->af_username); VATTR(key).af_lckhost = af_enterhost (locker->af_userhost); VATTR(key).af_lckdomain = af_enterdomain (locker->af_userdomain); VATTR(key).af_ltime = af_acttime(); if (afUpdateAso (key, AF_CHANGE) == ERROR) return (NULL); return (locker); } else FAIL ("lock", "", AF_ENOTLOCKED, NULL); } /*================================================================ * af_unlock *================================================================*/ EXPORT Af_user *af_unlock (key) Af_key *key; { static Af_user locker; if (afAccessAso (key, AF_ATTRS)) FAIL ("unlock", "", AF_EINVKEY, NULL); if (af_checkperm (key, AF_OWNER | AF_LOCKHOLDER) == ERROR) return (NULL); if (VATTR(key).af_lckname) { strcpy (locker.af_username, VATTR(key).af_lckname); strcpy (locker.af_userhost, VATTR(key).af_lckhost); strcpy (locker.af_userdomain, VATTR(key).af_lckdomain); VATTR(key).af_lckname = NULL; VATTR(key).af_lckhost = NULL; VATTR(key).af_lckdomain = NULL; VATTR(key).af_ltime = af_acttime(); if (afUpdateAso (key, AF_CHANGE) == ERROR) return (NULL); } else { locker.af_username[0] = '\0'; locker.af_userhost[0] = '\0'; locker.af_userdomain[0] = '\0'; } return (&locker); } /*================================================================ * af_testlock *================================================================*/ EXPORT Af_user *af_testlock (key) Af_key *key; { static Af_user locker; if (afAccessAso (key, AF_ATTRS)) FAIL ("testlock", "", AF_EINVKEY, NULL); if (VATTR(key).af_lckname) { strcpy (locker.af_username, VATTR(key).af_lckname); strcpy (locker.af_userhost, VATTR(key).af_lckhost); strcpy (locker.af_userdomain, VATTR(key).af_lckdomain); } else { locker.af_username[0] = '\0'; locker.af_userhost[0] = '\0'; locker.af_userdomain[0] = '\0'; } return (&locker); } shapetools-1.4pl6.orig/src/atfs/afmemory.c100444 2013 145 6571 5524437435 16673 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afmemory.c -- memory allocation module for AtFS archive handling * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afmemory.c[7.0] Fri Feb 4 13:55:32 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "afarchive.h" extern int af_listmem; /*========================================================================= * af_malloc -- allocate memory and registrate it * * all memory allocated for data in an archive is preceeded by a pointer * pointing to the prevoiusly allocated memory segment. * So we get a chain of allocated memory segments. * ( probably not portable ) * *=========================================================================*/ #define ALIGN sizeof(long) EXPORT char *af_malloc (list, size) Af_revlist *list; unsigned size; { register char **mem; register int i; if ((i = size%ALIGN)) size += ALIGN-i; size += sizeof(mem); if (afListSpace ((int) size) == ERROR) af_wng ("malloc", "Application exceeds memory limit"); if ((mem = (char **)malloc ((unsigned) (size))) == NULL) FAIL ("malloc", "malloc", AF_ESYSERR, NULL); list->af_totalmem += size; af_listmem += size; *mem = list->af_mem; list->af_mem = (char *)mem; mem++; /* increment by sizeof ptr */ return ((char *)mem); } EXPORT char *af_realloc (list, ptr, size) Af_revlist *list; char *ptr; unsigned size; { char **mem, **segptr, **nextptr; register int i; if ((i = size%ALIGN)) size += ALIGN-i; ptr -= sizeof ((char *)0); /* unregistrate memory segment to be realloc'ed */ segptr = &(list->af_mem); while (*segptr != ptr) segptr = (char **)*segptr; nextptr = (char **)*segptr; *segptr = *nextptr; if ((mem = (char **)realloc (ptr, (unsigned) (size + sizeof (mem)))) == NULL) return NULL; list->af_totalmem += size; /* not correct (size of old segment should */ af_listmem += size; /* be subtracted */ *mem = list->af_mem; /* registrate new segment */ list->af_mem = (char *)mem; mem++; /* increment by sizeof ptr */ return ((char *)mem); } EXPORT void af_free (list, ptr) Af_revlist *list; char *ptr; { char **segptr, **nextptr; ptr -= sizeof ((char *)0); segptr = &(list->af_mem); /* remove memory segment from registration list */ while (*segptr != ptr) segptr = (char **)*segptr; nextptr = (char **)*segptr; *segptr = *nextptr; free (ptr); } EXPORT void af_frmemlist (list) Af_revlist *list; { register char **ptr, **ptr1; ptr = (char **)list->af_mem; while ((char *)ptr) { ptr1 = (char **)*ptr; free (ptr); ptr = ptr1; } af_listmem -= list->af_totalmem; list->af_mem = NULL; list->af_totalmem = 0; } shapetools-1.4pl6.orig/src/atfs/afnames.c100444 2013 145 31705 5520502416 16467 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afnames.c -- deal with UNIX-Filesystem names * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afnames.c[7.0] Sun Jan 23 16:05:55 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "afarchive.h" /*============================================ * af_uniqpath -- build canonical pathname *============================================*/ static char *givenPath[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; static char *uniqPath[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; EXPORT char *af_uniqpath (pathSym) char *pathSym; { char curPath[PATH_MAX], tmpPath[PATH_MAX]; int i=0; if (!pathSym || !(*pathSym) || !strcmp (pathSym, ".")) { getcwd (tmpPath, PATH_MAX); return (af_entersym (tmpPath)); } /* check if "pathSym" is registered in cache */ while (givenPath[i] && (i < 8)) { if (pathSym == givenPath[i]) return (uniqPath[i]); i++; } /* add pathSym to cache */ if (i==8) i=0; getcwd (curPath, PATH_MAX); if (chdir (pathSym) == -1) { /* char tmpPath[PATH_MAX+64]; * sprintf (tmpPath, "cannot change to directory %s", pathSym); * af_wng ("uniqPath", tmpPath); */ return (pathSym); } getcwd (tmpPath, PATH_MAX); givenPath[i] = pathSym; uniqPath[i] = af_entersym (tmpPath); chdir (curPath); return (uniqPath[i]); } /*================================================================ * af_setarchpath *================================================================*/ static char *archpath = NULL; EXPORT char *af_setarchpath (pathname) char *pathname; { register char *oldpath = archpath; if (pathname == NULL) archpath = NULL; else archpath = af_uniqpath (af_entersym(pathname)); return (oldpath); } /*================================================================ * afArchiveOwner *================================================================*/ LOCAL char *curAtFSPath = NULL; LOCAL uid_t curAtFSuid = -1; LOCAL gid_t curAtFSgid = -1; LOCAL bool curAtFSWriteOk = FALSE; LOCAL mode_t curAtFSMode = 0; EXPORT Af_user *afArchiveOwner (archDirSym, writeok, gid) char *archDirSym; bool *writeok; /* out */ gid_t *gid; /* out */ { struct stat ibuf; *writeok = FALSE; *gid = -1; if (archDirSym == curAtFSPath) { *writeok = curAtFSWriteOk; *gid = curAtFSgid; return (af_afuser (curAtFSuid)); } if (stat (archDirSym, &ibuf) == ERROR) { curAtFSPath = NULL; curAtFSuid = -1; curAtFSgid = -1; curAtFSWriteOk = FALSE; curAtFSMode = 0; return (NULL); } if (!access (archDirSym, W_OK)) *writeok = TRUE; curAtFSPath = archDirSym; curAtFSuid = ibuf.st_uid; *gid = curAtFSgid = ibuf.st_gid; curAtFSWriteOk = *writeok; curAtFSMode = ibuf.st_mode; return (af_afuser (ibuf.st_uid)); } /* afArchiveOwner */ EXPORT mode_t afArchiveMode (archDirSym) char *archDirSym; { bool writeOk; gid_t dummy; if (archDirSym == curAtFSPath) { return (curAtFSMode); } afArchiveOwner (archDirSym, &writeOk, &dummy); return (curAtFSMode); /* returns 0 if afArchiveOwner fails */ } /*======================================================================== * afArchivePath -- build pathname for directory containing archive files * (realize symbolic links for AtFS subdirectory) *========================================================================*/ static struct { char *dirname, *atfsname; } arDirList[AF_MAXLISTS]; static int arDirCount = 0; EXPORT char *afArchivePath (pathname) char *pathname; { register int i = 0, len; char tmpname[PATH_MAX]; struct stat ibuf; register FILE *infile; /* see if there is an explicit pathname where archives shall be stored */ if (archpath) return (af_entersym (archpath)); while (arDirList[i].dirname != pathname) { if (i == arDirCount) { arDirList[i].dirname = pathname; ibuf.st_mode = 0; if (!strcmp (pathname, "/")) sprintf (tmpname, "/%s", AF_SUBDIR); else sprintf (tmpname, "%s/%s", pathname, AF_SUBDIR); stat (tmpname, &ibuf); if (S_ISREG(ibuf.st_mode)) { /* AF_SUBDIR is a regular file -- maybe it contains * a reference to another AtFS directory. * -> open file and read contents */ if ((infile = fopen (tmpname, "r"))) { fgets (tmpname, PATH_MAX, infile); fclose (infile); } /* remove trailing newline */ len = strlen(tmpname); if (tmpname[len-1] == '\n') tmpname[len-1] = '\0'; arDirList[i].atfsname = af_uniqpath (af_entersym (tmpname)); arDirCount++; break; } arDirList[i].atfsname = af_entersym (tmpname); arDirCount++; break; } else i++; } return (arDirList[i].atfsname); } /*================================================================ * Get Archive File Name *================================================================*/ EXPORT char *afArchiveName (archivePath, class, name, type, mode) char *archivePath, *class, *name, *type; int mode; { static char arName[PATH_MAX]; char *namePtr = arName, *tmpPtr; mode_t oldUmask; /* build only pathname first */ tmpPtr = archivePath; while ((*namePtr = *tmpPtr++)) namePtr++; *namePtr++ = '/'; if (class && class[0]) { tmpPtr = class; while ((*namePtr = *tmpPtr++)) namePtr++; } *namePtr = '\0'; oldUmask = umask (000); if (mode == AF_WRITE) { bool writeOk; gid_t dummy; struct stat dirIbuf; /* check existence of subdirectories */ if (afArchiveOwner (archivePath, &writeOk, &dummy)) { /* AtFS directory exists, look for subdirectory */ if (writeOk == TRUE) { if (stat (arName, &dirIbuf) == ERROR) { /* subdirectory does not exist, create it with same mode and group as AtFS dir */ mkdir (arName, curAtFSMode); if (chown (arName, curAtFSuid, curAtFSgid) == -1) chown (arName, -1, curAtFSgid); } else { /* subdirectory exists, check permission */ if (access (arName, W_OK)) { /* Hmm, no permision ? Try to change mode */ chmod (arName, curAtFSMode); if (chown (arName, curAtFSuid, curAtFSgid) == -1) chown (arName, -1, curAtFSgid); } } } /* else AtFS directory not writable */ } else { /* no AtFS directory -- try to create it (plus subdirectories) */ char subdirName[PATH_MAX]; mkdir (archivePath, 0755); sprintf (subdirName, "%s/%s", archivePath, AF_ATTRDIR); mkdir (subdirName, 0755); sprintf (subdirName, "%s/%s", archivePath, AF_DATADIR); mkdir (subdirName, 0755); } } umask (oldUmask); /* add file name */ if (name && name[0]) { *namePtr++ = '/'; tmpPtr = name; while ((*namePtr = *tmpPtr++)) namePtr++; } if (type && type[0]) { *namePtr++ = '.'; tmpPtr = type; while ((*namePtr = *tmpPtr++)) namePtr++; } *namePtr++ = '\0'; return (arName); } /*================================================================ * Build Object Cache File Name *================================================================*/ EXPORT char *afCacheFileName (archivePath, name) char *archivePath, *name; { static char cName[PATH_MAX]; char *namePtr = cName, *tmpPtr; tmpPtr = archivePath; while ((*namePtr = *tmpPtr++)) namePtr++; *namePtr++ = '/'; tmpPtr = name; while ((*namePtr = *tmpPtr++)) namePtr++; *namePtr++ = '\0'; return (cName); } /*==================================================================== * afCacheUniqueName -- get unique filename for file in object cache *====================================================================*/ #ifdef __STDC__ EXPORT char *afCacheUniqueName (char *unixName, char uniqChar) #else EXPORT char *afCacheUniqueName (unixName, uniqChar) char *unixName, uniqChar; #endif { char uniqName[NAME_MAX+1]; #if (NAME_MAX < 128) char nameFragment[NAME_MAX-4]; int nameLen = strlen (unixName); if (nameLen > NAME_MAX-5) { strcpy (nameFragment, &unixName[nameLen-(NAME_MAX-5)]); sprintf (uniqName, "%s%s%c", AF_CACHEFILEID, nameFragment, uniqChar); } else sprintf (uniqName, "%s%s%c", AF_CACHEFILEID, unixName, uniqChar); #else sprintf (uniqName, "%s%s%c", AF_CACHEFILEID, unixName, uniqChar); #endif return (af_entersym (uniqName)); } /*================================================================ * af_gtmpname *================================================================*/ static int count=0; EXPORT char *af_gtmpname (pathname) char *pathname; { char tmpname[PATH_MAX]; if (pathname && pathname[0]) sprintf (tmpname, "%s/tmp%d%d", pathname, getpid(), count++); else sprintf (tmpname, "%s/atfs%d%d", AF_TMPDIR, getpid(), count++); return (af_entersym (tmpname)); } /* af_gtmpname */ /*================================================================ * af_gbusname *================================================================*/ EXPORT char *af_gbusname (pathname, name, type) char *pathname; char *name, *type; { char busyname[PATH_MAX]; if (!pathname || !(*pathname)) strcpy (busyname, name); else if (!strcmp (pathname, "/")) sprintf (busyname, "/%s", name); else sprintf (busyname, "%s/%s", pathname, name); if (type && type[0]) { strcat (busyname, "."); strcat (busyname, type); } return (af_entersym (busyname)); } /* af_gbusname */ /*================================================================ * af_afpath *================================================================*/ EXPORT char *af_afpath (unixName) char *unixName; { register char *namePtr, *tmpPtr; static char afPath[PATH_MAX]; if (unixName) strcpy (afPath, unixName); else { afPath[0] = '\0'; return (afPath); } /* cut off version binding */ if (afPath[strlen(afPath)-1] == ']') if ((tmpPtr = strrchr (afPath, '['))) *tmpPtr = '\0'; /* cut name */ if ((namePtr = strrchr (afPath, '/'))) { if (namePtr == afPath) /* e.g. "/tmp" */ afPath[1] = '\0'; else namePtr[0] = '\0'; } else { afPath[0] = '\0'; return (afPath); } /* cut AtFS subdirectory name if present (eg. "AtFS" or "AtFS/Attr"*/ if ((namePtr = strrchr (afPath, '/'))) { if (!strcmp (AF_SUBDIR, namePtr+1)) namePtr[0] = '\0'; else { if ((namePtr > afPath) && (tmpPtr = strrchr (namePtr-1, '/'))) { if (!strcmp (AF_SUBDIR, tmpPtr+1) && (!strcmp (AF_ATTRDIR, namePtr+1) || !strcmp (AF_DATADIR, namePtr+1))) tmpPtr[0] = '\0'; } } } else if (!strcmp (AF_SUBDIR, afPath)) afPath[0] = '\0'; return (afPath); } /*================================================================ * af_afname *================================================================*/ EXPORT char *af_afname (unixName) char *unixName; { register char *typeptr, *namePtr; static char afname[PATH_MAX]; if (!unixName) { afname[0] = '\0'; return (afname); } /* set namePtr to beginning of name */ if ((namePtr = strrchr (unixName, '/')) == NULL) namePtr = unixName; else namePtr++; strcpy (afname, namePtr); /* special handling for "." and ".." */ if (!strcmp (afname, ".") || !strcmp (afname, "..")) return (afname); /* if a UNIX type-extension is given -- cut it, except the dot is */ /* at position 0 (e.g. .cshrc) */ if ((typeptr = strrchr (afname, '.'))) if ((typeptr != afname) && typeptr[1]) typeptr[0] = '\0'; return (afname); } /*================================================================ * af_aftype *================================================================*/ EXPORT char *af_aftype (unixName) char *unixName; { register char *typeptr, *namePtr; static char aftype[TYPE_MAX]; register bool isarch = FALSE; if (!unixName) { aftype[0] = '\0'; return (aftype); } /* set namePtr to beginning of name */ if ((namePtr = strrchr (unixName, '/')) == NULL) namePtr = unixName; else namePtr++; /* if there is no UNIX type-extension */ if ((typeptr = strrchr (namePtr, '.')) == NULL) aftype[0] = '\0'; else { /* if the found dot indicates a "hidden file" (eg. .cshrc) */ if (typeptr == namePtr) aftype[0] = '\0'; else { strcpy (aftype, typeptr + sizeof(char)); /* if the named file is an archive, cut the name-extension */ if (isarch) aftype [strlen (aftype) - sizeof (char)] = '\0'; } } return (aftype); } shapetools-1.4pl6.orig/src/atfs/afobjcache.c100444 2013 145 45765 5520510343 17133 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afobjcache.c -- manage derived object cache * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afobjcache.c[7.0] Sun Jan 23 16:05:57 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "afarchive.h" LOCAL int afObjCacheNameNum = AF_DEFAULT_CACHED_PER_NAME; LOCAL int afObjCacheAttrNum = AF_DEFAULT_CACHED_PER_ATTR; LOCAL int afObjCacheMax = AF_DEFAULT_CACHED_MAX; /*==================== * Object Cache Size *====================*/ extern int afCurTransaction; EXPORT int af_cachesize (path, totalMax, maxPerName, maxPerAttr, oldTotalMax, oldMaxPerName, oldMaxPerAttr) char *path; int totalMax, maxPerName, maxPerAttr; int *oldTotalMax, *oldMaxPerName, *oldMaxPerAttr; { char errMsg[512]; Af_revlist *list; if ((list = afInitObjCache (af_entersym (path))) == NULL) return (ERROR); *oldTotalMax = afObjCacheMax; *oldMaxPerName = afObjCacheNameNum; *oldMaxPerAttr = afObjCacheAttrNum; if (totalMax <= 0) totalMax = afObjCacheMax; if (maxPerName <= 0) maxPerName = afObjCacheNameNum; if (maxPerAttr <= 0) maxPerAttr = afObjCacheAttrNum; if (maxPerName < maxPerAttr) { sprintf (errMsg, "maxPerAttr (%d) may not be bigger than maxPerName (%d)", maxPerAttr, maxPerName); FAIL ("cachesize", errMsg, AF_EMISC, ERROR); } if (maxPerName > totalMax) { sprintf (errMsg, "maxPerName (%d) may not be bigger than totalMax (%d)", maxPerName, totalMax); FAIL ("cachesize", errMsg, AF_EMISC, ERROR); } if (maxPerName > AF_MAX_CACHED_PER_NAME) { sprintf (errMsg, "maxPerName (%d) may not be bigger than %d (system limit)", maxPerName, AF_MAX_CACHED_PER_NAME); FAIL ("cachesize", errMsg, AF_EMISC, ERROR); } if ((totalMax < afObjCacheMax) || (maxPerName < afObjCacheNameNum) || (maxPerAttr < afObjCacheAttrNum )) { if (list->af_nrevs > 0) { /* ToDo: reorganize derived object cache */ sprintf (errMsg, "cannot shrink derived object cache (yet)\n\t\t(current cache size is %d)", list->af_nrevs); FAIL ("cachesize", errMsg, AF_EMISC, ERROR); } } afObjCacheMax = totalMax; afObjCacheNameNum = maxPerName; afObjCacheAttrNum = maxPerAttr; if (afCurTransaction) return (afAddToTransactionList (list)); return (afObjCacheWrite (list)); } /*==================== * Read Object Cache *====================*/ EXPORT int afObjCacheRead (list) Af_revlist *list; { char idStr[AF_SEGSTRLEN+1], line[AF_LINESIZ], *itemPtr; char cacheName[PATH_MAX], *udaBuf; struct stat cacheIbuf; FILE *cacheFile; int i, j, objCacheVersion, tmpMode; Af_key tmpKey; strcpy (cacheName, afCacheFileName (list->af_arpath, AF_CACHENAME)); /* if object cache archive file has been modified */ if (stat (cacheName, &cacheIbuf) == -1) cacheIbuf.st_mtime = (time_t) 0; if (list->af_lastmod != cacheIbuf.st_mtime) { if (list->af_access > 0) { af_wng ("ObjCacheRead", "object cache has changed"); list->af_access = 0; } list->af_extent &= ~AF_SEGMASK; /* invalidate data */ } if (list->af_extent & AF_COMPLETE) return (AF_OK); af_frmemlist (list); /* open cache control file */ if ((cacheFile = afOpenLock (cacheName, AF_READ, list))) { idStr[AF_SEGSTRLEN] = '\0'; fgets (idStr, AF_SEGSTRLEN+1, cacheFile); if (strncmp (idStr, AF_CACHEHEADER, AF_SEGSTRLEN)) { afCloseUnlock (cacheFile, AF_READ, list); FATAL ("ObjCacheRead", "wrong header in cache control file", AF_EINCONSIST, ERROR); } /* read header */ fgets (line, AF_LINESIZ, cacheFile); itemPtr = afFirstItem (line); objCacheVersion = atoi (itemPtr); if (objCacheVersion != AF_CACHECURVERS) { afCloseUnlock (cacheFile, AF_READ, list); FATAL ("ObjCacheRead", "unknown cache format version", AF_EINCONSIST, ERROR); } itemPtr = afNextItem (itemPtr); list->af_nrevs = atoi (itemPtr); itemPtr = afNextItem (itemPtr); afObjCacheMax = atoi (itemPtr); itemPtr = afNextItem (itemPtr); afObjCacheNameNum = atoi (itemPtr); itemPtr = afNextItem (itemPtr); afObjCacheAttrNum = atoi (itemPtr); } else { list->af_nrevs = 0; } /* alloc memory for revision list (plus space for new revs) */ list->af_listlen = afObjCacheMax; if ((list->af_list = (Af_vattrs *)af_malloc (list, (unsigned) (afObjCacheMax * sizeof(Af_vattrs)))) == NULL) { if (cacheFile) afCloseUnlock (cacheFile, AF_READ, list); return (ERROR); } memset ((char *) list->af_list, 0, list->af_listlen * sizeof (Af_vattrs)); if (list->af_nrevs == 0) { if (cacheFile) afCloseUnlock (cacheFile, AF_READ, list); list->af_extent |= AF_COMPLETE; return (AF_OK); } tmpKey.af_ldes = list; if ((udaBuf = malloc ((unsigned) AF_UDASEGSIZ)) == NULL) { if (cacheFile) afCloseUnlock (cacheFile, AF_READ, list); FAIL ("ObjCacheRead", "malloc", AF_ESYSERR, ERROR); } for (i=0; i < list->af_nrevs; i++) { /* read name and revision ID */ fgets (idStr, AF_IDSTRLEN+1, cacheFile); if (strcmp (idStr, AF_NAMEID)) { afCloseUnlock (cacheFile, AF_READ, list); FATAL ("ObjCacheRead", "wrong name-ID in cache control file", AF_EINCONSIST, ERROR); } fgets (line, AF_LINESIZ, cacheFile); itemPtr = afFirstItem (line); list->af_list[i].af_name = af_entersym (itemPtr); itemPtr = afNextItem (itemPtr); if (strcmp (itemPtr, AF_NOSTRING)) list->af_list[i].af_type = af_entersym (itemPtr); else list->af_list[i].af_type = NULL; itemPtr = afNextItem (itemPtr); list->af_list[i].af_gen = atoi (itemPtr); itemPtr = afNextItem (itemPtr); list->af_list[i].af_rev = atoi (itemPtr); itemPtr = afNextItem (itemPtr); sscanf (itemPtr, "%o", &tmpMode); list->af_list[i].af_mode = (mode_t) tmpMode; itemPtr = afNextItem (itemPtr); list->af_list[i].af_hashname = af_entersym (itemPtr); list->af_list[i].af_state = AF_DERIVED; list->af_list[i].af_class = AF_CLASS_DERIVED | AF_VALID; /* read author*/ fgets (idStr, AF_IDSTRLEN+1, cacheFile); fgets (line, AF_LINESIZ, cacheFile); itemPtr = afFirstItem (line); list->af_list[i].af_auname = af_entersym (itemPtr); itemPtr = afNextItem (itemPtr); list->af_list[i].af_auhost = af_enterhost (itemPtr); itemPtr = afNextItem (itemPtr); list->af_list[i].af_audomain = af_enterdomain (itemPtr); list->af_list[i].af_lckname = NULL; list->af_list[i].af_lckhost = NULL; list->af_list[i].af_lckdomain = NULL; /* read dates */ fgets (idStr, AF_IDSTRLEN+1, cacheFile); fgets (line, AF_LINESIZ, cacheFile); itemPtr = afFirstItem (line); list->af_list[i].af_mtime = (time_t) atoi (itemPtr); itemPtr = afNextItem (itemPtr); list->af_list[i].af_atime = (time_t) atoi (itemPtr); itemPtr = afNextItem (itemPtr); list->af_list[i].af_ctime = (time_t) atoi (itemPtr); itemPtr = afNextItem (itemPtr); list->af_list[i].af_stime = (time_t) atoi (itemPtr); list->af_list[i].af_ltime = AF_NOTIME; list->af_list[i].af_notesize = 0; list->af_list[i].af_note = NULL; /* read kind of representation and size */ itemPtr = afNextItem (itemPtr); list->af_list[i].af_repr = (short) atoi (itemPtr); itemPtr = afNextItem (itemPtr); list->af_list[i].af_fsize = (size_t) atoi (itemPtr); itemPtr = afNextItem (itemPtr); list->af_list[i].af_dsize = (size_t) atoi (itemPtr); list->af_list[i].af_data = NULL; list->af_list[i].af_nrefs = 0; list->af_list[i].af_succgen = AF_NOVNUM; list->af_list[i].af_succrev = AF_NOVNUM; list->af_list[i].af_predgen = AF_NOVNUM; list->af_list[i].af_predrev = AF_NOVNUM; /* read user defined attributes */ fgets (idStr, AF_IDSTRLEN+1, cacheFile); if (strcmp (idStr, AF_UDAID)) { afCloseUnlock (cacheFile, AF_READ, list); FATAL ("ObjCacheRead", "wrong uda-ID in cache control file", AF_EINCONSIST, ERROR); } fgetc (cacheFile); /* skip newline char */ tmpKey.af_lpos = i; afInitUdas (&tmpKey); j = 0; while (TRUE) { char c; if ((udaBuf[j] = fgetc (cacheFile)) == '\0') { if (j != 0) { tmpKey.af_lpos = i; afEnterUda (&tmpKey, udaBuf); } /* a second nullbyte indicates the end of the list of udas */ if ((c = fgetc (cacheFile)) == '\0') break; udaBuf[0] = c; j = 1; } else if (udaBuf[j] == EOF) { afCloseUnlock (cacheFile, AF_READ, list); FATAL ("ObjCacheRead", "unexpected end of file", AF_EINCONSIST, ERROR); } else { j++; if ((j % AF_UDASEGSIZ) == 0) { /* if segment is full */ if ((udaBuf = realloc (udaBuf, (unsigned) ((j + AF_UDASEGSIZ) * sizeof (char)))) == NULL) { afCloseUnlock (cacheFile, AF_READ, list); FAIL ("ObjCacheRead", "realloc", AF_ESYSERR, ERROR); } } } } fgetc (cacheFile); /* skip trailing newline char */ } /* end for */ afCloseUnlock (cacheFile, AF_READ, list); free (udaBuf); list->af_lastmod = cacheIbuf.st_mtime; list->af_extent |= AF_COMPLETE; return (AF_OK); } /*==================== * Write Object Cache *====================*/ EXPORT int afObjCacheWrite (list) Af_revlist *list; { int i, j, maxIndex, err; size_t siz; FILE *tmpFile, *cacheFile; char *tmpName, cacheName[PATH_MAX], *attrList[AF_MAXUDAS+1], buf[BUFSIZ]; Af_key tmpKey; struct stat ibuf; tmpKey.af_ldes = list; strcpy (cacheName, afCacheFileName (list->af_arpath, AF_CACHENAME)); tmpName = af_gtmpname (list->af_arpath); af_regtmpfile (tmpName); /* open tmpfile */ if ((tmpFile = fopen (tmpName, "w")) == NULL) return (ERROR); /* write header */ fprintf (tmpFile, "%s %d %d %d %d %d\n", AF_CACHEHEADER, AF_CACHECURVERS, list->af_nrevs, afObjCacheMax, afObjCacheNameNum, afObjCacheAttrNum); /* write list of ASO attributes */ maxIndex = list->af_nrevs-1; for (i=0; i <= maxIndex; i++) { /* skip deleted ASOs */ if (!(list->af_list[i].af_class & AF_VALID)) { if (++maxIndex == list->af_listlen) { fclose (tmpFile); af_unregtmpfile (tmpName); unlink (tmpName); FATAL ("ObjCacheWrite", "revision count", AF_EINCONSIST, ERROR); } continue; } /* write name and version number */ fprintf (tmpFile, "%s %s %s %d %d %o %s\n", AF_NAMEID, list->af_list[i].af_name, NOTMT(list->af_list[i].af_type), list->af_list[i].af_gen, list->af_list[i].af_rev, list->af_list[i].af_mode, list->af_list[i].af_hashname); /* write author */ fprintf (tmpFile, "%s %s %s %s\n", AF_AUTHORID, list->af_list[i].af_auname, list->af_list[i].af_auhost, list->af_list[i].af_audomain); /* write dates and kind of representation */ fprintf (tmpFile, "%s %ld %ld %ld %ld %d %lu %lu\n", AF_DATEID, list->af_list[i].af_mtime, list->af_list[i].af_atime, list->af_list[i].af_stime, list->af_list[i].af_ctime, list->af_list[i].af_repr, list->af_list[i].af_fsize, list->af_list[i].af_dsize); /* write user defined attributes */ fprintf (tmpFile, "%s\n", AF_UDAID); tmpKey.af_lpos = i; afListUdas (&tmpKey, attrList); j=0; while (attrList[j]) fprintf (tmpFile, "%s%c", attrList[j++], '\0'); if (j==0) /* if no user defined attribute has been written */ fputc ('\0', tmpFile); fputc ('\0', tmpFile); fputc ('\n', tmpFile); fflush (tmpFile); } fclose (tmpFile); if ((tmpFile = fopen (tmpName, "r")) == NULL) { af_unregtmpfile (tmpName); unlink (tmpName); FATAL ("ObjCacheWrite", "temporary archive file lost", AF_EINTERNAL, ERROR); } disableSig (SIGINT); disableSig (SIGQUIT); /* set lock on old object cache file -- tmp file *is* still locked */ if ((cacheFile = afOpenLock (cacheName, AF_WRITE, list)) == NULL) { af_unregtmpfile (tmpName); unlink (tmpName); return (ERROR); } /* copy contents of temporary file to archive file */ err = FALSE; while ((siz = fread (buf, sizeof(char), (size_t) BUFSIZ, tmpFile)) == BUFSIZ) { if (fwrite (buf, sizeof(char), (size_t) BUFSIZ, cacheFile) != BUFSIZ) err = TRUE; } if ((fwrite (buf, sizeof(char), (size_t) siz, cacheFile) != siz) || err) { fclose (tmpFile); af_unregtmpfile (tmpName); unlink (tmpName); enableSig(); afCloseUnlock (cacheFile, AF_WRITE, list); FAIL ("ObjCacheWrite", "fwrite", AF_ESYSERR, ERROR); } fclose (tmpFile); af_unregtmpfile (tmpName); unlink (tmpName); enableSig(); afCloseUnlock (cacheFile, AF_WRITE, list); /* update list descriptor */ if (stat (cacheName, &ibuf) != ERROR) list->af_lastmod = ibuf.st_mtime; return (AF_OK); } /*============================================== * afObjCacheAdd -- add object cache entry *==============================================*/ EXPORT int afObjCacheAdd (aso, outKey, cacheAttr) Af_key *aso, *outKey; char *cacheAttr; { char *cacheAttrValue = NULL, *tmpAttr; int maxIndex, i, equalNameCount = 0, hasAttrCount = 0; time_t curAttrAtime, curNameAtime, curAtime; int freeIndex = -1, oldestAttrIndex = -1, oldestNameIndex = -1; Af_revlist *cacheList = outKey->af_ldes; Af_key tmpKey, *tmpKeyPtr = &tmpKey; int nameIndexList[AF_MAX_CACHED_PER_NAME]; int addAso = FALSE; char *cachedFileName, *uniqName = NULL; struct utimbuf timeBuf; struct stat iBuf; outKey->af_lpos = -1; if (cacheAttr && cacheAttr[0]) { if ((cacheAttrValue = strchr (cacheAttr, AF_UDANAMDEL))) cacheAttrValue++; else cacheAttrValue = ""; } /* assemble list of equally named objects and remember * - oldest ASO carrying the given attribute and * - oldest equally named ASO */ maxIndex = cacheList->af_nrevs-1; curAttrAtime = curNameAtime = af_acttime (); tmpKey.af_ldes = cacheList; for (i=0; i <= maxIndex; i++) { /* skip deleted ASOs */ if (!(cacheList->af_list[i].af_class & AF_VALID)) { if (++maxIndex == cacheList->af_listlen) FATAL ("ObjCacheAdd", "revision count", AF_EINCONSIST, ERROR); if (freeIndex == -1) freeIndex = i; continue; } /* check name */ if ((VATTR(aso).af_name == cacheList->af_list[i].af_name) && (VATTR(aso).af_type == cacheList->af_list[i].af_type)) { nameIndexList[equalNameCount++] = i; if (!cacheList->af_list[i].af_nrefs && (cacheList->af_list[i].af_atime < curNameAtime)) { oldestNameIndex = i; curNameAtime = cacheList->af_list[i].af_atime; } /* check attribute */ tmpKey.af_lpos = i; tmpAttr = af_retattr (&tmpKey, cacheAttr); if (tmpAttr && !strcmp (cacheAttrValue, tmpAttr)) { hasAttrCount++; if (!cacheList->af_list[i].af_nrefs && (cacheList->af_list[i].af_atime < curAttrAtime)) { oldestAttrIndex = i; curAttrAtime = cacheList->af_list[i].af_atime; } } /* if attr equal */ } /* if name equal */ } /* for */ if ((freeIndex == -1) && (++maxIndex < cacheList->af_listlen)) freeIndex = maxIndex; /* check if there is space for a new ASO */ if ((equalNameCount < afObjCacheNameNum) && (hasAttrCount < afObjCacheAttrNum) && (cacheList->af_nrevs < afObjCacheMax)) { if (freeIndex == -1) FATAL ("ObjCacheAdd", "derived object cache ASO count", AF_EINCONSIST, ERROR); outKey->af_lpos = freeIndex; addAso = TRUE; } else { /* we have to clean out an ASO */ if (oldestAttrIndex != -1) outKey->af_lpos = oldestAttrIndex; else if (oldestNameIndex != -1) outKey->af_lpos = oldestNameIndex; } /* if outKey is still not defined, clean out the oldest ASO of all */ if (outKey->af_lpos == -1) { maxIndex = cacheList->af_nrevs-1; curAtime = af_acttime (); for (i=0; i <= maxIndex; i++) { if (!(cacheList->af_list[i].af_class & AF_VALID)) { maxIndex++; continue; } tmpKey.af_lpos = i; if ((VATTR(tmpKeyPtr).af_atime < curAtime) && !VATTR(tmpKeyPtr).af_nrefs) { outKey->af_lpos = tmpKey.af_lpos; curAtime = VATTR(outKey).af_atime; } } /* for */ } if (outKey->af_lpos == -1) FAIL ("ObjCacheAdd", "cannot find space in derived object cache", AF_EMISC, ERROR); uniqName = VATTR(outKey).af_hashname; /*** create attributes ***/ VATTR(outKey) = VATTR(aso); VATTR(outKey).af_state = AF_DERIVED; VATTR(outKey).af_class |= AF_CLASS_DERIVED; VATTR(outKey).af_lckname = NULL; VATTR(outKey).af_lckhost = NULL; VATTR(outKey).af_lckdomain = NULL; VATTR(outKey).af_stime = af_acttime (); VATTR(outKey).af_ltime = AF_NOTIME; VATTR(outKey).af_notesize = 0; VATTR(outKey).af_note = NULL; VATTR(outKey).af_nrefs = 1; VATTR(outKey).af_succgen = AF_NOVNUM; VATTR(outKey).af_succrev = AF_NOVNUM; VATTR(outKey).af_predgen = AF_NOVNUM; VATTR(outKey).af_predrev = AF_NOVNUM; /*** copy user defined attributes ***/ afInitUdas (outKey); afCopyUdas (aso, outKey); /*** copy file ***/ if (!uniqName) { char *unixName = af_gbusname (NULL, VATTR(outKey).af_name, VATTR(outKey).af_type); char uniqChar = 'A'; int notUnique = TRUE; while (notUnique) { uniqName = afCacheUniqueName (unixName, uniqChar); /* check Name for uniqueness */ notUnique = FALSE; for (i=0; i < equalNameCount; i++) { tmpKey.af_lpos = nameIndexList[i]; if (VATTR(tmpKeyPtr).af_hashname == uniqName) { notUnique = TRUE; break; } } /* for */ if (uniqChar == 'Z') uniqChar = 'a'; else uniqChar++; } /* while */ } cachedFileName = afCacheFileName (outKey->af_ldes->af_arpath, uniqName); if (af_cpfile (aso->af_ldes->af_busyfilename, VATTR(aso).af_fsize, cachedFileName) == ERROR) { VATTR(outKey).af_class &= ~AF_VALID; cacheList->af_nrevs--; FAIL ("ObjCacheAdd", "cpfile", AF_ESYSERR, ERROR); } if (addAso) cacheList->af_nrevs++; VATTR(outKey).af_hashname = uniqName; stat (cachedFileName, &iBuf); VATTR(outKey).af_ctime = iBuf.st_ctime; /*** set modification and access date ***/ timeBuf.actime = VATTR(outKey).af_atime; timeBuf.modtime = VATTR(outKey).af_mtime; if (utime (cachedFileName, &timeBuf) == ERROR) af_wng ("ObjCacheAdd", "cannot set UNIX access and modification date"); return (afObjCacheWrite (outKey->af_ldes)); } /*================================================ * afObjCacheRestore -- restore object cache file *================================================*/ EXPORT int afObjCacheRestore (aso, fileName) Af_key *aso; char *fileName; { if (af_cpfile (afCacheFileName (aso->af_ldes->af_arpath, VATTR(aso).af_hashname), VATTR(aso).af_fsize, fileName) == ERROR) FAIL ("ObjCacheResore", "cpfile", AF_ESYSERR, ERROR); return (AF_OK); } shapetools-1.4pl6.orig/src/atfs/afretr.c100444 2013 145 43665 5522212776 16361 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afretr.c - retrieve interface * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afretr.c[7.0] Fri Jan 28 19:02:49 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" extern int af_errno; extern Af_hashent af_hashentry; /*============================== * af_histories *==============================*/ EXPORT char **af_histories (path, pattern) char *path, *pattern; { char **histList; int histListSize, histNum = 0, secondDir = FALSE, i; DIR *dirPtr; struct dirent *dirEntry; char *reMsg, *histSym, *archPath; if (!path || !(*path)) path = "."; /* open named directory */ if ((dirPtr = opendir (path)) == NULL) FAIL ("histories", "opendir", AF_ESYSERR, NULL); /* compile pattern */ if ((reMsg = re_comp (pattern))) af_wng ("histories", reMsg); /* allocate memory for result list */ if ((histList = (char **)malloc ((unsigned) (AF_SEGLEN * sizeof (char *)))) == NULL) FAIL ("histories", "malloc", AF_ESYSERR, NULL); histListSize = AF_SEGLEN; loop: /* lookup all files */ while ((dirEntry = (struct dirent *)readdir (dirPtr))) { if (!re_exec (dirEntry->d_name)) continue; /* see if name is already in "histLists" */ histSym = af_entersym (dirEntry->d_name); for (i=0; iaf_nrevs-1; for (i=0; i <= maxindex; i++) { /* skip invalid object cache files */ if (!(objCacheList->af_list[i].af_class & AF_VALID)) { if (++maxindex == objCacheList->af_listlen) FATAL ("cachenames", "bad revision count", AF_EINCONSIST, NULL); continue; } /* see if name is already in "nameLists" */ nameSym = af_gbusname (NULL, objCacheList->af_list[i].af_name, objCacheList->af_list[i].af_type); for (j=0; jaf_gen != AF_NOVNUM) && (attrbuf->af_gen != VATTR(key).af_gen)) return (ERROR); /*** revision number ***/ if ((attrbuf->af_rev != AF_NOVNUM) && (attrbuf->af_rev != VATTR(key).af_rev)) return (ERROR); /*** state ***/ if ((attrbuf->af_state != AF_NOSTATE) && (attrbuf->af_state != VATTR(key).af_state)) return (ERROR); /*** owner ***/ if ( (attrbuf->af_owner.af_username[0]) && (strcmp (attrbuf->af_owner.af_username, CATTR(key).af_ownname)) ) return (ERROR); if ( (attrbuf->af_owner.af_userhost[0]) && (strcmp (attrbuf->af_owner.af_userhost, CATTR(key).af_ownhost)) ) return (ERROR); if ( (attrbuf->af_owner.af_userdomain[0]) && (strcmp (attrbuf->af_owner.af_userdomain, CATTR(key).af_owndomain)) ) return (ERROR); /*** author ***/ if ( (attrbuf->af_author.af_username[0]) && (strcmp (attrbuf->af_author.af_username, VATTR(key).af_auname)) ) return (ERROR); if ( (attrbuf->af_author.af_userhost[0]) && (strcmp (attrbuf->af_author.af_userhost, VATTR(key).af_auhost)) ) return (ERROR); if ( (attrbuf->af_author.af_userdomain[0]) && (strcmp (attrbuf->af_author.af_userdomain, VATTR(key).af_audomain)) ) return (ERROR); /*** size ***/ if ((attrbuf->af_size != AF_NOSIZE) && (attrbuf->af_size != VATTR(key).af_fsize) ) return (ERROR); /*** mode ***/ if ((attrbuf->af_mode != AF_NOMODE) && ((attrbuf->af_mode & VATTR(key).af_mode) != attrbuf->af_mode)) return (ERROR); /*** locker ***/ if ( (attrbuf->af_locker.af_username[0] == '\01') && (attrbuf->af_locker.af_username[1] == '$') && VATTR(key).af_lckname) return (ERROR); if ( (attrbuf->af_locker.af_username[0]) && (strcmp (attrbuf->af_locker.af_username, NOTNIL(VATTR(key).af_lckname))) ) return (ERROR); if ( (attrbuf->af_locker.af_userhost[0]) && (strcmp (attrbuf->af_locker.af_userhost, NOTNIL(VATTR(key).af_lckhost))) ) return (ERROR); if ( (attrbuf->af_locker.af_userdomain[0]) && (strcmp (attrbuf->af_locker.af_userdomain, NOTNIL(VATTR(key).af_lckdomain))) ) return (ERROR); /*** date of last modification ***/ if ((attrbuf->af_mtime != AF_NOTIME) && (attrbuf->af_mtime != VATTR(key).af_mtime) ) return (ERROR); /*** date of last access ***/ if ((attrbuf->af_atime != AF_NOTIME) && (attrbuf->af_atime != VATTR(key).af_atime) ) return (ERROR); /*** date of last status change ***/ if ((attrbuf->af_ctime != AF_NOTIME) && (attrbuf->af_ctime != VATTR(key).af_ctime) ) return (ERROR); /*** saving date ***/ if ((attrbuf->af_stime != AF_NOTIME) && (attrbuf->af_stime != VATTR(key).af_stime) ) return (ERROR); /*** date of last lock change ***/ if ((attrbuf->af_stime != AF_NOTIME) && (attrbuf->af_stime != VATTR(key).af_stime) ) return (ERROR); /*** user defined attributes ***/ if (attrbuf->af_udattrs[0]) { /* if list of user defined attributes is not empty or there are attributes */ match = TRUE; if ((attrbuf->af_udattrs[0][0] != '\0') || (VATTR(key).af_udanum != 0)) { /* test all given entries */ j=0; while ((attrbuf->af_udattrs[j]) && (match = !afMatchUda (key, attrbuf->af_udattrs[j]))) j++; } /* if */ if (match == FALSE) return (ERROR); } /* if */ return (AF_OK); } /*=================== * af_cachefind *===================*/ EXPORT int af_cachefind (attrbuf, set) Af_attrs *attrbuf; Af_set *set; /* out */ { register Af_revlist *objCacheList; register int i, maxindex; char *pathsym; Af_key key; /* init set */ set->af_nkeys = 0; set->af_setlen = 0; set->af_klist = NULL; /* build pathname (default is current directory) */ pathsym = af_uniqpath (af_entersym (attrbuf->af_syspath)); if ((objCacheList = afInitObjCache (pathsym)) == NULL) if (af_errno == AF_ENOATFSDIR) return (0); else return (ERROR); /* alloacte memory for set */ if(objCacheList->af_nrevs) { if ((set->af_klist = (Af_key *)malloc ((unsigned) (sizeof (Af_key) * objCacheList->af_nrevs))) == NULL) FAIL ("cachefind", "malloc", AF_ESYSERR, ERROR); } set->af_setlen = objCacheList->af_nrevs; /* add all desired object cache files to set */ maxindex = objCacheList->af_nrevs-1; for (i=0; i <= maxindex; i++) { /* skip invalid object cache files */ if (!(objCacheList->af_list[i].af_class & AF_VALID)) { if (++maxindex == objCacheList->af_listlen) FATAL ("cachefind", "bad revision count", AF_EINCONSIST, ERROR); continue; } if ((strcmp (attrbuf->af_name, AF_PATTERN_ALL) && strcmp (attrbuf->af_name, objCacheList->af_list[i].af_name)) || (strcmp (attrbuf->af_type, AF_PATTERN_ALL) && strcmp (attrbuf->af_type, NOTNIL(objCacheList->af_list[i].af_type)))) continue; key.af_ldes = objCacheList; key.af_lpos = i; if (af_abufcmp (attrbuf, &key)) continue; /* else add object cache file to set */ set->af_klist[set->af_nkeys].af_ldes = objCacheList; set->af_klist[set->af_nkeys].af_lpos = i; afIncreaseAccess (&(set->af_klist[set->af_nkeys])); set->af_nkeys++; } /* if set is empty */ if ((set->af_nkeys == 0) && (set->af_klist)) { free ((char *)set->af_klist); set->af_setlen = 0; } return (set->af_nkeys); } /*============== * af_find *==============*/ EXPORT int af_find (attrBuf, set) Af_attrs *attrBuf; Af_set *set; /* out */ { char *pathSym, *nameSym, *typeSym; register int i, maxIndex; int nLists=0, listSize; Af_revlist **revList; Af_key key; /* init set */ set->af_nkeys = 0; set->af_setlen = 0; set->af_klist = NULL; /* build pathname (default is current directory) */ pathSym = af_uniqpath (af_entersym (attrBuf->af_syspath)); nameSym = af_entersym (attrBuf->af_name); typeSym = af_entersym (attrBuf->af_type); /* alloc memory for revlist */ if ((revList = (Af_revlist **)malloc ((unsigned) (sizeof(Af_revlist *) * AF_SEGLEN))) == NULL) FAIL ("find", "malloc", AF_ESYSERR, ERROR); listSize = AF_SEGLEN; if (!strcmp (attrBuf->af_name, AF_PATTERN_ALL) || !strcmp (attrBuf->af_type, AF_PATTERN_ALL)) { char **nameList = af_histories (pathSym, AF_PATTERN_ALL); char *histNameSym, *histTypeSym; i=0; if (nameList) { while (nameList[i]) { histNameSym = af_entersym (af_afname (nameList[i])); histTypeSym = af_entersym (af_aftype (nameList[i++])); /* IF name is 'PATTERN_ALL' OR matches history name AND type is 'PATTERN_ALL' OR matches history type -> add history to revList */ if ( ((nameSym && !strcmp (nameSym, AF_PATTERN_ALL)) || (nameSym == histNameSym)) && ((typeSym && !strcmp (typeSym, AF_PATTERN_ALL)) || (typeSym == histNameSym)) ) { /* realloc memory for revList if necessary*/ if (nLists == listSize) { if ((revList = (Af_revlist **)realloc ((char *)revList, (unsigned) (sizeof(Af_revlist *) * (listSize + AF_SEGLEN)))) == NULL) FAIL ("find","realloc", AF_ESYSERR, ERROR); listSize += AF_SEGLEN; } if ((revList[nLists] = afInitList (pathSym, histNameSym, histTypeSym)) == NULL) { if (af_errno == AF_ENOATFSFILE) continue; else return (ERROR); } revList[nLists++]->af_extent |= AF_LISTBUSY; } /* IF ... */ } /* while (nameList... */ free (nameList); } /* if (nameList) */ } /* if */ else { /* impossible: empty name and non-empty type */ if (!attrBuf->af_name[0] && attrBuf->af_type[0]) { free ((char *)revList); return (set->af_nkeys); /* no Af-files found */ } /* too much hassle to handle this case */ if (!strcmp (attrBuf->af_name, "..") && (!attrBuf->af_type[0])) { free ((char *)revList); FAIL ("find", "cannot handle name '..'", AF_EMISC, ERROR); } if ((!attrBuf->af_name[0] || !strcmp (attrBuf->af_name, ".")) && (!attrBuf->af_type[0])) revList[0] = afInitList (af_afpath (pathSym), af_afname (pathSym), af_aftype (pathSym)); else revList[0] = afInitList (pathSym, nameSym, typeSym); if (revList[0] == NULL) { if (af_errno == AF_ENOATFSFILE) nLists = 0; else { free ((char *)revList); return (ERROR); } } else nLists = 1; } if (nLists == 0) { free ((char *)revList); return (set->af_nkeys); /* no Af-files found */ } /* alloacte memory for set */ if ((set->af_klist = (Af_key *)malloc ((unsigned) (sizeof (Af_key) * AF_SEGLEN))) == NULL) FAIL ("find", "malloc", AF_ESYSERR, ERROR); set->af_setlen = AF_SEGLEN; /* lookup all revisions in all lists */ /* this part is implemented quite dull up to now */ /* -- the number of "if"'s should be reduced */ for (;nLists > 0; nLists--) { maxIndex = revList[nLists-1]->af_nrevs-1; for (i = 0; i <= maxIndex; i++) { /* skip holes in the list */ if (!(revList[nLists-1]->af_list[i].af_class & AF_VALID)) { maxIndex++; continue; } /* test all attributes -- returnes true if attrs do not match */ key.af_ldes = revList[nLists-1]; key.af_lpos = i; if (af_abufcmp (attrBuf, &key)) continue; /********************************************/ /********** put AF-file into set ************/ /********************************************/ /* if set is full, enlarge it */ if (set->af_nkeys == set->af_setlen) { if ((set->af_klist = (Af_key *)realloc ((char *)set->af_klist, (unsigned) (sizeof(Af_key) * (set->af_setlen + AF_SEGLEN)))) == NULL) FAIL ("find", "realloc", AF_ESYSERR, ERROR); set->af_setlen += AF_SEGLEN; } /* add revision to key-set */ set->af_klist[set->af_nkeys].af_ldes = revList[nLists-1]; set->af_klist[set->af_nkeys].af_lpos = i; afIncreaseAccess (&(set->af_klist[set->af_nkeys])); set->af_nkeys++; } /* for all revisions in archive */ revList[nLists-1]->af_extent &= ~AF_LISTBUSY; } /* for all archives */ /* if set is empty */ if (set->af_nkeys == 0) { free ((char *)set->af_klist); set->af_setlen = 0; } free ((char *)revList); return (set->af_nkeys); } /*================ * af_getkey *================*/ EXPORT int af_getkey (syspath, name, type, gen, rev, key) char *syspath, *name, *type; int gen, rev; Af_key *key; { char *uniqPath = af_uniqpath (af_entersym (syspath)); /* empty name argument */ if (!name || !(*name)) { if (type && *type) FAIL ("getkey", "cannot handle empty name and non-empty type", AF_EMISC, ERROR); name = "."; } /* too much hassle to handle this case */ if (!strcmp (name, "..") && (!type || !(*type))) FAIL ("getkey", "cannot handle name '..'", AF_EMISC, ERROR); /* when referring the current directory, busyname is just the pathname */ /* -- with the exception of "/." */ if (!strcmp (name, ".") && (!type || !(*type)) && strcmp (uniqPath, "/")) return (afGetAso (af_afpath (uniqPath), af_afname (uniqPath), af_aftype (uniqPath), gen, rev, key)); else return (afGetAso (uniqPath, name, type, gen, rev, key)); } /*================== * af_predsucc *==================*/ EXPORT int af_predsucc (inkey, mode, outkey) Af_key *inkey, *outkey; int mode; { if (afAccessAso (inkey, AF_ATTRS)) FAIL ("predsucc", "", AF_EINVKEY, ERROR); switch (mode) { case AF_LOGICAL_SUCC: FAIL ("predsucc", "not yet implemented", AF_EMISC, ERROR); case AF_LOGICAL_PRED: FAIL ("predsucc", "not yet implemented", AF_EMISC, ERROR); case AF_PHYSICAL_SUCC: if (VATTR(inkey).af_succgen == AF_NOVNUM) return (0); if (af_buildkey (inkey->af_ldes, VATTR(inkey).af_succgen, VATTR(inkey).af_succrev, outkey) == ERROR) FAIL ("predsucc", "successor not found", AF_EINTERNAL, ERROR); return (1); case AF_PHYSICAL_PRED: if (VATTR(inkey).af_predgen == AF_NOVNUM) return (0); if (af_buildkey (inkey->af_ldes, VATTR(inkey).af_predgen, VATTR(inkey).af_predrev, outkey) == ERROR) FAIL ("predsucc", "predecessor not found", AF_EINTERNAL, ERROR); return (1); } FAIL ("predsucc", "invalid mode argument", AF_EMISC, ERROR); } /*==================== * af_initattrs *====================*/ EXPORT void af_initattrs (attrs) Af_attrs *attrs; { attrs->af_host[0] = '\0'; attrs->af_syspath[0] = '\0'; strcpy (attrs->af_name, AF_PATTERN_ALL); strcpy (attrs->af_type, AF_PATTERN_ALL); attrs->af_gen = AF_NOVNUM; attrs->af_rev = AF_NOVNUM; attrs->af_state = AF_NOSTATE; attrs->af_owner.af_username[0] = '\0'; attrs->af_owner.af_userhost[0] = '\0'; attrs->af_owner.af_userdomain[0] = '\0'; attrs->af_author.af_username[0] = '\0'; attrs->af_author.af_userhost[0] = '\0'; attrs->af_author.af_userdomain[0] = '\0'; attrs->af_size = AF_NOSIZE; attrs->af_mode = AF_NOMODE; attrs->af_locker.af_username[0] = '\0'; attrs->af_locker.af_userhost[0] = '\0'; attrs->af_locker.af_userdomain[0] = '\0'; attrs->af_mtime = AF_NOTIME; attrs->af_atime = AF_NOTIME; attrs->af_ctime = AF_NOTIME; attrs->af_stime = AF_NOTIME; attrs->af_ltime = AF_NOTIME; attrs->af_udattrs[0] = NULL; } shapetools-1.4pl6.orig/src/atfs/afsattrs.c100444 2013 145 12637 5412540760 16713 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afsattrs.c - reading and writing special attributes * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afsattrs.c[7.0] Fri Jun 25 14:32:12 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*==================================================================== * af_chowner -- change owner *====================================================================*/ EXPORT int af_chowner (key, owner) Af_key *key; Af_user *owner; { /* not yet implemented (chowner) */ FAIL ("chowner", "", AF_EACCES, ERROR); } /*==================================================================== * af_chauthor -- return author *====================================================================*/ EXPORT int af_chauthor (key, author) Af_key *key; Af_user *author; { uid_t uid; gid_t gid; if (afAccessAso (key, AF_ATTRS)) FAIL ("chauthor", "", AF_EINVKEY, ERROR); if (af_checkperm (key, AF_OWNER) == ERROR) return (ERROR); if (VATTR(key).af_state == AF_DERIVED) FAIL ("chauthor", "", AF_EDERIVED, ERROR); if (VATTR(key).af_state == AF_BUSY) { if ((uid = af_getuid (author->af_username, author->af_userhost, author->af_userdomain)) == (uid_t) -1) FAIL ("chauthor", "", AF_EINVUSER, ERROR); if ((gid = af_getgid (author->af_username, author->af_userhost, author->af_userdomain)) == (gid_t) -1) FAIL ("chauthor", "", AF_EINVUSER, ERROR); if (chown (key->af_ldes->af_busyfilename, (int) uid, (int) gid) == ERROR) FAIL ("chauthor", "chown", AF_ESYSERR, ERROR); } else { VATTR(key).af_auname = af_entersym (author->af_username); VATTR(key).af_auhost = af_enterhost (author->af_userhost); VATTR(key).af_audomain = af_enterdomain (author->af_userdomain); } if (afUpdateAso (key, AF_CHANGE) == ERROR) return (ERROR); return (AF_OK); } /*==================================================================== * af_chmod -- change mode *====================================================================*/ EXPORT int af_chmod (key, mode) Af_key *key; int mode; { if (afAccessAso (key, AF_ATTRS)) FAIL ("chmod", "", AF_EINVKEY, ERROR); if (af_checkperm (key, AF_OWNER | AF_AUTHOR) == ERROR) return (ERROR); if (VATTR(key).af_state == AF_BUSY) { if (chmod (key->af_ldes->af_busyfilename, mode) == ERROR) FAIL ("chmod", "chmod", AF_ESYSERR, ERROR); } else { VATTR(key).af_mode &= ~07777; VATTR(key).af_mode |= mode & 07777; } if (afUpdateAso (key, AF_CHANGE) == ERROR) return (ERROR); return (AF_OK); } /*==================================================================== * af_snote -- set note (write note text) *====================================================================*/ EXPORT int af_snote (key, buf) Af_key *key; char *buf; { register int len; char internalbuf[1]; internalbuf[0] = '\0'; if (afAccessAso (key, AF_DATA)) FAIL ("snote", "", AF_EINVKEY, ERROR); if (VATTR(key).af_state == AF_BUSY) FAIL ("snote", "", AF_EBUSY, ERROR); if (VATTR(key).af_state == AF_DERIVED) FAIL ("snote", "", AF_EDERIVED, ERROR); if (af_checkperm (key, AF_LOCKHOLDER | AF_AUTHOR | AF_OWNER) == ERROR) FAIL ("snote", "", AF_EACCES, ERROR); if (!buf) /* if buf is a nil pointer */ buf = internalbuf; len = strlen(buf) + sizeof (char); /* length of string plus nullbyte */ if (len > VATTR(key).af_notesize) { if ((VATTR(key).af_note = af_malloc (key->af_ldes, (unsigned) (len * sizeof (char)))) == NULL) return (ERROR); } /* change datasize in header */ key->af_ldes->af_datasize -= VATTR(key).af_notesize; key->af_ldes->af_datasize += len; strncpy (VATTR(key).af_note, buf, len); VATTR(key).af_notesize = len; /* save changes */ if (afUpdateAso (key, AF_CHANGE) == ERROR) return (ERROR); return (AF_OK); } /*==================================================================== * af_rnote -- get pointer to note (read only) *====================================================================*/ EXPORT char *af_rnote (key) Af_key *key; { register char *note; if (afAccessAso (key, AF_DATA)) FAIL ("rnote", "", AF_EINVKEY, NULL); if (VATTR(key).af_state == AF_BUSY) FAIL ("rnote", "", AF_EBUSY, NULL); if (VATTR(key).af_state == AF_DERIVED) FAIL ("rnote", "", AF_EDERIVED, NULL); if (VATTR(key).af_notesize != 0) { if ((note = malloc ((unsigned) VATTR(key).af_notesize)) == NULL) FAIL ("rnote", "malloc", AF_ESYSERR, NULL); strcpy (note, VATTR(key).af_note); /* replace newline by nullbyte */ note[VATTR(key).af_notesize-1] = '\0'; } else { if ((note = malloc ((unsigned) sizeof (char))) == NULL) FAIL ("rnote", "malloc", AF_ESYSERR, NULL); note[0] = '\0'; } return (note); } shapetools-1.4pl6.orig/src/atfs/afsets.c100444 2013 145 43532 5504345433 16351 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afsets.c -- Operations on keysets * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afsets.c[7.0] Fri Dec 17 17:00:04 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*================================================================ * af_settest -- test plausibility of set descriptor * returnes TRUE (ERROR) if set descr. is invalid, * otherwise FALSE (AF_OK). * *================================================================*/ LOCAL int af_settest (set) Af_set *set; { if ((set->af_nkeys < 0) || (set->af_setlen < 0)) return (ERROR); /* if set is not empty, test if first key is valid */ if (set->af_nkeys >= 1) if (afAccessAso (&(set->af_klist[0]), 0)) return (ERROR); return (AF_OK); } /*================================================================ * af_initset -- initialize set descriptor *================================================================*/ EXPORT void af_initset (set) Af_set *set; { set->af_nkeys = 0; set->af_setlen = 0; set->af_klist = NULL; } /*================================================================ * af_copyset -- copy sets *================================================================*/ EXPORT int af_copyset (set1, set2) Af_set *set1, *set2; { register int i; if (af_settest (set1)) FAIL ("copyset", "", AF_EINVSET, ERROR); /* allocate memory for new set (incl. space for additional element) */ set2->af_setlen = set1->af_nkeys + 1; if ((set2->af_klist = (Af_key *)malloc ((unsigned) (set2->af_setlen * sizeof(Af_key)))) == NULL) FAIL ("copyset", "malloc", AF_ESYSERR, ERROR); /* do copying */ for (i=0; iaf_nkeys; i++) { set2->af_klist[i] = set1->af_klist[i]; afIncreaseAccess (&(set2->af_klist[i])); } set2->af_nkeys = set1->af_nkeys; return (set2->af_nkeys); } /*================================================================ * af_nrofkeys -- return number of keys in set *================================================================*/ EXPORT int af_nrofkeys (set) Af_set *set; { if (af_settest (set)) FAIL ("nrofkeys", "", AF_EINVSET, ERROR); return (set->af_nkeys); } /*================================================================ * af_sortset -- sort set by attribute *================================================================*/ struct cmpfun { int (*func) (); }; extern struct cmpfun af_cmpfuncts[]; extern char *af_attrlist[], af_udaname[]; EXPORT int af_sortset (set, attr) Af_set *set; char *attr; { register int hi = AF_ATTNUM-1, lo=0, anum, res=0; if (af_settest (set)) FAIL ("sortset", "", AF_EINVSET, ERROR); if (!attr) FAIL ("sortset", "invalid attribute name", AF_EMISC, ERROR); /* get attribute number (binary search) */ anum = (hi+lo)/2; while (hi >= lo) { res = strcmp (attr, af_attrlist[anum]); if (res == 0) break; if (res < 0) hi = anum - 1; else lo = anum + 1; anum = (hi+lo)/2; } /* attribute names, that are not in the list of standard attributes */ /* are assumed to be "user defined attributes" */ if (res != 0) { strcpy (af_udaname, attr); qsort ((char *)set->af_klist, set->af_nkeys, sizeof(Af_key), af_cmpuda); } else { strcpy (af_udaname, attr); qsort ((char *)set->af_klist, set->af_nkeys, sizeof(Af_key), af_cmpfuncts[anum].func); } return (AF_OK); } /*================================================================ * af_dropset -- drop set *================================================================*/ EXPORT int af_dropset (set) Af_set *set; { register int i; if (af_settest (set)) FAIL ("dropset", "", AF_EINVSET, ERROR); for (i=0; iaf_nkeys; i++) { /* decrease reference count in corresponding archive */ afDecreaseAccess (&(set->af_klist[i])); } set->af_nkeys = 0; if (set->af_setlen > 0) { free ((char *)set->af_klist); set->af_setlen = 0; } return (AF_OK); } /*================================================================ * af_setgkey -- return key from set *================================================================*/ EXPORT int af_setgkey (set, pos, key) Af_set *set; int pos; Af_key *key; /* out */ { if (af_settest (set)) FAIL ("setgkey", "", AF_EINVSET, ERROR); if ((pos >= set->af_nkeys) || (pos < 0)) FAIL ("setgkey", "", AF_ENOPOS, ERROR); afIncreaseAccess (&(set->af_klist[pos])); key->af_ldes = set->af_klist[pos].af_ldes; key->af_lpos = set->af_klist[pos].af_lpos; return (AF_OK); } /*================================================================ * af_setaddkey -- add key to set *================================================================*/ EXPORT int af_setaddkey (set, pos, key) Af_set *set; int pos; Af_key *key; { register int i; if (af_settest (set)) FAIL ("setaddkey", "", AF_EINVSET, ERROR); if (afAccessAso (key, 0)) FAIL ("setaddkey", "", AF_EINVKEY, ERROR); if (((pos > set->af_nkeys) || (pos < 0)) && (pos != AF_LASTPOS)) FAIL ("setaddkey", "", AF_ENOPOS, ERROR); if (pos == AF_LASTPOS) pos = set->af_nkeys; /* if set is full, enlarge it */ if (set->af_nkeys == set->af_setlen) { if (set->af_setlen == 0) { if ((set->af_klist = (Af_key *)malloc ((unsigned) (sizeof(Af_key) * AF_SEGLEN))) == NULL) FAIL ("setaddkey", "malloc", AF_ESYSERR, ERROR); } else { if ((set->af_klist = (Af_key *)realloc ((char *)set->af_klist, (unsigned) (sizeof(Af_key) * (set->af_setlen + AF_SEGLEN)))) == NULL) FAIL ("setaddkey", "realloc", AF_ESYSERR, ERROR); } set->af_setlen += AF_SEGLEN; } for ( i=set->af_nkeys; i>pos; i--) set->af_klist[i] = set->af_klist[i-1]; set->af_klist[pos] = *key; set->af_nkeys++; afIncreaseAccess (key); return (AF_OK); } /*================================================================ * af_setrmkey -- remove key from set *================================================================*/ EXPORT int af_setrmkey (set, key) Af_set *set; Af_key *key; { register int i; bool found = FALSE; if (af_settest (set)) FAIL ("setrmkey", "", AF_EINVSET, ERROR); if (afAccessAso (key, 0)) FAIL ("setrmkey", "", AF_EINVKEY, ERROR); for (i=0; iaf_nkeys; i++) { if (!found) { if (!af_keycmp (&(set->af_klist[i]), key)) found = TRUE; } else /* compress list */ set->af_klist[i-1] = set->af_klist[i]; } if (!found) FAIL ("setrmkey", "", AF_ENOKEY, ERROR); set->af_nkeys--; afDecreaseAccess (key); return (AF_OK); } /*================================================================ * af_setposrmkey -- remove key (identified by position) from set *================================================================*/ EXPORT int af_setposrmkey (set, pos) Af_set *set; int pos; { register int i; if (af_settest (set)) FAIL ("setposrmkey", "", AF_EINVSET, ERROR); if ((pos >= set->af_nkeys) || (pos < 0)) FAIL ("setposrmkey", "", AF_ENOPOS, ERROR); afDecreaseAccess (&(set->af_klist[pos])); for (i=pos; iaf_nkeys-1; i++) set->af_klist[i] = set->af_klist[i+1]; set->af_nkeys--; return (AF_OK); } /*================================================================ * af_subset -- build subset *================================================================*/ EXPORT int af_subset (set, attrbuf, newset) Af_set *set, *newset; Af_attrs *attrbuf; { register int i, j=0, k=0; int match; Af_set tmpset; if (af_settest (set)) FAIL ("subset", "", AF_EINVSET, ERROR); /* allocate memory for new set */ if ((tmpset.af_setlen = set->af_nkeys)) { if ((tmpset.af_klist = (Af_key *)malloc ((unsigned) (tmpset.af_setlen * sizeof(Af_key)))) == NULL) FAIL ("subset", "malloc", AF_ESYSERR, ERROR); } else tmpset.af_klist = NULL; /* if there are no disqualifying attributes, add key to new set */ for (i = 0; i < set->af_nkeys; i++) { if (afAccessAso (&(set->af_klist[i]), AF_ATTRS)) FAIL ("subset", "", AF_EINVKEY, ERROR); /* if an attribute is set an does not match, continue with next key */ /*** name ***/ if ( strcmp (attrbuf->af_name, AF_PATTERN_ALL) && strcmp (attrbuf->af_name, VATTR((&(set->af_klist[i]))).af_name) ) continue; /*** type ***/ if ( strcmp (attrbuf->af_type, AF_PATTERN_ALL) && strcmp (attrbuf->af_type, NOTNIL(VATTR((&(set->af_klist[i]))).af_type)) ) continue; /*** syspath ***/ if ( attrbuf->af_syspath[0] && strcmp (attrbuf->af_syspath, CATTR((&(set->af_klist[i]))).af_syspath) ) continue; /*** generation number ***/ if ( (attrbuf->af_gen != AF_NOVNUM) && (attrbuf->af_gen != VATTR((&(set->af_klist[i]))).af_gen) ) continue; /*** revision number ***/ if ( (attrbuf->af_rev != AF_NOVNUM) && (attrbuf->af_rev != VATTR((&(set->af_klist[i]))).af_rev) ) continue; /*** state ***/ if ( (attrbuf->af_state != AF_NOSTATE) && (attrbuf->af_state != VATTR((&(set->af_klist[i]))).af_state) ) continue; /*** owner ***/ if ( (attrbuf->af_owner.af_username[0]) && (strcmp (attrbuf->af_owner.af_username, CATTR((&(set->af_klist[i]))).af_ownname)) ) continue; if ( (attrbuf->af_owner.af_userhost[0]) && (strcmp (attrbuf->af_owner.af_userhost, CATTR((&(set->af_klist[i]))).af_ownhost)) ) continue; if ( (attrbuf->af_owner.af_userdomain[0]) && (strcmp (attrbuf->af_owner.af_userdomain, CATTR((&(set->af_klist[i]))).af_owndomain)) ) continue; /*** author ***/ if ( (attrbuf->af_author.af_username[0]) && (strcmp (attrbuf->af_author.af_username, VATTR((&(set->af_klist[i]))).af_auname)) ) continue; if ( (attrbuf->af_author.af_userhost[0]) && (strcmp (attrbuf->af_author.af_userhost, VATTR((&(set->af_klist[i]))).af_auhost)) ) continue; if ( (attrbuf->af_author.af_userdomain[0]) && (strcmp (attrbuf->af_author.af_userdomain, VATTR((&(set->af_klist[i]))).af_audomain)) ) continue; /*** size ***/ if ( (attrbuf->af_size != AF_NOSIZE) && (attrbuf->af_size != VATTR((&(set->af_klist[i]))).af_fsize) ) continue; /*** mode ***/ if ( (attrbuf->af_mode != AF_NOMODE) && (attrbuf->af_mode != VATTR((&(set->af_klist[i]))).af_mode) ) continue; /*** locker ***/ if ( (attrbuf->af_locker.af_username[0]) && (strcmp (attrbuf->af_locker.af_username, NOTNIL(VATTR((&(set->af_klist[i]))).af_lckname))) ) continue; if ( (attrbuf->af_locker.af_userhost[0]) && (strcmp (attrbuf->af_locker.af_userhost, NOTNIL(VATTR((&(set->af_klist[i]))).af_lckhost))) ) continue; if ( (attrbuf->af_locker.af_userdomain[0]) && (strcmp (attrbuf->af_locker.af_userdomain, NOTNIL(VATTR((&(set->af_klist[i]))).af_lckdomain))) ) continue; /*** date of last modification ***/ if ( (attrbuf->af_mtime != AF_NOTIME) && (attrbuf->af_mtime != VATTR((&(set->af_klist[i]))).af_mtime) ) continue; /*** date of last access ***/ if ( (attrbuf->af_atime != AF_NOTIME) && (attrbuf->af_atime != VATTR((&(set->af_klist[i]))).af_atime) ) continue; /*** date of last status change ***/ if ( (attrbuf->af_ctime != AF_NOTIME) && (attrbuf->af_ctime != VATTR((&(set->af_klist[i]))).af_ctime) ) continue; /*** saving date ***/ if ( (attrbuf->af_stime != AF_NOTIME) && (attrbuf->af_stime != VATTR((&(set->af_klist[i]))).af_stime) ) continue; /*** date of last lock change ***/ if ( (attrbuf->af_ltime != AF_NOTIME) && (attrbuf->af_ltime != VATTR((&(set->af_klist[i]))).af_ltime) ) continue; /*** user defined attributes ***/ if (attrbuf->af_udattrs[0]) { /* if list of user defined attributes is not empty or there are */ /* attributes */ match = TRUE; if ((attrbuf->af_udattrs[0][0] != '\0') || (VATTR((&(set->af_klist[i]))).af_udanum != 0)) { /* test all given entries */ j=0; while (attrbuf->af_udattrs[j] && (match = !afMatchUda (&(set->af_klist[i]), attrbuf->af_udattrs[j]))) { j++; } } /* if */ if (match == FALSE) continue; } /* if */ /* add key to new set */ tmpset.af_klist[k] = set->af_klist[i]; afIncreaseAccess (&(tmpset.af_klist[k])); k++; } /* for */ tmpset.af_nkeys = k; /* if the resulting set shall be stored in the old set */ if (set == newset) { af_dropset (set); *set = tmpset; } else *newset = tmpset; return (k); } /*================================================================ * af_intersect -- build intersection of two sets *================================================================*/ EXPORT int af_intersect (set1, set2, newset) Af_set *set1, *set2; Af_set *newset; { register int i, j, k; Af_set tmpset; if (af_settest (set1) || af_settest (set2)) FAIL ("intersect", "", AF_EINVSET, ERROR); /* allocate enough memory */ if (set1->af_nkeys >= set2->af_nkeys) tmpset.af_setlen = set1->af_nkeys; else tmpset.af_setlen = set2->af_nkeys; if (tmpset.af_setlen) { if ((tmpset.af_klist = (Af_key *)malloc ((unsigned) (tmpset.af_setlen * sizeof(Af_key)))) == NULL) FAIL ("intersect", "malloc", AF_ESYSERR, ERROR); } else tmpset.af_klist = NULL; /* build new set */ k=0; for (i=0; iaf_nkeys; i++) for (j=0; jaf_nkeys; j++) { if (!af_keycmp (&(set1->af_klist[i]), &(set2->af_klist[j]))) { tmpset.af_klist[k] = set1->af_klist[i]; afIncreaseAccess (&(tmpset.af_klist[k])); k++; } } tmpset.af_nkeys = k; /* if the new set shall be stored in one of the old ones */ if (newset == set1) { af_dropset (set1); *set1 = tmpset; } else { if (newset == set2) { af_dropset (set2); *set2 = tmpset; } else *newset = tmpset; } return (k); } /*================================================================ * af_union -- build union of two sets *================================================================*/ EXPORT int af_union (set1, set2, newset, checkDouble) Af_set *set1, *set2; Af_set *newset; int checkDouble; { int newLen = set1->af_nkeys + set2->af_nkeys, i, j, k; bool dbl=FALSE; Af_set tmpSet, *resultSetPtr, *secondSetPtr; if (af_settest (set1) || af_settest (set2)) FAIL ("union", "", AF_EINVSET, ERROR); if (newLen == 0) { af_initset (&tmpSet); *newset = tmpSet; return (0); } /* allocate memory and set restultSetPtr */ if ((newset == set1) && (set1->af_setlen > 0)) { if ((set1->af_klist = (Af_key *)realloc (set1->af_klist, (size_t) (newLen * sizeof(Af_key)))) == NULL) FAIL ("union", "malloc", AF_ESYSERR, ERROR); set1->af_setlen = newLen; resultSetPtr = set1; secondSetPtr = set2; } else if ((newset == set2) && (set2->af_setlen > 0)) { if ((set2->af_klist = (Af_key *)realloc (set2->af_klist, (size_t) (newLen * sizeof(Af_key)))) == NULL) FAIL ("union", "malloc", AF_ESYSERR, ERROR); set2->af_setlen = newLen; resultSetPtr = set2; secondSetPtr = set1; } else { if ((tmpSet.af_klist = (Af_key *)malloc ((size_t) (newLen * sizeof(Af_key)))) == NULL) FAIL ("union", "malloc", AF_ESYSERR, ERROR); tmpSet.af_setlen = newLen; /* copy set1 to result set */ for (i=0; iaf_nkeys; i++) { tmpSet.af_klist[i] = set1->af_klist[i]; afIncreaseAccess (&(tmpSet.af_klist[i])); } tmpSet.af_nkeys = i; resultSetPtr = &tmpSet; secondSetPtr = set2; } /* add second set to result set */ k = resultSetPtr->af_nkeys; for (j=0; jaf_nkeys; j++) { if (checkDouble) { for (i=0; iaf_nkeys; i++) { if (!af_keycmp (&(resultSetPtr->af_klist[i]), &(secondSetPtr->af_klist[j]))) dbl = TRUE; } } if (dbl) dbl = FALSE; else { resultSetPtr->af_klist[k] = secondSetPtr->af_klist[j]; afIncreaseAccess (&(resultSetPtr->af_klist[k])); k++; } } resultSetPtr->af_nkeys = k; *newset = *resultSetPtr; return (k); } /*================================================================ * af_diff -- build difference between two sets *================================================================*/ EXPORT int af_diff (set1, set2, newset) Af_set *set1, *set2; Af_set *newset; { register int i, j, k; bool found = FALSE; Af_set tmpset; if (af_settest (set1) || af_settest (set2)) FAIL ("diff", "", AF_EINVSET, ERROR); /* allocate enough memory */ if ((tmpset.af_setlen = set1->af_nkeys)) { if ((tmpset.af_klist = (Af_key *)malloc ((unsigned) (tmpset.af_setlen * sizeof(Af_key)))) == NULL) FAIL ("diff", "malloc", AF_ESYSERR, ERROR); } else tmpset.af_klist = NULL; /* build new set */ k=0; for (i=0; iaf_nkeys; i++) { for (j=0; jaf_nkeys; j++) { if (!af_keycmp (&(set1->af_klist[i]), &(set2->af_klist[j]))) found = TRUE; } if (found) found = FALSE; else { tmpset.af_klist[k] = set1->af_klist[i]; afIncreaseAccess (&(tmpset.af_klist[k])); k++; } } tmpset.af_nkeys = k; /* if the new set shall be stored in one of the old ones */ if (newset == set1) { af_dropset (set1); *set1 = tmpset; } else { if (newset == set2) { af_dropset (set2); *set2 = tmpset; } else *newset = tmpset; } return (k); } shapetools-1.4pl6.orig/src/atfs/afstates.c100444 2013 145 3200 5412540726 16642 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afstates.c - operations on version states * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afstates.c[7.0] Fri Jun 25 14:32:15 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*==================================================================== * af_sstate -- set version state *====================================================================*/ EXPORT int af_sstate (key, state) Af_key *key; int state; { if (afAccessAso (key, AF_ATTRS)) FAIL ("sstate", "", AF_EINVKEY, ERROR); if (VATTR(key).af_state == AF_DERIVED) FAIL ("sstate", "", AF_EDERIVED, ERROR); if (af_checkperm (key, AF_OWNER | AF_AUTHOR | AF_LOCKHOLDER) == ERROR) return (ERROR); if ((state < AF_SAVED) || (state > AF_FROZEN)) FAIL ("sstate", "", AF_ESTATE, ERROR); VATTR(key).af_state = state; /* save changes */ if (afUpdateAso (key, AF_CHANGE) == ERROR) return (ERROR); return (AF_OK); } /* af_sstate */ shapetools-1.4pl6.orig/src/atfs/afstore.c100444 2013 145 22524 5617464263 16535 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afstore.c -- interface to archives and derived object caches * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afstore.c[7.1] Thu Aug 4 16:02:58 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*================================================================ * afAccessAso -- prepare ASO for access (read Data if necessary) *================================================================*/ EXPORT int afAccessAso (key, mode) Af_key *key; int mode; { if (key == NULL) return (ERROR); if (key->af_ldes == NULL) return (ERROR); if ((key->af_lpos < 0) || (key->af_lpos >= key->af_ldes->af_listlen)) return (ERROR); if (mode == 0) return (AF_OK); return (afRefreshList (key->af_ldes, mode)); } /*==================================== * afUpdateAso -- Update existing ASO *====================================*/ extern int afCurTransaction; EXPORT int afUpdateAso (key, mode) Af_key *key; int mode; { int retVal; /* if (mode == AF_ALLVERS | AF_CHANGE) */ /* update time of last status change (ctime) for all versions */ /* not yet implemented (update ctime) */ if (mode & AF_CHANGE) /* update ctime only for this version */ VATTR(key).af_ctime = af_acttime (); if (afCurTransaction) return (afAddToTransactionList (key->af_ldes)); retVal = AF_OK; if (VATTR(key).af_state == AF_DERIVED) retVal = afObjCacheWrite (key->af_ldes); else retVal = afWriteArchive (key->af_ldes); return (retVal); } /*============================== * afNewAso -- generate new ASO *==============================*/ EXPORT int afNewAso (list, key, mode, generation) Af_revlist *list; Af_key *key; int mode; int generation; { int freepos, insertpos, i; if (mode != AF_CLASS_SOURCE) FAIL ("newAso", "invalid mode", AF_EINTERNAL, ERROR); key->af_ldes = list; /* get data from archive */ if (afRefreshList (list, AF_DATA) == ERROR) return (ERROR); if ((freepos = af_gfreepos (list)) == ERROR) FAIL ("newAso", "too many new revisions", AF_EINTERNAL, ERROR); if (generation == AF_LASTVERS) key->af_lpos = freepos; else { /* create a hole in the list */ if ((insertpos = af_glastgenpos (list, generation)) == ERROR) insertpos = freepos; insertpos++; for (i=freepos; i>insertpos; i--) if (list->af_list[i-1].af_nrefs > 0) FAIL ("newAso", "cannot create hole in history (reference count not zero)", AF_EMISC, ERROR); for (i=freepos; i>insertpos; i--) list->af_list[i] = list->af_list[i-1]; key->af_lpos = insertpos; } VATTR(key).af_nrefs = 0; afIncreaseAccess (key); return (AF_OK); } /*===================== * afAddAso -- add ASO *=====================*/ EXPORT int afAddAso (key) Af_key *key; { /* cannot be applied to derived object caches */ return (afWriteArchive (key->af_ldes)); } /*======================================== * afDeleteAso -- delete ASO from archive *========================================*/ EXPORT int afDeleteAso (key) Af_key *key; { int retVal; /* if key points to a file in a derived object cache */ switch (VATTR(key).af_state) { case AF_DERIVED: if (unlink (afCacheFileName (key->af_ldes->af_arpath, VATTR(key).af_hashname)) == -1) FAIL ("DeleteAso", "unlink", AF_ESYSERR, ERROR); break; case AF_BUSY: /* try to remove busy file */ if (unlink (af_gbusname (CATTR(key).af_syspath, VATTR(key).af_name, VATTR(key).af_type)) == -1) FAIL ("DeleteAso", "unlink", AF_ESYSERR, ERROR); VATTR(key).af_predgen = AF_NOVNUM; VATTR(key).af_predrev = AF_NOVNUM; VATTR(key).af_lckname = NULL; VATTR(key).af_lckhost = NULL; VATTR(key).af_lckdomain = NULL; VATTR(key).af_ltime = AF_NOTIME; break; default: /* remove delta */ /* read data section of archive */ if (afRefreshList (key->af_ldes, AF_DATA) == ERROR) return (ERROR); key->af_ldes->af_datasize -= VATTR(key).af_notesize; if (VATTR(key).af_repr == AF_DELTA) key->af_ldes->af_datasize -= VATTR(key).af_dsize; else key->af_ldes->af_datasize -= VATTR(key).af_fsize; if (af_rmdelta (key) != AF_OK) return (ERROR); } afDropUdas (key); /* clear "valid" bit and decrease refcount for corresponding archive */ VATTR(key).af_class &= ~AF_VALID; key->af_ldes->af_access -= VATTR(key).af_nrefs; VATTR(key).af_nrefs = 0; key->af_ldes->af_nrevs--; retVal = AF_OK; if (VATTR(key).af_state == AF_DERIVED) retVal = afObjCacheWrite (key->af_ldes); else retVal = afWriteArchive (key->af_ldes); return (retVal); } /*============================= * afGetAso -- get ASO by name *=============================*/ EXPORT int afGetAso (syspath, name, type, gen, rev, key) char *syspath, *name, *type; int gen, rev; Af_key *key; /* syspath must be a canonical filename */ { register Af_revlist *list; register char *pathsym, *namesym, *typesym; Af_key *keyptr; /* build pathname (default is current directory) */ pathsym = af_entersym (syspath); namesym = af_entersym (name); typesym = af_entersym (type); if ((list = afInitList (pathsym, namesym, typesym)) == NULL) FAIL ("getkey", "", AF_ENOREV, ERROR); key->af_ldes = list; /* handle special cases */ if ((gen < 0) || (rev < 0)) { switch (rev) { case AF_BUSYVERS: if (af_buildkey (list, gen, rev, key) == ERROR) FAIL ("getkey", "", AF_ENOREV, ERROR); break; case AF_LASTVERS: if (gen == AF_LASTVERS) { if ((keyptr = af_glastkey (list)) == NULL) FAIL ("getkey", "", AF_ENOREV, ERROR); key->af_lpos = keyptr->af_lpos; } else { if ((keyptr = af_glastgenkey (list, gen)) == NULL) FAIL ("getkey", "", AF_ENOREV, ERROR); key->af_lpos = keyptr->af_lpos; } break; case AF_FIRSTVERS: if (list->af_nrevs == 0) FAIL ("getkey", "", AF_ENOREV, ERROR); if (gen == AF_FIRSTVERS) { key->af_lpos = 0; while ((VATTR(key).af_state == AF_BUSY) || (!(VATTR(key).af_class & AF_VALID))) { if (key->af_lpos++ == list->af_listlen-1) FAIL ("getkey", "", AF_ENOREV, ERROR); } } else { key->af_lpos = 1; while ((!(VATTR(key).af_class & AF_VALID)) || (VATTR(key).af_gen != gen)) { if (key->af_lpos++ == list->af_listlen-1) FAIL ("getkey", "", AF_ENOREV, ERROR); } } break; default: FAIL ("getkey", "", AF_ENOREV, ERROR); } } else { if (af_buildkey (list, gen, rev, key) == ERROR) FAIL ("getkey", "", AF_ENOREV, ERROR); } afIncreaseAccess (key); return (AF_OK); } /*============================================== * afTestAso -- test existence of ASO (by name) *==============================================*/ EXPORT int afTestAso (path, name, type, mode) char *path, *name, *type; int mode; { register Af_revlist *list; register int i, maxindex; char *pathSym = af_entersym (path); char *nameSym = af_entersym (name); char *typeSym = af_entersym (type); if (mode & AF_CLASS_DERIVED) { /* look in derived object cache */ if ((list = afInitObjCache (pathSym)) == NULL) return (ERROR); maxindex = list->af_nrevs-1; for (i = 0; i <= maxindex; i++) { /* skip holes in the list */ if (!(list->af_list[i].af_class & AF_VALID)) { if (++maxindex == list->af_listlen) FATAL ("TestAso", "bad revision count", AF_EINCONSIST, ERROR); continue; } if ((nameSym == list->af_list[i].af_name) && (typeSym == list->af_list[i].af_type)) return (AF_OK); } } else { /* look in directory */ if ((list = afTestList (pathSym, nameSym, typeSym)) && list->af_nrevs > 0) return (AF_OK); if ((list = afInitList (pathSym, nameSym, typeSym)) && list->af_nrevs > 0) return (AF_OK); } return (ERROR); } /*============================================================ * afBuildFile -- write content data of ASO to temporary file *============================================================*/ EXPORT int afBuildFile (key, name) Af_key *key; char *name; { struct utimbuf utbuf; if (VATTR(key).af_state == AF_DERIVED) { /* get file from derived object cache */ if (afObjCacheRestore (key, name) == ERROR) return (ERROR); } else { /* get data from archive file */ if (afRefreshList (key->af_ldes, AF_DATA) == ERROR) return (ERROR); if (af_undodelta (key, name) == ERROR) return (ERROR); } /*** set modification and access date ***/ utbuf.actime = VATTR(key).af_atime; utbuf.modtime = VATTR(key).af_mtime; if (utime (name, &utbuf) == ERROR) af_wng ("BuildFile", "cannot set UNIX access and modification date"); chmod (name, (int) VATTR(key).af_mode); return (AF_OK); } shapetools-1.4pl6.orig/src/atfs/afsymtab.c100444 2013 145 11454 5412540706 16666 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afsymtab.c -- manage symbol table for AtFS * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afsymtab.c[7.0] Fri Jun 25 14:32:20 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*========================================================================== * definition of hashtable for symbols *==========================================================================*/ typedef struct AfSmnt AfSyment; struct AfSmnt { char *symbol; AfSyment *next; }; LOCAL AfSyment *afSymhash; LOCAL int symtabSize; /*========================================================================== * determine hash value *==========================================================================*/ EXPORT int afHashval (symbol, size) /* from Aho/Ullman */ char *symbol; int size; { register char *p; register unsigned long hval, g; hval = 0; for (p = symbol; *p != '\0'; p++) { hval = (hval << 4) ^ (*p); if ((g = hval & 0xf0000000)) { hval = hval ^ (g >> 24); hval = hval ^ g; } } return (hval % size); } /*========================================================================== * af_entersym -- return pointer of symbol in Symbol Table * (enter symbol if necessary) *==========================================================================*/ EXPORT char *af_entersym (symbol) char *symbol; { static bool hinit = FALSE; /* indicate if hashtable is yet initialized */ int symlen, where; AfSyment *new, *entry = NULL; if ((symbol == NULL) || (symbol[0] == '\0')) return (NULL); if (!hinit) { /* the reserved symbols could be added to the hashtable here */ /* but I don't think that it's worthwhile */ symtabSize = AF_SYMHASHSIZE * sizeof (AfSyment); if ((afSymhash = (AfSyment *)malloc ((unsigned) symtabSize)) == NULL) FAIL ("entersym", "malloc", AF_ESYSERR, NULL); /* set hashlist all zeros */ memset ((char *)afSymhash, 0, symtabSize); hinit = TRUE; } /* lookup symbol */ where = afHashval (symbol, AF_SYMHASHSIZE); if (afSymhash[where].symbol) /* found something */ { if (!strcmp (afSymhash[where].symbol, symbol)) return (afSymhash[where].symbol); else /* maybe it is somewhere down the gully */ { entry = &afSymhash[where]; while (entry->next) { entry = entry->next; if (!strcmp (entry->symbol, symbol)) return (entry->symbol); } } } /* the symbol hasn't been known */ symlen = strlen (symbol) + sizeof (char); if (!afSymhash[where].symbol) /* entry is not used yet */ { if ((afSymhash[where].symbol = malloc ((unsigned) (symlen)))==NULL) FAIL ("entersym", "malloc", AF_ESYSERR, NULL); symtabSize += symlen; strcpy (afSymhash[where].symbol, symbol); return (afSymhash[where].symbol); } else /* hash collision! */ { if ((new = (AfSyment *)malloc ((unsigned) sizeof (AfSyment))) == NULL) FAIL ("entersym", "malloc", AF_ESYSERR, NULL); symtabSize += sizeof (AfSyment); if ((new->symbol = malloc ((unsigned) (symlen))) == NULL) FAIL ("entersym", "malloc", AF_ESYSERR, NULL); symtabSize += symlen; strcpy (new->symbol, symbol); new->next = NULL; entry->next = new; return (new->symbol); } /* endif */ } /*========================================================================== * af_enterhost -- enter hostname into symbol table (do only once) *==========================================================================*/ EXPORT char *af_enterhost (hostname) char *hostname; { register char *hostsym; hostsym = af_gethostname(); if (strcmp (hostname, hostsym)) return (af_entersym (hostname)); else return (hostsym); } /*========================================================================== * af_enterdomain -- enter domain name into symbol table (do only once) *==========================================================================*/ EXPORT char *af_enterdomain (domain) char *domain; { register char *domainsym; domainsym = af_getdomain(); if (strcmp (domain, domainsym)) return (af_entersym (domain)); else return (domainsym); } shapetools-1.4pl6.orig/src/atfs/aftime.c100444 2013 145 2607 5412540667 16313 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * aftime.c -- time handling * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: aftime.c[7.0] Fri Jun 25 14:32:23 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*================================================================ * af_asctime *================================================================*/ EXPORT char *af_asctime () { time_t seconds; seconds = time ((time_t *)0); return (asctime (localtime (&seconds))); } /*================================================================ * af_acttime -- return actual time (in seconds after ...) *================================================================*/ EXPORT time_t af_acttime () { return (time ((time_t *)0)); } shapetools-1.4pl6.orig/src/atfs/aftmpfiles.c100444 2013 145 4246 5412540654 17175 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * aftmpfiles.c -- handle temporary- and lock-files * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: aftmpfiles.c[7.0] Fri Jun 25 14:32:25 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*================================================================ * list of tmp files *================================================================*/ static char *tmpfilelist[OPEN_MAX]; LOCAL void rmtmpfiles () { register int i; for (i=0; i < OPEN_MAX; i++) if (tmpfilelist[i]) unlink (tmpfilelist[i]); } EXPORT void af_regtmpfile (name) /* registrate tmp file */ char *name; { register int i; /* look for free space in list */ for (i=0; i < OPEN_MAX; i++) if (tmpfilelist[i] == NULL) { tmpfilelist[i] = name; break; } if (i == OPEN_MAX) /* list is full */ af_wng ("regtmpfile", "tmpfile list is full -- couldn't register"); } EXPORT void af_unregtmpfile (name) /* remove tmp file entry */ char *name; { register int i; for (i=0; i < OPEN_MAX; i++) if (tmpfilelist[i] == name) { tmpfilelist[i] = NULL; break; } if (i == OPEN_MAX) /* name not found */ af_wng ("unregtmpfile", "name of tmpfile has not been registered before"); } /*========================================================================= * af_cleanup -- do cleanup *=========================================================================*/ EXPORT void af_cleanup () { /* remove tmp files */ rmtmpfiles (); af_abort(); } shapetools-1.4pl6.orig/src/atfs/aftransact.c100444 2013 145 6346 5412540637 17175 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * aftransact.c -- a simple transaction mechanism * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: aftransact.c[7.0] Fri Jun 25 14:49:48 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*========================= * afAddToTransactionList *=========================*/ LOCAL Af_revlist **afTransactionList; LOCAL int afTransactionCount = 0; #define AF_TR_SEGSIZE 16 EXPORT int afAddToTransactionList (list) Af_revlist *list; { int i; if (afTransactionCount == 0) { if ((afTransactionList = (Af_revlist **)malloc ((unsigned) AF_TR_SEGSIZE * sizeof (Af_revlist*))) == NULL) FAIL ("AddToTransactionList", "malloc", AF_ESYSERR, ERROR); afTransactionCount = AF_TR_SEGSIZE; for (i=0; iaf_extent & AF_CACHE) == AF_CACHE) retVal = afObjCacheWrite (afTransactionList[i]); else retVal = afWriteArchive (afTransactionList[i]); if (retVal == ERROR) retCode = ERROR; afTransactionList[i] = NULL; if (++i == afTransactionCount) return (retCode); } return (retCode); } /*================= * af_abort *=================*/ EXPORT int af_abort () { int i=0; if (!afCurTransaction) return (AF_OK); afCurTransaction = 0; if (afTransactionCount == 0) return (AF_OK); while (afTransactionList[i]) { afDetachList (afTransactionList[i]); afTransactionList[i] = NULL; if (++i == afTransactionCount) return (AF_OK); } return (AF_OK); } shapetools-1.4pl6.orig/src/atfs/afudattrs.c100444 2013 145 32530 5515507357 17064 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afudattrs.c -- manage user defined attributes * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afudattrs.c[7.0] Fri Jan 14 13:35:27 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" LOCAL int af_fhash (htabsiz, hstr) /* from Aho/Ullman */ int htabsiz; char *hstr; { register char *p; register unsigned long hval, g; hval = 0; for (p = hstr; (*p!=AF_UDANAMDEL) && (*p!='\0'); p++) { hval = (hval << 4) ^ (*p); if ((g = hval & 0xf0000000)) { hval = hval ^ (g >> 24); hval = hval ^ g; } } return (hval % htabsiz); } /*=============================================================== * afAttrValCmp -- compare single values in a string of the form * name=[value1 value2 ...] * Return values like strcmp. *==============================================================*/ LOCAL int afAttrValCmp (str1, str2) char *str1, *str2; { while (*str1 == *str2) { if ((*str1 == AF_UDAVALDEL) || (*str1 == '\0')) return (0); str1++; str2++; } if (((*str1 == AF_UDAVALDEL) && (*str2 =='\0')) || ((*str1 =='\0') && (*str2 == AF_UDAVALDEL))) return (0); else return (*str1 - *str2); } /*===================================================================== * afValLookup -- look for single value *=====================================================================*/ LOCAL char *afValLookup (entry, value) char *entry, *value; { register char *valptr; if ((valptr = strchr (entry, AF_UDANAMDEL))) valptr += sizeof (char); /* search until value is found */ while (afAttrValCmp (valptr, value)) { if ((valptr = strchr (valptr, AF_UDAVALDEL)) == NULL) return NULL; valptr += sizeof (char); } return (valptr); } /*===================================================================== * afInitUdas -- Initialize Uda part in revision list *=====================================================================*/ EXPORT void afInitUdas (key) Af_key *key; { int i; VATTR(key).af_udanum = 0; VATTR(key).af_uhtab = NULL; for (i=0; iaf_ldes, (unsigned) (strlen (symbol) + sizeof (char)))) == NULL) return (ERROR); strcpy (symptr, symbol); /* if there is a hashtable */ if (VATTR(key).af_uhtab) { symindex = af_fhash (AF_UDAHASHSIZE, symbol); if (!VATTR(key).af_uhtab[symindex].symbol) /* entry is not used yet */ { VATTR(key).af_uhtab[symindex].symbol = symptr; VATTR(key).af_uhtab[symindex].next = NULL; } else { /* collision! */ if ((new = (Af_hashent*)af_malloc (key->af_ldes, (unsigned) sizeof (Af_hashent))) == NULL) return (ERROR); new->symbol = symptr; new->next = NULL; curptr = &(VATTR(key).af_uhtab[symindex]); while (curptr->next) curptr = curptr->next; curptr->next = new; } } else { /* if linear list of user defined attributes is full */ if (VATTR(key).af_udanum >= AF_UDANUM) { /* initialize hashtable */ totalSize = AF_UDAHASHSIZE * sizeof(Af_hashent); if ((VATTR(key).af_uhtab = (Af_hashent *)af_malloc (key->af_ldes, (unsigned) totalSize)) == NULL) return (ERROR); memset ((char *)VATTR(key).af_uhtab, 0, totalSize); for (i=0; iaf_ldes, VATTR(key).af_uhtab[symindex].symbol, (unsigned) (strlen (symbol) + sizeof (char)))) == NULL) return (ERROR); strcpy (VATTR(key).af_uhtab[symindex].symbol, symbol); return (AF_OK); } else { entry = &(VATTR(key).af_uhtab[symindex]); while (entry->next) { entry = entry->next; if (!afAttrNameCmp (entry->symbol, symbol)) { if ((entry->symbol = af_realloc (key->af_ldes, entry->symbol, (unsigned) (strlen (symbol) + sizeof (char)))) == NULL) return (ERROR); strcpy (entry->symbol, symbol); return (AF_OK); } /* if */ } /* while */ } /* else */ } /* if */ } else { for (i=0; iaf_ldes, VATTR(key).af_udalist[i], (unsigned) (strlen (symbol) + sizeof (char)))) == NULL) return (ERROR); strcpy (VATTR(key).af_udalist[i], symbol); return (AF_OK); } } } FATAL ("ReplUda", "user defined attribute not found", AF_EINTERNAL, ERROR); } /*===================================================================== * afDelUda -- delete user defined attribute *=====================================================================*/ EXPORT int afDelUda (key, symbol) Af_key *key; char *symbol; { int i, symindex; Af_hashent *del, *succ; /* if there is a hashtable */ if (VATTR(key).af_uhtab) { symindex = af_fhash (AF_UDAHASHSIZE, symbol); if (!VATTR(key).af_uhtab[symindex].symbol) FATAL ("DelUda", "symbol not found", AF_EINTERNAL, ERROR); del = &(VATTR(key).af_uhtab[symindex]); if (!afAttrNameCmp (del->symbol, symbol)) { /* found it ? */ af_free (key->af_ldes, del->symbol); if (del->next) { /* if there are more entries */ del->symbol = del->next->symbol; succ = del->next->next; af_free (key->af_ldes, (char *)del->next); del->next = succ; } else { del->symbol = NULL; del->next = NULL; } VATTR(key).af_udanum -= 1; return (AF_OK); } else { while (del->next) { if (!afAttrNameCmp (del->next->symbol, symbol)) { af_free (key->af_ldes, del->next->symbol); succ = del->next->next; af_free (key->af_ldes, (char *)del->next); del->next = succ; VATTR(key).af_udanum -= 1; return (AF_OK); } del = del->next; } } } else { for (i=0; iaf_ldes, VATTR(key).af_udalist[i]); VATTR(key).af_udalist[i] = NULL; VATTR(key).af_udanum -= 1; return (AF_OK); } } } FATAL ("DelUda", "user defined attribute not found", AF_EINTERNAL, ERROR); } /*===================================================================== * afLookupUda -- search user defined attribute *=====================================================================*/ EXPORT char *afLookupUda (key, symbol) Af_key *key; char *symbol; { int i, symindex; Af_hashent *targ; /* if there is a hashtable */ if (VATTR(key).af_uhtab) { symindex = af_fhash (AF_UDAHASHSIZE, symbol); if (VATTR(key).af_uhtab[symindex].symbol) { if (!afAttrNameCmp (VATTR(key).af_uhtab[symindex].symbol, symbol)) return (VATTR(key).af_uhtab[symindex].symbol); else { targ = &(VATTR(key).af_uhtab[symindex]); while (targ->next) { targ = targ->next; if (!afAttrNameCmp (targ->symbol, symbol)) return (targ->symbol); } } } } else { for (i=0; i Pointerlist terminated by NULL *=====================================================================*/ EXPORT int afListUdas (key, symbollist) Af_key *key; char **symbollist; { int i, j=0; Af_hashent *h; /* if there is a hashtable */ if (VATTR(key).af_uhtab) { for (i = 0; i < AF_UDAHASHSIZE; i++) if (VATTR(key).af_uhtab[i].symbol) { h = &(VATTR(key).af_uhtab[i]); while (h) { symbollist[j] = h->symbol; j++; h = h->next; } } } else { for (i=0; iaf_ldes, entry->symbol); af_free (key->af_ldes, (char *)entry); } while ((entry = entry->next)); } if (VATTR(key).af_uhtab[i].symbol) af_free (key->af_ldes, VATTR(key).af_uhtab[i].symbol); } af_free (key->af_ldes, (char *)VATTR(key).af_uhtab); VATTR(key).af_uhtab = NULL; } else { for (i=0; iaf_ldes, VATTR(key).af_udalist[i]); VATTR(key).af_udalist[i] = NULL; } } VATTR(key).af_udanum = 0; return (AF_OK); } /*===================================================================== * afCopyUdas -- Copy list of user defined attributes *=====================================================================*/ EXPORT int afCopyUdas (srckey, destkey) Af_key *srckey, *destkey; { int i; char *udalist[AF_MAXUDAS+1]; /* copy hashtable */ afListUdas (srckey, udalist); i=0; while (udalist[i]) { afEnterUda (destkey, udalist[i]); i++; } VATTR(destkey).af_udanum = VATTR(srckey).af_udanum; return (AF_OK); } /*=============================================================== * afAttrNameCmp -- check two attributes for name equality * Return values like strcmp. *==============================================================*/ EXPORT int afAttrNameCmp (str1, str) char *str1, *str; { while (*str1 == *str) { if ((*str1 == AF_UDANAMDEL) || (*str1 == '\0')) return (0); str1++; str++; } if (((*str1 == AF_UDANAMDEL) && (*str == '\0')) || ((*str1 == '\0') && (*str == AF_UDANAMDEL))) return (0); else return (*str1 - *str); } /**** DEBUG **** DEBUG **** DEBUG **** DEBUG **** DEBUG **** DEBUG ****/ /*===================================================================== * af_dumphtb -- dump hashtable *=====================================================================*/ EXPORT void af_dumphtb (htab) /* for debug purposes */ Af_hashent *htab; { register int i; register Af_hashent *h; for (i = 0; i < AF_UDAHASHSIZE; i++) { if (htab[i].symbol[0]) { h = &htab[i]; while (h) { fprintf (stderr, "\nsymbol: (%d) %s", i, h->symbol); h = h->next; } } else fprintf (stderr, "."); } } shapetools-1.4pl6.orig/src/atfs/afvers.c100444 2013 145 33144 5516533167 16356 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afversions.c - operations on revisions * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afvers.c[7.0] Thu Jan 20 12:05:48 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" /*==================================================================== * af_savecache *====================================================================*/ EXPORT int af_savecache (aso, outKey, uniqAttr, mode) Af_key *aso, *outKey; char* uniqAttr; int mode; { if (afAccessAso (aso, AF_DATA)) FAIL ("savecache", "", AF_EINVKEY, ERROR); if (VATTR(aso).af_state != AF_BUSY) FAIL ("savecache", "", AF_ENOTBUSY, ERROR); if (!S_ISREG (VATTR(aso).af_mode)) FAIL ("savecache", "", AF_ENOTREGULAR, ERROR); if (af_checkperm (aso, AF_WORLD) == ERROR) return (ERROR); if ((outKey->af_ldes = afInitObjCache (CATTR(aso).af_syspath)) == NULL) return (ERROR); if (afObjCacheAdd (aso, outKey, uniqAttr) == ERROR) return (ERROR); outKey->af_ldes->af_access++; return (AF_OK); } /*==================================================================== * af_saverev *====================================================================*/ EXPORT int af_saverev (busykey, savekey, generation, storeType) Af_key *busykey; Af_key *savekey; /* out */ int generation; int storeType; { register Af_key *lastkey, *lastgenkey = NULL; Af_key predkey; register Af_user *author; struct stat ibuf; if (afAccessAso (busykey, AF_ATTRS)) FAIL ("saverev", "", AF_EINVKEY, ERROR); if (VATTR(busykey).af_state != AF_BUSY) FAIL ("saverev", "", AF_ENOTBUSY, ERROR); if (!S_ISREG (VATTR(busykey).af_mode)) FAIL ("saverev", "", AF_ENOTREGULAR, ERROR); /* check for "AtFS"-file */ if (!strcmp (VATTR(busykey).af_name, AF_SUBDIR) && !VATTR(busykey).af_type) FAIL ("saverev", "cannot save file named 'AtFS'", AF_EMISC, ERROR); if (busykey->af_ldes->af_nrevs > 1) /* there are saved versions */ { lastkey = af_glastkey (busykey->af_ldes); if (generation != AF_LASTVERS) { if (generation < 0) FAIL ("saverev", "invalid generation number", AF_EMISC, ERROR); /* if generation is current generation */ if (VATTR(lastkey).af_gen == generation) generation = AF_LASTVERS; /* if generation is unknown */ if ((lastgenkey = af_glastgenkey (busykey->af_ldes, generation)) == NULL) FAIL ("saverev", "invalid generation number", AF_EMISC, ERROR); } if (generation != AF_LASTVERS) { if (af_checkperm (lastgenkey, AF_LOCKHOLDER) == ERROR) FAIL ("saverev", "", AF_ENOTLOCKED, ERROR); } else { if (af_checkperm (lastkey, AF_LOCKHOLDER) == ERROR) FAIL ("saverev", "", AF_ENOTLOCKED, ERROR); } } /* get attribute buffer (pointed to by "savekey") for new version */ /* invalidates "lastkey" */ if (afNewAso (busykey->af_ldes, savekey, AF_CLASS_SOURCE, generation) == ERROR) return (ERROR); /* set key and attributes of new version */ VATTR(savekey).af_name = VATTR(busykey).af_name; VATTR(savekey).af_type = VATTR(busykey).af_type; VATTR(savekey).af_lckname = VATTR(busykey).af_lckname; VATTR(savekey).af_lckhost = VATTR(busykey).af_lckhost; VATTR(savekey).af_lckdomain = VATTR(busykey).af_lckdomain; VATTR(savekey).af_ltime = af_acttime (); if (busykey->af_ldes->af_nrevs == 1) { /* there is only one (the busy-) revision (..nrevs == 1) */ VATTR(savekey).af_gen = AF_INITGEN; VATTR(savekey).af_rev = AF_INITREV; VATTR(savekey).af_predgen = AF_NOVNUM; VATTR(savekey).af_predrev = AF_NOVNUM; VATTR(savekey).af_succgen = AF_NOVNUM; VATTR(savekey).af_succrev = AF_NOVNUM; VATTR(busykey).af_predgen = AF_INITGEN; VATTR(busykey).af_predrev = AF_INITREV; if (af_nodelta (busykey, savekey) != AF_OK) return (ERROR); } else { /* get some attributes from preceding revision */ lastkey = af_glastkey (busykey->af_ldes); if (generation == AF_LASTVERS) { VATTR(savekey).af_gen = VATTR(lastkey).af_gen; VATTR(savekey).af_rev = VATTR(lastkey).af_rev+1; } else { VATTR(savekey).af_gen = VATTR(lastgenkey).af_gen; VATTR(savekey).af_rev = VATTR(lastgenkey).af_rev+1;; } VATTR(savekey).af_succgen = AF_NOVNUM; VATTR(savekey).af_succrev = AF_NOVNUM; if (storeType == AF_STORE_COMPLETE) { VATTR(savekey).af_predgen = AF_NOVNUM; VATTR(savekey).af_predrev = AF_NOVNUM; if (af_nodelta (busykey, savekey) != AF_OK) return (ERROR); } else { if (VATTR(busykey).af_predgen == AF_NOVNUM) { VATTR(savekey).af_predgen = VATTR(lastkey).af_gen; VATTR(savekey).af_predrev = VATTR(lastkey).af_rev; } else { VATTR(savekey).af_predgen = VATTR(busykey).af_predgen; VATTR(savekey).af_predrev = VATTR(busykey).af_predrev; } if (af_buildkey (busykey->af_ldes, VATTR(savekey).af_predgen, VATTR(savekey).af_predrev, &predkey) == ERROR) predkey.af_ldes = NULL; if (af_dodelta (busykey, &predkey, savekey) == ERROR) FAIL ("saverev", "", AF_EDELTA, ERROR); } VATTR(busykey).af_predgen = VATTR(savekey).af_gen; VATTR(busykey).af_predrev = VATTR(savekey).af_rev; } VATTR(savekey).af_state = AF_SAVED; VATTR(savekey).af_class = VATTR(busykey).af_class; author = af_afuser ((uid_t) geteuid()); VATTR(savekey).af_auname = af_entersym (author->af_username); VATTR(savekey).af_auhost = af_enterhost (author->af_userhost); VATTR(savekey).af_audomain = af_enterdomain (author->af_userdomain); stat (busykey->af_ldes->af_busyfilename, &ibuf); VATTR(savekey).af_mode = ibuf.st_mode; VATTR(savekey).af_mtime = ibuf.st_mtime; VATTR(savekey).af_atime = af_acttime (); VATTR(savekey).af_ctime = ibuf.st_ctime; VATTR(savekey).af_stime = af_acttime (); VATTR(savekey).af_notesize = 0; VATTR(savekey).af_note = NULL; VATTR(savekey).af_nrefs = 1; afInitUdas (savekey); afCopyUdas (busykey, savekey); VATTR(savekey).af_hashname = NULL; /* update list descriptor */ busykey->af_ldes->af_nrevs++; busykey->af_ldes->af_datasize += VATTR(savekey).af_notesize; /* save changes */ if (afAddAso (savekey) == ERROR) return (ERROR); return (AF_OK); } /* af_saverev */ /*==================================================================== * af_newgen *====================================================================*/ EXPORT int af_newgen (key, newkey) Af_key *key; Af_key *newkey; /* out */ { register Af_key *lastkey, *busykey; if (afAccessAso (key, AF_ATTRS)) FAIL ("newgen", "", AF_EINVKEY, ERROR); /* Hmm, I think this is not necessary, Andy 18.3.93. if (key->af_ldes->af_nrevs == 1) FAIL ("newgen", "", AF_ENOTVERS, ERROR); */ if (VATTR(key).af_state == AF_DERIVED) FAIL ("newgen", "", AF_EDERIVED, ERROR); if (!S_ISREG (VATTR(key).af_mode)) FAIL ("newgen", "", AF_ENOTREGULAR, ERROR); lastkey = af_glastkey (key->af_ldes); if (af_checkperm (lastkey, AF_LOCKHOLDER) == ERROR) FAIL ("newgen", "", AF_ENOTLOCKED, ERROR); if (afNewAso (key->af_ldes, newkey, AF_CLASS_SOURCE, AF_LASTVERS) == ERROR) return (ERROR); if ((VATTR(key).af_predgen == VATTR(lastkey).af_gen) && (VATTR(key).af_predrev == VATTR(lastkey).af_rev)) { VATTR(key).af_predgen++; VATTR(key).af_predrev = 0; } /* duplicate last revision */ VATTR(newkey).af_gen = VATTR(lastkey).af_gen+1; VATTR(newkey).af_rev = 0; VATTR(newkey).af_predgen = VATTR(lastkey).af_gen; VATTR(newkey).af_predrev = VATTR(lastkey).af_rev; if (af_dodelta (NULL, lastkey, newkey) == ERROR) FAIL ("newgen", "", AF_EDELTA, ERROR); VATTR(newkey).af_name = VATTR(lastkey).af_name; VATTR(newkey).af_type = VATTR(lastkey).af_type; VATTR(newkey).af_state = AF_SAVED; VATTR(newkey).af_class = VATTR(lastkey).af_class; VATTR(newkey).af_auname = VATTR(lastkey).af_auname; VATTR(newkey).af_auhost = VATTR(lastkey).af_auhost; VATTR(newkey).af_audomain = VATTR(lastkey).af_audomain; VATTR(newkey).af_mode = VATTR(lastkey).af_mode; VATTR(newkey).af_mtime = VATTR(lastkey).af_mtime; VATTR(newkey).af_atime = VATTR(lastkey).af_atime; VATTR(newkey).af_ctime = VATTR(lastkey).af_ctime; VATTR(newkey).af_stime = VATTR(lastkey).af_stime; VATTR(newkey).af_notesize = VATTR(lastkey).af_notesize; VATTR(newkey).af_note = VATTR(lastkey).af_note; VATTR(newkey).af_lckname = NULL; VATTR(newkey).af_lckhost = NULL; VATTR(newkey).af_lckdomain = NULL; VATTR(newkey).af_nrefs = 1; afInitUdas (newkey); afCopyUdas (lastkey, newkey); VATTR(newkey).af_succgen = AF_NOVNUM; VATTR(newkey).af_succrev = AF_NOVNUM; /* update list descriptor */ key->af_ldes->af_nrevs++; key->af_ldes->af_datasize += VATTR(newkey).af_notesize; /* update predecessor of busy version */ busykey = af_gbuskey (key->af_ldes); if ((VATTR(busykey).af_predgen == VATTR(lastkey).af_gen) && (VATTR(busykey).af_predrev == VATTR(lastkey).af_rev)) { VATTR(busykey).af_predgen = VATTR(newkey).af_gen; VATTR(busykey).af_predrev = VATTR(newkey).af_rev; } if (afAddAso (newkey) == ERROR) return (ERROR); return (AF_OK); } /*==================================================================== * af_setbusy *====================================================================*/ EXPORT int af_setbusy (busykey, key, prevkey) Af_key *busykey, *key, *prevkey; { int mtKey=FALSE; if ((key->af_ldes == NULL) && (key->af_lpos == -1)) mtKey = TRUE; else { if (afAccessAso (key, AF_ATTRS)) FAIL ("setbusy", "", AF_EINVKEY, ERROR); if (VATTR(key).af_state == AF_BUSY) FAIL ("setbusy", "", AF_EBUSY, ERROR); } if (busykey) { if (afAccessAso (busykey, AF_ATTRS)) FAIL ("setbusy", "", AF_EINVKEY, ERROR); if (VATTR(busykey).af_state != AF_BUSY) FAIL ("setbusy", "", AF_ENOTBUSY, ERROR); if (VATTR(busykey).af_state == AF_DERIVED) FAIL ("setbusy", "", AF_EDERIVED, ERROR); } else busykey = af_gbuskey (key->af_ldes); if (af_checkperm (busykey, AF_AUTHOR) == ERROR) return (ERROR); /* determine previous predecessor of busy version */ prevkey->af_ldes = NULL; prevkey->af_lpos = -1; if (VATTR(busykey).af_predgen != AF_NOVNUM) { if (af_buildkey (busykey->af_ldes, VATTR(busykey).af_predgen, VATTR(busykey).af_predrev, prevkey) == ERROR) af_wng ("setbusy", "corrupted predecessor information"); } if (mtKey || (busykey->af_ldes->af_busyfilename != key->af_ldes->af_busyfilename)) { VATTR(busykey).af_predgen = AF_NOVNUM; VATTR(busykey).af_predrev = AF_NOVNUM; } else { VATTR(busykey).af_predgen = VATTR(key).af_gen; VATTR(busykey).af_predrev = VATTR(key).af_rev; } if (afUpdateAso (busykey, AF_CHANGE) == ERROR) return (ERROR); return (AF_OK); } /*==================================================================== * af_svnum *====================================================================*/ EXPORT int af_svnum (key, gen, rev) Af_key *key; int gen, rev; { Af_key *lastkey, *busykey; Af_key predkey; if (afAccessAso (key, AF_ATTRS)) FAIL ("svnum", "", AF_EINVKEY, ERROR); if ((VATTR(key).af_state == AF_BUSY) || (VATTR(key).af_state > AF_PROPOSED)) FAIL ("svnum", "", AF_EWRONGSTATE, ERROR); if (VATTR(key).af_state != AF_DERIVED) { /* derived files can get any vnum */ if (af_checkperm (key, AF_LOCKHOLDER) == ERROR) FAIL ("svnum", "", AF_ENOTLOCKED, ERROR); /* only the version number of the last version in a generation can be modified */ lastkey = af_glastgenkey (key->af_ldes, VATTR(key).af_gen); if (af_keycmp (key, lastkey)) FAIL ("svnum", "can set version number only for last version of a generation", AF_EMISC, ERROR); /* if version number is from another generation, key must be last version at all */ if (VATTR(key).af_gen != gen) { lastkey = af_glastkey (key->af_ldes); if (af_keycmp (key, lastkey)) FAIL ("svnum", "can set version number only within generation", AF_EMISC, ERROR); } /* if new version number is smaller than the old one */ if (gen < VATTR(key).af_gen) FAIL ("svnum", "", AF_EINVVNUM, ERROR); if (gen == VATTR(key).af_gen) { if (rev < VATTR(key).af_rev) FAIL ("svnum", "", AF_EINVVNUM, ERROR); } /* read data file in order to get it updated */ if (afAccessAso (key, AF_DATA) == ERROR) return (ERROR); } /* check if version was predecessor of busy version */ busykey = af_gbuskey (key->af_ldes); if ((VATTR(busykey).af_predgen == VATTR(key).af_gen) && (VATTR(busykey).af_predrev == VATTR(key).af_rev)) { VATTR(busykey).af_predgen = (short)gen; VATTR(busykey).af_predrev = (short)rev; } VATTR(key).af_gen = (short)gen; VATTR(key).af_rev = (short)rev; /* if a predecessor exists, update its successor field */ if (af_buildkey (key->af_ldes, VATTR(key).af_predgen, VATTR(key).af_predrev, &predkey) == AF_OK) { VATTR((&predkey)).af_succgen = (short)gen; VATTR((&predkey)).af_succrev = (short)rev; } /* the predecessor is updated implicitely by af_updtvers (key) */ if (afUpdateAso (key, AF_CHANGE) == ERROR) return (ERROR); return (AF_OK); } shapetools-1.4pl6.orig/src/atfs/atfsrepair.c100444 2013 145 150447 5614753701 17253 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * atfsrepair.c -- try to repair corrupted archive * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: atfsrepair.c[7.1] Thu Aug 4 16:03:02 1994 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "afarchive.h" #include "atfsrepair.h" extern int errno; extern char *sys_errlist[]; /*========================================================================== * globals *==========================================================================*/ int repairCache = FALSE; /* -C option switches this on */ jmp_buf env; char *arTmpFilename, *datTmpFilename; int outputVersion = AF_ARCURVERS; Input attrIn, dataIn; ConstAttrs cAttrs; Revision revList[MAXREVS]; Udas udaList[MAXREVS]; Note noteList[MAXREVS]; Data dataList[MAXREVS]; int curRev, curUda, curNote, curData; extern char *optarg; extern int optind; LOCAL void errorExit () { unlink (arTmpFilename); unlink (datTmpFilename); exit (1); } LOCAL void cleanup () { unlink (arTmpFilename); unlink (datTmpFilename); af_cleanup(); fprintf (stderr, "-> Abort:\tprocessing of this file...\n"); longjmp (env, 1); } /*========================================================================== * afReadName -- for backward compatibility *==========================================================================*/ LOCAL char *xfirstitem (line) char *line; { register char *sptr; /* skip leading blank */ if ((sptr = strchr (&line[1], ' ')) == NULL) sptr = strchr (&line[1], '\n'); *sptr = '\0'; return (&line[1]); } LOCAL char *xnextitem (line) char *line; { register char *sptr, *finptr; sptr = &line[strlen(line)]+1; /* move to next entry */ if ((finptr = strchr (sptr, ' ')) == NULL) finptr = strchr (sptr, '\n'); *finptr = '\0'; return (sptr); } LOCAL char *afReadName (archname) char *archname; { register FILE *archfile; register char *itemptr; char newarname[PATH_MAX+1], line[AF_LINESIZ]; static char name[NAME_MAX+1]; archname[strlen (archname)-1] = AF_OLD_ARCHEXT; if ((archfile = fopen (archname, "r")) == NULL) { strcpy (newarname, afArchivePath (af_uniqpath ("."))); strcat (newarname, "/"); strcat (newarname, archname); if ((archfile = fopen (newarname, "r")) == NULL) { strcpy (name, archname + strlen (AF_OLD_ATFSFILEID)); name[strlen(name)-1] = '\0'; return (name); } } fgets (line, AF_LINESIZ, archfile); fgets (line, AF_LINESIZ, archfile); itemptr = xfirstitem (line); /* ID string */ itemptr = xnextitem (itemptr); /* host */ itemptr = xnextitem (itemptr); /* path */ itemptr = xnextitem (itemptr); /* name */ strcpy (name, itemptr); itemptr = xnextitem (itemptr); /* type */ if (strcmp (itemptr, AF_NOSTRING)) { strcat (name, "."); strcat (name, itemptr); } fclose (archfile); return (name); } /*=========================================================================== * askConfirm -- ask for confirmation *==========================================================================*/ LOCAL int askConfirm (expAnswer) char *expAnswer; { char strBuf[256], answer[10], *cp; fflush (stdin); printf ("[%s] ", expAnswer); strBuf[0] = '\0'; answer[0] = '\0'; gets (strBuf); sscanf (strBuf, "%s", answer); if (answer[0] == '\0') return TRUE; /* assumption acknowledged */ cp = answer; while (*cp ? (*cp++ |= ' ') : 0); /* make sure answer is lowercase */ return !strncmp (expAnswer, answer, strlen (expAnswer)); } /*=========================================================================== * lookup, netItem, itemCmp * Functions for random positioning in input stream *==========================================================================*/ LOCAL int itemCmp (baseStr, searchStr, len) char *baseStr, *searchStr; int len; { register int i=0; while (baseStr[i] == searchStr[i]) { i++; if (i == len) { if ((baseStr[i] == ' ') || (baseStr[i] == '\t') || (baseStr[i] == '\0') || (baseStr[i] == '\n')) return (0); else return (1); } } return (1); } LOCAL int lookup (input, searchStr, pos) Input *input; char *searchStr; int pos; { if (pos == 0) input->curPos = 0; if (input->curPos == input->length) return (-1); while (itemCmp (&(input->string[input->curPos]), searchStr, strlen (searchStr))) { input->curPos++; while (input->string[input->curPos] != searchStr[0]) { if (input->curPos == input->length) return (-1); input->curPos++; } } return (input->curPos); } LOCAL void nextItem (input) Input *input; { if (input->curPos == input->length) return; /* search next white space */ while ((input->string[input->curPos] != ' ') && (input->string[input->curPos] != '\t') && (input->string[input->curPos] != '\n')) if (++input->curPos == input->length) return; /* skip white spaces */ while ((input->string[input->curPos] == ' ') || (input->string[input->curPos] == '\t') || (input->string[input->curPos] == '\n')) if (++input->curPos == input->length) return; } LOCAL void nextLine(input) Input *input; { if (input->curPos == input->length) return; /* search beginning of next line */ while (input->string[input->curPos] != '\n') if (++input->curPos == input->length) return; /* skip newline */ if (++input->curPos == input->length) return; } LOCAL char *itemCopy (str1, str2) char *str1, *str2; { if (!strncmp (str2, AF_NOSTRING, 2)) { str1[0] = '\0'; return (str1); } while ((*str1 = *str2)) { if ((*str2 ==' ') || (*str2 =='\t') || (*str2 =='\n')) { *str1 = '\0'; return (str1); } str1++; str2++; } return (str1); } /*========================================================================= * verifyString, verifyInt, verifyDate, complainString *=========================================================================*/ int verbosityLevel = NORMAL; LOCAL char *verifyString (name, input, level) char *name; Input input; int level; { static char value[256]; itemCopy (value, &input.string[input.curPos]); if (level <= verbosityLevel) { fprintf (stdout, "-> Verify:\tassume %s to be: ->%s<-, ok ? (y/n) ", name, value); if (askConfirm ("y")) goto outhere; fprintf (stdout, "-> Enter:\tnew %s (*0* for empty string): ", name); fscanf (stdin, "%s", value); if (!strncmp (value, "*0*", 3)) return (NULL); } outhere: if (value[0]) return (value); else return (NULL); } LOCAL char *complainString (name, string1, string2, level) char *name, *string1, *string2; int level; { if (level <= verbosityLevel) { fprintf (stdout, "-> Inconsist:\tvalue for %s is ->%s<-\n", name, string1); fprintf (stdout, "\t\tshould be ->%s<- -- fix ? (y/n)", string2); if (!askConfirm ("y")) return (string1); } return (string2); } LOCAL int verifyInt (name, input, level) char *name; Input input; int level; { int value; value = atoi (&input.string[input.curPos]); if (level <= verbosityLevel) { fprintf (stdout, "-> Verify:\tassume %s to be: ->%d<-, ok ? (y/n) ", name, value); if (askConfirm ("y")) return (value); fprintf (stdout, "-> Enter:\tnew %s: ", name); fscanf (stdin, "%d", &value); } return (value); } LOCAL int verifyOct (name, input, level) char *name; Input input; int level; { unsigned int value; sscanf (&input.string[input.curPos], "%o", &value); if (level <= verbosityLevel) { fprintf (stdout, "-> Verify:\tassume %s to be: ->%o<-, ok ? (y/n) ", name, value); if (askConfirm ("y")) return (value); fprintf (stdout, "-> Enter:\tnew %s: ", name); fscanf (stdin, "%o", &value); } return (value); } LOCAL int verifyDate (name, input, level) char *name; Input input; int level; { int value; value = atoi (&input.string[input.curPos]); if (level <= verbosityLevel) { fprintf (stdout, "-> Verify:\tassume %s to be: ->%d<-, ok ? (y/n) ", name, value); if (askConfirm ("y")) return (value); fprintf (stdout, "-> Enter:\tnew date: "); fscanf (stdin, "%d", &value); } return (value); } LOCAL void backup (arPath, arType, arBackupDir, oldName) char *arPath; char *arType; char *arBackupDir; char *oldName; { int doBackup = TRUE; char *arBackupName; arBackupName = af_entersym (afArchiveName (arPath, arBackupDir, cAttrs.name, cAttrs.type, AF_WRITE)); if (SILENT < verbosityLevel) fprintf (stdout, "-> Moving old %s archive file to %s...\n", arType, arBackupName); /* check if there is already a backup */ if ((af_retfsize (oldName) < af_retfsize (arBackupName))) { fprintf (stderr,"-> Warning:\tThere already exists a backup file which is\n"); fprintf (stderr,"->\t\tlarger than the old %s file", arType); if (NORMAL <= verbosityLevel) { fprintf (stdout, " -- overwrite (y/n) ? "); if (askConfirm ("n")) doBackup = FALSE; } else doBackup = FALSE; } if (doBackup) { unlink (arBackupName); if (link (oldName, arBackupName) == ERROR) fprintf (stderr,"-> Warning:\tcannot create backup of %s archive file\n", arType); } } /*========= * repair *=========*/ LOCAL int repair (path, filename) char *path, *filename; { char *sPtr, commandLine[2*PATH_MAX+32], *updateStr = ""; char *arPath, *arFilename, *datFilename; register int i, j; Af_user *owner; bool error, writeOk, confirm = FALSE, busyEx = FALSE, needUpdate = FALSE; FILE *inFile, *tmpFile; struct stat ibuf; int size, arVersion=0; size_t newDeltaSize; gid_t arGid; mode_t attrArMode; cAttrs.host = af_gethostname (); arPath = afArchivePath (af_uniqpath(path)); cAttrs.name = af_afname (filename); cAttrs.type = af_aftype (filename); if (repairCache) { char *busyname = af_gbusname (NULL, cAttrs.name, cAttrs.type); if (NORMAL <= verbosityLevel) { fprintf (stdout, "Cannot repair derived object caches yet -- remove all\n"); fprintf (stdout, "cached files for %s from the derived object cache instead ? (y/n) ", busyname); if (askConfirm ("y")) { if (!path || !*path || !strcmp (path, ".")) fprintf (stdout, "Cleaning out %s from derived object cache in current directory ...\n", busyname); else fprintf (stdout, "Cleaning out %s from derived object cache in directory %s ...\n", busyname, path); sprintf (commandLine, "rm -f %s/%s%s* %s/%s%s*", arPath, AF_CACHEFILEID, busyname, arPath, AF_OLD_BPFILEID, busyname); system (commandLine); fprintf (stdout, "-> Done.\n"); } } else { sprintf (commandLine, "rm -f %s/%s%s* %s/%s%s*", arPath, AF_CACHEFILEID, busyname, arPath, AF_OLD_BPFILEID, busyname); system (commandLine); } return (AF_OK); } if (SILENT < verbosityLevel) { if (!path || !*path || !strcmp (path, ".")) fprintf (stdout, "Checking %s ...\n", af_gbusname (NULL, cAttrs.name, cAttrs.type)); else fprintf (stdout, "Checking %s/%s ...\n", path, af_gbusname (NULL, cAttrs.name, cAttrs.type)); } arFilename = af_entersym (afArchiveName (arPath, AF_ATTRDIR, cAttrs.name, cAttrs.type, AF_WRITE)); if ((owner = afArchiveOwner (arPath, &writeOk, &arGid)) == NULL) { if (NORMAL <= verbosityLevel) fprintf (stdout, "-> Warning:\tcannot determine owner of AtFS subdirectory !\n"); owner = af_afuser ((uid_t) geteuid()); } cAttrs.ownerName = af_entersym (owner->af_username); cAttrs.ownerHost = af_enterhost (owner->af_userhost); cAttrs.ownerDomain = af_enterdomain (owner->af_userdomain); /* read the two archive files (if present) */ if ((inFile = fopen (arFilename, "r"))) { #if defined(ATFS_OWN_LOCKING) char *lckFilename; struct stat ibuf; #else struct flock lockInfo; #endif if ((attrIn.length = af_retfsize (arFilename)) == 0) { fprintf (stderr, "-> Error:\tAttributes archive file is empty!\n"); /* ToDo: try to reconstruct attr archive file */ fclose (inFile); cleanup (); } #if defined(ATFS_OWN_LOCKING) /* look for Lockfile */ lckFilename = af_entersym (afArchiveName (arPath, AF_LOCKDIR, cAttrs.name, cAttrs.type, AF_WRITE)); if (stat (lckFilename, &ibuf) != ERROR) { /* lock file present */ if (NORMAL <= verbosityLevel) { fprintf (stdout, "-> Warning:\tArchive file is locked!\n"); fprintf (stdout, "\t\tThis might be a spurious lockfile, or another application is\n"); fprintf (stdout, "\t\tcurrently working on the archive file. Delete the lock ?"); if (!askConfirm ("y")) { fclose (inFile); cleanup (); } } unlink (lckFilename); } #else /* check for a read or write lock */ lockInfo.l_type = F_WRLCK; lockInfo.l_whence = SEEK_SET; lockInfo.l_start = (off_t) 0; lockInfo.l_len = (off_t) 0; lockInfo.l_pid = (pid_t)0; if (fcntl (fileno(inFile), F_GETLK, &lockInfo) == -1) { fprintf (stderr, "-> Error:\tCannot get lock info for %s -- fcntl failed (%s)!\n", arFilename, sys_errlist[errno]); fclose (inFile); cleanup (); } if (lockInfo.l_type != F_UNLCK) { char *lockMsg; if (lockInfo.l_type == F_WRLCK) lockMsg = "writing"; else lockMsg = "reading"; fprintf (stderr,"-> Warning:\tArchive file %s is locked for %s.\n", arFilename, lockMsg); if (NORMAL <= verbosityLevel) { fprintf (stdout, "->\t\t-- Unlock (y/n) ? "); if (!askConfirm ("y")) { fclose (inFile); cleanup (); } } } #endif #if !defined(ATFS_OWN_LOCKING) /* try to unlock attributes archive file */ lockInfo.l_type = F_UNLCK; lockInfo.l_whence = SEEK_SET; lockInfo.l_start = (off_t) 0; lockInfo.l_len = (off_t) 0; lockInfo.l_pid = (pid_t)0; if (fcntl (fileno(inFile), F_SETLK, &lockInfo) == -1) { fprintf (stderr, "-> Error:\tCannot unlock %s -- fcntl failed (%s)!\n", arFilename, sys_errlist[errno]); fclose (inFile); cleanup (); } #endif if ((attrIn.string = malloc ((unsigned) attrIn.length+2)) == NULL) { fprintf (stderr, "-> Syst. Error:\tnot enough memory (malloc)\n"); errorExit (); } if (fread (attrIn.string, sizeof (char), (size_t) attrIn.length, inFile) != attrIn.length) { fclose (inFile); fprintf (stderr, "-> Error:\tCannot read attributes archive file %s!\n", arFilename); fclose (inFile); cleanup (); } fclose (inFile); attrIn.string[attrIn.length] = '\0'; attrIn.string[attrIn.length+1] = '\0'; attrIn.curPos = 0; } else { if (access (arFilename, F_OK) == 0) { fprintf (stderr, "-> Error:\tCannot open attributes archive file %s!\n", arFilename); cleanup (); } attrIn.string = NULL; attrIn.length = 0; attrIn.curPos = 0; } datFilename = af_entersym (afArchiveName (arPath, AF_DATADIR, cAttrs.name, cAttrs.type,AF_WRITE)); if ((inFile = fopen (datFilename, "r"))) { if ((dataIn.length = af_retfsize (datFilename)) == 0) { fprintf (stderr, "-> Error:\tData archive file is empty!\n"); cleanup (); } if ((dataIn.string = malloc ((unsigned) dataIn.length+1)) == NULL) { fprintf (stderr, "-> Syst. Error:\tnot enough memory (malloc)\n\n"); errorExit (); } if (fread (dataIn.string, sizeof (char), (size_t) dataIn.length, inFile) != dataIn.length) { fclose (inFile); fprintf (stderr, "-> Error:\tCannot read data archive file %s!\n", datFilename); cleanup (); } fclose (inFile); dataIn.string[dataIn.length] = '\0'; } else { if (access (datFilename, F_OK) == 0) { fprintf (stderr, "-> Error:\tCannot open data archive file %s!\n", datFilename); cleanup (); } dataIn.string = NULL; dataIn.length = 0; dataIn.curPos = 0; } if ((attrIn.string == NULL) && (dataIn.string == NULL)) { if (SILENT < verbosityLevel) fprintf (stdout, "-> Warning:\tNo archive files for %s\n", af_gbusname (NULL, cAttrs.name, cAttrs.type)); return (1); } if ((attrIn.string == NULL) && dataIn.string) { fprintf (stderr, "-> Error:\tAttributes archive file for %s is missing!\n", af_gbusname (NULL, cAttrs.name, cAttrs.type)); cleanup (); } if (attrIn.string && (dataIn.string == NULL)) { fprintf (stderr, "-> Error:\tData archive file for %s is missing!\n", af_gbusname (NULL, cAttrs.name, cAttrs.type)); cleanup (); } /* test existence of busy file */ if (access (af_gbusname (NULL, cAttrs.name, cAttrs.type), F_OK) == 0) busyEx = TRUE; /*================================================= * Phase 1 (check version independent attributes) *================================================*/ /* try to determine archive version */ if (!strncmp (attrIn.string, AF_ARHEADER, AF_SEGSTRLEN)) arVersion = atoi (&(attrIn.string[AF_SEGSTRLEN+1])); lookup (&attrIn, AF_NAMEID, 0); nextItem (&attrIn); /* host */ sPtr = verifyString ("hostname", attrIn, EDIT); cAttrs.host = af_entersym (sPtr); nextItem (&attrIn); /* syspath */ sPtr = verifyString ("syspath", attrIn, EDIT); cAttrs.syspath = af_entersym (sPtr); nextItem (&attrIn); /* name */ sPtr = verifyString ("name", attrIn, EDIT); if (strcmp (sPtr, cAttrs.name)) sPtr = complainString ("name", sPtr, cAttrs.name, NORMAL); cAttrs.name = af_entersym (sPtr); nextItem (&attrIn); /* type */ sPtr = verifyString ("type", attrIn, EDIT); if (strcmp (sPtr ? sPtr : "", cAttrs.type)) sPtr = complainString ("type", sPtr, cAttrs.type, NORMAL); cAttrs.type = af_entersym (sPtr); lookup (&attrIn, AF_OWNID, 0); nextItem (&attrIn); /* owner's name */ sPtr = verifyString ("owner's name", attrIn, EDIT); cAttrs.ownerName = af_entersym (sPtr); nextItem (&attrIn); /* owner's host */ sPtr = verifyString ("owner's host", attrIn, EDIT); cAttrs.ownerHost = af_entersym (sPtr); if (arVersion > 2) { nextItem (&attrIn); /* owner's domain */ sPtr = verifyString ("owner's domain", attrIn, EDIT); } else { sPtr = af_getdomain(); } cAttrs.ownerDomain = af_entersym (sPtr); /*======================================== * Phase 2 (check version attributes) *========================================*/ /* initialize busy version --- not *all* attributes get initialized !!! */ revList[0].generation = AF_BUSYVERS; revList[0].revision = AF_BUSYVERS; lookup (&attrIn, AF_NAMEID, 0); nextItem (&attrIn); nextItem (&attrIn); nextItem (&attrIn); nextItem (&attrIn); nextItem (&attrIn); /* variant (ignore) */ lookup (&attrIn, AF_LOCKID, 0); nextItem (&attrIn); sPtr = verifyString ("locker's name", attrIn, EDIT); revList[0].lockerName = af_entersym (sPtr); nextItem (&attrIn); sPtr = verifyString ("locker's host", attrIn, EDIT); revList[0].lockerHost = af_entersym (sPtr); if (arVersion > 2) { nextItem (&attrIn); sPtr = verifyString ("locker's domain", attrIn, EDIT); } else { sPtr = af_getdomain (); } revList[0].lockerDomain = af_entersym (sPtr); if ((revList[0].lockerName == NULL) && revList[0].lockerHost) { if (SILENT < verbosityLevel) fprintf (stdout, "-> Warning:\tlockerID inconsistent -- lock cancelled\n"); revList[0].lockerName = NULL; revList[0].lockerHost = NULL; revList[0].lockerDomain = NULL; } if (revList[0].lockerName == NULL) revList[0].lockerDomain = NULL; if (revList[0].lockerName && (revList[0].lockerHost == NULL)) { if (SILENT < verbosityLevel) fprintf (stdout,"-> Warning:\tlocker's host missing - inserting author's host\n"); revList[0].lockerHost = revList[0].authorHost; } if (revList[0].lockerName && (revList[0].lockerDomain == NULL)) { if (SILENT < verbosityLevel) fprintf (stdout, "-> Warning:\tlocker's domain missing - inserting author's domain\n"); revList[0].lockerHost = revList[0].authorDomain; } nextItem (&attrIn); revList[0].lockTime = verifyDate ("locking date", attrIn, EDIT); if (revList[0].lockerName && (revList[0].lockTime == AF_NOTIME)) { if (SILENT < verbosityLevel) fprintf (stdout, "-> Warning:\tlocking date inconsistent -- setting actual date\n"); revList[0].lockTime = af_acttime(); } lookup (&attrIn, AF_PRDID, 0); nextItem (&attrIn); revList[0].predGen = verifyInt ("pred(gen) of busy version", attrIn, EDIT); nextItem (&attrIn); revList[0].predRev = verifyInt ("pred(rev) of busy version", attrIn, EDIT); attrIn.curPos = 0; curRev = 0; while (lookup (&attrIn, AF_REVID, 1) != -1) { curRev++; nextItem (&attrIn); revList[curRev].generation = verifyInt ("gen", attrIn, EDIT); nextItem (&attrIn); revList[curRev].revision = verifyInt ("rev", attrIn, EDIT); nextItem (&attrIn); revList[curRev].state = verifyInt ("state", attrIn, EDIT); nextItem (&attrIn); revList[curRev].mode = (mode_t) verifyOct ("mode", attrIn, EDIT); nextItem (&attrIn); /* variant (ignore) */ lookup (&attrIn, AF_AUTHORID, 1); nextItem (&attrIn); /* author's name */ sPtr = verifyString ("author's name", attrIn, EDIT); if (sPtr == NULL) { if (SILENT < verbosityLevel) fprintf (stdout,"-> Warning:\tauthor's name missing -- inserting owner's name\n"); revList[curRev].authorName = cAttrs.ownerName; } else revList[curRev].authorName = af_entersym (sPtr); nextItem (&attrIn); /* author's host */ sPtr = verifyString ("author's host", attrIn, EDIT); if (sPtr == NULL) { if (SILENT < verbosityLevel) fprintf (stdout,"-> Warning:\tauthor's host missing -- inserting owner's host\n"); revList[curRev].authorHost = cAttrs.ownerHost; } else revList[curRev].authorHost = af_entersym (sPtr); if (arVersion > 2) { nextItem (&attrIn); /* author's domain */ sPtr = verifyString ("author's domain", attrIn, EDIT); if (sPtr == NULL) { if (SILENT < verbosityLevel) fprintf (stdout,"-> Warning: author's domain missing -- inserting owner's domain\n"); revList[curRev].authorDomain = cAttrs.ownerDomain; } else revList[curRev].authorDomain = af_entersym (sPtr); } else { sPtr = af_getdomain (); revList[curRev].authorDomain = af_entersym (sPtr); } nextItem (&attrIn); /* locker's name */ sPtr = verifyString ("locker's name", attrIn, EDIT); revList[curRev].lockerName = af_entersym (sPtr); nextItem (&attrIn); /* locker's host */ sPtr = verifyString ("locker's host", attrIn, EDIT); if ((sPtr == NULL) && revList[curRev].lockerName) { if (SILENT < verbosityLevel) fprintf (stdout,"-> Warning:\tlocker's host missing - inserting author's host\n"); revList[curRev].lockerHost = revList[curRev].authorHost; } else revList[curRev].lockerHost = af_entersym (sPtr); if (arVersion > 2) { nextItem (&attrIn); /* locker's domain */ sPtr = verifyString ("locker's domain", attrIn, EDIT); if ((sPtr == NULL) && revList[curRev].lockerName) { if (SILENT < verbosityLevel) fprintf (stdout,"-> Warning:\tlocker's domain missing - inserting author's domain\n"); revList[curRev].lockerDomain = revList[curRev].authorDomain; } else revList[curRev].lockerDomain = af_entersym (sPtr); } else { sPtr = af_getdomain(); revList[curRev].lockerDomain = af_entersym (sPtr); } lookup (&attrIn, AF_DATEID, 1); nextItem (&attrIn); revList[curRev].modTime = verifyDate ("mod. date", attrIn, EDIT); if (revList[curRev].modTime == AF_NOTIME) { if (SILENT < verbosityLevel) fprintf (stdout, "-> Warning:\tmodification date missing -- %s\n", "inserting actual date"); revList[curRev].modTime = af_acttime(); } nextItem (&attrIn); revList[curRev].accessTime = verifyDate ("acc. date", attrIn,EDIT); if (revList[curRev].accessTime == AF_NOTIME) { if (SILENT < verbosityLevel) fprintf (stdout, "-> Warning:\taccess date missing -- %s\n", "inserting actual date"); revList[curRev].accessTime = af_acttime(); } nextItem (&attrIn); revList[curRev].statChangeTime = verifyDate ("status change date", attrIn, EDIT); if (revList[curRev].statChangeTime == AF_NOTIME) { if (SILENT < verbosityLevel) fprintf (stdout, "-> Warning:\tstatus change date missing -- %s\n", "inserting actual date"); revList[curRev].statChangeTime = af_acttime(); } nextItem (&attrIn); revList[curRev].saveTime = verifyDate ("save date", attrIn, EDIT); if (revList[curRev].saveTime == AF_NOTIME) { if (SILENT < verbosityLevel) fprintf (stdout, "-> Warning:\tsave date missing -- %s\n", "inserting actual date"); revList[curRev].saveTime = af_acttime(); } nextItem (&attrIn); revList[curRev].lockTime = verifyDate ("lock date", attrIn, EDIT); if ((revList[curRev].lockTime == AF_NOTIME) && revList[curRev].lockerName) { if (SILENT < verbosityLevel) fprintf (stdout, "-> Warning:\tlocking date missing -- %s\n", "inserting actual date"); revList[curRev].lockTime = af_acttime(); } lookup (&attrIn, AF_REPRID, 1); nextItem (&attrIn); revList[curRev].representation = verifyInt ("repr", attrIn, EDIT); nextItem (&attrIn); revList[curRev].fileSize = verifyInt ("filesize", attrIn, EDIT); nextItem (&attrIn); revList[curRev].deltaSize = verifyInt ("deltasize", attrIn, EDIT); nextItem (&attrIn); revList[curRev].succGen = verifyInt ("succ. gen", attrIn, EDIT); nextItem (&attrIn); revList[curRev].succRev = verifyInt ("succ. rev", attrIn, EDIT); nextItem (&attrIn); revList[curRev].predGen = verifyInt ("pred. gen", attrIn, EDIT); nextItem (&attrIn); revList[curRev].predRev = verifyInt ("pred. rev", attrIn, EDIT); } /* revision loop */ /*============================================ * Phase 3 (check user defined attributes) *============================================*/ attrIn.curPos = 0; curUda = 0; while (lookup (&attrIn, AF_UDAID, 1) != -1) { nextItem (&attrIn); udaList[curUda].generation = verifyInt ("gen", attrIn, EDIT); nextItem (&attrIn); udaList[curUda].revision = verifyInt ("rev", attrIn, EDIT); nextItem (&attrIn); i = 0; size = 0; while (i < MAXUDAS) { udaList[curUda].uda[i] = &attrIn.string[attrIn.curPos]; udaList[curUda].size = udaList[curUda].size + (strlen (udaList[curUda].uda[i]) + sizeof (char)); while (attrIn.string[attrIn.curPos] != '\0') attrIn.curPos++; attrIn.curPos++; i++; if (!strcmp (&attrIn.string[attrIn.curPos], AF_UDAID)) break; if (attrIn.string[attrIn.curPos] == '\0') { udaList[curUda].size++; break; } } /* uda loop */ udaList[curUda].uda[i] = NULL; curUda++; } /* revision loop */ /*========================= * Phase 4 (check notes) *=========================*/ dataIn.curPos = 0; curNote = 0; while (lookup (&dataIn, AF_NOTEID, 1) != -1) { nextItem (&dataIn); noteList[curNote].generation = verifyInt ("gen", dataIn, EDIT); nextItem (&dataIn); noteList[curNote].revision = verifyInt ("rev", dataIn, EDIT); nextItem (&dataIn); nextLine (&dataIn); /* skip size */ size = 0; noteList[curNote].contents = &dataIn.string[dataIn.curPos]; while (((noteList[curNote].contents)[size] != AF_DATAID[0]) && ((noteList[curNote].contents)[size] != '\0')) size++; if (size == 0) { noteList[curNote].contents = NULL; size = 1; } else (noteList[curNote].contents)[size-1] = '\0'; noteList[curNote].size = size; curNote++; } /* revision loop */ /*======================= * Phase 5 (check data) *=======================*/ /* try to determine archive version */ if (!strncmp (dataIn.string, AF_DATAHEADER, AF_SEGSTRLEN)) arVersion = atoi (&(dataIn.string[AF_SEGSTRLEN+1])); dataIn.curPos = 0; curData = 0; while (lookup (&dataIn, AF_DATAID, 1) != -1) { nextItem (&dataIn); dataList[curData].generation = verifyInt ("gen", dataIn, EDIT); nextItem (&dataIn); dataList[curData].revision = verifyInt ("rev", dataIn, EDIT); nextItem (&dataIn); dataList[curData].representation = verifyInt ("repr",dataIn, EDIT); nextItem (&dataIn); nextLine (&dataIn); /* skip size */ size = 0; if (dataIn.curPos == dataIn.length) goto loopexit; dataList[curData].contents = &dataIn.string[dataIn.curPos]; while (itemCmp (&(dataList[curData].contents)[size], AF_NOTEID, AF_IDSTRLEN) && itemCmp (&(dataList[curData].contents)[size], AF_DATAID, AF_IDSTRLEN)) { size++; while ((dataList[curData].contents)[size] != AF_NOTEID[0]) { size++; if ((dataIn.curPos + size) == dataIn.length) goto loopexit; } } loopexit: if (size == 0) dataList[curData].contents = NULL; dataList[curData].size = size; /* convert delta */ if ((size > 0) && (arVersion == 1) && (dataList[curData].representation == AF_DELTA)) { dataList[curData].contents = afConvertDelta (dataList[curData].contents, dataList[curData].size, &newDeltaSize); dataList[curData].size = newDeltaSize; } /* check plausibility of delta */ if ((dataList[curData].size > 0) && (dataList[curData].representation == AF_DELTA)) { if ((dataList[curData].contents[0] != '\0') && (dataList[curData].contents[0] != '\01')) { dataList[curData].representation = AF_CHUNK; if (SILENT < verbosityLevel) fprintf (stderr, "-> Warning:\tfound bogus delta -- fixed !\n"); } } curData++; } /* revision loop */ /*============================== * Phase 6 (check connectivity) *==============================*/ /* test order of revisions -- not yet implemented */ /* test existence on successors and predecessors -- not yet implemented */ /* look for zero size files (due to known AtFS error) */ for (i=1; i Warning:\tversion numbering inconsistent -- fixed !\n"); /* move lock from busy version to last saved version, * when reading a version 2 (or 1) archive */ if ((arVersion <= 2) && (cAttrs.noOfRevisions > 0)) { if (revList[0].lockerName) { revList[cAttrs.noOfRevisions-1].lockerName = revList[0].lockerName; revList[cAttrs.noOfRevisions-1].lockerHost = revList[0].lockerHost; revList[cAttrs.noOfRevisions-1].lockerDomain = revList[0].lockerDomain; revList[0].lockerName = NULL; revList[0].lockerHost = NULL; revList[0].lockerDomain = NULL; } } /* ensure delta type consistency */ for (i=0; i Syst. Error:\tcannot open temporary file %s for writing\n", arTmpFilename); cleanup (); } /* write header */ fprintf (tmpFile, "%s %d %d %ld\n", AF_ARHEADER, outputVersion, cAttrs.noOfRevisions + 1, cAttrs.datasize); /* write constant attributes */ fprintf (tmpFile, "%s %s %s %s %s %s\n", AF_NAMEID, cAttrs.host, cAttrs.syspath, cAttrs.name, NOTMT (cAttrs.type), AF_NOSTRING); /* former variant string */ /* write owner */ fprintf (tmpFile, "%s %s %s %s\n", AF_OWNID, cAttrs.ownerName, cAttrs.ownerHost, cAttrs.ownerDomain); /* write predecessor of busy version -- do not check if busy version exists */ fprintf (tmpFile, "%s %d %d\n", AF_PRDID, revList[0].predGen, revList[0].predRev); /* write locker of busy version */ fprintf (tmpFile, "%s %s %s %s %ld\n", AF_LOCKID, NOTMT (revList[0].lockerName), NOTMT (revList[0].lockerHost), NOTMT (revList[0].lockerDomain), revList[0].lockTime); /* write list of version attributes */ for (i=1; i <= cAttrs.noOfRevisions; i++) { /* write revision ID */ fprintf (tmpFile, "%s %d %d %d %o %s\n", AF_REVID, revList[i].generation, revList[i].revision, revList[i].state, revList[i].mode, AF_NOSTRING); /* former variant string */ /* write author */ fprintf (tmpFile, "\t%s %s %s %s %s %s %s\n", AF_AUTHORID, revList[i].authorName, revList[i].authorHost, revList[i].authorDomain, NOTMT (revList[i].lockerName), NOTMT (revList[i].lockerHost), NOTMT (revList[i].lockerDomain)); /* write dates */ fprintf (tmpFile, "\t%s %ld %ld %ld %ld %ld\n", AF_DATEID, revList[i].modTime, revList[i].accessTime, revList[i].statChangeTime, revList[i].saveTime, revList[i].lockTime); /* write kind of representation and tree connects */ fprintf (tmpFile, "\t%s %d %ld %ld %d %d %d %d\n", AF_REPRID, revList[i].representation, revList[i].fileSize, (revList[i].representation == AF_DELTA) ? dataList[i-1].size : revList[i].deltaSize, revList[i].succGen, revList[i].succRev, revList[i].predGen, revList[i].predRev); } /* write user defined attributes */ fprintf (tmpFile, "%s\n", AF_UDASEG); for (i=0; i <= cAttrs.noOfRevisions; i++) { fprintf (tmpFile, "%s %d %d\n", AF_UDAID, udaList[i].generation, udaList[i].revision); j=0; while (udaList[i].uda[j]) fprintf (tmpFile, "%s%c", udaList[i].uda[j++], '\0'); if (j==0) /* if no user defined attribute has been written */ fputc ('\0', tmpFile); fputc ('\0', tmpFile); if (fputc ('\n', tmpFile) == EOF) { fclose (tmpFile); fprintf (stderr, "-> Error:\tcannot write to temporary file %s\n", arTmpFilename); cleanup (); } } if (fclose (tmpFile) < 0) { fprintf (stderr, "-> Error:\tcannot write to temporary file %s (disk full ?)\n", arTmpFilename); cleanup (); } /* release attrIn */ free (attrIn.string); attrIn.string = NULL; attrIn.length = 0; attrIn.curPos = 0; /* open datatmpfile */ datTmpFilename = af_gtmpname (arPath); if ((tmpFile = fopen (datTmpFilename, "w")) == NULL) { fprintf (stderr, "-> Syst. Error:\tcannot open temporary file %s for writing\n", datTmpFilename); cleanup (); } fprintf (tmpFile, "%s %d\n", AF_DATAHEADER, AF_ARCURVERS); for (i=0; i < cAttrs.noOfRevisions; i++) { fprintf (tmpFile, "%s %d %d %ld\n", AF_NOTEID, noteList[i].generation, noteList[i].revision, noteList[i].size); if (noteList[i].size > 1) if (fwrite (noteList[i].contents, sizeof(char), (size_t)(noteList[i].size - sizeof(char)), tmpFile) == 0) { fclose (tmpFile); fprintf (stderr, "-> Error:\tcannot write to temporary file %s\n", datTmpFilename); cleanup (); } if (fputc ('\n', tmpFile) == EOF) { fclose (tmpFile); fprintf (stderr, "-> Error:\tcannot write to temporary file %s\n", datTmpFilename); cleanup (); } fprintf (tmpFile, "%s %d %d %d %ld\n", AF_DATAID, dataList[i].generation, dataList[i].revision, dataList[i].representation, dataList[i].size); if (dataList[i].size > 0) if (fwrite (dataList[i].contents, sizeof(char), (size_t)dataList[i].size, tmpFile) == 0) { fclose (tmpFile); fprintf (stderr, "-> Error:\tcannot write to temporary file %s\n", datTmpFilename); cleanup (); } } if (fclose (tmpFile) < 0) { fprintf (stderr, "-> Error:\tcannot write to temporary file %s (disk full ?)\n", arTmpFilename); cleanup (); } /* release dataIn */ free (dataIn.string); dataIn.string = NULL; dataIn.length = 0; dataIn.curPos = 0; /* check and eventually adjust attr archive protection */ /* compute corrcet protection */ if ((attrArMode = afArchiveMode (arPath))) attrArMode &= ~(S_IXUSR|S_IXGRP|S_IXOTH|S_ISUID|S_ISGID); else attrArMode = S_IRUSR|S_IWUSR|S_IRGRP|S_IXGRP; /* get old group and protection */ stat (arFilename, &ibuf); if (ibuf.st_gid != arGid) { if (SILENT < verbosityLevel) { fprintf (stdout, "-> group id of archive files not the same as group id of AtFS directory\n"); fprintf (stdout, "\t\t\t\t-- will try to update ... "); } if (chown (arFilename, -1, arGid) == -1) { if (SILENT < verbosityLevel) fprintf (stdout, "failed !\n"); needUpdate = TRUE; } else if (chown (datFilename, -1, arGid) == -1) { if (SILENT < verbosityLevel) fprintf (stdout, "failed !\n"); needUpdate = TRUE; } else { if (SILENT < verbosityLevel) fprintf (stdout, "Ok, done!\n"); updateStr = " contents"; } } if ((ibuf.st_mode & 07777) != (attrArMode & 07777)) { if (SILENT < verbosityLevel) { fprintf (stdout, "-> protection of archive file does not conform with protection of AtFS dir.\n"); fprintf (stdout, "\t\t\t\t-- will try to update ... "); } if (chmod (arFilename, attrArMode) == -1) { if (SILENT < verbosityLevel) fprintf (stdout, "failed !\n"); needUpdate = TRUE; } else if (chmod (datFilename, attrArMode) == -1) { if (SILENT < verbosityLevel) fprintf (stdout, "failed !\n"); needUpdate = TRUE; } else { if (SILENT < verbosityLevel) fprintf (stdout, "Ok, done!\n"); updateStr = " contents"; } } /* test, if archive files are changed -- if not, exit */ sprintf (commandLine, "cmp -s %s %s", arFilename, arTmpFilename); /* if files are identical and need not to be updated */ if (!needUpdate && (system (commandLine) == 0)) { sprintf (commandLine, "cmp -s %s %s", datFilename, datTmpFilename); if (system (commandLine) == 0) { unlink (arTmpFilename); unlink (datTmpFilename); if (SILENT < verbosityLevel) fprintf (stdout, "-> Ok -- archive files%s unchanged!\n", updateStr); return (AF_OK); } } switch (verbosityLevel) { case SILENT: confirm = TRUE; break; case NOASK: if (needUpdate) fprintf (stdout, "-> Archive files for %s must be rewritten due to mode change !\n", af_gbusname (NULL, cAttrs.name, cAttrs.type)); else fprintf (stdout, "-> Archive files for %s changed !\n", af_gbusname (NULL, cAttrs.name, cAttrs.type)); confirm = TRUE; break; case NORMAL: case EDIT: if (needUpdate) fprintf (stdout, "-> Archive files for %s must be rewritten due to mode change !", af_gbusname (NULL, cAttrs.name, cAttrs.type)); else fprintf (stdout, "-> Archive files for %s changed !", af_gbusname (NULL, cAttrs.name, cAttrs.type)); fprintf (stdout, " - write ? (y/n) "); confirm = askConfirm ("y"); } if (!confirm) { unlink (arTmpFilename); unlink (datTmpFilename); if (SILENT < verbosityLevel) fprintf (stdout, "-> No archive files written\n"); return (AF_OK); } /* keep old archive */ backup (arPath, "attribute", AF_ATTRBACKUPDIR, arFilename); if (SILENT < verbosityLevel) fprintf (stdout, "-> Writing updated archive attributes archive file...\n"); unlink (arFilename); if (link (arTmpFilename, arFilename) == ERROR) { fprintf (stderr,"-> Warning:\tcannot create new attributes archive file\n"); fprintf (stderr,"->\t\t -- preserving temporary file %s\n", arTmpFilename); } else { chown (arFilename, -1, arGid); chmod (arFilename, attrArMode); unlink (arTmpFilename); } /* keep old archive */ backup (arPath, "attribute", AF_DATABACKUPDIR, datFilename); if (SILENT < verbosityLevel) fprintf (stdout, "-> Writing updated archive data archive file...\n"); unlink (datFilename); if (link (datTmpFilename, datFilename) == ERROR) { fprintf (stderr,"-> Warning:\tcannot create new data archive file\n"); fprintf (stderr,"-> \t\t -- preserving temporary file %s\n", datTmpFilename); } else { chown (datFilename, -1, arGid); chmod (datFilename, attrArMode); unlink (datTmpFilename); } return (AF_OK); } /*========================================================================== * convert from old archive file naming style to new one *==========================================================================*/ LOCAL int convert (archivePath, archiveName, fileName) char *archivePath, *archiveName, *fileName; { char *newArFullName, *newDatFullName, oldArFullName[PATH_MAX], oldDatFullName[PATH_MAX]; char commandLine[PATH_MAX*4]; struct stat ibuf; if (verbosityLevel > SILENT) fprintf (stdout, "Moving archive files for %s to new locations\n", fileName); newArFullName = af_entersym (afArchiveName (archivePath, AF_ATTRDIR, af_afname (fileName), af_aftype (fileName), AF_WRITE)); newDatFullName = af_entersym (afArchiveName (archivePath, AF_DATADIR, af_afname (fileName), af_aftype (fileName), AF_WRITE)); /* check if destination file already exists -- if so, ask for confirmation */ if (stat (newArFullName, &ibuf) != ERROR) { if (verbosityLevel > SILENT) { fprintf (stdout, "-> Warning:\tDestination file %s already exists, overwrite ? (y/n) ", newArFullName); if (askConfirm ("n")) return (-1); } } sprintf (oldArFullName, "%s/%s", archivePath, archiveName); sprintf (oldDatFullName, "%s/%s", archivePath, archiveName); oldDatFullName[strlen(oldDatFullName)-1] = AF_OLD_DATAEXT; sprintf (commandLine, "mv -f %s %s; mv -f %s %s", oldArFullName, newArFullName, oldDatFullName, newDatFullName); disableSig (SIGINT); disableSig (SIGQUIT); system (commandLine); enableSig(); /* remove old style object cache */ sprintf (commandLine, "rm -f %s/%s* AFS/%s*", afArchivePath ("."), AF_OLD_BPFILEID, AF_OLD_BPFILEID); system (commandLine); return (0); } /*============ * repairDir *============*/ LOCAL int repairDir (dirName) char *dirName; { char *arPathPtr, attrArPath[PATH_MAX], commandLine[3*PATH_MAX+32]; char curPath[PATH_MAX]; int foundOldArchives = FALSE; int reallyRename = FALSE; DIR *dirPointer; struct dirent *dirEntry; struct stat atfsIbuf, subIbuf; getcwd (curPath, PATH_MAX); if (chdir (dirName) == -1) { fprintf (stderr, "-> Error:\tCannot change to directory %s\n", dirName); return (-1); } arPathPtr = afArchivePath (af_uniqpath (dirName)); /* check permissions */ if (stat (AF_SUBDIR, &atfsIbuf) != ERROR) { int i, modeConfirmed = FALSE, linkConfirmed = FALSE, ownerConfirmed = FALSE; /* check if AF_SUBDIR is a real directory */ if (S_ISREG (atfsIbuf.st_mode)) { if ((NORMAL <= verbosityLevel) && !modeConfirmed) { fprintf (stdout, "-> Warning:\t'%s' is not a directory nor a symbolic link!\n", AF_SUBDIR); fprintf (stdout, "\t\tIt seems to be a file containing the name of an AtFS\n"); fprintf (stdout, "\t\trepository elsewhere. This will not be able to straighten\n"); fprintf (stdout, "\t\tall permission bits. Proceed anyway (y/n) ? "); if (!askConfirm ("n")) linkConfirmed = TRUE; } if (!linkConfirmed) return (0); } else { /* check if protection of AtFS dir and subdirs conforms */ for (i=0; i<4; i++) { switch (i) { case 0: sprintf (attrArPath, "%s/%s", arPathPtr, AF_ATTRDIR); break; case 1: sprintf (attrArPath, "%s/%s", arPathPtr, AF_DATADIR); break; case 2: sprintf (attrArPath, "%s/%s", arPathPtr, AF_LOCKDIR); break; case 3: sprintf (attrArPath, "%s/%s", arPathPtr, AF_CACHENAME); break; } if (stat (attrArPath, &subIbuf) != ERROR) { if (i==3) { atfsIbuf.st_mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH|S_ISUID|S_ISGID); atfsIbuf.st_mode &= 0777; subIbuf.st_mode &= 0777; } if (atfsIbuf.st_mode != subIbuf.st_mode) { if ((NORMAL <= verbosityLevel) && !modeConfirmed) { fprintf (stdout, "-> Warning:\tProtection of '%s' directory\n", AF_SUBDIR); if (i==3) fprintf (stdout, "\t\tand derived object cache differ! Adjust (y/n) ? "); else fprintf (stdout, "\t\tand '%s' subdirectory differ! Adjust (y/n) ? ", attrArPath); if (askConfirm ("y")) modeConfirmed = TRUE; } if (modeConfirmed) { if (chmod (attrArPath, atfsIbuf.st_mode) == -1) fprintf (stderr, "Error:\tCannot change protection of '%s': %s\n", attrArPath, sys_errlist[errno]); } } if (atfsIbuf.st_gid != subIbuf.st_gid) { if ((NORMAL <= verbosityLevel) && !ownerConfirmed) { fprintf (stdout, "-> Warning:\tOwner/Group of '%s' directory\n", AF_SUBDIR); if (i==3) fprintf (stdout, "\t\tand derived object cache differ! Adjust (y/n) ? "); else fprintf (stdout, "\t\tand '%s' subdirectory differ! Adjust (y/n) ? ", attrArPath); if (askConfirm ("y")) ownerConfirmed = TRUE; } if (ownerConfirmed) if (chown (attrArPath, atfsIbuf.st_uid, atfsIbuf.st_gid) == -1) if (chown (attrArPath, geteuid(), atfsIbuf.st_gid) == -1) { fprintf (stderr, "Error:\tCannot change Owner/Group of '%s': %s\n", attrArPath, sys_errlist[errno]); } } } } /* for */ } /* else part */ } if (repairCache) { int tMax, nMax, aMax, otMax, onMax, oaMax, sizesOk; sizesOk = af_cachesize (".", -1, -1, -1, &tMax, &nMax, &aMax); if (NORMAL <= verbosityLevel) { fprintf (stdout, "Cannot repair derived object caches yet -- \nthe only way "); fprintf (stdout, "to fix a derived object cache is to clear it ! (y/n) ? "); if (askConfirm ("y")) { if (!strcmp (dirName, ".")) fprintf (stdout, "Clearing derived object cache in current directory ...\n"); else fprintf (stdout, "Clearing derived object cache in directory %s ...\n", dirName); sprintf (commandLine, "rm -f %s/%s* %s/%s* %s/%s*", arPathPtr, AF_CACHEFILEID, arPathPtr, AF_CACHENAME, arPathPtr, AF_OLD_BPFILEID); system (commandLine); fprintf (stdout, "-> Done.\n"); } } else { sprintf (commandLine, "rm -f %s/%s* %s/%s* %s/%s*", arPathPtr, AF_CACHEFILEID, arPathPtr, AF_CACHENAME, arPathPtr, AF_OLD_BPFILEID); system (commandLine); } if (sizesOk != -1) af_cachesize (dirName, tMax, nMax, aMax, &otMax, &onMax, &oaMax); return (1); } /* repair all archive files in AtFS subdirectory */ sprintf (attrArPath, "%s/%s", arPathPtr, AF_ATTRDIR); if ((dirPointer = opendir (attrArPath))) { while ((dirEntry = (struct dirent *)readdir (dirPointer))) { if (!strcmp (dirEntry->d_name, ".") || !strcmp (dirEntry->d_name, "..")) continue; if (setjmp (env) == 0) repair (dirName, dirEntry->d_name); } } /* Check for archive files with old style name */ if ((dirPointer = opendir (arPathPtr)) == NULL) { /* check for old AtFS directory */ if (access ("AFS", F_OK) == -1) { if (verbosityLevel > SILENT) fprintf (stderr, "Error:\tNo AtFS Database found\n"); chdir (curPath); return (-1); } sprintf (commandLine, "mv AFS %s", AF_SUBDIR); system (commandLine); if ((dirPointer = opendir (arPathPtr)) == NULL) { /* no way */ if (verbosityLevel > SILENT) fprintf (stderr, "Error:\tNo AtFS Database found\n"); chdir (curPath); return (-1); } } while ((dirEntry = (struct dirent *)readdir (dirPointer))) { int len; char fileName[NAME_MAX+1]; fileName[0] = '\0'; len = strlen (dirEntry->d_name); if (!strncmp (dirEntry->d_name, AF_OLD_ATFSFILEID, AF_IDSTRLEN) && (dirEntry->d_name[len - 1] == AF_OLD_ARCHEXT)) { if (!foundOldArchives) { foundOldArchives = TRUE; if (NORMAL <= verbosityLevel) { fprintf (stdout, "\nFound old style (1.3 or lower) named archive files -- rename them ? (y/n) ? "); if (!askConfirm ("y")) { chdir (curPath); return (0); } } } /* check if effective user id matches AtFS-dir owner id */ if (stat (arPathPtr, &atfsIbuf) == ERROR) { /* this should not happen */ fprintf (stdout, "Cannot stat %s directory", AF_SUBDIR); chdir (curPath); return (0); } if ((atfsIbuf.st_uid != geteuid()) && !reallyRename) { if (NORMAL <= verbosityLevel) { fprintf (stdout, "\nYou are not the owner of the AtFS directory -- really rename ? (y/n) ? "); if (!askConfirm ("n")) reallyRename = TRUE; } if (!reallyRename) { chdir (curPath); return (0); } } /* On System V machines, the name might be incomplete */ if (len == NAME_MAX) { strcpy (fileName, afReadName (dirEntry->d_name)); } else { strcpy (fileName, dirEntry->d_name + strlen (AF_OLD_ATFSFILEID)); len = strlen (fileName) - 1; fileName[len] = '\0'; } if (setjmp (env) == 0) { convert (arPathPtr, dirEntry->d_name, fileName); repair (dirName, fileName); } } } if (foundOldArchives) { /* remove old archive files and old object cache */ sprintf (commandLine, "rm -f %s/%s* %s/%s*", arPathPtr, AF_OLD_BPFILEID, arPathPtr, AF_OLD_ATFSFILEID); system (commandLine); } chdir (curPath); return (0); } /*========================================================================== * main and friends *==========================================================================*/ LOCAL void usage () { fprintf (stderr, "Usage:\tatfsrepair [-C] [-e] [-n] [-q] [-v] files\n"); } LOCAL Sigret_t sigHand () { unlink (arTmpFilename); unlink (datTmpFilename); exit (0); } EXPORT int main (argc, argv) int argc; char **argv; { short c, i, nfiles, retCode = 0; while ((c = getopt (argc, argv, "Ceinqv")) != EOF) { switch (c) { case 'C': /* repair derived object cache */ repairCache = TRUE; break; case 'e': /* edit mode */ verbosityLevel = EDIT; break; case 'i': /* interactive mode */ verbosityLevel = NORMAL; break; case 'n': /* don't ask mode */ verbosityLevel = NOASK; break; case 'q': /* really quiet mode */ verbosityLevel = SILENT; break; case 'v': /* print current version of this program */ printf ("This is atfsrepair version %s.\n", af_version()); exit (0); default: usage (); exit (1); } } /* end of command line parsing */ signal (SIGINT, sigHand); nfiles = argc - optind; if (nfiles > 0) { /* process arguments */ for (i = 0; i < nfiles; i++) { struct stat iBuf; /* check is argument is a directory */ if ((stat (argv[i+optind], &iBuf) != ERROR) && S_ISDIR(iBuf.st_mode)) { repairDir (argv[i+optind]); } else { char *path = af_afpath (argv[i+optind]); if (path && *path) { char curPath[PATH_MAX]; getcwd (curPath, PATH_MAX); if (chdir (path) == -1) { fprintf (stderr, "Error:\tCannot change to directory %s\n", path); chdir (curPath); continue; } if (setjmp (env) == 0) repair (path, argv[i+optind]); chdir (curPath); } else { if (setjmp (env) == 0) repair (path, argv[i+optind]); } } /*else*/ } /*for*/ exit (retCode); } return (repairDir (".")); } /* end of main */ shapetools-1.4pl6.orig/src/atfs/cacheadm.c100444 2013 145 10254 5617437050 16606 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * cacheadm.c -- administrate derived object cache * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: cacheadm.c[3.1] Thu Aug 4 16:03:05 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" int quietMode = FALSE; int maxCacheAttr = -1; int maxCacheName = -1; int maxCacheTotal = -1; LOCAL int setCacheSize (dir) char *dir; { int oldMaxCacheAttr, oldMaxCacheName, oldMaxCacheTotal; if (!quietMode && strcmp (dir, ".")) fprintf (stdout, "%s:\n", dir); if (af_cachesize (dir, maxCacheTotal, maxCacheName, maxCacheAttr, &oldMaxCacheTotal, &oldMaxCacheName, &oldMaxCacheAttr) == -1) { if (!quietMode) fprintf (stderr, " Error -- %s.\n", af_errmsg ("cachesize")); return (1); } if (!quietMode) { /* give feedback */ if (maxCacheTotal > 0) fprintf (stdout, " total max files: %4d (previously %4d)\n", maxCacheTotal, oldMaxCacheTotal); else fprintf (stdout, " total max files: %4d\n", oldMaxCacheTotal); if (maxCacheName > 0) fprintf (stdout, "max files per name: %4d (previously %4d)\n", maxCacheName, oldMaxCacheName); else fprintf (stdout, "max files per name: %4d\n", oldMaxCacheName); if (maxCacheAttr > 0) fprintf (stdout, "max files per attr: %4d (previously %4d)\n", maxCacheAttr, oldMaxCacheAttr); else fprintf (stdout, "max files per attr: %4d\n", oldMaxCacheAttr); } return (0); } /*========================================================================== * main and friends *==========================================================================*/ LOCAL void usage () { fprintf (stderr, "Usage:\tcacheadm [-A max_cached_per_uniq_attr] [-N max_cached_per_name]\n"); fprintf (stderr, "\t [-T max_total_cache_size] [-q] [-v] [dirs]\n"); } extern char *optarg; extern int optind; extern int errno; extern char *sys_errlist[]; EXPORT int main (argc, argv) int argc; char **argv; { short c, i, ndirs, retCode = 0; while ((c = getopt (argc, argv, "A:N:T:qv")) != EOF) { switch (c) { case 'A': /* max number of versions to be cached per attribute */ if ((maxCacheAttr = atoi (optarg)) < 0) { fprintf (stderr, " Error -- invalid argument for -A option (must not be negative)."); exit (1); } break; case 'N': /* max number of versions to be cached per name */ if ((maxCacheName = atoi (optarg)) < 0) { fprintf (stderr, " Error -- invalid argument for -N option (must not be negative)."); exit (1); } break; case 'q': /* quiet mode */ quietMode = TRUE; break; case 'T': /* total max number of versions to be cached */ if ((maxCacheTotal = atoi (optarg)) < 0) { fprintf (stderr, " Error -- invalid argument for -T option (must not be negative)."); exit (1); } break; case 'v': /* print current version of this program */ printf ("This is cacheadm version %s.\n", af_version()); exit (0); default: usage (); exit (1); } } /* end of command line parsing */ ndirs = argc - optind; if (ndirs == 0) { retCode += setCacheSize ("."); } else { /* process arguments */ for (i = 0; i < ndirs; i++) { struct stat iBuf; /* check if argument exists and is a directory */ if ((stat (argv[i+optind], &iBuf) != ERROR) && S_ISDIR(iBuf.st_mode)) { retCode += setCacheSize (argv[i+optind]); } else { fprintf (stderr, " Error -- %s: %s\n", argv[i+optind], sys_errlist[errno]); } } } exit (retCode); } /* end of main */ shapetools-1.4pl6.orig/src/atfs/config.c100444 2013 145 10131 5412537733 16322 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * config.c -- system dependent definitions * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: config.c[7.0] Fri Jun 25 14:32:35 1993 andy@cs.tu-berlin.de frozen $ */ #include "config.h" /*========================= * symlink *=========================*/ #if defined(NEED_SYMLINK) int symlink (origpath, name) char *origpath, *name; { /* * This is a faked BSD-type system-call to create a symbolic link. * What actually happens is that a file "name" will be created that * contains "origpath". This type of pseudo symbolic link is supported * by AtFS. */ FILE *slink; if ((slink = fopen (name, "w")) != NULL) { fprintf (slink, "%s", origpath); fclose (slink); return 0; } return -1; } #endif /*========================= * regex *=========================*/ #if defined(NEED_REGEX) extern char *regcmp(), *regex(); static char *re_pat; /* previously compiled pattern */ char *re_comp (s) char *s; { if (re_pat && *re_pat) free(re_pat); if ((re_pat = regcmp(s, (char *) NULL)) == (char *) NULL) return "Invalid argument"; return (char *) NULL; } int re_exec(s) char *s; { if (re_pat && *re_pat) return regex(re_pat, s) == (char *) NULL ? 0 : 1; else return 0; } #endif /*========================= * disable/enable signals *=========================*/ #if !defined(NO_SIGSET) /* Posix */ static sigset_t signalSet; static int firstTime = 1; #endif void disableSig (signo) int signo; { #if !defined(NO_SIGSET) if (firstTime) { sigemptyset (&signalSet); firstTime = 0; } sigaddset (&signalSet, signo); sigprocmask (SIG_BLOCK, &signalSet, NULL); #else sigblock (sigmask(signo)); #endif } void enableSig () { #if !defined(NO_SIGSET) sigprocmask (SIG_UNBLOCK, &signalSet, NULL); sigemptyset (&signalSet); #else sigsetmask (0); #endif } /*================== * strdup *==================*/ #if defined(NEED_STRDUP) #ifdef __STDC__ char *strdup (const char *str) #else char *strdup (str) char *str; #endif { char *newStr = malloc (strlen(str)+1); if (newStr) strcpy (newStr, str); return (newStr); } #endif /*================== * getcwd *==================*/ #if defined(NEED_GETCWD) char *getcwd (buf, size) char *buf; size_t size; { char *getwd(); if (!buf) if ((buf = malloc (size)) == NULL) return (NULL); return (getwd (buf)); } #endif /*=============== * mntent *===============*/ #if defined(NEED_MNTENT) #include #ifdef __STDC__ FILE *atSetmntent (const char *path, const char *type) #else FILE *atSetmntent (path, type) char *path, *type; #endif { setfsent (); return ((FILE *)1); } struct atMntent *atGetmntent (file) FILE *file; { static struct atMntent mountEntry; struct fstab *fstabEntry; if (fstabEntry = getfsent ()) { mountEntry.at_mnt_fsname = fstabEntry->fs_spec; mountEntry.at_mnt_dir = fstabEntry->fs_file; mountEntry.at_mnt_type = fstabEntry->fs_type; mountEntry.at_mnt_opts = ""; mountEntry.at_mnt_freq = fstabEntry->fs_freq; mountEntry.at_mnt_passno = fstabEntry->fs_passno; return (&mountEntry); } return (NULL); } int atEndmntent (file) FILE *file; { endfsent (); } #elif defined(HAS_MNTTAB) struct atMntent *atGetmntent (mountTable) FILE *mountTable; { static struct atMntent mountEntry; if (getmntent (mountTable, &mountEntry)) return (&mountEntry); return (NULL); } #endif shapetools-1.4pl6.orig/src/atfs/mkatfs.sh100555 2013 145 12066 5621412677 16547 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # AtFS -- Attribute Filesystem # # mkatfs.sh -- initialize and configure AtFS repository # # Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # # $Header: mkatfs.sh[7.2] Mon Aug 8 13:51:43 1994 andy@cs.tu-berlin.de frozen $ usage () { echo "usage: mkatfs [-cT max_total_cache_size] [-cN max_cached_per_name]" echo " [-cA max_cached_per_uniq_attribute] [-cQ]" echo " [-g group] [-h] [-l path] [-m mode] [-v] pathnames" } trapexit () { exit 1 } perror () { echo 1>&2 $* } trap trapexit 1 2 3 15 argc=$# pathgiven=false curdir=`pwd` maxTotal=0 maxPerName=0 maxPerAttr=0 configured=false while [ $argc -gt 0 ] do i=$1 shift argc=`expr $argc - 1` case $i in -cT) if [ $argc -gt 0 ] then maxTotal=$1 shift argc=`expr $argc - 1` else perror usage: mkatfs -cT requires an argument. exit 1 fi;; -cN) if [ $argc -gt 0 ] then maxPerName=$1 shift argc=`expr $argc - 1` else perror usage: mkatfs -cN requires an argument. exit 1 fi;; -cA) if [ $argc -gt 0 ] then maxPerAttr=$1 shift argc=`expr $argc - 1` else perror usage: mkatfs -cA requires an argument. exit 1 fi;; -cQ) cacheadm exit 0;; -g) if [ $argc -gt 0 ] then group=$1 shift argc=`expr $argc - 1` else perror usage: mkatfs -g requires a group argument. exit 1 fi;; -h) usage exit 0;; -l) if [ $argc -gt 0 ] then linkto=`echo $1 | sed -e 's,/$,,'` # cut trailing slash shift argc=`expr $argc - 1` else perror usage: mkatfs -l requires a path argument. exit 1 fi;; -m) if [ $argc -gt 0 ] then mode=$1 shift argc=`expr $argc - 1` else perror usage: mkatfs -m requires a mode argument. exit 1 fi;; -v) echo This is 'mkatfs release AtFS-1.71 (Tue Aug 23 17:54:06 1994 by andy@cs.tu-berlin.de).' exit 0;; -*) perror invalid option $i usage exit 1;; *) pathgiven=true cd $i if [ "$linkto" ] then linkbase=`basename $linkto` if [ $linkbase = AtFS ] then linkto=`dirname $linkto` fi ln -s $linkto/AtFS AtFS 2> /dev/null if [ $? -gt 0 ] then echo $linkto/AtFS > AtFS fi msg1=linked else if [ ! -d AtFS ] then mkdir AtFS AtFS/Attr AtFS/Data AtFS/Lock msg1=initialized else msg1=exists fi fi if [ "$group" ] then chgrp $group AtFS AtFS/Attr AtFS/Data AtFS/Lock if [ "$msg1" = "exists" ] then msg1="configured" else msg1="$msg1 and configured" fi configured=true fi if [ "$mode" ] then chmod $mode AtFS AtFS/Attr AtFS/Data AtFS/Lock if [ "$configured" = "false" ] then if [ "$msg1" = "exists" ] then msg1="configured" else msg1="$msg1 and configured" fi fi configured=true fi if [ $maxTotal != 0 ] || [ $maxPerName != 0 ] || [ $maxPerAttr != 0 ] then cacheadm -T $maxTotal -N $maxPerName -A $maxPerAttr if [ $? -eq 0 ] then if [ "$msg1" = "exists" ] then msg1="object cache configured" else msg1="$msg1 and object cache configured" fi fi fi cd $curdir esac done if [ $pathgiven = false ] then if [ "$linkto" ] then linkbase=`basename $linkto` if [ $linkbase = AtFS ] then linkto=`dirname $linkto` fi ln -s $linkto/AtFS AtFS 2> /dev/null if [ $? -gt 0 ] then echo $linkto/AtFS > AtFS fi msg1=linked else if [ ! -d AtFS ] then mkdir AtFS AtFS/Attr AtFS/Data AtFS/Lock msg1=initialized else msg1=exists fi fi if [ "$group" ] then chgrp $group AtFS AtFS/Attr AtFS/Data AtFS/Lock if [ "$msg1" = "exists" ] then msg1="configured" else msg1="$msg1 and configured" fi configured=true fi if [ "$mode" ] then chmod $mode AtFS AtFS/Attr AtFS/Data AtFS/Lock if [ "$configured" = "false" ] then if [ "$msg1" = "exists" ] then msg1="configured" else msg1="$msg1 and configured" fi fi configured=true fi if [ $maxTotal != 0 ] || [ $maxPerName != 0 ] || [ $maxPerAttr != 0 ] then cacheadm -T $maxTotal -N $maxPerName -A $maxPerAttr if [ $? -eq 0 ] then if [ "$msg1" = "exists" ] then msg1="object cache configured" else msg1="$msg1 and object cache configured" fi fi fi fi echo "AtFS repository $msg1." exit 0 shapetools-1.4pl6.orig/src/atfs/atfs.h100444 2013 145 25704 5504363430 16024 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * atfs.h - Type and Constant-Definitions for the * Attribute-Filesystem * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: atfs.h[7.0] Fri Dec 17 18:11:30 1993 andy@cs.tu-berlin.de frozen $ */ #ifndef _ATFSHDR_ #define _ATFSHDR_ /*========================================================================= * Installation dependent constants *=========================================================================*/ #include "config.h" #define USER_MAX 64 /*========================================================================= * External Type Definitions *=========================================================================*/ typedef struct afkey Af_key; typedef struct afuser Af_user; #include "afsys.h" /**** filekey ****/ struct afkey { Af_revlist *af_ldes; /* ptr to revlist descriptor */ int af_lpos; /* position in revlist */ }; /**** Set descriptor ****/ typedef struct { int af_nkeys; int af_setlen; Af_key *af_klist; } Af_set; /**** User Identification ****/ struct afuser { char af_username[USER_MAX]; char af_userhost[HOST_MAX]; char af_userdomain[DOMAIN_MAX]; }; /**** Attribute buffer ****/ #define AF_MAXUDAS 255 typedef struct { char af_host[HOST_MAX]; /* hostname */ char af_syspath[PATH_MAX]; /* system path */ char af_name[NAME_MAX+1]; /* filename */ char af_type[TYPE_MAX]; /* filename extension (type) */ int af_gen; /* generation number */ int af_rev; /* revision number */ int af_state; /* version state (see below) */ Af_user af_owner; /* owner */ Af_user af_author; /* author */ size_t af_size; /* size of file */ mode_t af_mode; /* protection (from inode) */ Af_user af_locker; /* locker */ time_t af_mtime; /* date of last modification */ time_t af_atime; /* date of last access */ time_t af_ctime; /* date of last status change*/ time_t af_stime; /* save date */ time_t af_ltime; /* date of last lock change */ char *af_udattrs[AF_MAXUDAS+1]; /* user def. attributes */ } Af_attrs; /*========================================================================= * Global Variables and Constant Definitions *=========================================================================*/ /**** Version states ****/ #define AF_DERIVED -2 #define AF_NOSTATE -1 #define AF_BUSY 0 #define AF_SAVED 1 #define AF_PROPOSED 2 #define AF_PUBLISHED 3 #define AF_ACCESSED 4 #define AF_FROZEN 5 /**** Settings for Attrbuf ****/ #define AF_NONAME "\0" #define AF_NOTYPE "\0" #define AF_NOVNUM -1 #define AF_NOSIZE -1 #define AF_NOMODE 0 #define AF_NOUSER { "\01$\0", "\0", "\0" } #define AF_NOTIME -1 /**** Modes ****/ #define AF_ADD 1 /* user-defined attributes */ #define AF_REMOVE 2 /* " */ #define AF_REPLACE 3 /* " */ #define AF_BUSYVERS -2 /* version identification */ #define AF_FIRSTVERS -3 /* " */ #define AF_LASTVERS -4 /* " */ #define AF_STORE_DELTA 0 /* version storage type */ #define AF_STORE_COMPLETE 1 /* " */ #define AF_STORE_COMPRESSED 2 /* " */ #define AF_LOGICAL_SUCC 1 /* logical successor */ #define AF_LOGICAL_PRED 2 /* logical predecessor */ #define AF_PHYSICAL_SUCC 3 /* physical successor */ #define AF_PHYSICAL_PRED 4 /* physical predecessor */ #define AF_LASTPOS -4 /* set position */ /**** Object classes ****/ #define AF_CLASS_SOURCE 00 #define AF_CLASS_DERIVED 01 #define AF_VALID 02 /*========================================================================= * Attribute names *=========================================================================*/ #define AF_UDANAMLEN 128 /* maximum length of uda name */ #define AF_ATTNUM 19 /* number of attrributes in attrbuf */ #define AF_ATTHOST "af_host" #define AF_ATTSPATH "af_syspath" #define AF_ATTNAME "af_name" #define AF_ATTTYPE "af_type" #define AF_ATTUNIXNAME "af_unixname" /* unix file name -- not for sorting */ #define AF_ATTUNIXPATH "af_unixpath" /* full unix path name -- not for sorting */ #define AF_ATTBOUND "af_bound" /* bound notation (e.g. foo.c[1.2]) */ #define AF_ATTBOUNDPATH "af_boundpath" /* " plus path (e.g. /u/andy/foo.c[1.2]) -- not for sorting */ #define AF_ATTGEN "af_gen" #define AF_ATTREV "af_rev" #define AF_ATTVERSION "af_version" /* compound attribute: gen.rev */ #define AF_ATTSTATE "af_state" #define AF_ATTOWNER "af_owner" #define AF_ATTAUTHOR "af_author" #define AF_ATTDSIZE "af_dsize" /* not for sorting */ #define AF_ATTSIZE "af_size" #define AF_ATTMODE "af_mode" #define AF_ATTLOCKER "af_locker" #define AF_ATTMTIME "af_mtime" #define AF_ATTATIME "af_atime" #define AF_ATTCTIME "af_ctime" #define AF_ATTSTIME "af_stime" #define AF_ATTLTIME "af_ltime" /*========================================================================= * Errorcodes *=========================================================================*/ /* General */ #define AF_OK 0 #define AF_ESYSERR -2 /* Error during execution of Syslib-command */ #define AF_EACCES -3 /* permission denied */ #define AF_EARCHANGED -4 /* archive has changed since last read */ #define AF_EBUSY -7 /* spec. revision must not be a busy version */ #define AF_EDERIVED -8 /* spec. revision is a derived object */ #define AF_EINVKEY -9 /* invalid key */ #define AF_EINVSET -10 /* invalid set */ #define AF_EINVUSER -11 /* invalid user */ #define AF_EINVVNUM -12 /* bad version number */ #define AF_EMISC -15 /* miscellaneous errors */ #define AF_EMODE -16 /* invalid mode */ #define AF_ENOATFSDIR -17 /* no AtFS subdirectory */ #define AF_ENOKEY -18 /* key does not exist in set */ #define AF_ENOPOS -19 /* invalid position in set */ #define AF_ENOREV -20 /* specified revision does not exist */ #define AF_ENOTBUSY -21 /* specified object is no busy version */ #define AF_ENOTDERIVED -22 /* specified object is no derived object */ #define AF_ENOTLOCKED -23 /* version is not locked or - by another user*/ #define AF_ENOTREGULAR -24 /* specified object is no regular file */ #define AF_ENOTVERS -25 /* specified object has no versions */ #define AF_ENOUDA -26 /* user defined attribute does not exist */ #define AF_ESAVED -27 /* saved versions cannot be modified */ #define AF_ESTATE -28 /* invalid state transition */ #define AF_EWRONGSTATE -31 /* wrong state */ /* codes for really serious errors */ #define AF_EDELTA -32 /* error during delta operation */ #define AF_EINCONSIST -33 /* Archive file inconsistent */ #define AF_EINTERNAL -34 /* internal error */ #define AF_ENOATFSFILE -35 /* no AtFS file */ /*========================================================================= * Declarations (ordered alphabetically) *=========================================================================*/ #ifdef __STDC__ #define A(alist) alist #else #define A(alist) () #endif extern int af_noReadLock; /* switch off archive file reader/writer locking */ extern int af_suppressUdas; /* do not read user defined attributes from archive file */ int af_abort A((void)); int af_access A((char *path, char *name, char *type, int mode)); char* af_afname A((char *unixname)); char* af_afpath A((char *unixname)); char* af_aftype A((char *unixname)); Af_user* af_afuser A((uid_t uid)); int af_allattrs A((Af_key *key, Af_attrs *attrbuf)); int af_cachefind A((Af_attrs *attrbuf, Af_set *set)); char** af_cachenames A((char *path, char *pattern)); int af_cachesize A((char *path, int tMax, int nMax, int aMax, int *otMax, int *onMax, int *oaMax)); int af_chauthor A((Af_key *key, Af_user *author)); int af_chmod A((Af_key *key, int mode)); int af_chowner A((Af_key *key, Af_user *owner)); void af_cleanup A((void)); int af_close A((FILE *file)); int af_commit A((void)); int af_copyset A((Af_set *set1, Af_set *set2)); int af_crkey A((char *path, char *name, char *type, Af_key *key)); int af_diff A((Af_set *set1, Af_set *set2, Af_set *newset)); int af_dropall A((void)); int af_dropkey A((Af_key *key)); int af_dropset A((Af_set *set)); char* af_errmsg A((char *string)); int af_establish A((Af_key *key, char *fileName)); int af_find A((Af_attrs *attrbuf, Af_set *set)); void af_freeattr A((char *attrValue)); void af_freeattrbuf A((Af_attrs *attrBuf)); int af_getkey A((char *syspath, char *name, char *type, int gen, int rev, Af_key *key)); char** af_histories A((char *path, char *pattern)); void af_initattrs A((Af_attrs *attrs)); void af_initset A((Af_set *set)); int af_intersect A((Af_set *set1, Af_set *set2, Af_set *newset)); int af_isstdval A((char *attrValue)); Af_user* af_lock A((Af_key *key, Af_user *locker)); int af_newgen A((Af_key *key, Af_key *newkey)); int af_nrofkeys A((Af_set *set)); FILE* af_open A((Af_key *key, char *mode)); void af_perror A((char *string)); int af_predsucc A((Af_key *inkey, int mode, Af_key *outkey)); int af_restore A((Af_key *key, Af_key *restkey)); char * af_retattr A((Af_key *key, char *attr)); int af_retnumattr A((Af_key *key, char *attr)); time_t af_rettimeattr A((Af_key *key, char *attr)); Af_user* af_retuserattr A((Af_key *key, char *attr)); int af_rm A((Af_key *key)); char* af_rnote A((Af_key *key)); int af_savecache A((Af_key *busykey, Af_key *savekey, char *uniqAttr, int mode)); int af_saverev A((Af_key *busykey, Af_key *savekey, int gen, int storetype)); int af_setaddkey A((Af_set *set, int pos, Af_key *key)); char* af_setarchpath A((char *pathname)); int af_setattr A((Af_key *key, int mode, char *attr)); int af_setbusy A((Af_key *busykey, Af_key *key, Af_key *prevkey)); int af_setgkey A((Af_set *set, int pos, Af_key *key)); int af_setposrmkey A((Af_set *set, int pos)); int af_setrmkey A((Af_set *set, Af_key *key)); int af_snote A((Af_key *key, char *buf)); int af_sortset A((Af_set *set, char *attr)); int af_sstate A((Af_key *key, int state)); int af_subset A((Af_set *set, Af_attrs *attrbuf, Af_set *newset)); int af_svnum A((Af_key *key, int gen, int rev)); Af_user* af_testlock A((Af_key *key)); void af_transaction A((void)); int af_union A((Af_set *set1, Af_set *set2, Af_set *newset, int checkDouble)); Af_user* af_unlock A((Af_key *key)); char* af_version A((void)); #endif /* __ATFSHDR__ */ shapetools-1.4pl6.orig/src/atfs/afsys.h100444 2013 145 34774 5515507261 16227 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afsys.h - Internal type and Constant-Definitions for the * Attribute-Filesystem * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afsys.h[7.0] Fri Jan 14 13:35:40 1994 andy@cs.tu-berlin.de frozen $ */ #ifndef _ATFSYS_ #define _ATFSYS_ /*========================================================================= * Installation dependent constants *=========================================================================*/ #define AF_SYMHASHSIZE 507 /* size of hashtable for symbols */ #define AF_UDAHASHSIZE 61 /* size of hashtable for user defined attrs */ #define AF_UDANUM 8 /* number of user defined attributes in */ /* linear list */ #define AF_SEGLEN 32 /* size of segment for (re-)allocation */ /*** Derived Object Cache Limits and Defaults ***/ #define AF_MAX_CACHED_PER_NAME 52 #define AF_DEFAULT_CACHED_PER_NAME 3 #define AF_DEFAULT_CACHED_PER_ATTR 1 #define AF_DEFAULT_CACHED_MAX 1024 /*========================================================================= * general constants *=========================================================================*/ #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define ERROR -1 #define LOCAL static #define EXPORT #define bool short /*========================================================================= * Hash stuff *=========================================================================*/ typedef struct Af_hshent Af_hashent; /*========================================================================= * Internal Type Definitions *=========================================================================*/ /**** buffer for version-independent attributes ****/ typedef struct { char *af_host; /* hostname */ char *af_syspath; /* system path */ char *af_globname; /* global filename */ char *af_globtype; /* global filename ext.(type)*/ char *af_ownname; /* name of owner */ char *af_ownhost; /* host of owner */ char *af_owndomain; /* domain of owner */ } Af_cattrs; /**** buffer for version-dependent attributes ****/ typedef struct { char *af_name; /* filename */ char *af_type; /* filename extension (type) */ int af_gen; /* generation number */ int af_rev; /* revision number */ short af_state; /* version state (see below) */ short af_class; /* file class */ char *af_auname; /* name of author */ char *af_auhost; /* host of author */ char *af_audomain; /* domain of author */ mode_t af_mode; /* protection (from inode) */ char *af_lckname; /* name of locker */ char *af_lckhost; /* host of locker */ char *af_lckdomain; /* domain of locker */ time_t af_mtime; /* date of last modification */ time_t af_atime; /* date of last access */ time_t af_ctime; /* date of last status change*/ time_t af_stime; /* save date */ time_t af_ltime; /* date of last lock change */ size_t af_notesize; /* size of note */ char *af_note; /* modification note */ int af_udanum; /* number of uda entries */ Af_hashent *af_uhtab; /* hash table for udefattrs */ char *af_udalist[AF_UDANUM+1]; /* list of udattrs if # <= 8 */ short af_repr; /* kind of representation */ size_t af_fsize; /* size of file */ size_t af_dsize; /* size of delta */ char *af_data; /* ptr to chunk or delta */ char *af_hashname; /* name of associated file */ short af_nrefs; /* # of references to rev. */ int af_succgen, /* physical */ af_succrev; /* successor */ int af_predgen, /* physical */ af_predrev; /* predecessor */ } Af_vattrs; /**** Descriptor for revision list ****/ typedef struct rvlist Af_revlist; struct rvlist { char *af_arpath; /* pathname of archive dir */ gid_t af_owngid; /* gid of archive's owner */ time_t af_lastmod; /* last mod. of archive file */ char *af_busyfilename; /* filename of busy version */ short af_nrevs; /* number of revs in list */ short af_listlen; /* total length of list */ size_t af_datasize; /* size of data-segment */ short af_extent; /* extent of revision list */ Af_cattrs af_cattrs; /* version-independent attrs */ Af_vattrs *af_list; /* pointer to revision list */ int af_access; /* access number */ char *af_mem; /* list of ptrs to alloc. mem. */ int af_totalmem; /* size of memory used */ Af_revlist *af_next; /* index of next freelist entry */ }; /* Constants for af_extent */ /**** extent and type of revision list ****/ #define AF_SEGMASK 0007 /* Mask for data flags */ #define AF_ATTRS 0001 /* Attributes are loaded */ #define AF_DATA 0002 /* Data are loaded */ #define AF_COMPLETE 0004 /* List is complete (derived object caches only) */ #define AF_CACHE 0010 /* Derived Object Cache */ #define AF_ARCHIVE 0020 /* Line of development */ #define AF_UXWRITE 0100 /* Unix write permission on AtFS subdir */ #define AF_LISTBUSY 0200 /* List is currently in use */ /*========================================================================= * More Hash stuff *=========================================================================*/ struct Af_hshent { char *symbol; Af_hashent *next; }; /*========================================================================= * Internal Installation dependent constants *=========================================================================*/ /**** "syntactical sugar" for user defined attributes ****/ #define AF_UDANAMDEL '=' /* Delimiter for UDA name in archive */ #define AF_UDAVALDEL '\01' /* Delimiter for UDA values in arch. */ /**** UNIX Environment ****/ #define AF_TMPDIR "/tmp" /* location of temporary files */ #define AF_SUBDIR "AtFS" /* subdirectory for archives */ #define AF_ATTRDIR "Attr" /* subdirectory for attr. archives */ #define AF_DATADIR "Data" /* subdirectory for data archives */ #define AF_LOCKDIR "Lock" /* subdirectory for locks */ #define AF_ATTRBACKUPDIR "Attr.bak" /* subdir for backups of attr. archives */ #define AF_DATABACKUPDIR "Data.bak" /* the same for data archives */ #define AF_CACHENAME "ObjCache" #define AF_CACHELCKNAME "ObjCache.lck" #define AF_CACHEFILEID "OC" /**** error message logging */ #define AF_ERRLOG "/tmp/AtFSerrlog" /*========================================================================= * Internal Constant Definitions *=========================================================================*/ /**** general ****/ #define AF_READ 0 #define AF_WRITE 1 #define AF_RDWR 2 /**** representation types ****/ #define AF_CHUNK 0 #define AF_DELTA 1 #define AF_FILE 2 /* version resides in an own file (busy version) */ /**** Version numbering ****/ #define AF_INITGEN 1 #define AF_INITREV 0 /**** Modes for archive manipulation ****/ #define AF_CHANGE 01 #define AF_ALLVERS 02 /**** Environment interaction ****/ /**** Permissions for checkperm ****/ #define AF_OWNER 0001 #define AF_AUTHOR 0002 #define AF_LOCKHOLDER 0004 #define AF_WORLD 0010 #define AF_REMOTE -2 /*========================================================================= * Useful macros *=========================================================================*/ #define CATTR(keyp) keyp->af_ldes->af_cattrs #define VATTR(keyp) keyp->af_ldes->af_list[keyp->af_lpos] /* compare filekeys -- returnes 0 if equal (like strcmp) */ #define af_keycmp(key1,key2) (((key1)->af_ldes != (key2)->af_ldes) || ((key1)->af_lpos != (key2)->af_lpos)) /* report error and return */ #define FATAL(msg1,msg2,errcd,retcd) { af_err (msg1, msg2, errcd); return (retcd); } #define FAIL(msg1,msg2,errcd,retcd) { af_serr (msg1, msg2, errcd); return (retcd); } /* convert nil pointer to empty string */ #define NOTNIL(str) (str ? str : "") /* regex pattern matching all strings */ #define AF_PATTERN_ALL "^.*$" /*========================================================================= * Declarations *=========================================================================*/ #ifdef __STDC__ #define A(alist) alist #else #define A(alist) () #endif /*** afarchive.c ***/ char* afFirstItem A((char *line)); char* afNextItem A((char *line)); int afReadData A((Af_revlist *list)); int afReadAttrs A((Af_revlist *list)); int afWriteArchive A((Af_revlist *list)); /*** afarlock.c ***/ FILE *afOpenLock A((char *filename, int mode, Af_revlist *list)); int afCloseUnlock A((FILE *file, int mode, Af_revlist *list)); /*** afcache.c ***/ Af_revlist *afInitList A((char *pathsym, char *namesym, char *typesym)); Af_revlist *afInitObjCache A((char *pathsym)); Af_revlist *afTestList A((char *pathsym, char *namesym, char *typesym)); int afRefreshList A((Af_revlist *list, int extent)); int afDetachList A((Af_revlist *list)); int afListSpace A((int size)); /*** afcompar.c ***/ int af_cmpatime A((Af_key *key1, Af_key *key2)); int af_cmpauthor A((Af_key *key1, Af_key *key2)); int af_cmpctime A((Af_key *key1, Af_key *key2)); int af_cmpgen A((Af_key *key1, Af_key *key2)); int af_cmphost A((Af_key *key1, Af_key *key2)); int af_cmpbound A((Af_key *key1, Af_key *key2)); int af_cmplocker A((Af_key *key1, Af_key *key2)); int af_cmpltime A((Af_key *key1, Af_key *key2)); int af_cmpmode A((Af_key *key1, Af_key *key2)); int af_cmpmtime A((Af_key *key1, Af_key *key2)); int af_cmpname A((Af_key *key1, Af_key *key2)); int af_cmpowner A((Af_key *key1, Af_key *key2)); int af_cmprev A((Af_key *key1, Af_key *key2)); int af_cmpsize A((Af_key *key1, Af_key *key2)); int af_cmpstate A((Af_key *key1, Af_key *key2)); int af_cmpsvtime A((Af_key *key1, Af_key *key2)); int af_cmpspath A((Af_key *key1, Af_key *key2)); int af_cmptype A((Af_key *key1, Af_key *key2)); int af_cmpversion A((Af_key *key1, Af_key *key2)); int af_cmpuda A((Af_key *key1, Af_key *key2)); /*** afdelta.c ***/ int af_nodelta A((Af_key *busykey, Af_key *savekey)); int af_dodelta A((Af_key *busykey, Af_key *predkey, Af_key *savekey)); int af_undodelta A((Af_key *deltakey, char *filename)); int af_rmdelta A((Af_key *deltakey)); /*** afdeltaproc.c ***/ char *afConvertDelta A((char *deltaStr, size_t deltaSize, size_t *newDeltaSize)); int afReconsData A((char *srcStr, char *deltaStr, size_t srcSize, size_t deltaSize, char *targetfn)); int afMakeDelta A((char *srcStr, char *targetStr, size_t srcSize, size_t targetSize, char *deltafn)); /*** afenviron.c ***/ uid_t af_getuid A((char *name, char *host, char *domain)); gid_t af_getgid A((char *name, char *host, char *domain)); int af_checkread A((Af_key *key)); int af_checkperm A((Af_key *key, int mode)); char *af_gethostname A((void)); char *af_getdomain A((void)); /*** aferror.c ***/ void af_serr A((char *routine, char *called, int errcd)); void af_err A((char *routine, char *called, int errcd)); void af_wng A((char *routine, char *comment)); /*** afkeys.c ***/ int af_buildkey A((Af_revlist *list, int gen, int rev, Af_key *key)); Af_key *af_gbuskey A((Af_revlist *list)); Af_key *af_glastkey A((Af_revlist *list)); Af_key *af_glastgenkey A((Af_revlist *list, int gen)); int af_gfreepos A((Af_revlist *list)); int af_glastgenpos A((Af_revlist *list, int gen)); void afIncreaseAccess A((Af_key *key)); void afDecreaseAccess A((Af_key *key)); /*** aflib.c ***/ size_t af_retfsize A((char *fileName)); int af_cpfile A((char *source, size_t size, char *dest)); int af_bsearch A((char **list, int size, char *target)); /*** afmemory.c***/ char *af_malloc A((Af_revlist *list, unsigned size)); char *af_realloc A((Af_revlist *list, char *ptr, unsigned size)); void af_free A((Af_revlist *list, char *ptr)); void af_frmemlist A((Af_revlist *list)); /*** afnames.c ***/ char *af_uniqpath A((char *path)); Af_user *afArchiveOwner A((char *archDir, bool *writeok, gid_t *gid)); mode_t afArchiveMode A((char *archDir)); char *afArchivePath A((char *path)); char *afArchiveName A((char *archivePath, char *arClass, char *name, char *type, int mod)); char *afCacheFileName A((char *archPath, char *name)); char *afCacheUniqueName A((char *unixName, char uniqChar)); char *af_gtmpname A((char *path)); char *af_gbusname A((char *path, char *name, char *type)); /*** afobjcache.c ***/ int afObjCacheRead A((Af_revlist *list)); int afObjCacheWrite A((Af_revlist *list)); int afObjCacheAdd A((Af_key *aso, Af_key *outKey, char *uniqAttr)); int afObjCacheRestore A((Af_key *aso, char *fileName)); /*** afstore.c ***/ int afAccessAso A((Af_key *key, int mode)); int afUpdateAso A((Af_key *key, int mode)); int afNewAso A((Af_revlist *list, Af_key *key, int mode, int gen)); int afAddAso A((Af_key *key)); int afDeleteAso A((Af_key *key)); int afGetAso A((char *syspath, char *name, char *type, int gen, int rev, Af_key *key)); int afTestAso A((char *path, char *name, char *type, int mode)); int afBuildFile A((Af_key *key, char *name)); /*** afsymtab.c ***/ int afHashval A((char *symbol, int size)); char *af_entersym A((char *symbol)); char *af_enterhost A((char *hostname)); char *af_enterdomain A((char *domain)); /*** aftime.c ***/ char *af_asctime A((void)); time_t af_acttime A((void)); /*** aftmpfiles.c ***/ void af_reglckfile A((char *name)); void af_unregtmpfile A((char *name)); void af_regtmpfile A((char *name)); /*** aftransaction.c ***/ int afAddToTransactionList A((Af_revlist *list)); /*** afudattrs.c ***/ void afInitUdas A((Af_key *key)); int afEnterUda A((Af_key *key, char *symbol)); int afReplUda A((Af_key *key, char *symbol)); int afDelUda A((Af_key *key, char *symbol)); char *afLookupUda A((Af_key *key, char *symbol)); int afMatchUda A((Af_key *key, char *entry)); int afListUdas A((Af_key *key, char **symbollist)); int afDropUdas A((Af_key *key)); int afCopyUdas A((Af_key *src, Af_key *dest)); int afAttrNameCmp A((char *attr1, char *attr2)); #endif shapetools-1.4pl6.orig/src/atfs/afarchive.h100444 2013 145 6672 5412537532 17006 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * afarchive.h - Constant-Definitions for AtFS-archives * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: afarchive.h[7.0] Fri Jun 25 14:32:45 1993 andy@cs.tu-berlin.de frozen $ */ /*========================================================================= * Internal Installation dependent constants *=========================================================================*/ #define AF_NEWREVS 8 /* add. space for new revisions in rev list */ #define AF_MAXLISTS 211 /* maximum number of read-in archives */ #define AF_MAXMEM 1000000 /* maximum size of memory occupied by */ /* read in archives */ #define AF_LISTSEG 8 /* size of segments of revlists-list */ #define AF_UDASEGSIZ 512 /* size of memory segment for UDAs */ /*========================================================================= * Identification strings in archive and derived object cache files *=========================================================================*/ #define AF_LINESIZ 1024 /* size of input line */ #define AF_SEGSTRLEN 5 #define AF_ARHEADER "\02ARHD" /* Header of Archive-file */ #define AF_DATAHEADER "\02DATA" /* Header of Data-file */ #define AF_CACHEHEADER "\02OCHD" /* Header of Cache Control file */ #define AF_UDASEG "\02USEG" /* User defined attributes Segment */ #define AF_IDSTRLEN 2 #define AF_NAMEID "\02I" /* Identification path, name, type */ #define AF_OWNID "\02O" /* Owner */ #define AF_PRDID "\02P" /* predecessor of busy version */ #define AF_LOCKID "\02L" /* Lock */ #define AF_REVID "\02R" /* revision specific attributes */ /* gen, rev, state, mode */ #define AF_AUTHORID "\02A" /* Author */ #define AF_DATEID "\02T" /* date of last mod., last access, */ /* creation, save */ #define AF_REPRID "\02M" /* kind of represetation, size of file, size */ /* of delta and other delta stuff (tree) */ #define AF_NOTEID "\02N" /* gen, rev, size, text of note */ #define AF_UDAID "\02U" /* gen, rev, size, text of udattrs */ #define AF_DATAID "\02D" /* gen, rev, size, repr, text of data */ /*====================================================================== * other constants *======================================================================*/ #define AF_ARCURVERS 4 #define AF_CACHECURVERS 2 #define AF_NOSTRING "\01$" /*========================================================================= * Useful macros and function definitions *=========================================================================*/ /* test if string is empty */ #define NOTMT(str) ((str && str[0]) ? str : AF_NOSTRING) #ifdef __STDC__ #define A(alist) alist #else #define A(alist) () #endif char *afFirstItem A((char *line)); char *afNextItem A((char *line)); shapetools-1.4pl6.orig/src/atfs/atfsrepair.h100444 2013 145 4673 5412537505 17215 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * atfsrepair.h -- definitions for archive repair tool * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: atfsrepair.h[7.0] Fri Jun 25 14:32:47 1993 andy@cs.tu-berlin.de frozen $ */ /*** levels ***/ #define SILENT 0 #define NOASK 1 #define NORMAL 2 #define EDIT 3 #define MAXREVS 256 #define MAXUDAS 256 /*** definitions for compatibility with old versions ***/ #define AF_OLD_ATFSFILEID "\02A" /* filename prefix for AtFS archives */ #define AF_OLD_ARCHEXT 'A' /* extension for archive names */ #define AF_OLD_DATAEXT 'D' /* extension for datafile names */ #define AF_OLD_BPFILEID "\02B" /* filename prefix for BP files */ typedef struct { char *string; int curPos; int length; } Input; typedef struct { off_t datasize; int noOfRevisions; char *host; char *syspath; char *name; char *type; char *ownerName; char *ownerHost; char *ownerDomain; } ConstAttrs; typedef struct { int generation; int revision; int state; mode_t mode; char *authorName; char *authorHost; char *authorDomain; char *lockerName; char *lockerHost; char *lockerDomain; time_t lockTime; time_t modTime; time_t accessTime; time_t statChangeTime; time_t saveTime; int representation; off_t fileSize; off_t deltaSize; int succGen; int succRev; int predGen; int predRev; } Revision; typedef struct { int generation; int revision; int size; char *uda[MAXUDAS]; } Udas; typedef struct { int generation; int revision; off_t size; char *contents; } Note; typedef struct { int generation; int revision; int representation; off_t size; char *contents; } Data; shapetools-1.4pl6.orig/src/atfs/config.h100444 2013 145 23265 5626406111 16333 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFS -- Attribute Filesystem * * config.h -- system dependent definitions * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: config.h[7.1] Tue Aug 23 16:58:49 1994 andy@cs.tu-berlin.de frozen $ */ /* do only once */ #ifndef _defs_ #define _defs_ /* if no explicit system type is defined */ #if (!defined(s_aix) && !defined(s_hpux) && !defined(s_irix) && !defined(s_mach) && !defined(s_sunos_4) && !defined(s_svr_4) && !defined(s_ultrix) && !defined(s_linux)) # define _system_ #endif #ifdef __STDC__ # define A(alist) alist #else # define A(alist) () #endif /*===================== * includes *=====================*/ /* POSIX include files */ #include #include #include #include #if !defined(s_irix) #ifdef NULL # undef NULL #endif #endif #include #include #include #include #include #include #if defined(s_mach) # include # include # include # include #else # include # include # include # include # include #endif /* system dependent includes */ #if !defined(_POSIX_SOURCE) # include # include #endif /* debugging */ #ifdef DEBUG_MALLOC #include "malloc.h" #endif /*================================== * constants and macros and types *==================================*/ /*** general ***/ #define Sfunc_t int /* type of function argument to signal call */ #define Sigret_t void /* return type of signal system call */ #if defined(s_aix) # if defined(_POSIX_SOURCE) # include # include # define NAME_MAX _D_NAME_MAX # else # define NAME_MAX MAXNAMLEN # define MAXHOSTNAMELEN 32 # endif # define MAXDOMAIN 255 # define NEED_MNTENT # define vfork fork #elif defined(s_hpux) # define MAXDOMAIN 255 # define PATH_MAX MAXPATHLEN # define NAME_MAX MAXNAMLEN # define OPEN_MAX NOFILE # define NEED_REGEX # define HAS_MNTENT #elif defined(s_irix) # define MAXDOMAIN 255 # define vfork fork # define HAS_MNTENT #elif defined(s_mach) # define MAXDOMAIN 255 # define PATH_MAX MAXPATHLEN # define NAME_MAX MAXNAMLEN # define OPEN_MAX NOFILE # define NGROUPS_MAX NGROUPS typedef unsigned short mode_t; typedef int pid_t; # define dirent direct # define NO_SIGSET # define NEED_GETCWD # define NEED_STRDUP # define NEED_UTIMBUF # define HAS_MNTENT #elif defined(s_osf1) # include # include # define MAXDOMAIN 255 # define OPEN_MAX NOFILE # define NEED_MNTENT #elif defined(s_sunos_4) # if defined(_POSIX_SOURCE) # define MAXDOMAIN 255 # define MAXHOSTNAMELEN 64 # define PATH_MAX 1024 # define NAME_MAX 255 # define OPEN_MAX 64 # else # define PATH_MAX MAXPATHLEN # define NAME_MAX MAXNAMLEN # define OPEN_MAX NOFILE # endif # define HAS_MNTENT #elif defined(s_svr_4) /* Solaris_2 */ # define MAXDOMAIN 255 # define MAXHOSTNAMELEN 64 # if defined(_POSIX_SOURCE) # define NAME_MAX 512 # define OPEN_MAX 64 # else # ifndef PATH_MAX # define PATH_MAX MAXPATHLEN # endif # ifndef NAME_MAX # define NAME_MAX MAXNAMLEN # endif # ifndef OPEN_MAX # define OPEN_MAX NOFILE # endif # endif # define NEED_REGEX # define HAS_MNTTAB #elif defined(s_linux) # include # include # define MAXDOMAIN 255 # define HAS_MNTENT #elif defined(s_ultrix) # define MAXDOMAIN 255 # define NEED_MNTENT # define NEED_STRDUP #endif /*** mount table stuff ***/ #if defined(HAS_MNTENT) # include # define atMntent mntent # define at_mnt_dir mnt_dir # define at_mnt_fsname mnt_fsname # define atSetmntent setmntent # define atGetmntent getmntent # define atEndmntent endmntent #elif defined(HAS_MNTTAB) # include # define atMntent mnttab # define at_mnt_dir mnt_mountp # define at_mnt_fsname mnt_special # define atSetmntent fopen # define atEndmntent fclose struct atMntent* atGetmntent A((FILE *file)); #else /* NEED_MNTENT */ struct atMntent { char *at_mnt_fsname; char *at_mnt_dir; char *at_mnt_type; char *at_mnt_opts; int at_mnt_freq; int at_mnt_passno; }; int atEndmntent A((FILE *file)); struct atMntent* atGetmntent A((FILE *file)); FILE* atSetmntent A((const char *path, const char *type)); #endif /*** specials ***/ #if defined(s_mach) #define S_IRWXU 0000700 /* rwx------ */ #define S_IRUSR 0000400 /* r-------- */ #define S_IWUSR 0000200 /* -w------- */ #define S_IXUSR 0000100 /* --x------ */ #define S_IRWXG 0000070 /* ---rwx--- */ #define S_IRGRP 0000040 /* ---r----- */ #define S_IWGRP 0000020 /* ----w---- */ #define S_IXGRP 0000010 /* -----x--- */ #define S_IRWXO 0000007 /* ------rwx */ #define S_IROTH 0000004 /* ------r-- */ #define S_IWOTH 0000002 /* -------w- */ #define S_IXOTH 0000001 /* --------x */ #define S_ISBLK(mode) ((mode & S_IFMT) == S_IFBLK) #define S_ISCHR(mode) ((mode & S_IFMT) == S_IFCHR) #define S_ISDIR(mode) ((mode & S_IFMT) == S_IFDIR) #define S_ISFIFO(mode) ((mode & S_IFMT) == S_IFIFO) #define S_ISREG(mode) ((mode & S_IFMT) == S_IFREG) #define WEXITSTATUS(a) ((a).w_T.w_Retcode) #endif /*** own definitions ***/ #define TYPE_MAX NAME_MAX #define HOST_MAX MAXHOSTNAMELEN #define DOMAIN_MAX MAXDOMAIN /*** obsolete definitions ***/ #define MAXUSERNAMELEN 64 /*===================== * types *=====================*/ #if defined(s_mach) #define Wait_t union wait #else #define Wait_t int /* type of argument for wait call */ #endif #if defined(NEED_UTIMBUF) struct utimbuf { time_t actime; /* set the access time */ time_t modtime; /* set the modification time */ }; #endif /*===================== * prototypes *=====================*/ /*** missing POSIX prototypes ***/ #if defined(s_aix) #elif defined(s_mach) void _exit A((int status)); int access A((const char *path, int amode)); int chdir A((const char *path)); int chmod A((const char *path, mode_t mode)); int chown A((const char *path, uid_t owner, gid_t group)); int close A((int filedes)); int creat A((const char *path, mode_t mode)); int dup A((int filedes)); int execve A((const char *path, const char *argv[], const char *envp[])); int execvp A((const char *file, const char *argv[])); int fcntl A((int filedes, int cmd, ...)); FILE *fdopen A((int filedes, const char *type)); int fileno A((FILE *stream)); pid_t fork A((void)); char *getcwd A((char *buf, size_t size)); gid_t getegid A((void)); uid_t geteuid A((void)); int getgroups A((int gidsetsize, gid_t grouplist[])); pid_t getpid A((void)); pid_t getppid A((void)); int isatty A((int filedes)); int kill A((pid_t oid, int signal)); int link A((const char *existing, const char *new)); int mkdir A((const char *path, mode_t mode)); int open A((const char *path, int oflag, ...)); int pipe A((int filedes[2])); int read A((int filedes, void *buf, unsigned int nbyte)); unsigned int sleep A((unsigned int seconds)); int tolower A((int c)); mode_t umask A((mode_t cmask)); int unlink A((const char *path)); int utime A((const char *path, const struct utimbuf *times)); int write A((int filedes, const void*buf, unsigned int nbyte)); #elif defined(s_sunos_4) int fflush A((FILE *stream)); int fclose A((FILE *stream)); int fprintf A((FILE *stream, const char *format, ...)); int printf A((const char *format, ...)); int fscanf A((FILE *stream, const char *format, ...)); int fputs A((const char *s, FILE *stream)); int fgetc A((FILE *stream)); int fputc A((int c, FILE *stream)); size_t fread A((void *ptr, size_t size, size_t nobj, FILE *stream)); size_t fwrite A((const void *ptr, size_t size, size_t nobj, FILE *stream)); void perror A((const char *s)); #ifndef DEBUG_MALLOC void *memmove A((void *dest, const void *source, size_t len)); void *memchr A((const void *string, int chr, size_t len)); void *memset A((void *string, int c, size_t len)); #endif time_t time A((time_t *timeptr)); time_t mktime A((struct tm *timeptr)); int system A((const char *string)); int tolower A((int c)); #elif defined(s_svr_4) int tolower A((int c)); #endif /*** non POSIX prototypes ***/ int openlog A((char *ident, int logopt, int facility)); int syslog A((int priority, char *message, ...)); int closelog A((void)); FILE* popen A((const char *command, const char *mode)); int pclose A((FILE *stream)); #if (!defined(s_linux)) int getdomainname A((char *name, int namelen)); #endif #if !defined(s_irix) char* re_comp A((char *string)); int re_exec A((char *string)); #endif char* strdup A((const char *string)); int symlink A((const char *name1, const char *name2)); #if (!defined(s_hpux) && !defined(s_svr_4) && !defined(s_irix)) int ioctl A((int fd, int request, caddr_t arg)); int vfork A((void)); #if (!defined(s_linux)) int getopt A((int argc, char **argv, char *optstring)); #endif #endif #if (!defined(s_hpux) && !defined(s_linux)) int gethostname A((char *name, int namelen)); #endif /*** own prototypes ***/ void disableSig A((int signo)); void enableSig A((void)); #endif /* _defs_ */ shapetools-1.4pl6.orig/src/atfs/af_version.c100444 2013 145 204 5626407373 17153 0ustar dokoswtchar *af_version () { static char release[] = "AtFS-1.71 (Tue Aug 23 17:54:14 1994 by andy@cs.tu-berlin.de)"; return release; } shapetools-1.4pl6.orig/src/atfs/Shapefile100444 2013 145 7161 5412536617 16525 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for AtFS # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[7.0] Fri Jun 25 14:33:26 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=pcc QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds # Local test environment. This definition is to be removed when # the Shapefile shall be used outside the AtFS development area. # _all: all $(LIBTARGET) $(BINTARGET): \ $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) $(CC) -c $(CFLAGS) $(VERSIONFILE) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) localinstall: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets localinstall: MAINTARGET=localinstall ALLTARGETS=subsystems localinstalltargets BINDDEFAULT=$(BINDINSTALL) install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean trace_keys: VARCFLAGS=-DAFTRACE #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/atfs/Makefile100444 2013 145 44626 5517562101 16362 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for AtFS # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[7.0] Thu Jan 20 21:10:59 1994 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/atfs # A short name for this node system NODENAME = AtFS # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = -DSYSLOG -DATFS_OWN_LOCKING # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = /home/stone/shape INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. LIBTARGET = libAtFS.a BINTARGET = atfsrepair CACHETARGET = cacheadm SHTARGET = mkatfs # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = af_version.c # source VERSIONOBJECT = af_version.o # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). LIBALIASES = BINALIASES = SHALIASES = # The regular source and header files. SHSOURCES = mkatfs.sh SOURCES = afarchive.c afarlock.c afattrs.c afcache.c afcompar.c afdelta.c \ afdeltaproc.c afenviron.c aferror.c affiles.c afkeys.c \ aflib.c aflock.c afmemory.c afnames.c afobjcache.c afretr.c \ afsattrs.c afsets.c afstates.c afstore.c afsymtab.c aftime.c \ aftmpfiles.c aftransact.c afudattrs.c afvers.c \ atfsrepair.c cacheadm.c config.c $(SHSOURCES) HEADERS = atfs.h afsys.h afarchive.h atfsrepair.h config.h # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = man/man1/atfsrepair.1 man/man1/cacheadm.1 man/man1/mkatfs.1 MAN3 = man/man3/af_intro.3 \ man/man3/af_attrs.3 man/man3/af_cache.3 man/man3/af_error.3 \ man/man3/af_files.3 man/man3/af_history.3 man/man3/af_lock.3 \ man/man3/af_misc.3 man/man3/af_note.3 man/man3/af_protect.3 \ man/man3/af_retrieve.3 man/man3/af_sets.3 \ man/man3/af_transact.3 man/man3/af_version.3 MAN4 = MAN5 = man/man5/af_archive.5 MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. LIBOBJECTS = afarchive.o afarlock.o afattrs.o afcache.o afcompar.o afdelta.o \ afdeltaproc.o afenviron.o aferror.o affiles.o afkeys.o \ aflib.o aflock.o afmemory.o afnames.o afobjcache.o afretr.o \ afsattrs.o afsets.o afstates.o afstore.o afsymtab.o aftime.o \ aftmpfiles.o aftransact.o afudattrs.o afvers.o \ $(VERSIONOBJECT) config.o OBJECTS = $(LIBOBJECTS) cacheadm.o atfsrepair.o # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) -D$(HOSTSYSTEM) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) targets: $(LIBTARGET) $(BINTARGET) $(CACHETARGET) $(SHTARGET) $(LIBTARGET): $(LIBOBJECTS) -ar ruv $(LIBTARGET) $(LIBOBJECTS) @-($(RANLIB) $(LIBTARGET)) 2> /dev/null; true @_aliases="$(LIBALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(LIBTARGET) to $$i; \ ln $(LIBTARGET) $$i; \ done $(BINTARGET): atfsrepair.o $(LIBTARGET) $(LOCALLIBS) $(CC) $(LDFLAGS) -o $(BINTARGET) atfsrepair.o $(LIBTARGET) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(BINALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(BINTARGET) to $$i; \ ln $(BINTARGET) $$i; \ done $(CACHETARGET): cacheadm.o $(LIBTARGET) $(CC) $(LDFLAGS) -o $(CACHETARGET) cacheadm.o $(LIBTARGET) $(SYSLIBS) @_aliases="$(CACHEALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(CACHETARGET) to $$i; \ ln $(CACHETARGET) $$i; \ done $(SHTARGET): $(SHSOURCES) @rm -f $(SHTARGET); \ if [ $(HOSTSYSTEM) = s_ultrix ]; \ then \ echo '#!/bin/sh5' > $(SHTARGET); \ else \ echo '#!/bin/sh' > $(SHTARGET); \ fi cat $(SHSOURCES) >> $(SHTARGET); @chmod +x $(SHTARGET) localinstalltargets: $(LOCALLIBPATH)/$(LIBTARGET) \ $(LOCALINCLUDEPATH)/atfs.h \ $(LOCALINCLUDEPATH)/afsys.h \ $(LOCALINCLUDEPATH)/config.h \ $(BINTARGET) $(CACHETARGET) $(SHTARGET) $(LOCALLIBPATH)/$(LIBTARGET): $(LIBTARGET) @-echo "Copying $(LIBTARGET) to $(LOCALLIBPATH)"; \ if [ -f $(LOCALLIBPATH)/$(LIBTARGET) ] ;\ then \ mv -f $(LOCALLIBPATH)/$(LIBTARGET) \ $(LOCALLIBPATH)/$(LIBTARGET).old;\ fi; \ cp $(LIBTARGET) $(LOCALLIBPATH)/$(LIBTARGET); \ chmod $(INSTALLLIBMODE) $(LOCALLIBPATH)/$(LIBTARGET); \ ($(RANLIB) $(LOCALLIBPATH)/$(LIBTARGET)) 2> /dev/null; \ _aliases="$(LIBALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(LOCALLIBPATH)/$$i; \ echo "linking $(LOCALLIBPATH)/$(LIBTARGET) to $(LOCALLIBPATH)/$$i"; \ ln $(LOCALLIBPATH)/$(LIBTARGET) $(LOCALLIBPATH)/$$i; \ done $(LOCALINCLUDEPATH)/atfs.h: atfs.h @-echo "Copying atfs.h to $(LOCALINCLUDEPATH)"; \ if [ -f $(LOCALINCLUDEPATH)/atfs.h ] && \ [ ! -w $(LOCALINCLUDEPATH)/atfs.h ]; \ then \ chmod u+w $(LOCALINCLUDEPATH)/atfs.h; \ fi; \ cp atfs.h $(LOCALINCLUDEPATH)/atfs.h; \ chmod $(INSTALLINCMODE) $(LOCALINCLUDEPATH)/atfs.h $(LOCALINCLUDEPATH)/afsys.h: afsys.h @-echo "Copying afsys.h to $(LOCALINCLUDEPATH)"; \ if [ -f $(LOCALINCLUDEPATH)/afsys.h ] && \ [ ! -w $(LOCALINCLUDEPATH)/afsys.h ]; \ then \ chmod u+w $(LOCALINCLUDEPATH)/afsys.h; \ fi; \ cp afsys.h $(LOCALINCLUDEPATH)/afsys.h; \ chmod $(INSTALLINCMODE) $(LOCALINCLUDEPATH)/afsys.h $(LOCALINCLUDEPATH)/config.h: config.h @-echo "Copying config.h to $(LOCALINCLUDEPATH)"; \ mv config.h config.h.orig; \ sed -e s/_system_/$(HOSTSYSTEM)/ config.h.orig > config.h; \ if [ -f $(LOCALINCLUDEPATH)/config.h ] && \ [ ! -w $(LOCALINCLUDEPATH)/config.h ]; \ then \ chmod u+w $(LOCALINCLUDEPATH)/config.h; \ fi; \ cp config.h $(LOCALINCLUDEPATH)/config.h; \ chmod $(INSTALLINCMODE) $(LOCALINCLUDEPATH)/config.h; \ rm -f config.h; \ mv config.h.orig config.h installtargets: $(INSTALLLIBPATH)/$(LIBTARGET) $(INSTALLINCPATH)/atfs.h \ $(INSTALLINCPATH)/afsys.h $(INSTALLINCPATH)/config.h \ $(INSTALLBINPATH)/$(BINTARGET) $(INSTALLBINPATH)/$(CACHETARGET) \ $(INSTALLBINPATH)/$(SHTARGET) $(INSTALLLIBPATH)/$(LIBTARGET): $(LIBTARGET) @-echo "Installing $(LIBTARGET) in $(INSTALLLIBPATH)"; \ if [ -f $(INSTALLLIBPATH)/$(LIBTARGET) ] ;\ then \ mv -f $(INSTALLLIBPATH)/$(LIBTARGET) \ $(INSTALLLIBPATH)/$(LIBTARGET).old;\ fi; \ cp $(LIBTARGET) $(INSTALLLIBPATH)/$(LIBTARGET); \ chmod $(INSTALLLIBMODE) $(INSTALLLIBPATH)/$(LIBTARGET); \ ($(RANLIB) $(INSTALLLIBPATH)/$(LIBTARGET)) 2> /dev/null; \ _aliases="$(LIBALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLLIBPATH)/$$i; \ echo "linking $(INSTALLLIBPATH)/$(LIBTARGET) to $(INSTALLLIBPATH)/$$i"; \ ln $(INSTALLLIBPATH)/$(LIBTARGET) $(INSTALLLIBPATH)/$$i; \ done $(INSTALLINCPATH)/atfs.h: atfs.h @-echo "Installing atfs.h in $(INSTALLINCPATH)"; \ if [ -f $(INSTALLINCPATH)/atfs.h ] && \ [ ! -w $(INSTALLINCPATH)/atfs.h ]; \ then \ chmod u+w $(INSTALLINCPATH)/atfs.h; \ fi; \ cp atfs.h $(INSTALLINCPATH)/atfs.h; \ chmod $(INSTALLINCMODE) $(INSTALLINCPATH)/atfs.h $(INSTALLINCPATH)/afsys.h: afsys.h @-echo "Installing afsys.h in $(INSTALLINCPATH)"; \ if [ -f $(INSTALLINCPATH)/afsys.h ] && \ [ ! -w $(INSTALLINCPATH)/afsys.h ]; \ then \ chmod u+w $(INSTALLINCPATH)/afsys.h; \ fi; \ cp afsys.h $(INSTALLINCPATH)/afsys.h; \ chmod $(INSTALLINCMODE) $(INSTALLINCPATH)/afsys.h $(INSTALLINCPATH)/config.h: config.h @-echo "Installing config.h in $(INSTALLINCPATH)"; \ mv config.h config.h.orig; \ sed -e s/_system_/$(HOSTSYSTEM)/ config.h.orig > config.h; \ if [ -f $(INSTALLINCPATH)/config.h ] && \ [ ! -w $(INSTALLINCPATH)/config.h ]; \ then \ chmod u+w $(INSTALLINCPATH)/config.h; \ fi; \ cp config.h $(INSTALLINCPATH)/config.h; \ chmod $(INSTALLINCMODE) $(INSTALLINCPATH)/config.h; \ rm -f config.h; \ mv config.h.orig config.h $(INSTALLBINPATH)/$(BINTARGET): $(BINTARGET) @-echo "Installing $(BINTARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(BINTARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(BINTARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(BINTARGET); \ fi; \ cp $(BINTARGET) $(INSTALLBINPATH)/$(BINTARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(BINTARGET); \ _aliases="$(BINALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(BINTARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(BINTARGET) $(INSTALLBINPATH)/$$i; \ done $(INSTALLBINPATH)/$(CACHETARGET): $(CACHETARGET) @-echo "Installing $(CACHETARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(CACHETARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(CACHETARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(CACHETARGET); \ fi; \ cp $(CACHETARGET) $(INSTALLBINPATH)/$(CACHETARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(CACHETARGET); \ _aliases="$(CACHEALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(CACHETARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(CACHETARGET) $(INSTALLBINPATH)/$$i; \ done $(INSTALLBINPATH)/$(SHTARGET): $(SHTARGET) @-echo "Installing $(SHTARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(SHTARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(SHTARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(SHTARGET); \ fi; \ cp $(SHTARGET) $(INSTALLBINPATH)/$(SHTARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(SHTARGET); \ _aliases="$(SHALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(SHTARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(SHTARGET) $(INSTALLBINPATH)/$$i; \ done installmanuals: @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ _current=`basename $$i`; \ echo "Installing $$_current in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$_current ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$_current ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$_current; \ fi; \ cp $(BASE)/$$i $(INSTALLMANPATH)/man1/$$_current; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$_current; \ done; \ _manuals="$(MAN3)"; \ for i in $$_manuals; \ do \ _current=`basename $$i`; \ echo "Installing $$_current in $(INSTALLMANPATH)/man3"; \ if [ -f $(INSTALLMANPATH)/man3/$$_current ] && \ [ ! -w $(INSTALLMANPATH)/man3/$$_current ]; \ then \ chmod u+w $(INSTALLMANPATH)/man3/$$_current; \ fi; \ cp $(BASE)/$$i $(INSTALLMANPATH)/man3/$$_current; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man3/$$_current; \ done; \ _manuals="$(MAN5)"; \ for i in $$_manuals; \ do \ _current=`basename $$i`; \ echo "Installing $$_current in $(INSTALLMANPATH)/man5"; \ if [ -f $(INSTALLMANPATH)/man5/$$_current ] && \ [ ! -w $(INSTALLMANPATH)/man5/$$_current ]; \ then \ chmod u+w $(INSTALLMANPATH)/man5/$$_current; \ fi; \ cp $(BASE)/$$i $(INSTALLMANPATH)/man5/$$_current; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man5/$$_current; \ done # Do not install libraries noinstall: $(INSTALLBINPATH)/$(BINTARGET) $(INSTALLBINPATH)/$(CACHETARGET) \ $(INSTALLBINPATH)/$(SHTARGET) # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(LIBTARGET) $(BINTARGET) $(CACHETARGET) $(SHTARGET) \ $(LIBALIASES) $(BINALIASES) $(SHALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) localinstall: +localinstall $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +localinstall: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems localinstalltargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(BASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" localinstall; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/atfs/Dependencies100444 2013 145 5256 5412544430 17206 0ustar dokoswtaf_version.o: af_version.c afarchive.o: ./afarchive.h afarchive.o: ./afsys.h afarchive.o: ./atfs.h afarchive.o: ./config.h afarchive.o: afarchive.c afarlock.o: ./afsys.h afarlock.o: ./atfs.h afarlock.o: ./config.h afarlock.o: afarlock.c afattrs.o: ./afsys.h afattrs.o: ./atfs.h afattrs.o: ./config.h afattrs.o: afattrs.c afcache.o: ./afarchive.h afcache.o: ./afsys.h afcache.o: ./atfs.h afcache.o: ./config.h afcache.o: afcache.c afcompar.o: ./afsys.h afcompar.o: ./atfs.h afcompar.o: ./config.h afcompar.o: afcompar.c afdelta.o: ./afsys.h afdelta.o: ./atfs.h afdelta.o: ./config.h afdelta.o: afdelta.c afdeltaproc.o: ./afsys.h afdeltaproc.o: ./atfs.h afdeltaproc.o: ./config.h afdeltaproc.o: afdeltaproc.c afenviron.o: ./afarchive.h afenviron.o: ./afsys.h afenviron.o: ./atfs.h afenviron.o: ./config.h afenviron.o: afenviron.c aferror.o: ./afsys.h aferror.o: ./atfs.h aferror.o: ./config.h aferror.o: aferror.c affiles.o: ./afsys.h affiles.o: ./atfs.h affiles.o: ./config.h affiles.o: affiles.c afkeys.o: ./afsys.h afkeys.o: ./atfs.h afkeys.o: ./config.h afkeys.o: afkeys.c aflib.o: ./afsys.h aflib.o: ./atfs.h aflib.o: ./config.h aflib.o: aflib.c aflock.o: ./afsys.h aflock.o: ./atfs.h aflock.o: ./config.h aflock.o: aflock.c afmemory.o: ./afarchive.h afmemory.o: ./afsys.h afmemory.o: ./atfs.h afmemory.o: ./config.h afmemory.o: afmemory.c afnames.o: ./afarchive.h afnames.o: ./afsys.h afnames.o: ./atfs.h afnames.o: ./config.h afnames.o: afnames.c afobjcache.o: ./afarchive.h afobjcache.o: ./afsys.h afobjcache.o: ./atfs.h afobjcache.o: ./config.h afobjcache.o: afobjcache.c afretr.o: ./afsys.h afretr.o: ./atfs.h afretr.o: ./config.h afretr.o: afretr.c afsattrs.o: ./afsys.h afsattrs.o: ./atfs.h afsattrs.o: ./config.h afsattrs.o: afsattrs.c afsets.o: ./afsys.h afsets.o: ./atfs.h afsets.o: ./config.h afsets.o: afsets.c afstates.o: ./afsys.h afstates.o: ./atfs.h afstates.o: ./config.h afstates.o: afstates.c afstore.o: ./afsys.h afstore.o: ./atfs.h afstore.o: ./config.h afstore.o: afstore.c afsymtab.o: ./afsys.h afsymtab.o: ./atfs.h afsymtab.o: ./config.h afsymtab.o: afsymtab.c aftime.o: ./afsys.h aftime.o: ./atfs.h aftime.o: ./config.h aftime.o: aftime.c aftmpfiles.o: ./afsys.h aftmpfiles.o: ./atfs.h aftmpfiles.o: ./config.h aftmpfiles.o: aftmpfiles.c aftransact.o: ./afsys.h aftransact.o: ./atfs.h aftransact.o: ./config.h aftransact.o: aftransact.c afudattrs.o: ./afsys.h afudattrs.o: ./atfs.h afudattrs.o: ./config.h afudattrs.o: afudattrs.c afvers.o: ./afsys.h afvers.o: ./atfs.h afvers.o: ./config.h afvers.o: afvers.c atfsrepair.o: ./afarchive.h atfsrepair.o: ./afsys.h atfsrepair.o: ./atfs.h atfsrepair.o: ./atfsrepair.h atfsrepair.o: ./config.h atfsrepair.o: atfsrepair.c config.o: ./config.h config.o: config.c shapetools-1.4pl6.orig/src/sttk/ 40755 2013 145 0 5626415766 14642 5ustar dokoswtshapetools-1.4pl6.orig/src/sttk/strtab.c100444 2013 145 6502 5412343613 16363 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * strtab.c - string table * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: strtab.c[4.0] Thu Jun 24 17:43:13 1993 andy@cs.tu-berlin.de frozen $ */ #include "config.h" #include "sttk.h" /*===================================== * definition of hashtable for symbols *=====================================*/ typedef struct StrTabX StrTabEntry; struct StrTabX { char *symbol; StrTabEntry *next; }; LOCAL StrTabEntry *strTabHash; LOCAL int strTabSize; /*=========================== * determine hash value *===========================*/ LOCAL int hashVal (symbol, size) /* from Aho/Ullman */ char *symbol; int size; { register char *p; register unsigned long hval, g; hval = 0; for (p = symbol; *p != '\0'; p++) { hval = (hval << 4) ^ (*p); if ((g = hval & 0xf0000000)) { hval = hval ^ (g >> 24); hval = hval ^ g; } } return (hval % size); } /*============================= * add string to string table *=============================*/ EXPORT char *stStrEnter (symbol) char *symbol; { static bool hinit = FALSE; /* indicate if hashtable is yet initialized */ int symLen, where; StrTabEntry *new, *entry = (StrTabEntry *)0; if ((symbol == (char *)0) || (symbol[0] == '\0')) return ((char *)0); if (!hinit) { strTabSize = ST_HASHSIZE * sizeof (StrTabEntry); if ((strTabHash = (StrTabEntry *)malloc ((unsigned) strTabSize)) == (StrTabEntry *)0) return (NULL); /* initialize hashlist */ memset ((char *)strTabHash, 0, strTabSize); hinit = TRUE; } /* lookup symbol */ where = hashVal (symbol, ST_HASHSIZE); if (strTabHash[where].symbol) { /* found something */ if (!strcmp (strTabHash[where].symbol, symbol)) return (strTabHash[where].symbol); else { entry = &strTabHash[where]; while (entry->next) { entry = entry->next; if (!strcmp (entry->symbol, symbol)) return (entry->symbol); } } } /* symbol is new */ symLen = strlen (symbol) + sizeof (char); if (!strTabHash[where].symbol) { /* entry is not used yet */ if ((strTabHash[where].symbol = malloc ((unsigned) (symLen)))==(char *)0) return (NULL); strTabSize += symLen; strcpy (strTabHash[where].symbol, symbol); return (strTabHash[where].symbol); } else { /* hash collision */ if ((new = (StrTabEntry *)malloc ((unsigned) sizeof (StrTabEntry))) == (StrTabEntry *)0) return (NULL); strTabSize += sizeof (StrTabEntry); if ((new->symbol = malloc ((unsigned) (symLen))) == (char *)0) return (NULL); strTabSize += symLen; strcpy (new->symbol, symbol); new->next = NULL; entry->next = new; return (new->symbol); } } shapetools-1.4pl6.orig/src/sttk/files.c100444 2013 145 6422 5412344041 16163 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * files.c -- various file handling procedures * * Authors: Uli Pralle (Uli.Pralle@cs.tu-berlin.de) * Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: files.c[4.0] Thu Jun 24 17:43:14 1993 andy@cs.tu-berlin.de frozen $ */ #include "config.h" #include "sttk.h" /*=========================== * register temporary files *===========================*/ static char *tmpNames[ST_MAX_TMPFILES]; EXPORT void stRmRegisteredFiles () { register int i; for (i=0; i < ST_MAX_TMPFILES; i++) if (tmpNames[i]) unlink (tmpNames[i]); } EXPORT void stRegisterFile (fileName) char *fileName; { register int i; if (!fileName) return; for (i=0; i < ST_MAX_TMPFILES; i++) if (!tmpNames[i]) { tmpNames[i] = stStrEnter (fileName); break; } if (i == ST_MAX_TMPFILES) /* list is full */ /* WARNING: tmpfile list is full -- couldn't register */ ; } static int tmpCount=0; EXPORT char *stTmpFile (path) char *path; { static char tmpName[PATH_MAX+1]; if (!path || !*path) path = "/tmp"; sprintf (tmpName, "%s/sttk%d%d", path, getpid(), tmpCount++); unlink (tmpName); stRegisterFile (tmpName); return (tmpName); } EXPORT void stUnRegisterFile (fileName) /* remove tmp file entry */ char *fileName; { register int i; char *nameSym = stStrEnter (fileName); for (i=0; i < ST_MAX_TMPFILES; i++) if (tmpNames[i] == nameSym) { tmpNames[i] = (char *)0; break; } if (i == ST_MAX_TMPFILES) /* fileName not found */ ; /* WARNING: name of tmpfile has not been registered before */ } /*=============== * find Program *===============*/ EXPORT char *stFindProgram (programName) char *programName; /* returns the full pathname of "programName", if program * is found and executable. Otherwise NULL. */ { static char this[PATH_MAX+1]; char *path; char *dir, *dirPtr; /* if program has already a '/' in it, assume existence */ if (strchr (programName, '/')) { if (access (programName, X_OK) == 0) return (programName); else return (NULL); } /* get path from enivronment */ if (!(path = getenv ("PATH"))) path = ST_DEFAULT_PATH; while (1) { if ((dir = path) == NULL) return (NULL); /* find end of dir in string */ if ((dirPtr = strchr (path, ':'))) { *dirPtr = '\0'; /* make "dir" null terminated */ path = dirPtr + 1; /* path points to next dir */ } else path = (NULL); /* end of path reached */ /* file found ? */ sprintf (this, "%s/%s", dir, programName); /* construct new filename */ if ((access (this, F_OK)) == 0) return (this); /* found */ } } shapetools-1.4pl6.orig/src/sttk/kbdio.c100444 2013 145 13305 5412344203 16167 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * kbdio.c -- ShapeTools toolkit library * * Authors: Uli Pralle (Uli.Pralle@cs.tu-berlin.de) * Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: kbdio.c[4.0] Thu Jun 24 17:43:16 1993 andy@cs.tu-berlin.de frozen $ */ #include "config.h" #include "sttk.h" #define INITIAL_BUFFER_SIZE 2048 /* for stGetFromStdin() */ EXPORT int stQuietFlag = FALSE; EXPORT int stShutupFlag = FALSE; EXPORT char* stProgramName = NULL; EXPORT char stMessage[ST_MSGLEN]; EXPORT void stLog (msg, logType) char *msg; int logType; { FILE *channel; if (stShutupFlag || (stQuietFlag && !(logType & ST_LOG_ERROR))) return; switch (logType & 077) { case ST_LOG_MSG: channel = stdout; break; case ST_LOG_MSGERR: channel = stderr; break; case ST_LOG_WARNING: channel = stderr; fprintf (channel, "%s - warning: ", stProgramName); break; case ST_LOG_ERROR: channel = stderr; fprintf (channel, "%s - error: ", stProgramName); break; } if (logType & ST_LOG_NONL) fprintf (channel, "%s", msg ? msg : ""); else fprintf (channel, "%s\n", msg ? msg : ""); fflush (channel); } EXPORT char *stGetFromStdin (termChar) int termChar; { /* * Reads from stdin a text terminated by ^D or by a specified * single charcter "termChar" at the beginning of a new line. * If term_char is -1 text is terminated by ^D. */ char *text ; /* pointer to text buffer */ char *tmp ; /* temporary pointer to text buffer */ int tindex ; /* index into text[] (last char read) */ int c ; /* char to be read */ int current_buffer_size = INITIAL_BUFFER_SIZE ; /* size of text[] buffer */ char *prompt = NULL ; /* prompt for reading from terminal, * also serves a flag whether we read * from a terminal */ if (isatty(fileno(stdin))) { char eofMsg[30] ; prompt = "> " ; if (termChar == -1) { eofMsg[0] = '\0' ; } else { sprintf (eofMsg, " or single '%c' on a line", termChar) ; } sprintf (stMessage, "Enter text, terminated with your EOF character%s:", eofMsg); stLog (stMessage, ST_LOG_MSG); stLog (prompt, ST_LOG_MSG | ST_LOG_NONL); } /* allocate initial text buffer */ text = malloc(INITIAL_BUFFER_SIZE) ; if (text == NULL) { return ("") ; } tindex = 0 ; /* read loop */ while ((c = fgetc (stdin)) != EOF) { /* check for single termChar on line */ if (c == '\n' && tindex > 0 && text[tindex - 1] == termChar && (tindex == 1 || text[tindex - 2] == '\n')) { /* termChar is only char on line, so stop reading */ tindex-- ; /* remove termChar from text */ break ; } /* add char to text */ text[tindex++] = c ; /* enlarge buffer if necessary */ if (tindex == current_buffer_size) { current_buffer_size *= 2 ; tmp = realloc(text, current_buffer_size) ; if (tmp == NULL) { /* if realloc() failed, return *something* at least */ text[tindex - 1] = '\0' ; return text ; } text = tmp ; } /* print prompt if necessary */ if (c == '\n' && prompt != NULL) { stLog (prompt, ST_LOG_MSG | ST_LOG_NONL) ; } } clearerr(stdin) ; /* make further reads from stdin possible */ if (c == EOF & prompt != NULL) { fputc ('\n', stdout) ; } /* free unneeded part of allocated memory */ text[tindex] = '\0' ; tmp = realloc(text, strlen(text) + 1) ; if (tmp != NULL) { text = tmp ; } /* and go! */ return text ; } /*=================== * stAskConfirm *===================*/ #define minimum(x,y) (((x) <= (y)) ? (x) : (y)) #ifdef SIGCONT LOCAL jmp_buf stHere; LOCAL Sigret_t conthand () { sprintf (stMessage, "%s:", stThisTransaction.tr_fname); stLog (stMessage, ST_LOG_MSG); longjmp (stHere, 1); } #endif EXPORT int stAskConfirm (message, defaultAnswer) char *message; char *defaultAnswer; { /* returns true if the answer is equivalent to 'defaultAnswer' (assumption) */ char strbuf[ST_MSGLEN], answer[ST_MSGLEN], *cp; if (message == (char *)NULL) return (TRUE); if (!isatty (fileno (stdin))) return (TRUE); if (stQuietFlag) return (TRUE); #ifdef SIGCONT setjmp (stHere); signal (SIGCONT, conthand); #endif fflush (stdin); sprintf (stMessage, "%s [%s] ", message, defaultAnswer); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); strbuf[0] = '\0'; answer[0] = '\0'; gets (strbuf); #ifdef SIGCONT signal (SIGCONT, SIG_DFL); #endif sscanf (strbuf, "%s", answer); if (answer[0] == '\0') return (TRUE); /* assumption acknowledged */ cp = answer; while (*cp ? (*cp++ |= ' ') : 0); /* make sure answer is lowercase */ return (!strncmp (defaultAnswer, answer, minimum(strlen(defaultAnswer), strlen(answer)))); } /*===================== * get terminal width *=====================*/ EXPORT int stGetTermWidth (fileDes) int fileDes; { #ifdef TIOCGWINSZ struct winsize termSize; if (ioctl (fileDes, TIOCGWINSZ, (caddr_t) &termSize) == 0) { /* some environments (e.g. emacs) return fishy values (0) -- correct this */ return (termSize.ws_col ? termSize.ws_col : 80); } #endif return 80; } shapetools-1.4pl6.orig/src/sttk/mktime.c100444 2013 145 20420 5523212704 16364 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * mktime.c - convert various time formats to "seconds since 1970" * * Authors: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: mktime.c[4.1] Mon Jan 31 15:29:40 1994 andy@cs.tu-berlin.de frozen $ */ #include #include "config.h" #include "sttk.h" /* all patterns are followed by an optional close bracket ([]]*) to make atScanBindinhg happy !! */ /* Mon Nov 2[,] 92 */ #define RE1 "^[MTWFS][oherau][nudeit][ ]*[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-9][,]*[ ]*[7-9][0-9][]]*$" /* Mon Nov 25[,] 92 */ #define RE2 "^[MTWFS][oherau][nudeit][ ]*[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-3][0-9][,]*[ ]*[7-9][0-9][]]*$" /* Mon Nov 2[,] 1992 */ #define RE3 "^[MTWFS][oherau][nudeit][ ]*[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-9][,]*[ ]*19[7-9][0-9][]]*$" /* Mon Nov 25[,] 1992 */ #define RE4 "^[MTWFS][oherau][nudeit][ ]*[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-3][0-9][,]*[ ]*19[7-9][0-9][]]*$" /* Nov 2[,] 92 */ #define RE5 "^[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-9][,]*[ ]*[7-9][0-9][]]*$" /* Nov 25[,] 92 */ #define RE6 "^[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-3][0-9][,]*[ ]*[7-9][0-9][]]*$" /* Nov 2[,] 1992 */ #define RE7 "^[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-9][,]*[ ]*19[7-9][0-9][]]*$" /* Nov 25[,] 1992 */ #define RE8 "^[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-3][0-9][,]*[ ]*19[7-9][0-9][]]*$" /* Nov 2 */ #define RE9 "^[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-9][]]*$" /* Nov 31 */ #define RE10 "^[JFMASOND][aepuco][nbrylgptvc]*[ ]*[1-3][0-9][]]*$" /* 1992/11/02 */ #define RE11 "^19[7-9][0-9]/[01][0-9]/[0-3][0-9][]]*$" /* 92/01/31 */ #define RE12 "^[7-9][0-9]/[01][0-9]/[0-3][0-9][]]*$" /* 1.5.92 */ #define RE13 "^[1-9][ ]*\\.[ ]*[1-9][ ]*\\.[ ]*[7-9][0-9][]]*$" /* 10.5.92 */ #define RE14 "^[1-3][0-9][ ]*\\.[ ]*[1-9][ ]*\\.[ ]*[7-9][0-9][]]*$" /* 1.10.92 */ #define RE15 "^[1-9][ ]*\\.[ ]*1[012][ ]*\\.[ ]*[7-9][0-9][]]*$" /* 12.10.92 */ #define RE16 "^[1-3][0-9][ ]*\\.[ ]*1[012][ ]*\\.[ ]*[7-9][0-9][]]*$" /* 1.5.1992 */ #define RE17 "^[1-9][ ]*\\.[ ]*[1-9][ ]*\\.[ ]*19[7-9][0-9][]]*$" /* 10.5.1992 */ #define RE18 "^[1-3][0-9][ ]*\\.[ ]*[1-9][ ]*\\.[ ]*19[7-9][0-9][]]*$" /* 1.10.1992 */ #define RE19 "^[1-9][ ]*\\.[ ]*1[012][ ]*\\.[ ]*19[7-9][0-9][]]*$" /* 12.10.1992 */ #define RE20 "^[1-3][0-9][ ]*\\.[ ]*1[012][ ]*\\.[ ]*19[7-9][0-9][]]*$" /* 1.5. */ #define RE21 "^[1-9][ ]*\\.[ ]*[1-9][ ]*\\.[]]*$" /* 10.5. */ #define RE22 "^[1-3][0-9][ ]*\\.[ ]*[1-9][ ]*\\.[]]*$" /* 1.10. */ #define RE23 "^[1-9][ ]*\\.[ ]*1[012][ ]*\\.[]]*$" /* 12.10. */ #define RE24 "^[1-3][0-9][ ]*\\.[ ]*1[012][ ]*\\.[]]*$" static struct df_map { char *pat, *fmt; } date_fmts[] = { { RE1, ""}, { RE2, ""}, { RE3, ""}, { RE4, ""}, { RE5, ""}, { RE6, ""}, { RE7, ""}, { RE8, ""}, { RE9, ""}, { RE10, ""}, { RE11, ""}, { RE12, ""}, { RE13, ""}, { RE14, ""}, { RE15, ""}, { RE16, ""}, { RE17, ""}, { RE18, ""}, { RE19, ""}, { RE20, ""}, { RE21, ""}, { RE22, ""}, { RE23, ""}, { RE24, ""}, { (char *)0, (char *)0} }; /*=================== * month handling *===================*/ static char *mon_tab[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", (char *)0 }; LOCAL int scanMonth(monthStr) char *monthStr; { /* converts "Jan", "Feb" etc. to 0, 1 etc. */ register int i; for (i = 0; mon_tab[i]; i++) { if (!strncmp (mon_tab[i], monthStr, strlen (mon_tab[i]))) return (i); } return (0); } /*=========================================== * convert date string to normalized format *===========================================*/ LOCAL time_t str2tval (str, format, hour, min, sec) char *str; int format, hour, min, sec; { char *ptr; struct tm givenTime, *tmNow; time_t now, givenSecs; givenTime.tm_sec = sec; givenTime.tm_min = min; givenTime.tm_hour = hour; givenTime.tm_mday = 1; givenTime.tm_mon = 0; givenTime.tm_year = 0; givenTime.tm_wday = -1; givenTime.tm_yday = -1; givenTime.tm_isdst = -1; switch (format) { case 1: /* Mon Nov[,] 2 92 */ case 2: /* Mon Nov[,] 25 92 */ case 3: /* Mon Nov[,] 2 1992 */ case 4: /* Mon Nov[,] 25 1992 */ str = strchr (str, ' '); if (!str) str = strchr (str, '\t'); while (isspace (*str)) str++; case 5: /* Nov[,] 2 92 */ case 6: /* Nov[,] 25 92 */ case 7: /* Nov[,] 2 1992 */ case 8: /* Nov[,] 25 1992 */ case 9: /* Nov[,] 2 */ case 10: /* Nov[,] 31 */ givenTime.tm_mon = scanMonth (str); str = strchr (str, ' '); if (!str) str = strchr (str, '\t'); while (isspace (*str)) str++; if ((ptr = strchr (str, ','))) *ptr = ' '; while (*str && !isdigit(*str)) str++; sscanf (str, "%d", &givenTime.tm_mday); while (*str && isdigit(*str)) str++; /* Skip the day */ while (*str && !isdigit(*str)) str++; /* Skip non-numerics, including timezone */ sscanf (str, "%d", &givenTime.tm_year); break; case 11: /* 1992/11/02 */ case 12: /* 92/01/31 */ sscanf (str, "%d/%d/%d", &givenTime.tm_year, &givenTime.tm_mon, &givenTime.tm_mday); givenTime.tm_mon--; break; case 13: /* 1.5.92 */ case 14: /* 10.5.92 */ case 15: /* 1.10.92 */ case 16: /* 12.10.92 */ case 17: /* 1.5.1992 */ case 18: /* 10.5.1992 */ case 19: /* 1.10.1992 */ case 20: /* 12.10.1992 */ case 21: /* 12.10. */ case 22: /* 12.10. */ case 23: /* 12.10. */ case 24: /* 12.10. */ sscanf (str, "%d.%d.%d", &givenTime.tm_mday, &givenTime.tm_mon, &givenTime.tm_year); givenTime.tm_mon--; break; default: return (0); break; } now = time(NULL); tmNow = localtime (&now); if (givenTime.tm_year) { givenTime.tm_year = givenTime.tm_year%100; if (givenTime.tm_year < 70) /* these are years beyond 2000 */ givenTime.tm_year += 100; } else givenTime.tm_year = tmNow->tm_year; if ((givenSecs = mktime (&givenTime)) == -1) return (0); return (givenSecs); } /*======================= * stMktime *=======================*/ EXPORT time_t stMktime (timeStr) char *timeStr; { int i=0, hours=12, mins=0, secs=0; char dateBuf[32], *colonPtr, *startPtr, *endPtr, *p; if (!timeStr || !(*timeStr)) return (0); /* cut out time -- assume that time portion contains colon */ if ((colonPtr = strchr (timeStr, ':'))) { if (colonPtr == timeStr) /* string starts with : */ return (0); /* find beginning of time substring */ startPtr = colonPtr-1; while ((startPtr >= timeStr) && isspace (*startPtr)) startPtr--; while ((startPtr >= timeStr) && isdigit (*startPtr)) startPtr--; hours = atoi (startPtr); /* find end of time substring */ endPtr = colonPtr+1; while (isspace (*endPtr)) endPtr++; mins = atoi (endPtr); while (isdigit (*endPtr)) endPtr++; if (*endPtr == ':') { endPtr++; while (isspace (*endPtr)) endPtr++; secs = atoi (endPtr); while (isdigit (*endPtr)) endPtr++; } i = 0; p = timeStr; while (p < startPtr) dateBuf[i++] = *p++; p = endPtr; while (*p) dateBuf[i++] = *p++; dateBuf[i] = '\0'; } else strcpy (dateBuf, timeStr); i = 0; if (re_comp (date_fmts[0].pat)) { return (0); } while (date_fmts[i].pat) { if (re_exec (dateBuf)) { return (str2tval (dateBuf, i+1, hours, mins, secs)); } i++; if (re_comp (date_fmts[i].pat)) { return (0); } } return (0); } /*======================= * stMktime *=======================*/ EXPORT char *stWriteTime (date) time_t date; { static char timeBuf[64]; strcpy (timeBuf, asctime (localtime (&date))); timeBuf[strlen(timeBuf)-1] = '\0'; return (timeBuf); } shapetools-1.4pl6.orig/src/sttk/parseargs.c100444 2013 145 17654 5412344375 17113 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * parseargs.c -- parse command line * * Author: Uli Pralle (Uli.Pralle@cs.tu-berlin.de) * * $Header: parseargs.c[4.0] Thu Jun 24 17:43:19 1993 andy@cs.tu-berlin.de frozen $ */ #include "config.h" #include "sttk.h" #define MINUS_CHAR_REQUIRED 1 LOCAL int GetNextToken (str, odesc, minus_char_required) char *str; StOptDesc odesc[]; int minus_char_required; { int i; if (!str) return (-1); if (minus_char_required && (*str != '-')) return (-1); if (*str == '-') str++; for (i = 0; odesc[i].OptName; i++) { if (!strncmp(odesc[i].OptName, str, strlen(odesc[i].OptName))) return (i); } return (-1); } LOCAL char *SkipThisToken (str, length) char *str; int length; { if (*str == '-') str++; return (str + length); } LOCAL int cmp_length (left, right) StOptDesc *left, *right; { return (strlen(right->OptName) - strlen(left->OptName)); } LOCAL int cmp_alpha (left, right) StOptDesc *left, *right; { return (strcmp(left->OptName, right->OptName)); } LOCAL void RearrangeOptDesc (odesc, cmp_function) StOptDesc odesc[]; int (*cmp_function)(); /* function that compares */ { int nelem; for (nelem = 0; odesc[nelem].OptName; nelem++) ; qsort((char *) odesc, nelem, sizeof (StOptDesc), cmp_function); } EXPORT void stShortUsage (progname, odesc, extra_text) char *progname; StOptDesc odesc[]; char *extra_text; { int i; int twidth = stGetTermWidth (2); /* stderr */ int c_printed = 1; int length = 0; int nextlineoff; char buf[ST_MSGLEN]; RearrangeOptDesc (odesc, cmp_alpha); if (progname && *progname) { sprintf (stMessage, " %s:", progname); stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); c_printed += strlen(progname) + 2; } nextlineoff = c_printed + 3; /* first switches than option requiring an agrument */ sprintf (stMessage, " [-"); stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); c_printed += 3; for (i = 0; odesc[i].OptName; i++) { if ((odesc[i].OptKind & PATTRS) == PHIDDEN) continue; if ((odesc[i].OptKind & PKIND) == PSWITCH) { length = strlen(odesc[i].OptName); length++; if (c_printed + length > twidth) { c_printed = length + nextlineoff; sprintf (buf, "\n%%%dc", nextlineoff); sprintf (stMessage, buf, ' '); stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); } else { c_printed += length; } sprintf (stMessage, " %s", odesc[i].OptName); stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); } } sprintf (stMessage, "]"); c_printed++; stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); nextlineoff -= 3; for (i = 0; odesc[i].OptName; i++) { if ((odesc[i].OptKind & PATTRS) == PHIDDEN) continue; length = strlen(odesc[i].OptName); switch (odesc[i].OptKind & PKIND) { case PSWITCH: break; case POARG: if ((c_printed + 14 + length) > twidth) { c_printed = length + nextlineoff + 14; sprintf (buf, "\n%%%dc", nextlineoff); sprintf (stMessage, buf, ' '); stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); } else { c_printed += length + 14; } sprintf (stMessage, " [-%s ]", odesc[i].OptName); stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); break; case PARG: if ((c_printed + 10 + length) > twidth) { c_printed = length + nextlineoff + 10; sprintf (buf, "\n%%%dc", nextlineoff); sprintf (stMessage, buf, ' '); stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); } else { c_printed += length + 10; } sprintf (stMessage, " [-%s ]", odesc[i].OptName); stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); break; default: break; } } if ((extra_text) && ((strlen(extra_text) + c_printed + 1) > twidth)) { sprintf (buf, "\n%%%dc", nextlineoff); sprintf (stMessage, buf, ' '); stLog (stMessage, ST_LOG_MSGERR | ST_LOG_NONL); } sprintf (stMessage, " %s", extra_text ? extra_text : ""); stLog (stMessage, ST_LOG_MSGERR); } LOCAL int handle (progname, odesc, idx, arg) char *progname; StOptDesc *odesc; int idx; char *arg; { switch (odesc[idx].OptKind & PACTION) { case PCALL: return (odesc[idx].OptFunc(odesc[idx].OptName, arg)); case PSET: *odesc[idx].OptVar = 1; return (0); case PCLEAR: *odesc[idx].OptVar = 0; return (0); case PTOGGLE: *odesc[idx].OptVar = *odesc[idx].OptVar ? 0 : 1; return (0); case PUSAGE: stShortUsage(progname, odesc, odesc[idx].OptStr); return (0); case PFAIL: stShortUsage(progname, odesc, odesc[idx].OptStr); return (1); } /* ERROR: unknown flag type */ return (1); } /*===================== * parseArgs *=====================*/ EXPORT int stParseArgs (argc, argv, nargc, nargv, odesc) int argc; char **argv; int *nargc; char *(*nargv[]); StOptDesc odesc[]; { char **localArgv, *tkn; int opt, minus_char_required, opterr = 0; *nargc = 0; /* allocate some memory for newav */ if ((localArgv = (char **) malloc((unsigned) (sizeof (char *) * (argc + 1)))) == NULL) { /* ERROR: out of memory */ return (-1); } /* sort by length */ RearrangeOptDesc (odesc, cmp_length); while (argv && *argv) { tkn = *argv; /* beginning of next argument */ minus_char_required = 1; /* require a '-' if argument is a option */ while (tkn && *tkn) { if ((opt = GetNextToken(tkn, odesc, minus_char_required)) >= 0) { tkn = SkipThisToken(tkn, strlen (odesc[opt].OptName)); /* allow joined options */ minus_char_required = 0; switch (odesc[opt].OptKind & PKIND) { case PSWITCH: opterr += handle (stProgramName, odesc, opt, ""); break; case POARG: /* * at this point, tkn points to the next char after * the detected option or tkn has reached the end. */ if (!*tkn) { if (*++argv) { /* next arg exists */ tkn = *argv; /* always '-' required */ if (GetNextToken (tkn, odesc, MINUS_CHAR_REQUIRED) >= 0) { opterr += handle (stProgramName, odesc, opt, ""); tkn = NULL; argv--; } else { opterr += handle (stProgramName, odesc, opt, tkn); tkn = NULL; } } else { /* end of argv reached */ opterr += handle (stProgramName, odesc, opt, ""); tkn = NULL; argv--; } } else { if (!(GetNextToken (tkn, odesc, (! MINUS_CHAR_REQUIRED)) >= 0)) { /* rest of tkn contains arg */ opterr += handle (stProgramName, odesc, opt, tkn); tkn = NULL; } else { opterr += handle (stProgramName, odesc, opt, ""); } } break; case PARG: if (!*tkn) { /* end of this arg reached */ argv++; tkn = *argv; if (!tkn) { /* end of argv reached */ opterr += handle (stProgramName, odesc, opt, ""); tkn = NULL; argv--; } else { opterr += handle (stProgramName, odesc, opt, tkn); tkn = NULL; } } else { opterr += handle (stProgramName, odesc, opt, tkn); tkn = NULL; } break; default: /* ERROR: Non option detected as option */ return (-1); } /* end switch */ } /* end then */ else { /* argument is not a options */ localArgv[*nargc] = tkn; (*nargc)++; tkn = NULL; } } /* select next argument */ argv++; } localArgv[*nargc] = (char *) NULL; *nargv = localArgv; /* return # of errors. 0 means no error */ return (opterr); } shapetools-1.4pl6.orig/src/sttk/ststring.c100444 2013 145 11505 5466450341 16766 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ststring.c -- ShapeTools toolkit library * * Authors: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: ststring.c[4.0] Fri Nov 5 14:11:05 1993 andy@cs.tu-berlin.de frozen $ */ #include #include "config.h" #include "sttk.h" /*================================= * convertPattern *=================================*/ EXPORT char *stConvertPattern (pattern) char *pattern; /* converts "sh" pattern to "ed" pattern */ { static char resultPattern[NAME_MAX+1]; char *patPtr = pattern, *resPtr = resultPattern; if (!pattern || !(*pattern)) return (""); *resPtr++ = '^'; while (*patPtr) { switch (*patPtr) { case '?': *resPtr++ = '.'; break; case '*': *resPtr++ = '.'; *resPtr++ = '*'; break; case '.': *resPtr++ = '\\'; *resPtr++ = '.'; break; case '!': /* should check if there is a closing square bracket */ if ((patPtr > pattern) || (*(patPtr-1) == '[')) *resPtr++ = '^'; else *resPtr++ = *patPtr; break; default: *resPtr++ = *patPtr; } patPtr++; } *resPtr++ = '$'; *resPtr++ = '\0'; return (resultPattern); } EXPORT char *stSubstituteString (subject, oldStr, newStr) char *subject, *oldStr, *newStr; { /* * replace all occurrences of substring "oldStr" in "subject" by * string "newStr". Return a pointer to a statically allocated * string that is the result of this operation. Return NULL * if anything goes seriously wrong. */ int subject_len, old_len, new_len; char *result; register char *p, *s; register int j; if (subject == NULL) return ""; else subject_len = strlen (subject); old_len = oldStr ? strlen (oldStr) : 0; new_len = newStr ? strlen (newStr) : 0; if ((result = (char *)malloc (subject_len + 1)) == (char *)NULL) return (char *)NULL; if ((old_len == 0) || (old_len > subject_len)) { (void) strcpy (result, subject); return result; } p = subject; s = oldStr; j = 0; while (*p) { register int i; i = 0; while (*s && (*(p+i) == *s)) { s++; i++; } if (*s) { result[j++] = *p++; } else { p += old_len; result[j] = '\0'; if (j+new_len >= subject_len) { if ((result = (char *)realloc (result, j+new_len+subject_len) ) == (char *)NULL) return (char *)NULL; } (void) strcat (result, newStr); j += new_len; } s = oldStr; } result[j] = '\0'; return result; } EXPORT char *stStrtok (str) char *str; { /* * considers the string str to consist of a sequence of zero or more * text tokens separated by whitespace. The first call (with pointer * str specified) returns a pointer to the first character of the * first token, and will have written a null character into str * immediately following the returned token. The function keeps * track of its position between separate calls, so that subsequent * calls (which must be made with the str argument set to NULL) will * work through the string immediately following that token. In * this way subsequent calls will work through the string until no * tokens remain. When no token remains in str, a NULL pointer is * returned. */ static int buf_is_initialized, bufsiz; static char *buf, *thistoken = NULL, *nexttoken = NULL; register int i; if (str) { int strsiz = strlen (str); if (buf_is_initialized) { if (bufsiz < strsiz+1) { buf = realloc (buf, strsiz+1); if (!buf) return (char *)NULL; } } else { buf = malloc (strsiz+1); if (!buf) return (char *)NULL; } (void) strcpy (buf, str); bufsiz = strsiz+1; buf_is_initialized = TRUE; thistoken = buf; while (*thistoken && isspace (*thistoken)) thistoken++; } else { thistoken = nexttoken; } if (thistoken) { i = 0; while (thistoken[i] && !isspace(thistoken[i])) i++; if (thistoken[i]) { thistoken[i++] = '\0'; while (isspace(thistoken[i])) i++; } nexttoken = &thistoken[i]; } return (thistoken && *thistoken) ? thistoken : (char *)NULL; } shapetools-1.4pl6.orig/src/sttk/sighand.c100444 2013 145 7253 5416053653 16513 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * sighand.c -- ShapeTools toolkit library * * Authors: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * $Header: sighand.c[4.0] Mon Jul 5 18:36:25 1993 axel@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "sttk.h" EXPORT struct stTransaction stThisTransaction = {"",0,0,0,{0}}; /*========= * quit *=========*/ LOCAL void quit () { signal (SIGQUIT, SIG_DFL); kill (getpid(), SIGQUIT); } /*======================== * cleanup and exit *========================*/ EXPORT void stCleanup () { fflush (stdout); stRmRegisteredFiles (); af_cleanup(); } EXPORT void stExit (i) int i; { stCleanup(); exit(i); } /*===================== * signal handlers *=====================*/ EXPORT Sigret_t (*stInterruptAction)(), (*stQuitAction)(), (*stTermAction)(); LOCAL Sigret_t die2 () { disableSig (SIGINT); signal (SIGINT, die2); enableSig (); if (stInterruptAction) stInterruptAction(); } LOCAL Sigret_t die3 () { disableSig (SIGQUIT); stLog ("Oh! Oh! ... received SIGQUIT -- goodbye.\n", ST_LOG_ERROR); if (stQuitAction) stQuitAction (); stCleanup (); enableSig (); quit (); } LOCAL Sigret_t die8 () { disableSig (SIGFPE); stLog ("Oh! Oh! ... this was a floating exception -- goodbye.\n", ST_LOG_ERROR); if (stQuitAction) stQuitAction (); stCleanup (); enableSig (); quit (); } LOCAL Sigret_t die10 () { disableSig (SIGBUS); stLog ("Oh! Oh! ... this was a buserror -- goodbye.\n", ST_LOG_ERROR); stLog ("Dumping core...", ST_LOG_ERROR); if (stQuitAction) stQuitAction (); stCleanup (); enableSig (); quit (); } LOCAL Sigret_t die11 () { disableSig (SIGSEGV); stLog ("Oh! Oh! ... this was a segmentation violation -- goodbye.\n", ST_LOG_ERROR); stLog ("Dumping core...", ST_LOG_ERROR); if (stQuitAction) stQuitAction (); stCleanup (); enableSig (); quit (); } LOCAL Sigret_t die13 () { disableSig (SIGPIPE); stCleanup (); enableSig (); quit (); } LOCAL Sigret_t die15 () { stLog ("Aborted ... goodbye.\n", ST_LOG_MSGERR); disableSig (SIGTERM); if (stTermAction) stTermAction (); stCleanup (); enableSig (); quit (); } /*================ * catch signals *================*/ EXPORT void stCatchSigs () { /* Setup signal handlers for various signals. * On receipt of a signal, the * original handler for this signal will be invoked after specified * action has been taken. */ signal (SIGINT, die2); signal (SIGQUIT, die3); signal (SIGFPE, die8); signal (SIGBUS, die10); signal (SIGSEGV, die11); signal (SIGPIPE, die13); signal (SIGTERM, die15); } /*==================== * abort transaction *====================*/ EXPORT void stAbortThis (domsg) int domsg; { /* abort current execution phase and restore * a clean context for next phase */ if (domsg) stLog ("...aborting", ST_LOG_MSGERR); stRmRegisteredFiles (); if (!stThisTransaction.tr_rc) stThisTransaction.tr_rc = TRUE; longjmp (stThisTransaction.tr_env, 1); } shapetools-1.4pl6.orig/src/sttk/call.c100444 2013 145 25274 5412345170 16026 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * call.c - call program * * Authors: Uli Pralle (Uli.Pralle@cs.tu-berlin.de) * Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) * * $Header: call.c[4.0] Thu Jun 24 17:43:24 1993 andy@cs.tu-berlin.de frozen $ */ #include #include "config.h" #include "sttk.h" LOCAL int doCall (progName, argv) char *progName; char **argv; { Wait_t status; pid_t pid, offered_pid; extern char **environ; if (!strrchr (progName, '/')) { if ((progName = stFindProgram (progName)) == NULL) return 0; } pid = fork (); if (pid == -1) { /* ERROR: Can't fork */ return 0; } if (!pid) { /* child */ /* close open files ? */ execve (progName, argv, environ); /* ERROR: Can't exec */ _exit (1); } else { /* parent */ /* here we must redefine actual interrupt handler. */ while ( ((offered_pid = wait (&status)) != pid) && (offered_pid != -1)) ; /* nothing to do */ if (offered_pid == -1) { return 0; } /* here we must reconstruct old sighandl */ if (WEXITSTATUS(status)) return 0; else return 1; } return 0; } /*===================== * call editor *=====================*/ EXPORT int stCallEditor (editor, file, contents, newcontents) char *editor, *file, *contents; char **newcontents; { /* * Calls editor "editor" with file "file" and returns its * contents after the editor session in "newcontents". * Return value is the length of the new text. * * On failure, 0 is returned to indicate the error. newcontents * is *not* updated and points to nowhere. On error the file * will be removed. * * If "contents" points to a valid text, this text is put (not appended) * into the temporary file before editor starts. Text must be * NULL terminated, otherwise strange things will happen... */ FILE *fid; char *new; int length; struct stat sbuf; char *argv[10]; *newcontents = NULL; /* don't get confused on error. */ stRegisterFile (file); if ((fid = fopen (file, "w")) == NULL) { /* create a file */ stUnRegisterFile (file); /* ERROR: Can't open temporary file */ return -1; } if (contents && *contents) { length = strlen (contents); if (fwrite (contents, sizeof (char), length, fid) != length) { /* ERROR: lost bytes while writing to file */ fclose (fid); unlink (file); stUnRegisterFile (file); return -1; } } fclose (fid); argv[0] = editor; argv[1] = file; argv[2] = (char *) NULL; sprintf (stMessage, "starting up %s %s...\n", editor, file); stLog (stMessage, ST_LOG_MSG); if (! doCall (editor, argv)) { /* ERROR: Editor exited abnormally */ unlink (file); stUnRegisterFile (file); return -1; } if (stat (file, &sbuf) == -1) { /* ERROR: Can't stat temporary file */ return -1; } if ((fid = fopen (file, "r")) == NULL) { /* ERROR: Can't reopen temporary file */ unlink (file); stUnRegisterFile (file); return -1; } unlink (file); stUnRegisterFile (file); length = sbuf.st_size; if ((new = malloc ((unsigned)(sizeof (char) * (length + 1)))) == NULL) { /* ERROR: Can't malloc for new */ fclose (fid); return -1; } if (!fread (new, sizeof (char), (size_t)length, fid)) { /* ERROR: lost bytes while reading from file */ fclose (fid); return -1; } new[length] = '\0'; fclose (fid); *newcontents = new; return length; } /*===================== * call command *=====================*/ /* * int callCmd(char *command_processor, char *commandstring) ; * Call command_processor with commandstring. Commandstring is sent * to command_processor's stdin. If Commandstring is not terminated * with newline, a newline is added. * For return codes see sttk.h. * * int stCallCmdErrno ; * Contains additional status information if callCmd fails. */ #include extern int errno ; /* to obtain error information after * failed syscalls */ /* definition of return codes in sttk.h */ #define DELIM_CHARS " \t" /* delimiter characters for breaking * command_processor into argv */ EXPORT int stCallCmdErrno ; /* to export additional status information */ static int sigpipe_occurred ; /* flag: true if SIGPIPE was caught */ static int sigusr_occurred ; /* flag: true if SIGUSR[12] was caught */ /* function to send commandstring to child */ static int write_to_child() ; /* catch SIGUSR[12] and set flag */ static Sigret_t sigusr_handler(signal) int signal ; { sigusr_occurred = signal ; } EXPORT int stCallCmd (command_processor, commandstring) char *command_processor ; char *commandstring ; { char **argv ; /* built from command_processor */ char *cmdproc2 ; /* copy of command_processor for stStrtok */ int numtok ; /* number of tokens in command_processor */ int i ; /* loop counter */ pid_t child_pid ; /* PID of forked process */ Wait_t child_status ; /* exit status of child process */ int pipefd[2] ; /* file descriptors for pipe to child */ int write_result ; /* result of write_to_child() */ int wait_result ; /* return value of wait(2) */ int commandflag ; /* do we have a commandstring? */ static Sigret_t (*old_sigusr1hand)() ; /* old signal handler for SIGUSR1 */ static Sigret_t (*old_sigusr2hand)() ; /* ... and SIGUSR2 */ /* do we have a command string? */ commandflag = commandstring != NULL && *commandstring != 0 ; /* no signals or errors yet */ sigpipe_occurred = 0 ; sigusr_occurred = 0 ; stCallCmdErrno = 0 ; /* copy command_processor for stStrtok */ if ((cmdproc2 = malloc(strlen(command_processor) + 1)) == NULL) { stCallCmdErrno = ENOMEM ; return NO_MORE_CORE ; } strcpy(cmdproc2, command_processor) ; if (command_processor == NULL || *command_processor == 0 || stStrtok(cmdproc2) == NULL) { return CMDPROC_EMPTY ; } /* allocate and set up argv for child process */ for (numtok = 1; stStrtok(NULL); numtok++) ; /* copy command_processor for stStrtok */ if ((cmdproc2 = malloc(strlen(command_processor) + 1)) == NULL) { stCallCmdErrno = ENOMEM ; return NO_MORE_CORE ; } strcpy(cmdproc2, command_processor) ; argv = (char **) calloc(numtok + 1, sizeof(char *)) ; if (argv == NULL) { stCallCmdErrno = ENOMEM ; return NO_MORE_CORE ; } argv[0] = stStrtok(cmdproc2) ; for (i = 1; i < numtok; i++) { argv[i] = stStrtok(NULL) ; } argv[i] = NULL ; if (commandflag) { /* set up pipe to child's stdin */ if (pipe(pipefd) != 0) { stCallCmdErrno = errno ; return PIPE_FAILED ; } } /* set up signal handler for SIGUSR1 and SIGUSR2 */ old_sigusr1hand = signal(SIGUSR1, sigusr_handler) ; old_sigusr2hand = signal(SIGUSR2, sigusr_handler) ; /* and now let things go */ switch (child_pid = vfork()) { case -1: /* aehem... */ stCallCmdErrno = errno ; free((char *) argv) ; signal(SIGUSR1, old_sigusr1hand) ; signal(SIGUSR2, old_sigusr2hand) ; return FORK_FAILED ; case 0: /* child process */ if (commandflag) { /* set up pipe as stdin */ close(pipefd[1]) ; close(0) ; dup(pipefd[0]) ; close(pipefd[0]) ; } signal(SIGUSR1, old_sigusr1hand) ; signal(SIGUSR2, old_sigusr2hand) ; /* execute program */ execvp(argv[0], argv) ; /* this failed, so notify parent */ stCallCmdErrno = errno ; /* this only works with vfork(2) */ kill(getppid(), errno == ENOENT ? SIGUSR1 : SIGUSR2) ; _exit(0) ; /* Don't flush parent's buffers! */ break ; default: /* parent process */ close(pipefd[0]) ; /* write commandstring to child process */ if (commandflag) { write_result = write_to_child(pipefd[1], commandstring) ; } else { write_result = OK ; } close(pipefd[1]) ; /* check termination of child process */ while ((wait_result = wait(&child_status)) != child_pid) { if (wait_result == -1) { stCallCmdErrno = errno ; signal(SIGUSR1, old_sigusr1hand) ; /* reset signal handlers */ signal(SIGUSR2, old_sigusr2hand) ; return WAIT_ERROR ; } } signal(SIGUSR1, old_sigusr1hand) ; /* reset signal handlers */ signal(SIGUSR2, old_sigusr2hand) ; /* execvp(3) may have failed: * if we can use vfork(2), stCallCmdErrno contains the * reason of exec's failure */ switch (sigusr_occurred) { case SIGUSR1: return NO_PROGRAM ; case SIGUSR2: return EXEC_FAILED ; } /* write to pipe may have had problems */ if (write_result != OK) { stCallCmdErrno = write_result ; return WRITE_FAILED ; } /* report child's exit status or reason of death */ if (WIFEXITED(child_status)) { return WEXITSTATUS(child_status) ; } else { /* the only case where stCallCmdErrno can't be interpreted * like errno */ memcpy(&stCallCmdErrno, &child_status, sizeof(int)) ; return CHILD_KILLED ; } } /* not reached, but to make gcc happy: */ return 0 ; } /* write command into fd, append newline if necessary */ static int write_to_child(fd, command) int fd ; /* input file descriptor of pipe to child */ char *command ; /* command string */ { int written ; /* no. of bytes written to child */ int cmd_write ; /* length of rest of commandstring to write */ int w_stat ; /* return value of write(2) */ static Sigret_t (*old_sigpipehand)() ; /* old signal handler for SIGPIPE */ /* block SIGPPIPE, errno will report it anyway */ old_sigpipehand = signal(SIGPIPE, SIG_IGN) ; cmd_write = strlen(command) ; written = 0 ; /* write in pieces to avoid pipe constipation */ while (cmd_write > 0) { if ((w_stat = write(fd, command + written, cmd_write > BUFSIZ ? BUFSIZ : cmd_write)) == -1) { stCallCmdErrno = errno ; signal(SIGPIPE, old_sigpipehand) ; return stCallCmdErrno; } written += w_stat ; cmd_write -= w_stat ; } /* append newline if necessary */ if (command[written - 1] != '\n') { if (write(fd, "\n", 1) == -1) { stCallCmdErrno = errno ; signal(SIGPIPE, old_sigpipehand) ; return errno ; } } signal(SIGPIPE, old_sigpipehand) ; return OK ; } shapetools-1.4pl6.orig/src/sttk/sttk.h100444 2013 145 12336 5466450225 16107 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * sttk.h - definitions for ShapeTools toolkit library * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: sttk.h[4.0] Fri Nov 5 14:11:15 1993 andy@cs.tu-berlin.de frozen $ */ #ifndef _STTKHDR_ #define _STTKHDR_ /*==================== * general constants *====================*/ #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef ERROR #define ERROR -1 #endif #ifndef LOCAL #define LOCAL static #endif #ifndef EXPORT #define EXPORT #endif #ifndef bool #define bool short #endif /*============== * constants *==============*/ #define ST_ENV "SHAPETOOLS" /* ShapeTools shell environment variable */ #define ST_ENV_DEFAULT "/usr/local" #define ST_ENV_INCLUDE "/include" #define ST_ENV_LIB "/lib" #define ST_ENV_SHAPELIB "/lib/shape" #define ST_DEFAULT_PATH "/bin:/usr/bin:/usr/ucb:" #define ST_HASHSIZE 501 /* size of hash list for string table */ #define ST_MSGLEN PATH_MAX+128 #define ST_MAX_TMPFILES 16 #define ST_LOG_MSG 001 #define ST_LOG_MSGERR 002 #define ST_LOG_WARNING 004 #define ST_LOG_ERROR 010 #define ST_LOG_NONL 0100 /*======================= * callCmd stuff *=======================*/ /* return values (zero or positive number is exit status of child process) */ #define OK 0 /* this is not exactly an error */ #define CMDPROC_EMPTY -1 /* empty string for command processor */ #define NO_MORE_CORE -3 /* calloc(3) failed */ #define FORK_FAILED -4 /* [v]fork(2) failed */ #define PIPE_FAILED -5 /* pipe(2) failed */ #define WAIT_ERROR -6 /* waitpid(2) failed */ #define EXEC_FAILED -7 /* execvp(3) failed */ #define CHILD_KILLED -8 /* child process did not terminate normally */ #define WRITE_FAILED -9 /* write(2) to pipe failed */ #define NO_PROGRAM -10 /* command processor program not found */ /*======================= * Parseargs stuff *=======================*/ #define PSWITCH 0 /* argument is a switch (default) */ #define PARG 01 /* argument has argument */ #define POARG 02 /* argument hat optional argument */ #define PKIND 07 /* option attribute */ #define PHIDDEN (01 << 4) /* not used */ #define PATTRS (07 << 4) /* action to be performed */ #define PCALL 0 /* call function (default) */ #define PSET (01 << 8) /* set variable to 1 */ #define PCLEAR (02 << 8) /* set variable to 0 */ #define PTOGGLE (04 << 8) /* toggle variable */ #define PUSAGE (010 << 8) /* call usage */ #define PFAIL (020 << 8) /* call usage and return 1 */ #define PACTION (077 << 8) typedef struct { char *OptName; int OptKind; int (*OptFunc)(); int *OptVar; char *OptStr; } StOptDesc; /*======================= * Sighand stuff *=======================*/ #include struct stTransaction { char tr_fname[PATH_MAX+1]; int tr_done; int tr_seqno; int tr_rc; jmp_buf tr_env; }; /*===================================== * exported functions *=====================================*/ #ifdef __STDC__ #define A(alist) alist #else #define A(alist) () #endif /*** call.c */ int stCallEditor A((char *ed, char *file, char *cnt, char **newcnt)); int stCallCmd A((char *commandProc, char *commandStr)); extern int stCallCmdErrno ; /*** files.c ***/ char* stTmpFile A((char *path)); void stRmRegisteredFiles A((void)); void stRegisterFile A((char *fileName)); void stUnRegisterFile A((char *fileName)); char* stFindProgram A((char *fileName)); /*** kbdio.c ***/ extern int stQuietFlag; extern int stShutupFlag; extern char* stProgramName; extern char stMessage[]; void stLog A((char *logMsg, int logType)); char* stGetFromStdin A((int termChar)); int stAskConfirm A((char *message, char *defaultAnswer)); int stGetTermWidth A((int fdes)); /*** mktime.c ***/ time_t stMktime A((char *string)); char* stWriteTime A((time_t date)); /*** parseargs.c ***/ int stParseArgs A((int ac, char **av, int *nac, char *(*nav[]), StOptDesc od[])); void stShortUsage A((char *progname, StOptDesc od[], char *extra_text)); /*** ststring.c ***/ char* stConvertPattern A((char *pattern)); char* stSubstituteString A((char *original, char *oldStr, char *newStr)); char* stStrtok A((char *string)); /***sighand.c ***/ extern Sigret_t (*stInterruptAction)(); extern Sigret_t (*stQuitAction)(); extern Sigret_t (*stTermAction)(); extern struct stTransaction stThisTransaction; void stCatchSigs A((void)); void stAbortThis A((int domsg)); void stCleanup A((void)); void stExit A((int exitCode)); /*** strtab.c ***/ char* stStrEnter A((char *string)); /*** sttk_version.c ***/ char* stVersion A((void)); #endif /* _STTKHDR_ */ shapetools-1.4pl6.orig/src/sttk/sttk_version.c100444 2013 145 202 5574605042 17573 0ustar dokoswtchar *stVersion () { static char release[] = "sttk-1.7 (Tue Aug 23 17:55:25 1994 by andy@cs.tu-berlin.de)"; return release; } shapetools-1.4pl6.orig/src/sttk/Shapefile100444 2013 145 6720 5443124674 16555 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for ShapeTools toolkit library (sttk) # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[4.0] Tue Sep 7 17:33:44 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds _all: all $(LIBTARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) $(CC) -c $(CFLAGS) $(VERSIONFILE) localinstall: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .NOBPOOL: $(LIBTARGET) # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) localinstall: MAINTARGET=localinstall ALLTARGETS=subsystems localinstalltargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/sttk/Makefile100444 2013 145 26511 5426221434 16403 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for ShapeTools toolkit library (sttk) # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[4.0] Fri Jul 30 16:00:00 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/sttk # A short name for this node system NODENAME = sttk # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = /home/stone/shape INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. LIBTARGET = libsttk.a # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = sttk_version.c # source VERSIONOBJECT = sttk_version.o # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = # The regular source and header files. SOURCES = strtab.c files.c kbdio.c mktime.c parseargs.c \ ststring.c sighand.c call.c HEADERS = sttk.h # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = MAN3 = sttkintro.3 stcall.3 stparseargs.3 stsignal.3 ststring.3 \ sttime.3 sttmpfiles.3 sttransaction.3 stuserio.3 MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. LIBOBJECTS = strtab.o files.o kbdio.o mktime.o parseargs.o \ ststring.o sighand.o call.o $(VERSIONOBJECT) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(LIBTARGET) $(LIBTARGET): $(LIBOBJECTS) -ar ruv $(LIBTARGET) $(LIBOBJECTS) @-($(RANLIB) $(LIBTARGET)) 2> /dev/null; true localinstalltargets: $(LOCALLIBPATH)/$(LIBTARGET) \ $(LOCALINCLUDEPATH)/sttk.h $(LOCALLIBPATH)/$(LIBTARGET): $(LIBTARGET) @-echo "Copying $(LIBTARGET) to $(LOCALLIBPATH)"; \ if [ -f $(LOCALLIBPATH)/$(LIBTARGET) ] ;\ then \ mv -f $(LOCALLIBPATH)/$(LIBTARGET) \ $(LOCALLIBPATH)/$(LIBTARGET).old;\ fi; \ cp $(LIBTARGET) $(LOCALLIBPATH)/$(LIBTARGET); \ chmod $(INSTALLLIBMODE) $(LOCALLIBPATH)/$(LIBTARGET); \ ($(RANLIB) $(LOCALLIBPATH)/$(LIBTARGET)) 2> /dev/null; true $(LOCALINCLUDEPATH)/sttk.h: sttk.h @-echo "Copying sttk.h to $(LOCALINCLUDEPATH)"; \ if [ -f $(LOCALINCLUDEPATH)/sttk.h ] && \ [ ! -w $(LOCALINCLUDEPATH)/sttk.h ]; \ then \ chmod u+w $(LOCALINCLUDEPATH)/sttk.h; \ fi; \ cp sttk.h $(LOCALINCLUDEPATH)/sttk.h; \ chmod $(INSTALLINCMODE) $(LOCALINCLUDEPATH)/sttk.h installtargets: $(INSTALLLIBPATH)/$(LIBTARGET) \ $(INSTALLINCPATH)/sttk.h $(INSTALLLIBPATH)/$(LIBTARGET): $(LIBTARGET) @-echo "Installing $(LIBTARGET) in $(INSTALLLIBPATH)"; \ if [ -f $(INSTALLLIBPATH)/$(LIBTARGET) ] ;\ then \ mv -f $(INSTALLLIBPATH)/$(LIBTARGET) \ $(INSTALLLIBPATH)/$(LIBTARGET).old;\ fi; \ cp $(LIBTARGET) $(INSTALLLIBPATH)/$(LIBTARGET); \ chmod $(INSTALLLIBMODE) $(INSTALLLIBPATH)/$(LIBTARGET); \ ($(RANLIB) $(INSTALLLIBPATH)/$(LIBTARGET)) 2> /dev/null; true $(INSTALLINCPATH)/sttk.h: sttk.h @-echo "Installing sttk.h in $(INSTALLINCPATH)"; \ if [ -f $(INSTALLINCPATH)/sttk.h ] && \ [ ! -w $(INSTALLINCPATH)/sttk.h ]; \ then \ chmod u+w $(INSTALLINCPATH)/sttk.h; \ fi; \ cp sttk.h $(INSTALLINCPATH)/sttk.h; \ chmod $(INSTALLINCMODE) $(INSTALLINCPATH)/sttk.h installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(LIBTARGET) $(ALIASES) $(LIBOBJECTS) # Do nothing noinstall: @true # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) localinstall: +localinstall $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +localinstall: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems localinstalltargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(BASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" localinstall; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(BASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/sttk/Dependencies100444 2013 145 1264 5341216065 17232 0ustar dokoswtcall.o: ./sttk.h call.o: $(BASE)/include/config.h call.o: call.c files.o: ./sttk.h files.o: $(BASE)/include/config.h files.o: files.c kbdio.o: ./sttk.h kbdio.o: $(BASE)/include/config.h kbdio.o: kbdio.c mktime.o: ./sttk.h mktime.o: $(BASE)/include/config.h mktime.o: mktime.c parseargs.o: ./sttk.h parseargs.o: $(BASE)/include/config.h parseargs.o: parseargs.c sighand.o: ./sttk.h sighand.o: $(BASE)/include/afsys.h sighand.o: $(BASE)/include/atfs.h sighand.o: $(BASE)/include/config.h sighand.o: sighand.c strtab.o: ./sttk.h strtab.o: $(BASE)/include/config.h strtab.o: strtab.c ststring.o: ./sttk.h ststring.o: $(BASE)/include/config.h ststring.o: ststring.c sttk_version.o: sttk_version.c shapetools-1.4pl6.orig/src/atfstk/ 40755 2013 145 0 5626416053 15137 5ustar dokoswtshapetools-1.4pl6.orig/src/atfstk/atfstk_lib.c100444 2013 145 2165 5412606512 17516 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * atfstk_lib.c -- AtFS toolkit library * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: atfstk_lib.c[7.0] Fri Jun 25 16:38:49 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "atfstk.h" /*================= * Error Handling *=================*/ EXPORT int atErrno; EXPORT char *atErrMsg; EXPORT void atError (code, msg) int code; char *msg; { atErrno = code; atErrMsg = msg; } shapetools-1.4pl6.orig/src/atfstk/attrs.c100444 2013 145 13650 5412606474 16561 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * attrs.c -- AtFS toolkit library * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: attrs.c[7.0] Fri Jun 25 16:38:51 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "atfstk.h" /*======= * name *=======*/ EXPORT char *atFileClassExt (aso) Af_key *aso; { static char classStr[4]; char *strPtr = classStr; mode_t mode; Af_user *locker; classStr[0] = classStr[1] = classStr[2] = classStr[3] = '\0'; mode = af_retnumattr (aso, AF_ATTMODE); if (S_ISDIR (mode)) *strPtr++ = '/'; #ifdef S_ISLNK else if (S_ISLNK (mode)) *strPtr++ = '@'; #endif #ifdef S_ISSOCK else if (S_ISSOCK (mode)) *strPtr++ = '='; #endif else if ((mode & S_IXUSR) || (mode & S_IXGRP) || (mode & S_IXOTH)) *strPtr++ = '*'; if (af_retnumattr (aso, AF_ATTSTATE) == AF_DERIVED) *strPtr++ = '$'; /* derived object */ else { locker = af_testlock (aso); if (locker->af_username[0]) *strPtr++ = '^'; } return (classStr); } /*=============== * version status *===============*/ LOCAL struct { char *name; int code; } statusTable[] = { { "busy", AF_BUSY }, { "b", AF_BUSY }, { "saved", AF_SAVED }, { "save", AF_SAVED }, { "s", AF_SAVED }, { "proposed", AF_PROPOSED }, { "prop", AF_PROPOSED }, { "p", AF_PROPOSED }, { "published", AF_PUBLISHED }, { "publishd", AF_PUBLISHED }, { "publ", AF_PUBLISHED }, { "P", AF_PUBLISHED }, { "accessed", AF_ACCESSED }, { "acce", AF_ACCESSED }, { "a", AF_ACCESSED }, { "frozen", AF_FROZEN }, { "froz", AF_FROZEN }, { "f", AF_FROZEN }, { (char *)0x0, AF_NOSTATE } }; EXPORT int atScanStatus (statusStr) char *statusStr; { int i; register char *strPtr; if (!(strcmp (statusStr, "P"))) return (AF_PUBLISHED); strPtr = statusStr; while ((*strPtr = tolower (*strPtr))) strPtr++; for (i = 0; statusTable[i].name; i++) if (!(strcmp (statusStr, statusTable[i].name))) return (statusTable[i].code); return (AF_NOSTATE); } EXPORT char *atWriteStatus (aso, verbose) Af_key *aso; int verbose; { switch (af_retnumattr (aso, AF_ATTSTATE)) { case AF_BUSY: return verbose ? "busy " : "b"; case AF_SAVED: return verbose ? "saved " : "s"; case AF_PROPOSED: return verbose ? "proposed" : "p"; case AF_PUBLISHED: return verbose ? "publishd" : "P"; case AF_ACCESSED: return verbose ? "accessed" : "a"; case AF_FROZEN: return verbose ? "frozen " : "f"; case AF_DERIVED: return verbose ? "derived " : "d"; default: return verbose ? "none " : "n"; } } EXPORT int atIsDerived (aso) Af_key *aso; { if (af_retnumattr (aso, AF_ATTSTATE) == AF_DERIVED) return (TRUE); return (FALSE); } /*======= * mode *=======*/ EXPORT char *atWriteMode (aso) Af_key *aso; { static char fileMode[12]; mode_t mode = af_retnumattr (aso, AF_ATTMODE); (void) sprintf(fileMode, " %c%c%c%c%c%c%c%c%c", (mode & S_IRUSR) ? 'r' : '-', (mode & S_IWUSR) ? 'w' : '-', (mode & S_IXUSR) ? 'x' : '-', (mode & S_IRGRP) ? 'r' : '-', (mode & S_IWGRP) ? 'w' : '-', (mode & S_IXGRP) ? 'x' : '-', (mode & S_IROTH) ? 'r' : '-', (mode & S_IWOTH) ? 'w' : '-', (mode & S_IXOTH) ? 'x' : '-'); if (S_ISDIR(mode)) fileMode[0] = 'd'; else if (S_ISCHR(mode)) fileMode[0] = 'c'; else if (S_ISBLK(mode)) fileMode[0] = 'b'; else if (S_ISREG(mode)) fileMode[0] = '-'; #ifdef S_ISLNK else if (S_ISLNK(mode)) fileMode[0] = 'l'; #endif #ifdef S_ISSOCK else if (S_ISSOCK(mode)) fileMode[0] = 's'; #endif if (mode & S_ISUID) fileMode[3] = 's'; if (mode & S_ISGID) fileMode[6] = 's'; #ifdef S_ISVTX if (mode & S_ISVTX) fileMode[9] = 't'; #endif return (fileMode); } /*================= * atWriteDate *=================*/ #define HALF_YEAR_MAX_SECS 15897600 /* 184 days */ #define HALF_YEAR_MIN_SECS 15638400 /* 181 days */ EXPORT char *atWriteDate (aso, date) Af_key *aso; char *date; { static char resultTime[16]; time_t asoTime, curTime; int timeDiff, dateType; char *asoTimeString = af_retattr (aso, date); if (!asoTimeString[0]) { /* time not available */ strcpy (resultTime, " "); return (resultTime); } asoTime = af_rettimeattr (aso, date); curTime = time (&curTime); timeDiff = curTime - asoTime; if (timeDiff < HALF_YEAR_MIN_SECS) dateType = 0; /* Month Day Time */ else if (timeDiff > HALF_YEAR_MAX_SECS) dateType = 1; /* Month Day Year */ else { dateType = 0; /* ToDo: do closer examination */ } resultTime[12] = '\0'; switch (dateType) { case 0: strncpy (resultTime, &asoTimeString[4], 12); break; case 1: strncpy (resultTime, &asoTimeString[4], 7); strncpy (&resultTime[7], &asoTimeString[19], 5); break; } return (resultTime); } /*================= * atWriteName *=================*/ EXPORT char *atWriteName (aso, path) Af_key *aso; char *path; { static char name[PATH_MAX]; if (!path) path = ""; if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) sprintf (name, "%s%s%s", path, *path ? "/" : "", af_retattr (aso, AF_ATTUNIXNAME)); else sprintf (name, "%s%s%s", path, *path ? "/" : "", af_retattr (aso, AF_ATTBOUND)); return (name); } shapetools-1.4pl6.orig/src/atfstk/version.c100444 2013 145 7336 5437116703 17073 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * version.c -- AtFS toolkit library * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: version.c[7.0] Thu Aug 26 13:52:22 1993 axel@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "atfstk.h" /*================ * version number *================*/ EXPORT int atVno (aso) Af_key *aso; { return ((af_retnumattr (aso, AF_ATTGEN) << 16) | (0x0000FFFF & af_retnumattr (aso, AF_ATTREV))); } /*========================== * version number aliases *==========================*/ EXPORT int atSetVersAlias (aso, alias) Af_key *aso; char *alias; { Af_attrs attrBuf; Af_set hitSet; int hitCount; Af_key foundAso; char aliasAttr[AT_MAXALIASLEN]; sprintf (aliasAttr, "%s=%s", AT_ATTALIAS, alias); af_initattrs (&attrBuf); strcpy (attrBuf.af_syspath, af_retattr (aso, AF_ATTSPATH)); strcpy (attrBuf.af_name, af_retattr (aso, AF_ATTNAME)); strcpy (attrBuf.af_type, af_retattr (aso, AF_ATTTYPE)); attrBuf.af_udattrs[0] = aliasAttr; attrBuf.af_udattrs[1] = NULL; if ((hitCount = af_find (&attrBuf, &hitSet)) < 0) { af_dropset (&hitSet); atError (AT_ERROR, af_errmsg ("atSetVersAlias")); return (FALSE); } if (hitCount > 0) { char msgBuf[NAME_MAX + AT_MAXALIASLEN + 64]; /* version number alias already in use */ af_setgkey (&hitSet, 0, &foundAso); af_dropset (&hitSet); if ((af_retnumattr (aso, AF_ATTGEN) == af_retnumattr (&foundAso, AF_ATTGEN)) && (af_retnumattr (aso, AF_ATTREV) == af_retnumattr (&foundAso, AF_ATTREV))) return (TRUE); sprintf (msgBuf, "version number alias %s already in use for: %s", alias, af_retattr (&foundAso, AF_ATTBOUND)); atError (AT_MSG, msgBuf); return (FALSE); } if (af_setattr (aso, AF_ADD, aliasAttr) == -1) { atError (AT_ERROR, af_errmsg ("atSetVersAlias")); return (FALSE); } return (TRUE); } EXPORT int atDelVersAlias (aso, alias) Af_key *aso; char *alias; { char *aliasValPtr, *thisPtr, *nextPtr; char aliasAttr[AT_MAXALIASLEN]; aliasValPtr = thisPtr = af_retattr (aso, AT_ATTALIAS); if (!(thisPtr && thisPtr[0])) { af_freeattr (aliasValPtr); return (TRUE); } if (af_setattr (aso, AF_REMOVE, AT_ATTALIAS) == -1) { atError (AT_ERROR, af_errmsg ("atDelVersAlias")); af_freeattr (aliasValPtr); return (FALSE); } /* if alias argument is emty, delete all alias names */ if (!(alias && alias[0])) { af_freeattr (aliasValPtr); return (TRUE); } if ((nextPtr = strchr (thisPtr, '\n'))) { *nextPtr = '\0'; nextPtr++; } while (thisPtr) { if (strcmp (thisPtr, alias)) { /* no, this is not the value we are looking for */ sprintf (aliasAttr, "%s=%s", AT_ATTALIAS, thisPtr); if (af_setattr (aso, AF_ADD, aliasAttr) == -1) { atError (AT_ERROR, af_errmsg ("atDelVersAlias")); af_freeattr (aliasValPtr); return (FALSE); } } thisPtr = nextPtr; if (thisPtr && (nextPtr = strchr (thisPtr, '\n'))) { *nextPtr = '\0'; nextPtr++; } } af_freeattr (aliasValPtr); return (TRUE); } shapetools-1.4pl6.orig/src/atfstk/user.c100444 2013 145 6505 5412606405 16355 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * user.c -- AtFS toolkit library * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: user.c[7.0] Fri Jun 25 16:38:54 1993 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "atfstk.h" /*======= * user *=======*/ EXPORT int atUserValid (user) Af_user *user; { if (!user) return (FALSE);; return (user->af_username[0]); } EXPORT void atScanUser (userName, resultUser) char *userName; Af_user *resultUser; { char fullName[USER_MAX+HOST_MAX+DOMAIN_MAX+2]; char *hostPtr, *domainPtr; resultUser->af_username[0] = resultUser->af_username[USER_MAX-1] = '\0'; resultUser->af_userhost[0] = resultUser->af_userhost[HOST_MAX-1] = '\0'; resultUser->af_userdomain[0] = resultUser->af_userdomain[DOMAIN_MAX-1] = '\0'; if (!(userName && userName[0])) return; strcpy (fullName, userName); /* no host and no domain name */ if ((hostPtr = strrchr (fullName, '@')) == NULL) { strncpy (resultUser->af_username, fullName, USER_MAX); strcpy (resultUser->af_userdomain, af_getdomain()); return; } *(hostPtr++) = '\0'; strncpy (resultUser->af_username, fullName, USER_MAX); /* only domain name */ if (!strcmp (hostPtr, af_getdomain())) { strncpy (resultUser->af_userdomain, hostPtr, DOMAIN_MAX); return; } /* only host name */ if ((domainPtr = strchr (hostPtr, '.')) == NULL) { strncpy (resultUser->af_userhost, hostPtr, HOST_MAX); strcpy (resultUser->af_userdomain, af_getdomain()); return; } /* host and domain */ if (!strcmp (domainPtr+1, af_getdomain())) { *(domainPtr++) = '\0'; strncpy (resultUser->af_userhost, hostPtr, HOST_MAX); strncpy (resultUser->af_userdomain, domainPtr, DOMAIN_MAX); return; } /* An user identification string with a domain name different to the * local domain is treated as user@domain (without host) */ (void) strncpy (resultUser->af_userdomain, hostPtr, DOMAIN_MAX); } EXPORT char *atUserName (user) Af_user *user; { static char result[USER_MAX+HOST_MAX+DOMAIN_MAX+2]; result[0] = '\0'; if (user) { if (user->af_userdomain[0]) sprintf (result, "%s@%s", user->af_username, user->af_userdomain); else if (user->af_userhost[0]) sprintf (result, "%s@%s", user->af_username, user->af_userhost); else strcpy (result, user->af_username); } return (result); } EXPORT uid_t atUserUid (user) Af_user *user; { struct passwd *pw; if (!user) return (-1); if (!strcmp (user->af_userdomain, af_getdomain())) { pw = getpwnam (user->af_username); if (pw) return pw->pw_uid; else return (-1); } else return (-1); } shapetools-1.4pl6.orig/src/atfstk/uda.c100444 2013 145 63247 5565664175 16217 0ustar dokoswt/*$__copyright$*/ /* * AtFStk -- Attribute Filesystem Toolkit Library * * uda.c -- AtFS toolkit library * * Authors: Andreas.Lampen@cs.tu-berlin.de * Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: uda.c[7.0] Mon May 16 15:50:33 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "sttk.h" #include "atfstk.h" static char logMem[8192]; static char headerStr[PATH_MAX*2]; static char *valueXpon="xpon", *valueXpoff="xpoff", *valueNa="n/a"; /*=============================== * standard attribute names *===============================*/ EXPORT struct atAttrTab atStdAttrTab[] = { { AT_CODE_DESCRIPTION,"Description", NULL }, { AT_CODE_HEADER, "Header", NULL }, { AT_CODE_INTENT, "Intent", NULL }, { AT_CODE_LOG, "Log", NULL }, { AT_CODE_ALIAS, "alias", NULL }, { AT_CODE_ATIME, "atime", AF_ATTATIME }, { AT_CODE_AUTHOR, "author", AF_ATTAUTHOR }, { AT_CODE_CACHEKEY, "cachekey", NULL }, { AT_CODE_CLEAD, "clead", NULL }, { AT_CODE_CTIME, "ctime", AF_ATTCTIME }, { AT_CODE_DSIZE, "dsize", AF_ATTDSIZE }, { AT_CODE_GENERATION, "generation", AF_ATTGEN }, { AT_CODE_HOST, "host", AF_ATTHOST }, { AT_CODE_LOCK, "lock", AF_ATTLOCKER }, { AT_CODE_LOCK, "locker", AF_ATTLOCKER }, { AT_CODE_LTIME, "ltime", AF_ATTLTIME }, { AT_CODE_MODE, "mode", AF_ATTMODE }, { AT_CODE_MTIME, "mtime", AF_ATTMTIME }, { AT_CODE_NAME, "name", AF_ATTNAME }, { AT_CODE_NOTE, "note", NULL }, { AT_CODE_OWNER, "owner", AF_ATTOWNER }, { AT_CODE_PRED, "pred", NULL }, { AT_CODE_REVISION, "revision", AF_ATTREV }, { AT_CODE_RTIME, "rtime", NULL }, { AT_CODE_SELF, "self", AF_ATTBOUND }, { AT_CODE_SELFPATH, "selfpath", AF_ATTBOUNDPATH }, { AT_CODE_SIZE, "size", AF_ATTSIZE }, { AT_CODE_STATE, "state", AF_ATTSTATE }, { AT_CODE_STATE, "status", AF_ATTSTATE }, { AT_CODE_STIME, "stime", AF_ATTSTIME }, { AT_CODE_SUCC, "succ", NULL }, { AT_CODE_SYSPATH, "syspath", AF_ATTSPATH }, { AT_CODE_TYPE, "type", AF_ATTTYPE }, { AT_CODE_UNIXNAME, "unixname", AF_ATTUNIXNAME }, { AT_CODE_UNIXPATH, "unixpath", AF_ATTUNIXPATH }, { AT_CODE_VERSION, "version", AF_ATTVERSION }, { AT_CODE_VTIME, "vtime", NULL }, { AT_CODE_XPOFF, "xpoff", NULL }, { AT_CODE_XPON, "xpon", NULL }, { -1, NULL, NULL } }; LOCAL int prevExpand = TRUE; LOCAL char *logAttr (aso) Af_key *aso; { Af_attrs attrBuf; Af_set versionSet; Af_key tmpAso; int curGen, curRev, tmpGen, versionCount, i; char *valPtr, *notePtr, *tmpPtr, commentLeader[32]; int headerPrinted = FALSE, noNewline; char *logPtr; af_initattrs (&attrBuf); strcpy (attrBuf.af_syspath, af_retattr (aso, AF_ATTSPATH)); strcpy (attrBuf.af_name, af_retattr (aso, AF_ATTNAME)); strcpy (attrBuf.af_type, af_retattr (aso, AF_ATTTYPE)); af_find (&attrBuf, &versionSet); af_sortset (&versionSet, AF_ATTVERSION); curGen = af_retnumattr (aso, AF_ATTGEN); curRev = af_retnumattr (aso, AF_ATTREV); versionCount = af_nrofkeys (&versionSet); /* determine comment leader sym to prepend it to loglines */ if ((valPtr = af_retattr (aso, AT_ATTCLEAD))) { strcpy (commentLeader, valPtr); free (valPtr); } else commentLeader[0] = '\0'; /* ToDo: allocate memory for version log */ logPtr = logMem; /* write log for each version up to current */ for (i = 0 ; i < versionCount; i++) { af_setgkey (&versionSet, i, &tmpAso); if (af_retnumattr (&tmpAso, AF_ATTSTATE) == AF_BUSY) continue; /* don't consider busy version */ if (curGen != AF_BUSYVERS) { if ((tmpGen = af_retnumattr (&tmpAso, AF_ATTGEN)) > curGen) break; if ((tmpGen == curGen) && (af_retnumattr (&tmpAso, AF_ATTREV) > curRev)) break; } if (!headerPrinted) { strcpy (logPtr, commentLeader); logPtr += strlen (logPtr); strcpy (logPtr, "Log for "); logPtr += strlen (logPtr); strcpy (logPtr, af_retattr (aso, AF_ATTBOUNDPATH)); logPtr += strlen (logPtr); *logPtr++ = ':'; headerPrinted = TRUE; } else { /* precede log by version header */ strcpy (logPtr, commentLeader); logPtr += strlen (logPtr); *logPtr++ = '['; strcpy (logPtr, af_retattr (&tmpAso, AF_ATTVERSION)); logPtr += strlen (logPtr); *logPtr++ = ']'; *logPtr++ = ' '; strcpy (logPtr, af_retattr (&tmpAso, AF_ATTSTIME)); logPtr += strlen (logPtr); *logPtr++ = ' '; strcpy (logPtr, af_retattr (&tmpAso, AF_ATTAUTHOR)); logPtr += strlen (logPtr); *logPtr++ = ' '; strcpy (logPtr, af_retattr (&tmpAso, AF_ATTSTATE)); logPtr += strlen (logPtr); } *logPtr++ = '\n'; valPtr = af_rnote (&tmpAso); if (valPtr && !strcmp (valPtr, AT_EMPTYLOG)) notePtr = ""; else notePtr = valPtr; /* break log text into separate strings */ noNewline = FALSE; while (notePtr) { tmpPtr = notePtr; while (*tmpPtr && (*tmpPtr != '\n')) tmpPtr++; strcpy (logPtr, commentLeader); logPtr += strlen (logPtr); *logPtr++ = ' '; *logPtr++ = ' '; if (*tmpPtr == '\n') { if (tmpPtr[1]) { *tmpPtr++ = '\0'; /* make it end of an ordinary string */ } else { /* this is the case when the last comment line ends with a newline character. Do not add extra newline then. */ tmpPtr = NULL; /* we're ready */ noNewline = TRUE; } } else { tmpPtr = NULL; /* we're ready */ } strcpy (logPtr, notePtr); logPtr += strlen (logPtr); if (!noNewline) *logPtr++ = '\n'; notePtr = tmpPtr; } if (valPtr) free (valPtr); } /* chop off very last newline character */ if (logPtr > logMem) *(logPtr-1) = '\0'; af_dropset (&versionSet); return (logMem); } LOCAL char *retStdAttr (aso, attrName) Af_key *aso; char *attrName; { register int i; char *attrVal; Af_key tmpAso; for (i = 0; atStdAttrTab[i].name; i++) { if (!(strcmp (attrName, atStdAttrTab[i].name))) break; } switch (atStdAttrTab[i].code) { case AT_CODE_ATIME: case AT_CODE_AUTHOR: case AT_CODE_CTIME: case AT_CODE_DSIZE: case AT_CODE_GENERATION: case AT_CODE_HOST: case AT_CODE_LOCK: case AT_CODE_LTIME: case AT_CODE_MTIME: case AT_CODE_NAME: case AT_CODE_OWNER: case AT_CODE_REVISION: case AT_CODE_SELF: case AT_CODE_SELFPATH: case AT_CODE_SIZE: case AT_CODE_STATE: case AT_CODE_STIME: case AT_CODE_SYSPATH: case AT_CODE_TYPE: case AT_CODE_UNIXNAME: case AT_CODE_UNIXPATH: case AT_CODE_VERSION: return (af_retattr (aso, atStdAttrTab[i].atfsName)); case AT_CODE_ALIAS: return (af_retattr (aso, AT_ATTALIAS)); case AT_CODE_CACHEKEY: return (af_retattr (aso, AT_ATTCACHEKEY)); case AT_CODE_CLEAD: return (af_retattr (aso, AT_ATTCLEAD)); case AT_CODE_DESCRIPTION: { /* search first version */ char tmpPath[PATH_MAX], tmpName[NAME_MAX], tmpType[TYPE_MAX], *retPtr; Af_key firstAso; strcpy (tmpPath, af_retattr (aso, AF_ATTSPATH)); strcpy (tmpName, af_retattr (aso, AF_ATTNAME)); strcpy (tmpType, af_retattr (aso, AF_ATTTYPE)); if (af_getkey (tmpPath, tmpName, tmpType, AF_FIRSTVERS, AF_FIRSTVERS, &firstAso) < 0) return (NULL); retPtr = af_rnote (&firstAso); af_dropkey (&firstAso); return (retPtr); } case AT_CODE_HEADER: { strcpy (headerStr, "$Header: "); strcat (headerStr, af_retattr (aso, AF_ATTBOUND)); strcat (headerStr, " "); if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) strcat (headerStr, af_retattr (aso, AF_ATTMTIME)); else strcat (headerStr, af_retattr (aso, AF_ATTSTIME)); strcat (headerStr, " "); strcat (headerStr, af_retattr (aso, AF_ATTAUTHOR)); strcat (headerStr, " "); strcat (headerStr, af_retattr (aso, AF_ATTSTATE)); strcat (headerStr, " $"); return (headerStr); } case AT_CODE_INTENT: return (af_retattr (aso, AT_ATTINTENT)); case AT_CODE_LOG: return (logAttr (aso)); case AT_CODE_MODE: return (atWriteMode (aso)); case AT_CODE_NOTE: return (af_rnote (aso)); case AT_CODE_PRED: switch (af_predsucc (aso, AF_PHYSICAL_PRED, &tmpAso)) { case -1: return (NULL); case 0: return (valueNa); default: attrVal = af_retattr (&tmpAso, AF_ATTBOUND); af_dropkey (&tmpAso); return (attrVal); } case AT_CODE_RTIME: return (af_retattr (aso, atStdAttrTab[i].name)); case AT_CODE_SUCC: switch (af_predsucc (aso, AF_PHYSICAL_SUCC, &tmpAso)) { case -1: return (NULL); case 0: return (valueNa); default: attrVal = af_retattr (&tmpAso, AF_ATTBOUND); af_dropkey (&tmpAso); return (attrVal); } case AT_CODE_VTIME: if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) return (af_retattr (aso, AF_ATTMTIME)); return (af_retattr (aso, AF_ATTSTIME)); case AT_CODE_XPON: atExpand = prevExpand; return (valueXpon); case AT_CODE_XPOFF: prevExpand = atExpand; atExpand = FALSE; return (valueXpoff); } return (NULL); } LOCAL int setStdAttr (aso, setMode, attrName, attrValue) Af_key *aso; int setMode; char *attrName, *attrValue; { register int i; Af_user user; int mode, state, gen, rev; time_t date; char *strPtr; for (i = 0; atStdAttrTab[i].name; i++) { if (!(strcmp (attrName, atStdAttrTab[i].name))) break; if (atStdAttrTab[i].atfsName && !(strcmp (attrName, atStdAttrTab[i].atfsName))) break; } switch (atStdAttrTab[i].code) { case AT_CODE_ATIME: case AT_CODE_CACHEKEY: case AT_CODE_CTIME: case AT_CODE_DESCRIPTION: case AT_CODE_DSIZE: case AT_CODE_HEADER: case AT_CODE_HOST: case AT_CODE_INTENT: case AT_CODE_LOCK: case AT_CODE_LOG: case AT_CODE_LTIME: case AT_CODE_MTIME: case AT_CODE_NAME: case AT_CODE_PRED: case AT_CODE_RTIME: case AT_CODE_SELF: case AT_CODE_SELFPATH: case AT_CODE_SIZE: case AT_CODE_STIME: case AT_CODE_SUCC: case AT_CODE_SYSPATH: case AT_CODE_TYPE: case AT_CODE_UNIXNAME: case AT_CODE_UNIXPATH: case AT_CODE_VTIME: case AT_CODE_XPOFF: case AT_CODE_XPON: atError (AT_WARNING, "cannot set attribute with reserved name (no effect)"); return (0); case AT_CODE_ALIAS: switch (setMode) { case AF_REMOVE: if (atDelVersAlias (aso, attrValue)) return (1); default: if (atSetVersAlias (aso, attrValue)) return (1); } return (0); case AT_CODE_AUTHOR: atScanUser (attrValue, &user); if (af_chauthor (aso, &user) == -1) { atError (AT_WARNING, af_errmsg ("chauthor")); return (0); } return (1); case AT_CODE_CLEAD: { char tmpAttr[AT_CLEADMAXLEN+32]; strcpy (tmpAttr, AT_ATTCLEAD); strcat (tmpAttr, "="); strncat (tmpAttr, attrValue, AT_CLEADMAXLEN); tmpAttr[AT_CLEADMAXLEN+31] = '\0'; if (af_setattr (aso, setMode, tmpAttr) == -1) { atError (AT_WARNING, af_errmsg ("setattr")); return (0); } return (1); } case AT_CODE_GENERATION: gen = atoi (attrValue); rev = af_retnumattr (aso, AF_ATTREV); if (af_svnum (aso, gen, rev) == -1) { atError (AT_WARNING, af_errmsg ("svnum")); return (0); } return (1); case AT_CODE_MODE: mode = atoi (attrValue); if (af_chmod (aso, mode) == -1) { atError (AT_WARNING, af_errmsg ("chmod")); return (0); } return (1); case AT_CODE_OWNER: atScanUser (attrValue, &user); if (af_chowner (aso, &user) == -1) { atError (AT_WARNING, af_errmsg ("chowner")); return (0); } return (1); case AT_CODE_REVISION: gen = af_retnumattr (aso, AF_ATTGEN); rev = atoi (attrValue); if (af_svnum (aso, gen, rev) == -1) { atError (AT_WARNING, af_errmsg ("svnum")); return (0); } return (1); case AT_CODE_VERSION: if (atScanBinding (attrValue, &strPtr, &gen, &rev, &date) != AT_BIND_VNUM) { atError (AT_WARNING, "cannot decipher version number"); return (0); } if (af_svnum (aso, gen, rev) == -1) { atError (AT_WARNING, af_errmsg ("svnum")); return (0); } return (1); case AT_CODE_STATE: state = atScanStatus (attrValue); if (af_sstate (aso, state) == -1) { atError (AT_WARNING, af_errmsg ("sstate")); return (0); } return (1); case AT_CODE_NOTE: if (af_snote (aso, attrValue) == -1) { atError (AT_WARNING, af_errmsg ("snote")); return (0); } return (1); } return (-1); } /*================================= * return user defined attribute *=================================*/ static int recursionDepth = 0; EXPORT char *atRetAttr (aso, attr) Af_key *aso; char *attr; { char *attrValue, *attrName, attrMem[AT_MAXATTRSIZE]; int attrSize; if (recursionDepth >= 10) { atError (AT_ERROR, "infinite citation loop"); return (NULL); } if ((attr == NULL) || (attr[0] == '\0')) { atError (AT_ERROR, "no attribute name given"); return (NULL); } attrName = atAttrName (attr); if ((attrValue = retStdAttr (aso, attrName)) == NULL) if ((attrValue = af_retattr (aso, attrName)) == NULL) return (NULL); /* If attribute is a standard attribute, don't try to expand */ if (af_isstdval (attrValue)) return (attrValue); /* ToDo: there should be no limit for attribute length */ attrMem[0] = '\0'; recursionDepth++; if ((attrSize = atExpandAttrs (aso, attrValue, strlen(attrValue), attrMem, AT_MAXATTRSIZE, AT_EXPAND_STRING)) == -1) { recursionDepth--; atError (AT_ERROR, "attribute expansion too long"); return (NULL); } recursionDepth--; atFreeAttr (attrValue); if ((attrValue = malloc (attrSize+1)) == NULL) { atError (AT_ERROR, "not enough memory"); return (NULL); } strcpy (attrValue, attrMem); /* file reference attribute */ if (attrValue[0] == '^') { char *aFileContents, *tmpFileName; FILE *aFile, *tmpFile; Af_key *aFileKey; size_t aFileSize; /* ToDo: handle multiple values */ if (!(aFileKey = atBindVersion (attrValue+1, "[]"))) return (attrValue); /* or return (NULL); ??? */ if ((aFile = af_open (aFileKey, "r")) == NULL) { af_dropkey (aFileKey); return (attrValue); /* or return (NULL); ??? */ } aFileSize = af_retnumattr (aFileKey, AF_ATTSIZE); if ((aFileContents = malloc (aFileSize+1)) == NULL) { af_close (aFile); af_dropkey (aFileKey); return (NULL); } fread (aFileContents, sizeof (char), aFileSize, aFile); af_close (aFile); aFileContents[aFileSize] = '\0'; tmpFileName = stTmpFile(NULL); if ((tmpFile = fopen (tmpFileName, "w")) == NULL) { free (aFileContents); af_dropkey (aFileKey); atError (AT_ERROR, "cannot open temporary file"); return (NULL); } recursionDepth++; attrSize = atExpandAttrs (aFileKey, aFileContents, aFileSize, tmpFile, 0, AT_EXPAND_FILE); recursionDepth--; fclose (tmpFile); af_dropkey (aFileKey); free (aFileContents); if ((attrValue = realloc (attrValue, attrSize+1)) == NULL) { fclose (tmpFile); atError (AT_ERROR, "not enough memory"); return (NULL); } tmpFile = fopen (tmpFileName, "r"); fread (attrValue, sizeof (char), attrSize, tmpFile); attrValue[attrSize] = '\0'; fclose (tmpFile); unlink (tmpFileName); stUnRegisterFile (tmpFileName); } /* execution attribute */ if (attrValue[0] == '!') { #define BUFLEN 1024 FILE *cPipe; char *cResultBuf, *cResultPtr; int cByteCount; size_t cBufSize; /* ToDo: handle multiple values */ if ((cPipe = popen (attrValue+1, "r")) == (FILE *)NULL) return (attrValue); /* or return (NULL); ??? */ cBufSize = BUFLEN; if ((cResultBuf = malloc (cBufSize)) == NULL) { atError (AT_ERROR, "not enough memory"); pclose (cPipe); return (NULL); } cResultPtr = cResultBuf; while (1) { cByteCount = fread (cResultPtr, sizeof (char), BUFLEN, cPipe); if (cByteCount != BUFLEN) { cBufSize = (cBufSize - BUFLEN) + cByteCount; break; } cBufSize += BUFLEN; if ((cResultBuf = realloc (cResultBuf, cBufSize)) == NULL) { atError (AT_ERROR, "not enough memory"); pclose (cPipe); return (NULL); } cResultPtr += BUFLEN; } pclose (cPipe); /* ToDo: there should be no limit for attribute length */ attrMem[0] = '\0'; recursionDepth++; if ((attrSize = atExpandAttrs (aso, cResultBuf, cBufSize, attrMem, AT_MAXATTRSIZE, AT_EXPAND_STRING)) == -1) { recursionDepth--; atError (AT_ERROR, "attribute expansion too long"); return (NULL); } recursionDepth--; atFreeAttr (attrValue); if ((attrValue = malloc (attrSize+1)) == NULL) { atError (AT_ERROR, "not enough memory"); return (NULL); } strcpy (attrValue, attrMem); } /* ASO reference attribute */ if (attrValue[0] == '*') { /* ToDo: there should be no limit for attribute length (attrMem) */ char *curVal = &attrValue[1], *nextVal, *resultPtr = attrMem; /* handle multiple values */ nextVal = strchr (curVal, '\n'); while (nextVal) { *nextVal = '\0'; strcpy (resultPtr, atLocalPath (curVal)); resultPtr = strchr (resultPtr, '\0'); *resultPtr = '\n'; resultPtr++; curVal = nextVal+1; if (*curVal == '*') curVal++; else atError (AT_WARNING, "unrecognized value in pointer attribute"); nextVal = strchr (curVal, '\n'); } strcpy (resultPtr, atLocalPath (curVal)); atFreeAttr (attrValue); if ((attrValue = malloc (strlen (attrMem+1))) == NULL) { atError (AT_ERROR, "not enough memory"); return (NULL); } strcpy (attrValue, attrMem); } return (attrValue); } /*============================== * set user defined attribute *==============================*/ EXPORT int atSetAttr (aso, attr, mode) Af_key *aso; char *attr; int mode; { char attrFileName[PATH_MAX], msgBuf[PATH_MAX+64]; char *attrMem, *attrName, *valPtr, *valId = ""; unsigned int attrMemLen = 0; int attrNameLen, retCode; FILE *attrFile; if ((attr == NULL) || (attr[0] == '\0')) { atError (AT_ERROR, "no attribute given"); return (FALSE); } attrFileName[0] = '\0'; attrFileName[PATH_MAX-1] = '\0'; if ((valPtr = strchr (attr, AF_UDANAMDEL)) == NULL) { /* no value */ /* cut off + or - at the end of the name */ attrNameLen = strlen (attr); if ((attr[attrNameLen-1] == '+') || (attr[attrNameLen-1] == '-')) attr[attrNameLen-1] = '\0'; if (strlen (attr) > AF_UDANAMLEN) { atError (AT_ERROR, "attribute name too long"); return (FALSE); } if ((retCode = setStdAttr (aso, mode, attr, NULL)) == 0) return (FALSE); else if (retCode == -1) if (af_setattr (aso, mode, attr) == -1) { atError (AT_ERROR, af_errmsg ("atSetAttr")); return (FALSE); } return (TRUE); } if (attr == valPtr) { /* No attribute name */ atError (AT_ERROR, "no attribute name given"); return (FALSE); } if ((valPtr-attr) > AF_UDANAMLEN) { atError (AT_ERROR, "attribute name too long"); return (FALSE); } attrName = atAttrName (attr); if (*(valPtr-1) == '+') { mode = AF_ADD; attrMemLen = strlen (attr); } if (*(valPtr-1) == '-') { /* * mode = AF_REMOVE; * attrMemLen = strlen (attr); */ atError (AT_ERROR, "Cannot delete single value from attribute (yet)"); return (FALSE); } valPtr++; if (*valPtr != '@') { /* take attribute value literally */ int i; for (i=0; valPtr[i]; i++) { if (valPtr[i] == 1) { /* Ctl-A not allowed */ atError (AT_ERROR, "invalid attribute value (contains Ctl-A character)"); return (FALSE); } } if (*valPtr == '*') { /* ASO reference attribute */ Af_key *destAso; /* perform version binding */ if ((destAso = atBindVersion (valPtr+1, "[]")) == NULL) { atError (AT_ERROR, "invalid reference attribute value (cannot be uniquely bound)"); return (FALSE); } valPtr = atNetworkPath (destAso); valId = "*"; attrMemLen = PATH_MAX+HOST_MAX+AF_UDANAMLEN+16; } if (attrMemLen) { /* copy attribute and eliminate + and - char */ if ((attrMem = malloc (attrMemLen)) == NULL) { atError (AT_ERROR, "not enough memory"); return (FALSE); } sprintf (attrMem, "%s%c%s%s", attrName, AF_UDANAMDEL, valId, valPtr); } else attrMem = attr; if ((retCode = setStdAttr (aso, mode, attrName, valPtr)) == 0) return (FALSE); else if (retCode == -1) if (af_setattr (aso, mode, attrMem) == -1) { if (attrMem != attr) free (attrMem); atError (AT_ERROR, af_errmsg ("atSetAttr")); return (FALSE); } if (attrMem != attr) free (attrMem); return (TRUE); } /* take attribute value from file */ strncpy (attrFileName, valPtr+1, PATH_MAX-1); if (strcmp (attrFileName, "-")) { /* read from a regular file */ struct stat attrIbuf; if ((attrFile = fopen (attrFileName, "r")) == NULL) { sprintf (msgBuf, "Can't open attribute value file %s.", attrFileName); atError (AT_ERROR, msgBuf); return (FALSE); } if (fstat (fileno (attrFile), &attrIbuf) < 0) { sprintf (msgBuf, "Can't open attribute value file %s.", attrFileName); atError (AT_ERROR, msgBuf); return (FALSE); } attrMemLen = strlen (attrName) + attrIbuf.st_size + 2; if ((attrMem = malloc (attrMemLen)) == NULL) { atError (AT_ERROR, "not enough memory"); return (FALSE); } sprintf (attrMem, "%s%d", attrName, AF_UDANAMDEL); fread (&attrMem[strlen(attrName)+1], sizeof (char), (size_t)attrIbuf.st_size, attrFile); fclose (attrFile); attrMem[attrMemLen-1] = '\0'; } else { /* read from standard input */ char *memPtr; int charNum; attrMemLen = AT_MAXATTRSIZE; if ((attrMem = malloc (attrMemLen)) == NULL) { atError (AT_ERROR, "not enough memory"); return (FALSE); } sprintf (attrMem, "%s%d", attrName, AF_UDANAMDEL); memPtr = &attrMem[strlen(attrName)+1]; charNum = fread (memPtr, sizeof (char), (size_t)(attrMemLen-2)-strlen(attrName), stdin); memPtr[charNum] = '\0'; } if ((retCode = setStdAttr (aso, mode, attrName, &attrMem[strlen(attrName)+1])) == 0) { free (attrMem); return (FALSE); } else if (retCode == -1) if (af_setattr (aso, mode, attrMem) == -1) { free (attrMem); atError (AT_ERROR, af_errmsg ("atSetAttr")); return (FALSE); } free (attrMem); return (TRUE); } /*================================================== * read user defined attributes from file and set *==================================================*/ EXPORT int atSetAttrFile (aso, fileName) Af_key *aso; char *fileName; { FILE *attrFile; struct stat iBuf; char msgBuf[PATH_MAX+64], *attrBuf, *attrPtr; int i, retCode = TRUE; if ((attrFile = fopen (fileName, "r")) == NULL) { sprintf (msgBuf, "Cannot open attribute file %s.", fileName); atError (AT_ERROR, msgBuf); return (FALSE); } if (fstat (fileno (attrFile), &iBuf) < 0) { sprintf (msgBuf, "Couldn't stat attribute file %s.", fileName); atError (AT_ERROR, msgBuf); return (FALSE); } if ((attrBuf = malloc ((unsigned)iBuf.st_size+1)) == NULL) { atError (AT_ERROR, "Not enough memory for attribute file."); return (FALSE); } fread (attrBuf, sizeof (char), (size_t)iBuf.st_size, attrFile); attrBuf[iBuf.st_size] = '\0'; attrPtr = attrBuf; for (i=0; i < iBuf.st_size; i++) { if (attrBuf[i] == '\n') { attrBuf[i] = '\0'; retCode = atSetAttr (aso, attrPtr, AF_REPLACE); attrPtr = &attrBuf[i+1]; } } /* When the last line of the file has no newline, one attribute remains */ if (*attrPtr) retCode = atSetAttr (aso, attrPtr, AF_REPLACE); free (attrBuf); return (retCode); } /*================================= * return attr name and value *=================================*/ EXPORT char *atAttrName (attr) char *attr; { static char attrName[AF_UDANAMLEN]; char *origPtr = attr, *newPtr = attrName; while (*origPtr && (*origPtr != AF_UDANAMDEL) && (*origPtr != '+') && (newPtr < &attrName[AF_UDANAMLEN])) { *newPtr++ = *origPtr++; if (newPtr == &attrName[AF_UDANAMLEN-1]) break; } *newPtr = '\0'; return (attrName); } EXPORT char *atAttrValue (attr) char *attr; { char *valPtr = attr; while (*valPtr) { if (*valPtr == AF_UDANAMDEL) { valPtr++; if (*valPtr) return (valPtr); else return (NULL); } valPtr++; } return (NULL); } /*================================= * other stuff *=================================*/ EXPORT int atMatchAttr (aso, attr) Af_key *aso; char *attr; /* check if 'aso' has the given 'attr'. Result values are TRUE or FALSE. If just an attribute name is given, we return a positive result if the attribute exists or, in the case that it is a standard attribute, if it's value is non null. A full attribute (name and value) must match (value may be a pattern). */ { char *asoAttr, *valuePattern, *cp; /* attribute not found */ if ((asoAttr = atRetAttr (aso, attr)) == NULL) return (FALSE); /* standard attribute with empty value */ if (af_isstdval (asoAttr) && !*asoAttr) return (FALSE); valuePattern = stConvertPattern (atAttrValue (attr)); /* no value given and attribute exists */ if (!*valuePattern) { atFreeAttr (asoAttr); return (TRUE); } if ((cp = re_comp (valuePattern))) { atError (AT_ERROR, cp); atFreeAttr (asoAttr); return (FALSE); } /* ToDo: check each single value */ if (re_exec (asoAttr)) { atFreeAttr (asoAttr); return (TRUE); } atFreeAttr (asoAttr); return (FALSE); } EXPORT void atFreeAttr (attr) char *attr; { if ((attr != logMem) && (attr != headerStr) && (attr != valueXpon) && (attr != valueXpoff) && (attr != valueNa)) af_freeattr (attr); } shapetools-1.4pl6.orig/src/atfstk/citeattr.c100444 2013 145 10712 5425766220 17237 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * citeattr.c -- AtFS toolkit library * * Authors: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: citeattr.c[7.0] Fri Jul 30 16:08:03 1993 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "bind.h" #include "atfstk.h" EXPORT int atExpand = TRUE; LOCAL int reallyExpand = TRUE; /*======================= * atExpandAttrs *=======================*/ EXPORT int atExpandAttrs (aso, buf, bufSize, dest, destSize, mode) Af_key *aso; char *buf; size_t bufSize; void *dest; size_t destSize; int mode; { /* * atExpandAttrs scans the char buffer 'buf' to the extent of bufSize * for strings of the form '$__attribute_name'. If such a string * is found, the buffer contents up to the character preceding the * first '$' will be sent to the destination output 'dest'. * If an attribute with name 'atttribute_name' is set for the current * attribute file, the citation-string will be substituted by the value * of that attribute. Output of 'buf' contents resumes with the first * character after the blank delimiting the 'attribute_name'. */ int i=0, citeNamePos=0, stringEnd, appendDollar = FALSE; size_t outSize = 0; char attrName[AF_UDANAMLEN]; char *startPtr, *curPtr, *attrValue; if (mode == AT_EXPAND_FILE) destSize = INT_MAX; startPtr = curPtr = buf; while (i < (int)(bufSize-3)) { if (buf[i++] != '$') continue; if ((buf[i] != '_') || (buf[i+1] != '_')) continue; i += 2; if (strchr (" \n\t$", buf[i])) continue; curPtr = &(buf[i-3]); citeNamePos = 0; while ((i < bufSize) && (!strchr (" \n\t$", buf[i]))) attrName[citeNamePos++] = buf[i++]; /* buf[i] is the first char after attribute name */ if ((i < bufSize) && (buf[i] == '$')) { appendDollar = TRUE; i++; } else appendDollar = FALSE; attrName[citeNamePos] = '\0'; /* write out everything up to beginning of cite_mark */ if ((outSize += curPtr - startPtr) >= destSize) return (-1); if (mode == AT_EXPAND_FILE) fwrite (startPtr, sizeof (char), curPtr - startPtr, (FILE *)dest); else { stringEnd = strlen ((char *)dest); strncat ((char *)dest, startPtr, curPtr - startPtr); if (curPtr - startPtr) ((char *)dest)[stringEnd+(curPtr-startPtr)] = '\0'; } startPtr = curPtr = &(buf[i]); /* check for (atExpand && reallyExpand) and do attribute expansion only * if both are true. This causes *both* expansion switches (xpon and xpoff) * *not* to be expanded. */ if (((attrValue = atRetAttr (aso, attrName)) == NULL) || !(atExpand && reallyExpand)) { outSize += strlen(attrName)+3; if (appendDollar) outSize++; if (outSize >= destSize) return (-1); if (mode == AT_EXPAND_FILE) { fputs ("$__", (FILE *)dest); fputs (attrName, (FILE *)dest); if (appendDollar) fputs ("$", (FILE *)dest); } else { strcat ((char *)dest, "$__"); strcat ((char *)dest, attrName); if (appendDollar) strcat ((char *)dest, "$"); } } else { if ((outSize += strlen(attrValue)) >= destSize) return (-1); if (mode == AT_EXPAND_FILE) fputs (attrValue, (FILE *)dest); else strcat ((char *)dest, attrValue); } reallyExpand = atExpand; } /* write remaining chars */ if ((outSize += &buf[bufSize] - startPtr) >= destSize) return (-1); if (mode == AT_EXPAND_FILE) fwrite (startPtr, sizeof (char), &buf[bufSize] - startPtr, (FILE *)dest); else { stringEnd = strlen ((char *)dest); strncat ((char *)dest, startPtr, &buf[bufSize] - startPtr); if (&buf[bufSize] - startPtr) ((char *)dest)[stringEnd + (&buf[bufSize] - startPtr)] = '\0'; } return (outSize); } shapetools-1.4pl6.orig/src/atfstk/lock.c100444 2013 145 17356 5412606221 16351 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * lock.c -- AtFS toolkit library * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: lock.c[7.0] Fri Jun 25 16:38:59 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "sttk.h" #include "atfstk.h" LOCAL char *getText (msgText, msg) char *msgText, *msg; { static char *txt = AT_EMPTYLOG; FILE *txtFile; struct stat statbuf; static int firsttime = TRUE; if (firsttime) { firsttime = FALSE; if (!msgText || !*msgText) { sprintf (stMessage, "empty %s.", msg); stLog (stMessage, ST_LOG_WARNING); return (txt); } if (*msgText == '@') { /* filename */ if ((txtFile = fopen (&msgText[1], "r")) == NULL) { sprintf (stMessage, "cannot open '%s' -- empty %s.", &msgText[1], msg); stLog (stMessage, ST_LOG_WARNING); return (txt); } if (fstat (fileno(txtFile), &statbuf) == -1) { sprintf (stMessage, "cannot stat '%s' -- empty %s.", &msgText[1], msg); stLog (stMessage, ST_LOG_WARNING); return (txt); } if ((txt = malloc ((unsigned)(statbuf.st_size+1))) == NULL) { sprintf (stMessage, "not enough memory for %s.", msg); stLog (stMessage, ST_LOG_WARNING); return (txt); } memset (txt, 0, (int) statbuf.st_size+1); fread (txt, sizeof (char), (size_t)statbuf.st_size, txtFile); fclose (txtFile); } else { /* plain message text */ txt = msgText; } } return (txt); } LOCAL int setLogAttribute (aso, attrName, prologue, attrText) Af_key *aso; char *attrName, *prologue, *attrText; { char *completeAttr; if ((completeAttr = malloc ((unsigned)(strlen (attrName) + strlen (prologue) + strlen (attrText) + 2))) == NULL) { atError (AT_ERROR, "not enough memory"); return (FALSE); } if (!strcmp (attrName, AT_ATTINTENT)) { sprintf (completeAttr, "%s=%s%s", attrName, prologue, attrText); if (af_setattr (aso, AF_REPLACE, completeAttr) == -1) { free (completeAttr); atError (AT_ERROR, af_errmsg ("af_setattr")); return (FALSE); } } else { sprintf (completeAttr, "%s%s", prologue, attrText); if (af_snote (aso, completeAttr) == -1) { free (completeAttr); atError (AT_ERROR, af_errmsg ("af_snote")); return (FALSE); } } free (completeAttr); return (TRUE); } static char *commentText = NULL; static char *oldText = NULL; EXPORT int atSetComment (aso, commentType, newText, mode) Af_key *aso; int commentType; char *newText; int mode; /* mode = AT_FROMSTDIN -- read text from standard input * AT_REUSE -- reuse old text * AT_CONFIRM -- ask for confirmation */ { char *tmpName, *edName; char prologue[64], *timeStr = af_asctime(), *ptr; char *commentAttrName, *commentEmptyText, *commentLogText; FILE *tmpFile; if ((ptr = strrchr (timeStr, '\n'))) *ptr = '\0'; switch (commentType) { case AT_COMMENT_INTENT: commentAttrName = AT_ATTINTENT; sprintf (prologue, "[%s]%s", timeStr, AT_STARTINTENT); commentEmptyText = AT_EMPTYINTENT; commentLogText = "change intent"; break; case AT_COMMENT_DESCR: commentAttrName = AT_ATTDESCR; sprintf (prologue, "[%s]%s", timeStr, AT_STARTDESCR); commentEmptyText = AT_EMPTYDESCR; commentLogText = "description"; break; case AT_COMMENT_LOG: commentAttrName = AT_ATTLOG; sprintf (prologue, "[%s]%s", timeStr, AT_STARTLOG); commentEmptyText = AT_EMPTYLOG; commentLogText = "change log"; break; } if (!(mode & AT_REUSE)) { if (commentText) free (commentText); commentText = NULL; } if (newText && *newText) { if (commentText) free (commentText); commentText = getText (newText, commentLogText); return (setLogAttribute (aso, commentAttrName, prologue, commentText)); } if (oldText) free(oldText); if (commentType == AT_COMMENT_INTENT) oldText = af_retattr (aso, commentAttrName); else oldText = af_rnote (aso); if (mode & AT_FROMSTDIN) { if (feof(stdin)) { if (commentText) return (setLogAttribute (aso, commentAttrName, prologue, commentText)); else return (setLogAttribute (aso, commentAttrName, prologue, oldText ? oldText : commentEmptyText)); } else { if (commentText) free (commentText); commentText = stGetFromStdin ('.'); return (setLogAttribute (aso, commentAttrName, prologue, commentText[0] ? commentText : (oldText ? oldText : commentEmptyText))); } } if (!(isatty (fileno(stdin)))) return (setLogAttribute (aso, commentAttrName, prologue, oldText ? oldText : commentEmptyText)); if (commentText) { sprintf (stMessage, "Same %s as before for %s ?", commentLogText, af_retattr (aso, AF_ATTUNIXNAME)); if (stAskConfirm (stMessage, "yes")) { return (setLogAttribute (aso, commentAttrName, prologue, commentText)); } else { free (commentText); commentText = NULL; } } if (mode & AT_CONFIRM) { sprintf (stMessage, "Write %s for %s ?", commentLogText, af_retattr (aso, AF_ATTUNIXNAME)); if (!stAskConfirm (stMessage, "yes")) return (setLogAttribute (aso, commentAttrName, prologue, oldText ? oldText : commentEmptyText)); } tmpName = stTmpFile (NULL); tmpFile = fopen (tmpName, "w"); fwrite (prologue, sizeof (char), (size_t)strlen (prologue), tmpFile); if (oldText) fwrite (oldText, sizeof (char), (size_t)strlen (oldText), tmpFile); fclose (tmpFile); if (!(edName = getenv ("EDITOR"))) edName = AT_DEFAULT_EDITOR; sprintf (stMessage, "starting up %s ...", edName); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, "%s %s", edName, tmpName); if (system (stMessage) == AT_NOSHELL) { stLog ("couldn't execute shell", ST_LOG_ERROR); atError (AT_WARNING, "couldn't execute shell"); } else { if ((tmpFile = fopen (tmpName, "r")) == NULL) { sprintf (stMessage, "empty %s.", commentLogText); stLog (stMessage, ST_LOG_MSG); return (setLogAttribute (aso, commentAttrName, prologue, commentEmptyText)); } else { struct stat statbuf; if (fstat (fileno(tmpFile), &statbuf) == -1) { atError (AT_ERROR, "couldn't stat temporary file"); } else { if ((commentText = malloc ((size_t)(statbuf.st_size+1))) == NULL) if (!commentText) { atError (AT_ERROR, "not enough memory."); } fread (commentText, sizeof (char), (size_t)statbuf.st_size, tmpFile); fclose (tmpFile); unlink (tmpName); stUnRegisterFile (tmpName); commentText[statbuf.st_size] = '\0'; return (setLogAttribute (aso, commentAttrName, "", commentText)); } } } stLog ("Couldn't start editor. Please check EDITOR environment variable.", ST_LOG_ERROR); atError (AT_WARNING, "Couldn't start editor"); return (setLogAttribute (aso, commentAttrName, prologue, commentEmptyText)); } /*==================== * Locking *====================*/ EXPORT int atUnlock (aso) Af_key *aso; { Af_user *waslocker; waslocker = af_unlock (aso); if (waslocker) { af_setattr (aso, AF_REMOVE, AT_ATTINTENT); return (TRUE); } return (FALSE); } shapetools-1.4pl6.orig/src/atfstk/cache.c100444 2013 145 3015 5412606073 16434 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * cache.c -- AtFS toolkit library * * Authors: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: cache.c[7.0] Fri Jun 25 16:39:01 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "atfstk.h" EXPORT char *atCacheKey (aso) Af_key *aso; { static int serial = 1; static char keyBuf[AT_CACHEKEYLEN]; (void) sprintf (keyBuf, "%s=%ld.%d.%d", AT_ATTCACHEKEY, af_rettimeattr (aso, AF_ATTMTIME), getpid (), serial++); return (keyBuf); } EXPORT int atSaveCache (oldAso, newAso, uniqAttr, storeType) Af_key *oldAso, *newAso; char *uniqAttr; int storeType; { char *cacheKey = atCacheKey (oldAso); int retVal; af_setattr (oldAso, AF_REPLACE, cacheKey); retVal = af_savecache (oldAso, newAso, uniqAttr, storeType); return (retVal); } shapetools-1.4pl6.orig/src/atfstk/network.c100444 2013 145 12747 5412605720 17114 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * network.c -- AtFS toolkit library * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: network.c[7.0] Fri Jun 25 16:39:02 1993 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "atfstk.h" /*========================================================================= * Path juggling *=========================================================================*/ EXPORT char *atNetworkPath (aso) Af_key *aso; /* returns: network path name ":" */ { static char networkPath[PATH_MAX+HOST_MAX+AT_CACHEKEYLEN]; char *realPath, curPath[PATH_MAX], tmpPath[PATH_MAX]; FILE *mountTable; struct atMntent *mountEntry; int curStatus, curNameLen, dirNameLen = 0, isDir = FALSE; getcwd (curPath, PATH_MAX-2); curStatus = af_retnumattr (aso, AF_ATTSTATE); if ((curStatus > AF_BUSY) || (curStatus == AF_DERIVED)) { if (chdir (aso->af_ldes->af_arpath) == -1) { realPath = curPath; } else { char *dirPtr; getcwd (tmpPath, PATH_MAX-2); /* cut archive directory name if present */ if ((dirPtr = strrchr (tmpPath, '/')) && !strcmp (dirPtr+1, AF_SUBDIR)) *dirPtr = '\0'; realPath = tmpPath; } } else { /* check if aso is directory */ if (S_ISDIR ((mode_t) af_retnumattr (aso, AF_ATTMODE))) { char *typePtr; isDir = TRUE; strcpy (tmpPath, af_retattr (aso, AF_ATTSPATH)); strcat (tmpPath, "/"); strcat (tmpPath, af_retattr (aso, AF_ATTNAME)); typePtr = af_retattr (aso, AF_ATTTYPE); if (*typePtr) { strcat (tmpPath, "."); strcat (tmpPath, typePtr); } chdir (tmpPath); } else chdir (af_retattr (aso, AF_ATTSPATH)); getcwd (tmpPath, PATH_MAX-2); realPath = tmpPath; } chdir (curPath); /* go back */ if (realPath == tmpPath) { strcpy (curPath, tmpPath); realPath = curPath; } if ((mountTable = atSetmntent ("/etc/mtab", "r")) == NULL) return (NULL); while ((mountEntry = atGetmntent (mountTable))) { curNameLen = strlen (mountEntry->at_mnt_dir); if (!strncmp (mountEntry->at_mnt_dir, realPath, curNameLen)) { if (curNameLen < dirNameLen) continue; dirNameLen = curNameLen; strcpy (tmpPath, mountEntry->at_mnt_fsname); } } atEndmntent (mountTable); if (dirNameLen == 0) /* nothingFound */ return (NULL); if (strchr (tmpPath, ':')) { /* if filesystem is remote */ strcpy (networkPath, tmpPath); if (realPath[dirNameLen]) strcat (networkPath, &realPath[dirNameLen]); } else { strcpy (networkPath, af_gethostname ()); strcat (networkPath, ":"); strcat (networkPath, realPath); } if (!isDir) { strcat (networkPath, "/"); strcat (networkPath, af_retattr (aso, AF_ATTUNIXNAME)); } if (curStatus == AF_BUSY) { strcat (networkPath, "@busy"); } else if (curStatus == AF_DERIVED) { strcat (networkPath, "~"); strcat (networkPath, af_retattr (aso, AT_ATTCACHEKEY)); } else { strcat (networkPath, "@"); strcat (networkPath, af_retattr (aso, AF_ATTVERSION)); } return (networkPath); } EXPORT char *atLocalPath (networkPath) char *networkPath; { static char localPath[PATH_MAX+AT_CACHEKEYLEN]; int hostNameLen; char *strPtr, *tmpPtr; FILE *mountTable; struct atMntent *mountEntry; int curNameLen, dirNameLen = 0; if (!networkPath) return (NULL); if ((strPtr = strchr (networkPath, ':')) == NULL) return (networkPath); hostNameLen = strPtr - networkPath; if (strncmp (networkPath, af_gethostname(), hostNameLen)) { /* remote path */ if ((mountTable = atSetmntent ("/etc/mtab", "r")) == NULL) return (networkPath); while ((mountEntry = atGetmntent (mountTable))) { curNameLen = strlen (mountEntry->at_mnt_fsname); if (!strncmp (mountEntry->at_mnt_fsname, networkPath, curNameLen)) { if (curNameLen < dirNameLen) continue; dirNameLen = curNameLen; strcpy (localPath, mountEntry->at_mnt_dir); } } atEndmntent (mountTable); if (dirNameLen == 0) /* nothingFound */ return (networkPath); strcat (localPath, &networkPath[dirNameLen]); } else strcpy (localPath, strPtr+1); /* change version number representation */ if ((strPtr = strrchr (localPath, '@'))) { /* saved or busy version */ tmpPtr = strPtr+1; if (!strncmp (tmpPtr, "busy", 4)) *strPtr = '\0'; else { while (*tmpPtr) { if ((!isdigit (*tmpPtr)) && (*tmpPtr != '.')) return (localPath); tmpPtr++; } *strPtr = '['; *tmpPtr++ = ']'; *tmpPtr = '\0'; } } else if ((strPtr = strrchr (localPath, '~'))) { tmpPtr = strPtr+1; while (*tmpPtr) { if ((!isdigit (*tmpPtr)) && (*tmpPtr != '.')) return (localPath); tmpPtr++; } *strPtr = '['; *tmpPtr++ = ']'; *tmpPtr = '\0'; } return (localPath); } shapetools-1.4pl6.orig/src/atfstk/read.c100444 2013 145 32336 5412605704 16334 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * read.c * * Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) * * $Header: read.c[7.0] Fri Jun 25 16:39:04 1993 andy@cs.tu-berlin.de frozen $ */ /* * Read versions with attributes expanded. * * For each version opened with atOpenExpand() a descriptor is * allocated in desc_table[]. This descriptor contains: * * all necessary data about the version (AtFS key, FILE *, file * descriptor, name, contents), * * two flags if expansion shall be done (toggled by $__xoff$, * xpon) and if expansion shall be done at all (e.g. usually * not for busy versions), * * state of the reader (position in version contents, current * expansion (if one is active), position in current expansion). * * Contents of the version means that the complete contents of the * version is read into memory (readin_version()). * * atReadExpand() copies data from the descriptor buffer to the * user-supplied buffer. When it encounters an attribute citation, the * citation is expanded with retrieve_expansion(), which calls * atRetAttr(). Then characters are copied from the expansion buffer * to the user-supplied buffer. * * atCloseExpand() frees the descriptor and associated resources. */ #include #include #include "atfs.h" #include "atfstk.h" extern int errno ; #define INITIAL_BUFFER_SIZE 8192 #define NO_AR_DESC 64 #define XPOFF_ATTR "xpoff" #define XPON_ATTR "xpon" /* descriptor for an open version */ typedef struct at_read_desc { char *ar_name ; /* name of version */ Af_key *ar_key ; /* AtFS key of version */ FILE *ar_fp ; /* returned by af_open() */ int ar_fd ; /* file descriptor */ char *ar_buffer ; /* buffer for version contents */ char *ar_bufend ; /* ptr to first byte after end of buffer */ char *ar_pos ; /* position in buffer */ char ar_noexpand ; /* no expansion at all */ char ar_expand ; /* non-zero if expansion shall be done */ char *ar_expansion; /* active expansion */ char *ar_exp_pos ; /* position in expansion */ } at_read_desc ; /* descriptor table */ static at_read_desc *desc_table[NO_AR_DESC] ; /* * INTERNALS */ static int allocate_descriptor A((void)) ; static int readin_version A((at_read_desc *dp)) ; static int std_attr_p A((Af_key *key, char *attr)) ; static char *end_of_attribute_or_not A((char *p, char *limit)) ; static int retrieve_expansion A((at_read_desc *dp, char *attrname)) ; /* allocate and initialize a descriptor */ static int allocate_descriptor() { int index ; /* Look for free index (0 is reserved for stdin handling). * desc_table[] should be small enough not to make linear search a * pain. */ for (index = 1; index < NO_AR_DESC && desc_table[index] != 0; index++) ; if (index == NO_AR_DESC) { errno = EMFILE ; return -1 ; } /* allocate and clean descriptor structure */ desc_table[index] = (at_read_desc *) malloc(sizeof(at_read_desc)) ; if (desc_table[index] == 0) { errno = ENOMEM ; return -1 ; } memset((char *) desc_table[index], 0, sizeof(at_read_desc)) ; return index ; } /* Read contents of version into a buffer. * Return appropriate errno on failure, else 0. */ static int readin_version(dp) at_read_desc *dp ; { unsigned long buffer_size ; /* size of buffer */ struct stat statbuf ; /* argument to fstat(2) */ unsigned long nbytes ; /* no of bytes already read */ unsigned long nread ; /* no of bytes read at one time */ char *newbuf ; if (fstat(dp->ar_fd, &statbuf) == -1) { return -1 ; } /* regular file? */ if (S_ISREG(statbuf.st_mode)) { /* yes, so we try to read it in one chunk */ /* allocate and initialize buffer */ buffer_size = statbuf.st_size ; dp->ar_buffer = malloc(buffer_size) ; if (dp->ar_buffer == 0) { return EFBIG ; } dp->ar_pos = dp->ar_buffer ; /* read data */ nbytes = 0 ; while (nbytes < buffer_size) { nread = read(dp->ar_fd, dp->ar_pos, buffer_size - nbytes) ; if (nread == -1) { return errno ; } if (nread == 0) { break ; } dp->ar_pos += nread ; nbytes += nread ; } dp->ar_bufend = dp->ar_pos ; } else { /* not a regular file (urgh) */ unsigned long increment ; /* for growing of buffer */ buffer_size = INITIAL_BUFFER_SIZE ; increment = INITIAL_BUFFER_SIZE ; /* allocate initial buffer */ dp->ar_buffer = malloc(buffer_size) ; if (dp->ar_buffer == 0) { return ENOMEM ; } /* read data */ nbytes = 0 ; nread = 1 ; /* fake initial condition */ while (nread > 0) { nread = read(dp->ar_fd, dp->ar_buffer + nbytes, buffer_size - nbytes) ; if (nread == -1) { return errno ; } if (nread == 0) { break ; } nbytes += nread ; /* if buffer gets full, allocate larger buffer */ if (nbytes > 3 * buffer_size / 4) { increment = increment * 4 / 3 ; newbuf = realloc(dp->ar_buffer, buffer_size + increment) ; if (newbuf == 0) { return EFBIG ; } dp->ar_buffer = newbuf ; buffer_size += increment ; } } /* adjust buffer to final size */ dp->ar_buffer = realloc(dp->ar_buffer, nbytes) ; if (dp->ar_buffer == 0) { return ENOMEM ; } dp->ar_bufend = dp->ar_buffer + nbytes ; } dp->ar_pos = dp->ar_buffer ; return 0 ; } /* open a version for reading with atReadExpand() */ int atOpenExpand(vname, expand_busy) char *vname ; /* name of version */ int expand_busy ; /* expand attributes of busy versions */ { Af_key *key ; /* key returned by atBindVersion() */ int desc ; /* index into desc_table */ struct at_read_desc *dp ; /* descriptor struct */ /* get AtFS key for vname */ if (!(key = atBindVersion (vname, ""))) { return -1 ; } /* initialize std_attr_p() */ std_attr_p(key, 0) ; /* allocate descriptor */ desc = allocate_descriptor() ; if (desc == -1) { af_dropkey(key) ; return -1 ; } dp = desc_table[desc] ; dp->ar_key = key ; dp->ar_name = strdup(atWriteName(key, af_afpath(vname))) ; if (dp->ar_name == 0) { errno = ENOMEM ; atCloseExpand(desc) ; return -1 ; } /* open version */ if ((dp->ar_fp = af_open(key, "r")) == 0) { /* this should not happen: * atBindVersion() promised a version */ atCloseExpand(desc) ; return -1 ; } dp->ar_fd = fileno(dp->ar_fp) ; /* expand attribute citations in busy version only * if expand_busy is non-zero */ if (af_retnumattr(key, AF_ATTSTATE) == AF_BUSY) { dp->ar_noexpand = ! expand_busy ; dp->ar_expand = expand_busy ; } else { dp->ar_noexpand = 0 ; dp->ar_expand = 1 ; } /* read version contents into buffer */ if (readin_version(dp) != 0) { atCloseExpand(desc) ; return -1 ; } fclose(dp->ar_fp) ; dp->ar_fp = 0 ; return desc ; } /* return the name of a version opened with atOpenExpand() */ char *atGetWriteName(desc) int desc ; { return desc_table[desc]->ar_name ; } /* Returns non-zero if attribute is standard attribute. * Must be initialized with a valid key first. * Kludge recommended by Andy. */ static int std_attr_p(key, attr) Af_key *key ; /* only for initialization */ char *attr ; /* name of attribute */ { static char *stdattr_ptr = 0 ; /* ptr to location of standard attributes */ if (stdattr_ptr == 0) { stdattr_ptr = af_retattr(key, AF_ATTTYPE) ; /* this does not fail */ } return attr == stdattr_ptr ; } /* free resources allocated to descriptor */ void atCloseExpand(desc) int desc ; { at_read_desc *dp ; dp = desc_table[desc] ; if (dp != 0) { if (dp->ar_expansion) { free(dp->ar_expansion) ; } if (dp->ar_key) { af_dropkey(dp->ar_key) ; } if (dp->ar_fp != 0) { fclose(dp->ar_fp) ; } if (dp->ar_buffer != 0) { free(dp->ar_buffer) ; } if (dp->ar_name != 0) { free(dp->ar_name) ; } free(dp) ; desc_table[desc] = 0 ; } } /* return ptr to end of attribute name or 0 if no attribute present */ static char *end_of_attribute_or_not(p, limit) char *p ; /* expected to point to "$" */ char *limit ; { enum { dollar, first_, second_, inname } state ; char *endp ; state = dollar ; if (*p++ != '$') { return 0 ; } endp = p ; while (endp <= limit) { switch (state) { case dollar: if (*p++ != '_') { return 0 ; } state = first_ ; break ; case first_: if (*p++ != '_') { return 0 ; } state = second_ ; break ; case second_: if (*p == '\0' || *p == '$' || isspace(*p)) { return 0 ; } p++ ; state = inname ; break ; case inname: if (*p == '\0' || *p == '$' || isspace(*p)) { return p ; } p++ ; } } return p ; } /* Retrieve attribute, * handle xpoff and xpon pseudo attributes. * Return 0 if no value exists. * If an error occurs, return value is also 0, but hopefully * on of atRetAttr() or strdup() has set errno appropriately. */ static int retrieve_expansion(dp, attrname) at_read_desc *dp ; char *attrname ; { char *value ; /* attribute value */ int ret = 0 ; /* return value to be */ errno = 0 ; /* may get set by atRetAttr() or * strdup() */ /* confusing if-statement follows */ if (dp->ar_noexpand) { ret = 0 ; } else if (dp->ar_expand) { if (!strcmp(attrname, XPOFF_ATTR)) { dp->ar_expand = 0 ; ret = 0 ; } else { value = atRetAttr(dp->ar_key, attrname) ; if (value) { /* atRetAttr returns standard and "Header" attributes * in static memory. These must be copied. */ if (!strcmp(attrname, "Header") || std_attr_p(0, value)) { dp->ar_expansion = strdup(value) ; if (dp->ar_expansion == 0) { errno = ENOMEM ; ret = 0 ; } else { ret = 1 ; } } else { dp->ar_expansion = value ; ret = 1 ; } dp->ar_exp_pos = dp->ar_expansion ; } else { ret = 0 ; } } } else if (!strcmp(attrname, XPON_ATTR)) { dp->ar_expand = 1 ; ret = 0 ; } free(attrname) ; /* This is not as nice as it should * be, but the caller has no * opportunity to free() attrname. */ return ret ; } /* Read from a version opened with atOpenExpand(). */ int atReadExpand(desc, bufp, size) int desc ; /* descriptor, index into desc_table[] */ char *bufp ; /* ptr to data area */ int size ; /* read thus many bytes */ { at_read_desc *dp ; /* descriptor struct */ char *endattr ; /* ptr to end of attribute name */ char *attrname ; /* ptr to allocated attribute name */ int wanted = size ; char *old_pos ; /* previous position in version buffer */ if (desc == 0) { /* read from stdin */ return read(0, bufp, size) ; } dp = desc_table[desc] ; if (dp == 0) { /* check if desc is valid */ errno = EBADF ; return -1 ; } old_pos = dp->ar_pos ; /* save position for rollback */ read_expansion: /* the name of this label is nearly * enough comment for the following * while loop */ while (dp->ar_expansion && size > 0) { /* there is an expansion, so read it */ *bufp++ = *dp->ar_exp_pos++ ; size-- ; /* at end of attribute value? */ if (*dp->ar_exp_pos == 0) { /* free expansion */ free(dp->ar_expansion) ; dp->ar_exp_pos = 0 ; dp->ar_expansion = 0 ; } } /* read from version contents */ while (size > 0 && dp->ar_pos < dp->ar_bufend) { if (*dp->ar_pos == '$') { /* maybe an attribute citation here */ endattr = end_of_attribute_or_not(dp->ar_pos, dp->ar_bufend) ; if (endattr) { /* Yes, indeed. Skip to beginning of name. */ dp->ar_pos += 3 ; /* copy attribute name, * gets free()d in retrieve_expansion() */ attrname = malloc(endattr - dp->ar_pos + 1) ; if (attrname == 0) { dp->ar_pos = old_pos ; /* rollback */ errno = ENOMEM ; return -1 ; } memcpy(attrname, dp->ar_pos, endattr - dp->ar_pos) ; *(attrname + (endattr - dp->ar_pos)) = 0 ; /* retrieve attribute value */ if (retrieve_expansion(dp, attrname)) { dp->ar_pos = endattr ; if (*dp->ar_pos == '$') { dp->ar_pos++ ; } goto read_expansion ; /* If memory serves me right, * this is my first goto statement * in a C program ever. */ } else { switch (errno) { case 0: break ; case ENOMEM: dp->ar_pos = old_pos ; default: return -1 ; } } /* inhibit expansion of the following comment with $__xpoff$ */ /* no expansion, skip back to "$__" */ /* now we can switch $__xpon$ again */ dp->ar_pos -= 3 ; } } /* copy a character (yes, finally!) */ *bufp++ = *dp->ar_pos++ ; size-- ; } return wanted - size ; } /* EOF */ shapetools-1.4pl6.orig/src/atfstk/bind.c100444 2013 145 110565 5617434704 16365 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * bind.c -- AtFS toolkit library (Version Binding) * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: bind.c[7.1] Thu Aug 4 16:05:12 1994 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "sttk.h" #include "atfstk.h" #include "bind.h" EXPORT int atBindError; EXPORT char atBindErrorMsg[256]; EXPORT int atBindTrace = FALSE; EXPORT int atBindNoMsg = FALSE; extern BindBaseline bindExact, bindBefore, bindSince; /*========================== * atScanBinding *==========================*/ LOCAL int getNumber (ptr, digits) char *ptr; int digits; { int result=0, i; if (!digits) return (AF_NOVNUM); for (i = 0; i < digits; i++) result = (result*10)+(ptr[i]-48); return (result); } EXPORT int atScanBinding (binding, str, genNo, revNo, date) char *binding; char **str; int *genNo; int *revNo; time_t *date; /* scan version binding * '{digit}*.{digit}*' is interpreted as version number, * ':' is interpreted as rule name, * '' as version number alias (symbolic name), * '' as rule name (with an optional colon) and * NULL, empty string, :, [], [.], [:], [, [: as default version binding. * Square brackets around the string are ignore. * RETURN: type of version binding (see above) */ { char *resultStr, *startPtr, *ptr, *auxPtr; int genDigits=0, revDigits=0, cacheKeyLen; *str = NULL; if (!binding) return (AT_BIND_DEFAULT); /* binding is NULL */ if (*binding == '[') startPtr = ptr = binding+1; else startPtr = ptr = binding; /* determine format */ while (isdigit(*ptr)) { ptr++; genDigits++; } if (*ptr == '*') ptr++; /* handles [*.] */ if (*ptr == '.') { ptr++; auxPtr = ptr; while (isdigit(*ptr)) { ptr++; revDigits++; } if (*ptr == '*') ptr++; /* handles [.*] */ if (*ptr == '.') { /* hmm, seems to be a cache key or a date (German format) */ ptr++; cacheKeyLen = genDigits + revDigits + 2; while (isdigit(*ptr)) { ptr++; cacheKeyLen++; } if (*ptr == ']') ptr++; if (!*ptr) { /* ok, got everything -- seems to be a cache key or a German date */ /* check date first */ if (date && (*date = stMktime (startPtr))) return (AT_BIND_DATE); if ((resultStr = malloc (cacheKeyLen + 1)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (AT_BIND_DEFAULT); } strncpy (resultStr, startPtr, cacheKeyLen); resultStr[cacheKeyLen] = '\0'; *str = resultStr; return (AT_BIND_CACHEKEY); } } else { if (*ptr == ']') ptr++; if (!*ptr) { /* ok, got everything -- seems to be a version number */ *genNo = getNumber (startPtr, genDigits); *revNo = getNumber (auxPtr, revDigits); if ((*genNo == AF_NOVNUM) && (*revNo == AF_NOVNUM)) return (AT_BIND_DEFAULT); /* binding is "[.]" */ else return (AT_BIND_VNUM); } } } if (!strncmp (startPtr, "*]", 5) || !strcmp (startPtr, "*")) { *genNo = AF_NOVNUM; *revNo = AF_NOVNUM; return (AT_BIND_VNUM); } if (!strncmp (startPtr, "busy]", 5) || !strcmp (startPtr, "busy")) { *genNo = AF_BUSYVERS; *revNo = AF_BUSYVERS; return (AT_BIND_VNUM); } /* else assume alias or rule name */ if ((resultStr = malloc (strlen (binding)+1)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (AT_BIND_DEFAULT); } resultStr[0] = '\0'; *str = resultStr; ptr = startPtr; auxPtr = resultStr; while (*ptr) *auxPtr++ = *ptr++; if ((ptr > startPtr ) && (*(ptr-1) == ']')) *--auxPtr = '\0'; else *auxPtr = '\0'; if (!resultStr[0] || ((resultStr[0] == ':') && !resultStr[1])) return (AT_BIND_DEFAULT); /* binding is "[]", "[:]", "[" or "[:" */ /* eliminate escape chars */ auxPtr = ptr = resultStr; while (*ptr) { if (*ptr == '\\') ptr++; *auxPtr++ = *ptr++; } *auxPtr = *ptr; if ((ptr > resultStr) && (*(ptr-1) == ':')) { *(ptr-1) = '\0'; return (AT_BIND_RULE); } if (date && (*date = stMktime (resultStr))) return (AT_BIND_DATE); return (AT_BIND_ALIAS); } /*======================= * narrowSet *=======================*/ #define NARROW_SINCE 0 #define NARROW_BEFORE 1 LOCAL void narrowSet (set, baselinePtr, narrowMode) Af_set *set; BindBaseline *baselinePtr; int narrowMode; { int setSize = af_nrofkeys (set), i=0; time_t discrDate = (time_t)0, tmpDate; Af_key tmpKey; Af_attrs attrBuf; Af_set baselineSet; af_initattrs (&attrBuf); af_initset (&baselineSet); switch (baselinePtr->baselineType) { case AT_BIND_DATE: discrDate = baselinePtr->baselineDate; break; case AT_BIND_VNUM: attrBuf.af_gen = baselinePtr->baselineGen; attrBuf.af_rev = baselinePtr->baselineRev; af_subset (set, &attrBuf, &baselineSet); if (af_nrofkeys (&baselineSet) == 1) { af_setgkey (&baselineSet, 0, &tmpKey); if (af_retnumattr (&tmpKey, AF_ATTSTATE) == AF_BUSY) discrDate = af_rettimeattr (&tmpKey, AF_ATTMTIME); else discrDate = af_rettimeattr (&tmpKey, AF_ATTSTIME); af_dropkey (&tmpKey); } else { discrDate = 0; } af_dropset (&baselineSet); break; case AT_BIND_ALIAS: { char aliasAttr[AT_MAXALIASLEN]; sprintf (aliasAttr, "%s=%s", AT_ATTALIAS, baselinePtr->baselineString); attrBuf.af_udattrs[0] = aliasAttr; attrBuf.af_udattrs[1] = NULL; af_subset (set, &attrBuf, &baselineSet); if (af_nrofkeys (&baselineSet) == 1) { af_setgkey (&baselineSet, 0, &tmpKey); if (af_retnumattr (&tmpKey, AF_ATTSTATE) == AF_BUSY) discrDate = af_rettimeattr (&tmpKey, AF_ATTMTIME); else discrDate = af_rettimeattr (&tmpKey, AF_ATTSTIME); af_dropkey (&tmpKey); } else { discrDate = 0; } af_dropset (&baselineSet); break; } } /* switch */ while (i < setSize) { af_setgkey (set, i, &tmpKey); /* if version is a busy version compare modification date, * otherwise compare save date */ if (af_retnumattr (&tmpKey, AF_ATTSTATE) == AF_BUSY) tmpDate = af_rettimeattr (&tmpKey, AF_ATTMTIME); else tmpDate = af_rettimeattr (&tmpKey, AF_ATTSTIME); if (narrowMode == NARROW_BEFORE) { if ((discrDate == 0) || (tmpDate >= discrDate)) { af_setrmkey (set, &tmpKey); setSize--; continue; } } else { if ((discrDate == 0) || (tmpDate <= discrDate)) { af_setrmkey (set, &tmpKey); setSize--; continue; } } af_dropkey (&tmpKey); i++; } } /*======================= * bindByDate *=======================*/ LOCAL int bindByDate (reqAttrs, date, resultSet) Af_attrs *reqAttrs; time_t date; Af_set *resultSet; { int versCount, i, hitCount; Af_set hitSet; Af_key curKey, prevKey; af_initset (resultSet); if ((versCount = af_find (reqAttrs, &hitSet)) < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("bindByDate")); return (-1); } if (versCount == 0) return (0); /* check exact match */ for (i=0; i 0) return (hitCount); /* arrange set (sort by modification date) */ af_sortset (&hitSet, AF_ATTMTIME); af_setgkey (&hitSet, 0, &prevKey); for (i=1; i af_rettimeattr (&prevKey, AF_ATTMTIME)) && (date < af_rettimeattr (&curKey, AF_ATTMTIME)) ) af_setaddkey (resultSet, AF_LASTPOS, &prevKey); af_dropkey (&prevKey); prevKey = curKey; } if (date > af_rettimeattr (&curKey, AF_ATTMTIME)) af_setaddkey (resultSet, AF_LASTPOS, &curKey); af_dropkey (&prevKey); af_dropset (&hitSet); return (af_nrofkeys (resultSet)); } /*======================= * bindByRule *=======================*/ LOCAL void showHitSet (hitSet) Af_set *hitSet; { int i, len, termWidth = stGetTermWidth (1), hitCount = af_nrofkeys (hitSet); Af_key tmpKey; stLog ("\n\t-> Hit Set:", ST_LOG_MSG | ST_LOG_NONL); len = 19; for (i = 0; i < hitCount; i++) { if ((termWidth - len) < 10) { stLog ("\n\t ", ST_LOG_MSG | ST_LOG_NONL); len = 19; } af_setgkey (hitSet, i, &tmpKey); if (af_retnumattr (&tmpKey, AF_ATTSTATE) == AF_BUSY) { stLog (" [busy]", ST_LOG_MSG | ST_LOG_NONL); len += 7; } else if (af_retnumattr (&tmpKey, AF_ATTSTATE) == AF_DERIVED) { sprintf (stMessage, " [%d.%d,cached]", af_retnumattr (&tmpKey, AF_ATTGEN), af_retnumattr (&tmpKey, AF_ATTREV)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); len += strlen (stMessage); } else { sprintf (stMessage, " [%d.%d]", af_retnumattr (&tmpKey, AF_ATTGEN), af_retnumattr (&tmpKey, AF_ATTREV)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); len += strlen (stMessage); } af_dropkey (&tmpKey); } stLog ("", ST_LOG_MSG); } LOCAL int bindByRule (reqAttrs, ruleName, mode, cache, resultSet) Af_attrs *reqAttrs; char *ruleName; int mode; /* only AT_BIND_SET and AT_BIND_UNIQUE are allowed */ int cache; /* if TRUE bind cached objects */ Af_set *resultSet; { int altError, retCode, predPos, predCode, altCount = 1, bindHitCount; char *pattern, patternBuf[PATH_MAX+AT_CACHEKEYLEN]; char *bindPtr = NULL, *arg1, *arg2, bindTargName[NAME_MAX+1]; char *reMsg, *predName; Af_set *tmpSet, bindHitSet; Af_key *tmpKey; atBindInitRules (); if (reqAttrs->af_syspath[0]) { if (!strcmp (reqAttrs->af_syspath, "/")) sprintf (bindTargName, "/%s", reqAttrs->af_name); else sprintf (bindTargName, "%s/%s", reqAttrs->af_syspath, reqAttrs->af_name); } else strcpy (bindTargName, reqAttrs->af_name); if (reqAttrs->af_type[0]) { strcat (bindTargName, "."); strcat (bindTargName, reqAttrs->af_type); } af_initset (&bindHitSet); switch (atBindSetRule (ruleName, bindTargName, TRUE)) { case -2: /* rule not found */ return (0); case -1: /* error during execution */ return (-1); case 0: /* ok */ break; default: atBindUnsetRule (TRUE); atBindError = TRUE; strcpy (atBindErrorMsg, "invalid rule (syntax error in rule)"); return (-1); } while ((pattern = atBindRuleAlt (&bindHitSet))) { /* check if pattern is a network path name -- if not, nothing happens to "pattern" during "atLocalPath" */ pattern = atLocalPath (pattern); /* copy pattern to a local buffer */ strcpy (patternBuf, pattern); pattern = patternBuf; /* strip off version binding (if there is one) */ if ((bindPtr = strrchr (pattern, '['))) *bindPtr = '\0'; /* do trace output */ if (atBindTrace) { sprintf (stMessage, " %d)\t%s - pattern: %s (%s)", altCount++, atCurRuleName(), pattern, stConvertPattern (pattern)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } /* check if given name matches pattern (with binding stripped off) */ if ((pattern[0] != '*') || pattern[1]) { if ((reMsg = re_comp (stConvertPattern (pattern)))) { atBindError = TRUE; strcpy (atBindErrorMsg, "re_comp: "); strcat (atBindErrorMsg, reMsg); atBindUnsetRule (TRUE); return (-1); } if (!re_exec (bindTargName)) { /* pattern did not match, assume version binding to be part of pattern */ if (bindPtr) { *bindPtr = '['; bindPtr = NULL; reMsg = re_comp (stConvertPattern (pattern)); if (!re_exec (bindTargName)) { /* not found in both tries */ if (atBindTrace) { af_initset (&bindHitSet); showHitSet (&bindHitSet); } continue; } /* else: found in second try */ } else { /* not found during first try and there was no version binding */ if (atBindTrace) { af_initset (&bindHitSet); showHitSet (&bindHitSet); } continue; } } /* else: found in first try */ } /* else: pattern is '*' */ if (bindPtr) { bindPtr++; if (cache) tmpSet = atBindCache (bindTargName, bindPtr); else tmpSet = atBindSet (bindTargName, bindPtr, AT_BIND_SET); if (tmpSet) af_copyset (tmpSet, &bindHitSet); else af_initset (&bindHitSet); bindHitCount = af_nrofkeys (&bindHitSet); } else { /* no version binding necessary */ if (cache) bindHitCount = af_cachefind (reqAttrs, &bindHitSet); else bindHitCount = af_find (reqAttrs, &bindHitSet); if (bindHitCount == -1) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("bindByRule")); atBindUnsetRule (TRUE); return (-1); } } if (atBindTrace) showHitSet (&bindHitSet); altError = FALSE; while ((predPos = atBindRulePred (&arg1, &arg2, &bindHitSet)) != -1) { predCode = atBindPredCode (predPos); predName = atBindPredName (predPos); switch (predCode) { case BIND_PRED_ATTR: if (atBindTrace) { sprintf (stMessage, "\t%s (%s,%s)", predName, NOTNIL(arg1), NOTNIL(arg2)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } bindHitCount = atBindAttrAbsolute (&bindHitSet, arg1, arg2); break; case BIND_PRED_ATTREX: if (atBindTrace) { sprintf (stMessage, "\t%s (%s)", predName, NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } bindHitCount = atBindAttrAbsolute (&bindHitSet, arg1, NULL); break; case BIND_PRED_ATTRGE: if (atBindTrace) { sprintf (stMessage, "\t%s (%s,%s)", predName, NOTNIL(arg1), NOTNIL(arg2)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } bindHitCount = atBindAttrRelative (&bindHitSet, arg1, arg2, predCode); break; case BIND_PRED_ATTRGT: if (atBindTrace) { sprintf (stMessage, "\t%s (%s,%s)", predName, NOTNIL(arg1), NOTNIL(arg2)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } bindHitCount = atBindAttrRelative (&bindHitSet, arg1, arg2, predCode); break; case BIND_PRED_ATTRLE: if (atBindTrace) { sprintf (stMessage, "\t%s (%s,%s)", predName, NOTNIL(arg1), NOTNIL(arg2)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } bindHitCount = atBindAttrRelative (&bindHitSet, arg1, arg2, predCode); break; case BIND_PRED_ATTRLT: if (atBindTrace) { sprintf (stMessage, "\t%s (%s,%s)", predName, NOTNIL(arg1), NOTNIL(arg2)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } bindHitCount = atBindAttrRelative (&bindHitSet, arg1, arg2, predCode); break; case BIND_PRED_ATTRNOT: if (atBindTrace) { sprintf (stMessage, "\t%s (%s,%s)", predName, NOTNIL(arg1), NOTNIL(arg2)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } bindHitCount = atBindAttrRelative (&bindHitSet, arg1, arg2, predCode); break; case BIND_PRED_ATTRMAX: if (atBindTrace) { sprintf (stMessage, "\t%s (%s)", predName, NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } bindHitCount = atBindAttrMinMax (&bindHitSet, arg1, predCode); break; case BIND_PRED_ATTRMIN: if (atBindTrace) { sprintf (stMessage, "\t%s (%s)", predName, NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } bindHitCount = atBindAttrMinMax (&bindHitSet, arg1, predCode); break; case BIND_PRED_CONDEX: if (atBindTrace) { sprintf (stMessage, "\t%s (%s)", predName, NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } if ((tmpSet = atBindSet (arg1, NULL, 0))) { if (af_nrofkeys (tmpSet) == 0) { af_dropset (&bindHitSet); bindHitCount = 0; } af_dropset (tmpSet); } else { af_dropset (&bindHitSet); bindHitCount = 0; } break; case BIND_PRED_CONDEXPR: if (atBindTrace) { sprintf (stMessage, "\t%s (%s,%s)", predName, NOTNIL(arg1), NOTNIL(arg2)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } if (!arg1) arg1 = "sh"; if ((retCode = stCallCmd (arg1, arg2)) < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, "during execution of subprocess"); } if (retCode > 0) { af_dropset (&bindHitSet); bindHitCount = 0; } break; case BIND_PRED_CONDNOT: if (atBindTrace) { sprintf (stMessage, "\t%s (%s)", predName, NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } if ((tmpSet = atBindSet (arg1, NULL, 0)) && (af_nrofkeys (tmpSet) > 0)) { af_dropset (tmpSet); af_dropset (&bindHitSet); bindHitCount = 0; } break; case BIND_PRED_CONDUNIQ: if (atBindTrace) { sprintf (stMessage, "\t%s (%s)", predName, NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } if ((tmpKey = atBindVersion (arg1, NULL))) af_dropkey (tmpKey); else { af_dropset (&bindHitSet); bindHitCount = 0; } break; case BIND_PRED_CONFIRM: if (atBindTrace) { sprintf (stMessage, "\t%s (%s,%s)", predName, NOTNIL(arg1), NOTNIL(arg2)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } if (!stAskConfirm (arg1, arg2)) { af_dropset (&bindHitSet); bindHitCount = 0; } break; case BIND_PRED_RULE: if (atBindTrace) { sprintf (stMessage, "\t%s (%s)", predName, NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } switch (atBindSetRule (arg1, bindTargName, FALSE)) { case -2: if (atBindTrace) stLog (" -- not found", ST_LOG_MSG | ST_LOG_NONL); break; case -1: /* error during execution */ break; case 0: /* ok */ break; default: atBindUnsetRule (FALSE); atBindError = TRUE; strcpy (atBindErrorMsg, "invalid rule (syntax error in rule)"); break; } /* switch to another rule */ af_dropset (&bindHitSet); bindHitCount = 0; break; case BIND_PRED_CUT: if (atBindTrace) { sprintf (stMessage, "\t%s (%s)", predName, NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } if (arg1 && !atBindNoMsg) { sprintf (stMessage, "%s", NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG); } af_dropset (&bindHitSet); atBindUnsetRule (TRUE); return (-1); case BIND_PRED_MSG: if (atBindTrace) { sprintf (stMessage, "\t%s (%s)", predName, NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG); } if (arg1 && !atBindNoMsg) { sprintf (stMessage, "%s", NOTNIL(arg1)); stLog (stMessage, ST_LOG_MSG); } break; } if (atBindError) { if (atBindDisplayErrors) { sprintf (stMessage, "in bind rule -- %s", atBindErrorMsg); stLog (stMessage, ST_LOG_ERROR); } af_dropset (&bindHitSet); bindHitCount = 0; atBindError = FALSE; } if (atBindTrace) showHitSet (&bindHitSet); if (bindHitCount <= 0) /* cut processing of alternative */ break; } /* end of predicate loop */ if ( ((mode == AT_BIND_UNIQUE) && (bindHitCount == 1)) || ((mode == AT_BIND_SET) && (bindHitCount >=1)) ) { af_copyset (&bindHitSet, resultSet); af_dropset (&bindHitSet); atBindUnsetRule (TRUE); return (bindHitCount); } } /* end of alternative loop */ af_dropset (&bindHitSet); atBindUnsetRule (TRUE); return (0); } /*======================= * atBindVersion *=======================*/ EXPORT Af_key *atBindVersion (name, binding) char *name; char *binding; /* bind name to single unique version. * RETURN: key of found Aso */ { Af_key *resultKey; Af_attrs reqAttrs; Af_set hitSet; int bindType, genNo, revNo, hitCount; char *bindStr = NULL, *afPath, *afName, *afType; char *bindName, aliasAttr[AT_MAXALIASLEN]; time_t date; atBindError = FALSE; name = atLocalPath (name); if ((resultKey = (Af_key *)malloc (sizeof (Af_key))) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (NULL); } if ((bindStr = strrchr (name, '['))) bindType = atScanBinding (bindStr, &bindName, &genNo, &revNo, &date); else if (binding && *binding) bindType = atScanBinding (binding, &bindName, &genNo, &revNo, &date); else bindType = AT_BIND_DEFAULT; if ((bindType == AT_BIND_DEFAULT) && !(binding && *binding) && (bindExact.baselineType != AT_BIND_DEFAULT)) { /* if no explicit binding is given, take unique binding from command line */ bindType = bindExact.baselineType; bindName = bindExact.baselineString; genNo = bindExact.baselineGen; revNo = bindExact.baselineRev; date = bindExact.baselineDate; } if (bindStr) *bindStr = '\0'; /* isolate name */ afPath = af_afpath (name); afName = af_afname (name); afType = af_aftype (name); switch (bindType) { case AT_BIND_DEFAULT: if (atBindTrace) { sprintf (stMessage, " Bind unique: %s[] (default)", name); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; if (af_getkey (afPath, afName, afType, AF_BUSYVERS, AF_BUSYVERS, resultKey) == -1) if (af_getkey (afPath, afName, afType, AF_LASTVERS, AF_LASTVERS, resultKey) == -1) return (NULL); return (resultKey); case AT_BIND_VNUM: if (atBindTrace) { sprintf (stMessage, " Bind unique %s[%d.%d] (vnum)", name, genNo, revNo); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; if (af_getkey (afPath, afName, afType, genNo, revNo, resultKey) == -1) return (NULL); return (resultKey); case AT_BIND_ALIAS: af_initattrs (&reqAttrs); sprintf (aliasAttr, "%s=%s", AT_ATTALIAS, bindName); reqAttrs.af_udattrs[0] = aliasAttr; reqAttrs.af_udattrs[1] = NULL; strcpy (reqAttrs.af_syspath, afPath); strcpy (reqAttrs.af_name, afName); strcpy (reqAttrs.af_type, afType); if ((hitCount = af_find (&reqAttrs, &hitSet)) != 0) { if (atBindTrace) { sprintf (stMessage, " Bind unique: %s[%s] (alias)", name, bindName); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; if (hitCount > 1) { atBindError = TRUE; strcpy (atBindErrorMsg, "version number alias (symbolic name) does not uniquely identify version"); af_dropset (&hitSet); return (NULL); } else if (hitCount < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindVersion")); af_dropset (&hitSet); return (NULL); } else { af_setgkey (&hitSet, 0, resultKey); af_dropset (&hitSet); return (resultKey); } } /* no return, no break: go on with case AT_BIND_RULE if hitSet is empty */ reqAttrs.af_udattrs[0] = NULL; case AT_BIND_RULE: if (atBindTrace) { sprintf (stMessage, " Bind unique %s[%s:] (rule)", name, bindName); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; af_initattrs (&reqAttrs); strcpy (reqAttrs.af_syspath, afPath); strcpy (reqAttrs.af_name, afName); strcpy (reqAttrs.af_type, afType); if (bindByRule (&reqAttrs, bindName, AT_BIND_UNIQUE, FALSE, &hitSet) <= 0) return (NULL); af_setgkey (&hitSet, 0, resultKey); af_dropset (&hitSet); return (resultKey); case AT_BIND_DATE: if (atBindTrace) { sprintf (stMessage, " Bind unique %s[%s] (date)", name, stWriteTime (date)); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; af_initattrs (&reqAttrs); strcpy (reqAttrs.af_syspath, afPath); strcpy (reqAttrs.af_name, afName); strcpy (reqAttrs.af_type, afType); if (bindByDate (&reqAttrs, date, &hitSet) <= 0) return (NULL); af_setgkey (&hitSet, 0, resultKey); af_dropset (&hitSet); return (resultKey); case AT_BIND_CACHEKEY: if (atBindTrace) { sprintf (stMessage, " Bind unique: %s[%s] (cache key)", name, bindName); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; af_initattrs (&reqAttrs); sprintf (aliasAttr, "%s=%s", AT_ATTCACHEKEY, bindName); reqAttrs.af_udattrs[0] = aliasAttr; reqAttrs.af_udattrs[1] = NULL; strcpy (reqAttrs.af_syspath, afPath); strcpy (reqAttrs.af_name, afName); strcpy (reqAttrs.af_type, afType); if ((hitCount = af_cachefind (&reqAttrs, &hitSet)) < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindVersion")); af_dropset (&hitSet); return (NULL); } if (hitCount == 0) return (NULL); else { af_setgkey (&hitSet, 0, resultKey); af_dropset (&hitSet); return (resultKey); } } atBindError = TRUE; strcpy (atBindErrorMsg, "internal error (should be never reached)"); return (NULL); } /*======================= * atBindSet *=======================*/ EXPORT Af_set *atBindSet (pattern, binding, bindMode) char *pattern; char *binding; int bindMode; /* bind names (generated from pattern) to set of source versions * RETURN: set of Aso keys */ { static Af_set returnSet; Af_set tmpSet, resultSet; Af_attrs reqAttrs; int bindType, genNo, revNo, hitCount, i; char *bindStr = NULL, *bindName, aliasAttr[AT_MAXALIASLEN]; char *namePatternPtr, **nameList; time_t date; if (!pattern || !*pattern) { atBindError = TRUE; strcpy (atBindErrorMsg, "no name/pattern argument given (atBindSet)"); return (NULL); } atBindError = FALSE; pattern = atLocalPath (pattern); af_initset (&resultSet); af_initattrs (&reqAttrs); /* if no explicit bind mode is given */ if (!bindMode) { if (atBindModeOption) bindMode = atBindModeOption; else bindMode = AT_BIND_SET; } if ((bindStr = strrchr (pattern, '['))) bindType = atScanBinding (bindStr, &bindName, &genNo, &revNo, &date); else if (binding && *binding) bindType = atScanBinding (binding, &bindName, &genNo, &revNo, &date); else bindType = AT_BIND_DEFAULT; if ((bindType == AT_BIND_DEFAULT) && !(binding && *binding) && !bindStr && (bindExact.baselineType != AT_BIND_DEFAULT)) { /* if no explicit binding is given, take unique binding from command line */ bindType = bindExact.baselineType; bindName = bindExact.baselineString; genNo = bindExact.baselineGen; revNo = bindExact.baselineRev; date = bindExact.baselineDate; } if (bindStr) *bindStr = '\0'; /* isolate pattern */ /* ToDo: handle path patterns */ strcpy (reqAttrs.af_syspath, af_afpath (pattern)); /* If no path is given, assume current directory */ if (!reqAttrs.af_syspath[0]) getcwd (reqAttrs.af_syspath, PATH_MAX); /* generate List of history names from pattern */ if ((namePatternPtr = strrchr (pattern, '/')) == NULL) namePatternPtr = pattern; else namePatternPtr++; if (!(nameList = af_histories (reqAttrs.af_syspath, stConvertPattern (namePatternPtr)))) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindSet")); return (NULL); } i=0; while (nameList[i]) { /* ignore "." and ".." */ if (nameList[i][0] == '.') { if (!nameList[i][1] || ((nameList[i][1] == '.') && !nameList[i][2])) { i++; continue; } } af_initset (&tmpSet); strcpy (reqAttrs.af_name, af_afname (nameList[i])); strcpy (reqAttrs.af_type, af_aftype (nameList[i])); switch (bindType) { case AT_BIND_DEFAULT: if (atBindTrace) { sprintf (stMessage, " Bind set: %s[] (default)", nameList[i]); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; if (af_find (&reqAttrs, &tmpSet) < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindSet")); } break; case AT_BIND_VNUM: if (atBindTrace) { sprintf (stMessage, " Bind set: %s[%d.%d] (vnum)", nameList[i], genNo, revNo); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; reqAttrs.af_gen = genNo; reqAttrs.af_rev = revNo; if (af_find (&reqAttrs, &tmpSet) < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindSet")); } break; case AT_BIND_ALIAS: case AT_BIND_CACHEKEY: sprintf (aliasAttr, "%s=%s", AT_ATTALIAS, bindName); reqAttrs.af_udattrs[0] = aliasAttr; reqAttrs.af_udattrs[1] = (char *)NULL; if ((hitCount = af_find (&reqAttrs, &tmpSet)) != 0) { if (atBindTrace) { sprintf (stMessage, " Bind set: %s[%s] (alias)", nameList[i], bindName); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; if (hitCount < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindSet")); } break; } /* no break: go on with case AT_BIND_RULE if hitSet is empty */ reqAttrs.af_udattrs[0] = NULL; case AT_BIND_RULE: if (atBindTrace) { sprintf (stMessage, " Bind set: %s[%s:] (rule)", nameList[i], bindName); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; if (bindMode == AT_BIND_UNIQUE) bindByRule (&reqAttrs, bindName, AT_BIND_UNIQUE, FALSE, &tmpSet); else bindByRule (&reqAttrs, bindName, AT_BIND_SET, FALSE, &tmpSet); break; case AT_BIND_DATE: if (atBindTrace) { sprintf (stMessage, " Bind set: %s[%s] (date)", nameList[i], stWriteTime (date)); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; bindByDate (&reqAttrs, date, &tmpSet); break; } /* switch */ if (atBindError) { free (nameList); return (NULL); } if (!(binding && *binding)) { /* check -since and -before baseline if given */ if (bindSince.baselineType != AT_BIND_DEFAULT) narrowSet (&tmpSet, &bindSince, NARROW_SINCE); if (bindBefore.baselineType != AT_BIND_DEFAULT) narrowSet (&tmpSet, &bindBefore, NARROW_BEFORE); } hitCount = af_nrofkeys (&tmpSet); if ((hitCount > 0) && ((bindMode == AT_BIND_LAST) || (bindMode == AT_BIND_LASTSAVED))) { Af_key tmpKey, tmpKey2; int j; if (bindMode == AT_BIND_LAST) { af_sortset (&tmpSet, AF_ATTMTIME); af_setgkey (&tmpSet, hitCount-1, &tmpKey); if (af_retnumattr (&tmpKey, AF_ATTSTATE) != AF_BUSY) { /* check if there is a busy version with the same modification date */ time_t mtimeOfLastInSet = af_rettimeattr (&tmpKey, AF_ATTMTIME); j=2; while ((hitCount-j) >= 0) { af_setgkey (&tmpSet, hitCount-j, &tmpKey2); if (af_rettimeattr (&tmpKey2, AF_ATTMTIME) < mtimeOfLastInSet) { af_dropkey (&tmpKey2); break; } if (af_retnumattr (&tmpKey2, AF_ATTSTATE) == AF_BUSY) { af_dropkey (&tmpKey); af_setgkey (&tmpSet, hitCount-j, &tmpKey); af_dropkey (&tmpKey2); } j++; } /* while */ } /* if */ af_setaddkey (&resultSet, AF_LASTPOS, &tmpKey); } else { /* AT_BIND_LASTSAVED */ af_sortset (&tmpSet, AF_ATTVERSION); af_setgkey (&tmpSet, hitCount-1, &tmpKey); /* add last version to result sey only if it is no busy version */ if (af_retnumattr (&tmpKey, AF_ATTSTATE) != AF_BUSY) af_setaddkey (&resultSet, AF_LASTPOS, &tmpKey); } af_dropkey (&tmpKey); } else if ((hitCount > 1) && (bindMode == AT_BIND_UNIQUE)) { /* uniqueness is not given, just do nothing */ ; } else { /* fourth parameter "FALSE" means, that no checking for duplicated elements in the result set is performed */ if (af_union (&resultSet, &tmpSet, &resultSet, FALSE) == -1) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindSet")); free (nameList); return (NULL); } } af_dropset (&tmpSet); i++; } /* while */ if (bindStr) *bindStr = '['; free (nameList); returnSet = resultSet; return (&returnSet); } /*======================= * atBindCache *=======================*/ EXPORT Af_set *atBindCache (pattern, binding) char *pattern; char *binding; /* bind names (generated from pattern) to set of cached versions * RETURN: set of Aso keys */ { static Af_set returnSet; Af_set tmpSet, resultSet; Af_attrs reqAttrs; int bindType, genNo, revNo, hitCount, i; char *bindStr = NULL, *bindName, cacheKeyAttr[AT_CACHEKEYLEN]; char *namePatternPtr, **nameList; time_t date; if (!pattern || !*pattern) { atBindError = TRUE; strcpy (atBindErrorMsg, "no name/pattern argument given (atBindCache)"); return (NULL); } atBindError = FALSE; pattern = atLocalPath (pattern); af_initset (&resultSet); af_initattrs (&reqAttrs); if ((bindStr = strrchr (pattern, '['))) bindType = atScanBinding (bindStr, &bindName, &genNo, &revNo, &date); else if (binding && *binding) bindType = atScanBinding (binding, &bindName, &genNo, &revNo, &date); else bindType = AT_BIND_DEFAULT; if ((bindType == AT_BIND_DEFAULT) && !(binding && *binding) && (bindExact.baselineType != AT_BIND_DEFAULT)) { /* if no explicit binding is given, take unique binding from command line */ bindType = bindExact.baselineType; bindName = bindExact.baselineString; genNo = bindExact.baselineGen; revNo = bindExact.baselineRev; date = bindExact.baselineDate; } if (bindType == AT_BIND_DATE) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot bind cached objects by date (atBindCache)"); return (NULL); } if (bindStr) *bindStr = '\0'; /* isolate pattern */ /* ToDo: handle path patterns */ strcpy (reqAttrs.af_syspath, af_afpath (pattern)); /* If no path is given, assume current directory */ if (!reqAttrs.af_syspath[0]) getcwd (reqAttrs.af_syspath, PATH_MAX); /* generate List of names from pattern */ if ((namePatternPtr = strrchr (pattern, '/')) == NULL) namePatternPtr = pattern; else namePatternPtr++; if (!(nameList = af_cachenames (reqAttrs.af_syspath, stConvertPattern (namePatternPtr)))) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindCache")); return (NULL); } i=0; while (nameList[i]) { af_initset (&tmpSet); strcpy (reqAttrs.af_name, af_afname (nameList[i])); strcpy (reqAttrs.af_type, af_aftype (nameList[i])); switch (bindType) { case AT_BIND_DEFAULT: if (atBindTrace) { sprintf (stMessage, " Bind cache: %s[] (default)", nameList[i]); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; if (af_cachefind (&reqAttrs, &tmpSet) < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindCache")); } break; case AT_BIND_VNUM: if (atBindTrace) { sprintf (stMessage, " Bind cache: %s[%d.%d] (vnum)", nameList[i], genNo, revNo); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; reqAttrs.af_gen = genNo; reqAttrs.af_rev = revNo; if (af_cachefind (&reqAttrs, &tmpSet) < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindCache")); } break; case AT_BIND_ALIAS: case AT_BIND_RULE: if (atBindTrace) { sprintf (stMessage, " Bind cache: %s[%s:] (rule)", nameList[i], bindName); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; bindByRule (&reqAttrs, bindName, AT_BIND_SET, TRUE, &tmpSet); break; case AT_BIND_CACHEKEY: if (atBindTrace) { sprintf (stMessage, " Bind cache: %s[%d.%d] (cache key)", nameList[i], genNo, revNo); stLog (stMessage, ST_LOG_MSG); } if (bindStr) *bindStr = '['; sprintf (cacheKeyAttr, "%s=%s", AT_ATTCACHEKEY, bindName); reqAttrs.af_udattrs[0] = cacheKeyAttr; reqAttrs.af_udattrs[1] = (char *)NULL; if (af_cachefind (&reqAttrs, &tmpSet) < 0) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindCache")); } break; } /* switch */ if (atBindError) { free (nameList); return (NULL); } hitCount = af_nrofkeys (&tmpSet); /* fourth parameter "FALSE" means, that no checking for duplicated elements in the result set is performed */ if (af_union (&resultSet, &tmpSet, &resultSet, FALSE) == -1) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindCache")); free (nameList); return (NULL); } af_dropset (&tmpSet); i++; } /* while */ if (bindStr) *bindStr = '['; free (nameList); returnSet = resultSet; return (&returnSet); } shapetools-1.4pl6.orig/src/atfstk/bind_options.c100444 2013 145 16010 5503371503 20075 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * bind_options.c - AtFS toolkit library (Version Binding) * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: bind_options.c[7.0] Tue Dec 14 18:40:58 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "sttk.h" #include "atfstk.h" #include "bind.h" /*==================== * global variables *====================*/ EXPORT BindBaseline bindExact = {AT_BIND_DEFAULT, NULL, 0, 0, 0}; EXPORT BindBaseline bindBefore = {AT_BIND_DEFAULT, NULL, 0, 0, 0}; EXPORT BindBaseline bindSince = {AT_BIND_DEFAULT, NULL, 0, 0, 0}; EXPORT int atBindModeOption = 0; /*======================== * command line parsing *========================*/ LOCAL int handleBaseline (option, arg) char *option, *arg; { BindBaseline *bPtr; if (!arg || !(*arg)) { sprintf (stMessage, "No baseline specified -- '%s' ignored.", option); stLog (stMessage, ST_LOG_ERROR); return (1); } if (*option == 'b') { /* bind or before */ if (option[1] == 'i') bPtr = &bindExact; else bPtr = &bindBefore; } else /* since */ bPtr = &bindSince; bPtr->baselineType = atScanBinding (arg, &bPtr->baselineString, &bPtr->baselineGen, &bPtr->baselineRev, &bPtr->baselineDate); if (bPtr->baselineType == AT_BIND_DEFAULT) { sprintf (stMessage, "cannot scan baseline -- '%s' option ignored.", option); stLog (stMessage, ST_LOG_ERROR); return (1); } return (0); } LOCAL int handleMode (option, arg) char *option, *arg; { if (*option == 'l') { /* last or lastsaved */ if (option[4] == 's') atBindModeOption = AT_BIND_LASTSAVED; else atBindModeOption = AT_BIND_LAST; } else if (*option == 'u') /* uniq */ atBindModeOption = AT_BIND_UNIQUE; else /* nonuniq */ atBindModeOption = AT_BIND_SET; return (0); } /*========================== * rules *==========================*/ #define AT_CMDLINERULE "_CommandLineRule_" LOCAL int handleRule (option, arg) char *option, *arg; { int argLen; if (!arg || !(*arg)) { sprintf (stMessage, "No rule specified -- '%s' ignored.", option); stLog (stMessage, ST_LOG_ERROR); return (1); } /* If string ends with a priod (.), try to scan rule */ argLen = strlen(arg); if (arg[argLen-1] == '.') { if (atBindAddRule (AT_CMDLINERULE, arg, "command line", 0)) { bindExact.baselineString = AT_CMDLINERULE; bindExact.baselineType = AT_BIND_RULE; return (0); } sprintf (stMessage, "Cannot recognize rule body -- taking '%s' argument as rule name", option); stLog (stMessage, ST_LOG_MSGERR); } bindExact.baselineString = arg; bindExact.baselineType = AT_BIND_RULE; return (0); } LOCAL int handleRuleFile (option, arg) char *option, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No rule file name specified -- '%s' ignored.", option); stLog (stMessage, ST_LOG_ERROR); return (1); } if (atBindRuleFile (arg) == FALSE) { sprintf (stMessage, "while loading %s: %s", arg, atBindErrorMsg); stLog (stMessage, ST_LOG_ERROR); return (1); } return (0); } /*========================== * option vector *==========================*/ EXPORT StOptDesc bindOptions[] = { { "before", PCALL|PARG, handleBaseline, NULL, NULL }, { "bind", PCALL|PARG, handleBaseline, NULL, NULL }, { "since", PCALL|PARG, handleBaseline, NULL, NULL }, { "uniq", PCALL, handleMode, NULL, NULL }, { "nonuniq", PCALL, handleMode, NULL, NULL }, { "last", PCALL, handleMode, NULL, NULL }, { "lastsaved", PCALL, handleMode, NULL, NULL }, { "rule", PCALL|PARG, handleRule, NULL, NULL }, { "rulefile", PCALL|PARG, handleRuleFile, NULL, NULL }, { "trace", PSWITCH|PSET, NULL, &atBindTrace, NULL }, { NULL, 0, NULL, NULL, NULL }, }; /*============================ * Parse Options *============================*/ EXPORT int atBindOptions (argc, argv, newArgc, newArgv) int argc; char **argv; int *newArgc; char *(*newArgv[]); { return (stParseArgs (argc, argv, newArgc, newArgv, bindOptions)); } EXPORT void atBindUsage (extraText) char *extraText; { stShortUsage ("version binding", bindOptions, extraText); } /*============================ * Expand Command Line *============================*/ EXPORT int atBindSetArgv (argc, argv) int *argc; char *(*argv[]); { int tmpArgc, newArgc, maxArgc = 256, pathLen, i, j; char **tmpArgv, **newArgv, *newArg, *path; Af_set *tmpSet; Af_key tmpKey; if (stParseArgs (*argc, *argv, &tmpArgc, &tmpArgv, bindOptions) == -1) return (ERROR); if ((newArgv = (char **)malloc (sizeof(char *) * maxArgc)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (ERROR); } newArgv[0] = tmpArgv[0]; newArgc = 1; for (i = 1; i < tmpArgc; i++) { path = af_afpath (tmpArgv[i]); if ((pathLen = strlen (path)) > 0) pathLen ++; if ((tmpSet = atBindSet (tmpArgv[i], NULL, 0)) == NULL) { return (ERROR); } for (j=0; j #include "atfs.h" #include "sttk.h" #include "atfstk.h" #include "bind.h" static BindRule *curRule; /*========================= * bindRuleErrors *=========================*/ #define BIND_SCAN_ERROR -1 LOCAL char *bindRuleErrorMsgs[] = { "no error", /* 0 */ "invalid predicate name", /* 1 */ "unexpected end of rule", /* 2 */ "garbage after end of rule", /* 3 */ "argument expected", /* 4 */ "'(' expected", /* 5 */ "')' expected", /* 6 */ "',', ';', or '.' expected", /* 7 */ "invalid macro citation", /* 8 */ "rule name missing", /* 9 */ "too many rule arguments", /* 10 */ "incomplete argument definition list", /* 11 */ "", }; LOCAL char *bindRuleErrorPtr; LOCAL void reportError () { char ruleText[16]; int i; memset (ruleText, 0, 16); if (bindRuleErrorPtr) { for (i=0; i<12; i++) { switch (*bindRuleErrorPtr) { case '\n': ruleText[i++] = '\\'; ruleText[i] = 'n'; break; case '\f': ruleText[i++] = '\\'; ruleText[i] = 'f'; break; case '\t': ruleText[i++] = '\\'; ruleText[i] = 't'; break; default: ruleText[i] = *bindRuleErrorPtr; } if (!(*bindRuleErrorPtr++)) break; } if (ruleText[11]) ruleText[12] = ruleText[13] = ruleText[14] = '.'; } sprintf (stMessage, "\n%s:%d: ERROR in bind rule -- %s%s%s", curRule->fileName, curRule->srcLine, bindRuleErrorMsgs[curRule->status], ruleText[0] ? " at ->" : "", ruleText[0] ? ruleText : ""); stLog (stMessage, ST_LOG_MSGERR); } LOCAL void bindRuleError (code, pos) int code; char *pos; { int saveCode = curRule->status; curRule->status = code; bindRuleErrorPtr = pos; if (code && atBindDisplayErrors) reportError (); atBindError = TRUE; strcpy (atBindErrorMsg, "rule scan error(s)"); if (saveCode) curRule->status = saveCode; /* preserve first error condition */ } /*========================= * local routines *=========================*/ #define skipWhitespace(p) while (isspace (*p)) p++; #define ALTCHAR ';' #define PREDCHAR ',' LOCAL char *moveToNextAlt (ptr) char *ptr; /* only called in case of ERROR */ /* moves forward to next alternative */ { #define SINGLEQ 01 #define DOUBLEQ 02 int parenth = 0; if (ptr && (*ptr == '\\')) ptr++; while (*ptr++) { if (*ptr == '\\') { ptr++; continue; } /* quotes and parentheses are ignored */ /* The code in comments does not work satisfactory if (*ptr == '"') quotes ^= DOUBLEQ; if (*ptr == '\'') quotes ^= SINGLEQ; if (quotes) continue; if (*ptr == '(') { parenth++; continue; } if (*ptr == ')') { parenth--; continue; } */ if ((*ptr == ';') && !parenth) { ptr++; return (ptr); } } return (NULL); } /*============================== * macro handling *==============================*/ #define NO_MACRO 0 #define SHAPE_MACRO 1 #define RULE_MACRO 2 #define RULE_PARAMETER 3 #define SHELL_COMMAND 4 LOCAL char *skipMacroCitation (ptr, macroType) char *ptr; int *macroType; { char *macroPtr = ptr; if (!*++macroPtr) { *macroType = NO_MACRO; return (ptr); } *macroType = RULE_MACRO; if ((*macroPtr == '+') || (*macroPtr == '=')) return (++macroPtr); if (*macroPtr == '_') { if (!(*++macroPtr)) { *macroType = NO_MACRO; return (ptr); } /* perhaps we should check for RULE_PARAMETER */ while (*macroPtr) { if ((*macroPtr == ',') || (*macroPtr == ')')) return (macroPtr); else if ((*macroPtr == '$') || isspace (*macroPtr)) return (++macroPtr); else macroPtr++; } bindRuleError (8, macroPtr); *macroType = -1; return (ptr); } *macroType = SHAPE_MACRO; if ((*macroPtr != '(') && (*macroPtr != '{')) return (++macroPtr); while (*macroPtr && (*macroPtr != '\n')) { if ((*macroPtr == ')') || (*macroPtr == '}')) return (++macroPtr); else macroPtr++; } bindRuleError (8, macroPtr); *macroType = -1; return (ptr); } /*======================== * ruleInit *========================*/ static char *nextAlt; static char *nextPred; LOCAL int ruleInit (rule) BindRule *rule; /* do initial parsing if necessary (preprocessing ?). * set alternative pointer to first alternative. * RETURN: TRUE or FALSE */ { curRule = rule; curRule->status = 0; curRule->altList = NULL; nextAlt = curRule->body; nextPred = NULL; if (!curRule->body) { bindRuleError (2, (char *)0); return (FALSE); } return (TRUE); } /*========================== * predicate list *==========================*/ /* predicate names -- ordered alphabetically */ #define PREDCOUNT 29 /* number of valid predicate names */ LOCAL struct { char *name; int argCount; int predCode; } predicates[] = { { "attr", 2, BIND_PRED_ATTR }, { "attrex", 1, BIND_PRED_ATTREX }, { "attrge", 2, BIND_PRED_ATTRGE }, { "attrgt", 2, BIND_PRED_ATTRGT }, { "attrle", 2, BIND_PRED_ATTRLE }, { "attrlt", 2, BIND_PRED_ATTRLT }, { "attrmax", 1, BIND_PRED_ATTRMAX }, { "attrmin", 1, BIND_PRED_ATTRMIN }, { "attrnot", 2, BIND_PRED_ATTRNOT }, { "bindrule", 1, BIND_PRED_RULE }, { "condex", 1, BIND_PRED_CONDEX }, { "condexpr", 2, BIND_PRED_CONDEXPR }, { "condnot", 1, BIND_PRED_CONDNOT }, { "conduniq", 1, BIND_PRED_CONDUNIQ }, { "confirm", 2, BIND_PRED_CONFIRM }, { "cut", 1, BIND_PRED_CUT }, { "eq", 2, BIND_PRED_ATTR }, { "exists", 1, BIND_PRED_CONDEX }, { "existsnot", 1, BIND_PRED_CONDNOT }, { "existsuniq", 1, BIND_PRED_CONDUNIQ }, { "ge", 2, BIND_PRED_ATTRGE }, { "gt", 2, BIND_PRED_ATTRGT }, { "hasattr", 1, BIND_PRED_ATTREX }, { "le", 2, BIND_PRED_ATTRLE }, { "lt", 2, BIND_PRED_ATTRLT }, { "max", 1, BIND_PRED_ATTRMAX }, { "min", 1, BIND_PRED_ATTRMIN }, { "msg", 1, BIND_PRED_MSG }, { "ne", 2, BIND_PRED_ATTRNOT } }; LOCAL int getPred (str) char *str; { int hi = PREDCOUNT-1, lo=0, predNum, res; if ((str[0] == '-') && !str[1]) str = "cut"; /* get predicate number (binary search) */ predNum = (hi+lo)/2; while (hi >= lo) { if ((res = strcmp (str, predicates[predNum].name)) == 0) { return (predNum); } if (res < 0) hi = predNum - 1; else lo = predNum + 1; predNum = (hi+lo)/2; } return (-1); } EXPORT char *atBindPredName (pos) int pos; { return (predicates[pos].name); } EXPORT int atBindPredCode (pos) int pos; { return (predicates[pos].predCode); } /*========================= * rulePredArgs *==========================*/ LOCAL char *rulePredArgs (ptr, pred) char *ptr; Predicate *pred; { int singleQuotes = FALSE, doubleQuotes = FALSE; int parenthCount=0, foundEscape, macroType; char lastChar, *spacePtr, *auxPtr1, *auxPtr2; pred->args[0] = (char *)0; pred->args[1] = (char *)0; skipWhitespace (ptr); if (*ptr != '(') { bindRuleError (5, ptr); return (NULL); } ptr++; skipWhitespace (ptr); /* first argument */ switch (*ptr) { case '"': doubleQuotes = TRUE; ptr++; break; case '\'': singleQuotes = TRUE; ptr++; break; case ')': /* empty argument list */ ptr++; switch (predicates[pred->position].argCount) { case 0: return (ptr); case 1: pred->args[0] = ""; return (ptr); case 2: bindRuleError (4, ptr); return (NULL); } break; case ',': /* empty first argument */ pred->args[0] = ""; lastChar = *ptr++; goto secondArg; break; } if (predicates[pred->position].argCount == 0) { bindRuleError (6, ptr); return (NULL); } foundEscape = FALSE; spacePtr = NULL; pred->args[0] = ptr; while (*ptr) { if (*ptr == '\\') { foundEscape = TRUE; ptr++; ptr++; continue; } if ((*ptr == '(') && !(doubleQuotes || singleQuotes)) parenthCount++; if ((*ptr == '`') && !singleQuotes) pred->info |= BIND_ARG1_SHELL_COMMAND; if ((*ptr == '$') && !singleQuotes) { ptr = skipMacroCitation (ptr, ¯oType); switch (macroType) { case SHAPE_MACRO: pred->info |= BIND_ARG1_SHAPE_MACRO; break; case RULE_MACRO: case RULE_PARAMETER: pred->info |= BIND_ARG1_RULE_MACRO; break; case NO_MACRO: ptr++; break; default: return (NULL); } } else ptr++; if (isspace (*ptr) && !(doubleQuotes || singleQuotes)) { spacePtr = ptr; skipWhitespace (ptr); } if ((*ptr == ')') && !(doubleQuotes || singleQuotes)) { if (parenthCount) parenthCount--; else break; } else if ((*ptr == ',') && (!parenthCount || doubleQuotes || singleQuotes)) break; if (((*ptr == '"') && doubleQuotes) || ((*ptr == '\'') && singleQuotes)) { *ptr++ = '\0'; doubleQuotes = FALSE; singleQuotes = FALSE; skipWhitespace (ptr); break; } spacePtr = NULL; } if (!*ptr) { bindRuleError (2, (char *)0); return (FALSE); } else lastChar = *ptr; if (spacePtr) *spacePtr = '\0'; else *ptr = '\0'; ptr++; /* eliminate escape chars */ if (foundEscape && (auxPtr1 = auxPtr2 = pred->args[0])) { while (*auxPtr1) { if (*auxPtr1 == '\\') auxPtr1++; *auxPtr2++ = *auxPtr1++; } *auxPtr2 = *auxPtr1; } secondArg: if (lastChar == ',') { if (predicates[pred->position].argCount == 1) { bindRuleError (6, ptr); return (NULL); } skipWhitespace (ptr); /* second argument */ switch (*ptr) { case '"': doubleQuotes = TRUE; ptr++; break; case '\'': singleQuotes = TRUE; ptr++; break; case ')': /* empty second argument */ pred->args[1] = ""; ptr++; return (ptr); break; } foundEscape = FALSE; spacePtr = NULL; pred->args[1] = ptr; while (*ptr) { if (*ptr == '\\') { foundEscape = TRUE; ptr++; ptr++; continue; } if ((*ptr == '(') && !(doubleQuotes || singleQuotes)) parenthCount++; if ((*ptr == '`') && !singleQuotes) pred->info |= BIND_ARG2_SHELL_COMMAND; if ((*ptr == '$') && !singleQuotes) { ptr = skipMacroCitation (ptr, ¯oType); switch (macroType) { case SHAPE_MACRO: pred->info |= BIND_ARG2_SHAPE_MACRO; break; case RULE_MACRO: case RULE_PARAMETER: pred->info |= BIND_ARG2_RULE_MACRO; break; case NO_MACRO: ptr++; break; default: return (NULL); } } else ptr++; if (isspace (*ptr) && !(doubleQuotes || singleQuotes)) { spacePtr = ptr; skipWhitespace (ptr); } if ((*ptr == ')') && !(doubleQuotes || singleQuotes)) { if (parenthCount) parenthCount--; else break; } if (((*ptr == '"') && doubleQuotes) || ((*ptr == '\'') && singleQuotes)) { *ptr++ = '\0'; doubleQuotes = FALSE; singleQuotes = FALSE; skipWhitespace (ptr); break; } spacePtr = NULL; } if (!*ptr) { bindRuleError (2, (char *)0); return (FALSE); } else lastChar = *ptr; if (spacePtr) *spacePtr = '\0'; else *ptr = '\0'; ptr++; /* eliminate escape chars */ if (foundEscape && (auxPtr1 = auxPtr2 = pred->args[1])) { while (*auxPtr1) { if (*auxPtr1 == '\\') auxPtr1++; *auxPtr2++ = *auxPtr1++; } *auxPtr2 = *auxPtr1; } } else { if (predicates[pred->position].argCount == 2) { bindRuleError (4, ptr); return (NULL); } } if (lastChar != ')') { bindRuleError (6, ptr); return (NULL); } return (ptr); } /*========================= * rulePredicate *==========================*/ LOCAL int rulePredicate (curPred) Predicate *curPred; /* scan next predicate and promote predicate pointer. * RETURN: FALSE on end of predicate, BIND_SCAN_ERROR on error, else TRUE. */ { char predName[16], *ptr, *newPtr; int i; if ((!nextPred) || (!*nextPred)) return (FALSE); ptr = nextPred; skipWhitespace (ptr); /* skip empty predicates */ while (*ptr == ',') { ptr++; skipWhitespace (ptr); } /* check for end of alternative */ if (*ptr == ';') { nextAlt = ptr+1; nextPred = NULL; return (FALSE); } /* check for end of rule */ if (*ptr == '.') { nextPred = NULL; nextAlt = NULL; ptr++; skipWhitespace (ptr); if (*ptr) { bindRuleError (3, ptr); return (BIND_SCAN_ERROR); } else return (FALSE); } curPred->info = 0; i=0; while (isalnum (*ptr) || (*ptr == '-')) { predName[i++] = *ptr++; if (i == 16) { bindRuleError (1, ptr); nextPred = NULL; nextAlt = moveToNextAlt (ptr); return (BIND_SCAN_ERROR); } } predName[i] = '\0'; if ((curPred->position = getPred (predName)) == -1) { bindRuleError (1, ptr); nextPred = NULL; nextAlt = moveToNextAlt (ptr); return (BIND_SCAN_ERROR); } if (!strcmp (predName, "-")) { /* special treatment of cut operator */ curPred->args[0] = "\0"; curPred->args[1] = (char *)0; } else { if ((newPtr = rulePredArgs (ptr, curPred)) == (char *)0) { nextPred = NULL; nextAlt = moveToNextAlt (ptr); return (BIND_SCAN_ERROR); } ptr = newPtr; } skipWhitespace (ptr); switch (*ptr) { case ';': nextAlt = ptr+1; nextPred = NULL; return (TRUE); case '.': nextAlt = NULL; nextPred = NULL; return (TRUE); case ',': nextPred = ptr+1; return (TRUE); default: bindRuleError (7, ptr); nextPred = NULL; nextAlt = moveToNextAlt (ptr); return (BIND_SCAN_ERROR); } } /*========================= * ruleAlternative *==========================*/ LOCAL int ruleAlternative (curAlt) Alternative *curAlt; /* determine pattern of next alternative to be processed. * set predicate pointer to first predicate. * initialize curAlt with pattern and NULL values. * RETURN: FALSE on end of rule BIND_SCAN_ERROR on error, else TRUE. */ { char *ptr, *auxPtr, *spacePtr = NULL; int foundEscape=FALSE, macroType; curAlt->pattern = (char *)0; curAlt->predList = (Predicate *)0; curAlt->info = 0; curAlt->next = (Alternative *)0; if ((!nextAlt) || (!*nextAlt)) return (FALSE); ptr = nextAlt; skipWhitespace (ptr); switch (*ptr) { case ',': /* empty pattern */ nextPred = ptr+1; return (TRUE); case ';': /* empty alternative */ nextPred = NULL; nextAlt = ptr+1; return (TRUE); case '.': /* possible end of rule */ auxPtr = ptr+1; skipWhitespace (auxPtr); if (!*auxPtr) { /* end of rule */ nextAlt = NULL; nextPred = NULL; return (TRUE); } break; } curAlt->pattern = ptr; while (*ptr) { if (*ptr == '\\') { foundEscape = TRUE; ptr++; ptr++; continue; } if (*ptr == '`') curAlt->info |= BIND_PATTERN_SHELL_COMMAND; if (*ptr == '$') { ptr = skipMacroCitation (ptr, ¯oType); switch (macroType) { case SHAPE_MACRO: curAlt->info |= BIND_PATTERN_SHAPE_MACRO; break; case RULE_MACRO: case RULE_PARAMETER: curAlt->info |= BIND_PATTERN_RULE_MACRO; break; case NO_MACRO: ptr++; break; default: nextPred = NULL; nextAlt = moveToNextAlt (ptr); return (BIND_SCAN_ERROR); } } else ptr++; if (isspace (*ptr)) { spacePtr = ptr; skipWhitespace (ptr); } if ((*ptr == ',') || (*ptr == ';')) break; if (*ptr == '.') { auxPtr = ptr+1; skipWhitespace (auxPtr); if (!*auxPtr) { /* end of rule */ *ptr = '\0'; nextAlt = NULL; nextPred = NULL; goto finish; } } if (*ptr == '(') { /* check if rule starts with a predicate instead of a pattern */ if (spacePtr) *spacePtr = '\0'; else *ptr = '\0'; if (getPred (curAlt->pattern) != -1) { /* found regular predicate -- assume no explicit pattern */ curAlt->pattern = (char *)0; if (spacePtr) *spacePtr = ' '; else *ptr = '('; nextPred = nextAlt; return (TRUE); } else { if (spacePtr) *spacePtr = ' '; else *ptr = '('; } } if (spacePtr) spacePtr = NULL; } /* while */ if (!*ptr) { bindRuleError (2, (char *)0); nextAlt = NULL; nextPred = NULL; return (BIND_SCAN_ERROR); } if (*ptr == ',') nextPred = ptr+1; if (*ptr == ';') { nextPred = NULL; nextAlt = ptr+1; } if (spacePtr) *spacePtr = '\0'; else *ptr = '\0'; finish: /* if pattern is empty or just an asterisk */ if (!*(curAlt->pattern)) curAlt->pattern = (char *)0; else if ((curAlt->pattern[0] == '*') && !curAlt->pattern[1]) curAlt->pattern = (char *)0; /* eliminate escape chars */ if (foundEscape && (auxPtr = ptr = curAlt->pattern)) { while (*ptr) { if (*ptr == '\\') ptr++; *auxPtr++ = *ptr++; } *auxPtr = *ptr; } return (TRUE); } /*========================= * atRuleNameScan *=========================*/ EXPORT int atRuleNameScan (rule) BindRule *rule; /* see if rule name contains parameter definitions */ { char *endPtr, *argPtr = strchr (rule->name, '('); rule->argNum = 0; if (!rule->name) { bindRuleError (9, rule->name); return (FALSE); } if (!argPtr) endPtr = &(rule->name[strlen(rule->name)-1]); else endPtr = argPtr-1; if (endPtr < rule->name) { bindRuleError (9, rule->name); return (FALSE); } /* remove trailing whitespace */ while (isspace (*endPtr)) { *endPtr = '\0'; if (endPtr-- == rule->name) { bindRuleError (9, rule->name); return (FALSE); } } if (!argPtr) /* no arguments */ return (TRUE); *argPtr++ = '\0'; while (1) { while (isspace (*argPtr)) argPtr++; rule->argList[rule->argNum++] = argPtr; if (rule->argNum == BIND_MAX_RULEARGS) { bindRuleError (10, argPtr); return (FALSE); } while (isgraph (*argPtr) && (*argPtr != ',') && (*argPtr != ')')) argPtr++; while (isspace (*argPtr)) *argPtr++ = '\0'; if (!*argPtr) { bindRuleError (11, argPtr); return (FALSE); } if (*argPtr == ')') { /* end of argument list */ *argPtr = '\0'; return (TRUE); } *argPtr++ = '\0'; } } /*========================= * atRuleScan *=========================*/ #define LISTSEG_SIZE 128 LOCAL Alternative *altList; LOCAL int altListIndex = LISTSEG_SIZE; LOCAL Predicate *predList; LOCAL int predListIndex = LISTSEG_SIZE; EXPORT int atRuleScan (rule) BindRule *rule; /* do syntax and plausibility check for version binding rule. * write error messages to stderr, if "displayErrors" is set TRUE. * else be silent and give up on first error occured. * RETURN: 0 or scan error code */ { Alternative **nextAltPtr; Predicate **nextPredPtr; int retCode = TRUE, resultCode; if (ruleInit (rule) == FALSE) return (FALSE); /* scan rule name */ if (atRuleNameScan (rule) == FALSE) return (FALSE); nextAltPtr = &(rule->altList); while (1) { if (altListIndex == LISTSEG_SIZE) { /* need new Alternative buffers */ if ((altList = (Alternative *) malloc ((size_t) LISTSEG_SIZE*sizeof(Alternative))) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (FALSE); } altListIndex = 0; } if (!(resultCode = ruleAlternative (&altList[altListIndex]))) { /* end of rule */ *nextAltPtr = (Alternative *)0; return (retCode); } if (resultCode == BIND_SCAN_ERROR) { retCode = FALSE; continue; } *nextAltPtr = &altList[altListIndex]; nextAltPtr = &(altList[altListIndex].next); nextPredPtr = &(altList[altListIndex].predList); altListIndex++; while (1) { if (predListIndex == LISTSEG_SIZE) { /* need new Predicate bufs */ if ((predList = (Predicate *) malloc ((size_t) LISTSEG_SIZE*sizeof(Predicate))) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (FALSE); } predListIndex = 0; } if (!(resultCode = rulePredicate (&predList[predListIndex]))) { /* end of alternative */ *nextPredPtr = (Predicate *)0; break; } if (resultCode == BIND_SCAN_ERROR) { retCode = FALSE; continue; } *nextPredPtr = &predList[predListIndex]; nextPredPtr = &(predList[predListIndex].next); predListIndex++; } } } /*========================= * atRuleDisplay *=========================*/ EXPORT void atRuleDisplay (rule) BindRule *rule; /* display selection rule */ { Alternative *alt = rule->altList; Predicate *pred; int firstAlt = TRUE; stLog ("", ST_LOG_MSG); if (rule->fileName) { sprintf (stMessage, "# from file %s (line %d)", rule->fileName, rule->srcLine); stLog (stMessage, ST_LOG_MSG); } if (rule->status) { sprintf (stMessage, "# ERROR -- %s", bindRuleErrorMsgs[rule->status]); stLog (stMessage, ST_LOG_MSG); } if (rule->argNum) { int i; sprintf (stMessage, "%s (", rule->name); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); for (i=0; iargNum-1; i++) { sprintf (stMessage, "%s, ", rule->argList[i]); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); } sprintf (stMessage, "%s):-", rule->argList[i]); stLog (stMessage, ST_LOG_MSG); } else sprintf (stMessage, "%s:-", rule->name); stLog (stMessage, ST_LOG_MSG); while (alt) { if (firstAlt) { sprintf (stMessage, "\t%s", alt->pattern ? alt->pattern : "*"); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); fflush (stdout); firstAlt = FALSE; } else { sprintf (stMessage, ";\n\t%s", alt->pattern ? alt->pattern : "*"); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); fflush (stdout); } pred = alt->predList; while (pred) { sprintf (stMessage, ",\n\t %s \t", predicates[pred->position].name); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); fflush (stdout); switch (predicates[pred->position].argCount) { case 0: stLog ("()", ST_LOG_MSG | ST_LOG_NONL); fflush (stdout); break; case 1: sprintf (stMessage, "(%s)", pred->args[0] ? pred->args[0] : ""); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); fflush (stdout); break; case 2: sprintf (stMessage, "(%s, %s)", pred->args[0] ? pred->args[0] : "", pred->args[1] ? pred->args[1] : ""); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); fflush (stdout); break; } pred = pred->next; } alt = alt->next; } if (!firstAlt) { stLog (".", ST_LOG_MSG); fflush (stdout); } } shapetools-1.4pl6.orig/src/atfstk/bind_rules.c100444 2013 145 50540 5537601015 17543 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * bind_rules.c -- AtFS toolkit library (Version Binding) * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: bind_rules.c[7.0] Thu Mar 10 12:23:24 1994 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "sttk.h" #include "atfstk.h" #include "bind.h" /*========================= * rules list etc. *=========================*/ #define RULE_SEG_SIZE 64 LOCAL BindRule *bindRules; LOCAL int ruleCount=0, ruleListSize=0; EXPORT char *(*atBindExpandMacro)(); EXPORT int atBindDisplayErrors = FALSE; /*========================= * atBindInitRules *=========================*/ LOCAL int rulesInitialized = FALSE; EXPORT int atBindInitRules () { struct stat inodeBuf; char *envPtr, ruleFileName[PATH_MAX]; if (rulesInitialized) return (TRUE); else rulesInitialized = TRUE; if (!(envPtr = getenv (ST_ENV))) envPtr = ST_ENV_DEFAULT; strcpy (ruleFileName, envPtr); strcat (ruleFileName, ST_ENV_SHAPELIB); strcat (ruleFileName, "/"); strcat (ruleFileName, BIND_RULES_FILENAME); if (stat (ruleFileName, &inodeBuf) != -1) return (atBindRuleFile (ruleFileName)); return (TRUE); /* no file found, this is ok */ } /*========================= * atBindShowRules *=========================*/ EXPORT int atBindShowRules () { int i; atBindInitRules (); stLog ("# The following rule section is a atBind rule database dump !", ST_LOG_MSG); for (i=0; i=0; i--) { if (!strcmp (bindRules[i].name, name)) { if (parenthPtr) *parenthPtr = '('; return (TRUE); } } if (parenthPtr) *parenthPtr = '('; return (FALSE); } /*========================= * atBindRuleFile *=========================*/ #define nextLine(p) { while (*p && (*p++ != '\n')); lineNo++; } LOCAL int scanFile (ruleBuf) char *ruleBuf; { char *rulePtr = ruleBuf; int lineNo = 1; if (!rulePtr || !*rulePtr) return (TRUE); /* ToDo: scan Shapefiles */ while (*rulePtr) { if (*rulePtr == '\\') { rulePtr++; rulePtr++; continue; } if (*rulePtr == '#') { while (*rulePtr) { if (*rulePtr == '\\') { *rulePtr++ = ' '; *rulePtr++ = ' '; continue; } if (*rulePtr == '\n') break; *rulePtr++ = ' '; } } else rulePtr++; } rulePtr = ruleBuf; while (1) { if (!*rulePtr) return (TRUE); if (ruleCount == ruleListSize) { if (ruleListSize == 0) bindRules = (BindRule *)malloc ((size_t) RULE_SEG_SIZE * sizeof (BindRule)); else bindRules = (BindRule *)realloc (bindRules, (size_t) (ruleListSize + RULE_SEG_SIZE) * sizeof (BindRule)); if (!bindRules) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (FALSE); } ruleListSize += RULE_SEG_SIZE; } /* lookout for rule name */ if (isgraph (*rulePtr)) { bindRules[ruleCount].name = rulePtr; bindRules[ruleCount].srcLine = lineNo+1; while (*rulePtr && (*rulePtr != ':') && (*rulePtr != '\n')) rulePtr++; if (*rulePtr) { if (*rulePtr == '\n') { *rulePtr++ = '\0'; lineNo++; } else { *rulePtr++ = '\0'; nextLine (rulePtr); } } else { bindRules[ruleCount++].body = (char *)0; return (TRUE); } } else { nextLine (rulePtr); continue; } /* get rule body */ if (!*rulePtr || (*rulePtr != '\t')) { bindRules[ruleCount++].body = (char *)0; continue; } bindRules[ruleCount++].body = rulePtr; while (*rulePtr == '\t') nextLine(rulePtr); if (!*rulePtr) return (TRUE); *(rulePtr-1) = '\0'; } } EXPORT int atBindRuleFile (fileName) char *fileName; { Af_key *ruleFileKey; FILE *ruleFile; char *ruleBuf, *fileNameBuf; int i, retCode = TRUE; size_t fileSize; atBindError = FALSE; atBindInitRules (); if ((ruleFileKey = atBindVersion (fileName, "[]")) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot find "); strcat (atBindErrorMsg, fileName); return (FALSE); } fileSize = af_retnumattr (ruleFileKey, AF_ATTSIZE); if ((ruleBuf = malloc (fileSize+1)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (FALSE); } if ((ruleFile = af_open (ruleFileKey, "r")) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot open "); strcat (atBindErrorMsg, fileName); return (FALSE); } fread (ruleBuf, sizeof(char), fileSize, ruleFile); ruleBuf[fileSize] = '\0'; af_close (ruleFile); if ((fileNameBuf = malloc ((size_t) strlen (fileName)+1)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (FALSE); } strcpy (fileNameBuf, fileName); i = ruleCount; retCode = scanFile (ruleBuf); for (; i= maxSize) { \ maxSize += (ns+255); \ if ((newString = realloc (newString, maxSize)) == NULL) { \ atBindError = TRUE; \ strcpy (atBindErrorMsg, "not enough memory"); \ return (NULL); } } LOCAL char *ruleExpandMacro (str, hitSet) char *str; Af_set *hitSet; { char *newString; char *ptr = str, *newPtr; size_t newSize = 0, maxSize = strlen(str)+256; char attrNameBuf[256], *attrNamePtr, *attrBuf, numBuf[16]; int attrLen, i, hitCount = af_nrofkeys(hitSet); if ((newString = malloc (maxSize)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (NULL); } newPtr = newString; while ((*newPtr = *ptr)) { needSpace (1); if (*ptr != '$') { newPtr++; ptr++; continue; } /* check if dollar sign was escaped */ if ((ptr > str) && *(ptr-1) == '\\') { newPtr++; ptr++; continue; } ptr++; if (*ptr == '+') { int targNameLen = strlen(curEval->targName); ptr++; needSpace (targNameLen); strncpy (newPtr, curEval->targName, targNameLen); newPtr += targNameLen; continue; } if (*ptr == '=') { char numBuf[16]; int numLen; ptr++; sprintf (numBuf, "%d", hitCount); numLen = strlen (numBuf); needSpace (numLen); strncpy (newPtr, numBuf, numLen); newPtr += numLen; continue; } if (*ptr != '_') { newPtr++; continue; } ptr++; if (!strncmp (ptr, "hits", 4)) { ptr += 4; if (*ptr == '$') ptr++; sprintf (numBuf, "%d", hitCount); attrLen = strlen (numBuf); needSpace (attrLen); strncpy (newPtr, numBuf, attrLen); newPtr += attrLen; continue; } if (!strncmp (ptr, "rule", 4)) { ptr += 4; if (*ptr == '$') ptr++; attrLen = strlen (bindRules[curEval->ruleTabIdx].name); needSpace (attrLen); strncpy (newPtr, bindRules[curEval->ruleTabIdx].name, attrLen); newPtr += attrLen; continue; } if (!strncmp (ptr, "target", 6)) { ptr += 6; if (*ptr == '$') ptr++; attrLen = strlen (curEval->targName); needSpace (attrLen); strncpy (newPtr, curEval->targName, attrLen); newPtr += attrLen; continue; } /* else: regular attribute citation or rule parameter */ attrNamePtr = attrNameBuf; while (*ptr && (*ptr != '$') && (*ptr != ',') && (*ptr != ')') && !isspace(*ptr)) *attrNamePtr++ = *ptr++; *attrNamePtr = '\0'; attrBuf = NULL; for (i=0; iruleTabIdx].argNum; i++) { if (!strcmp (bindRules[curEval->ruleTabIdx].argList[i], attrNameBuf)) attrBuf = curEval->ruleArgs[i]; } if (!attrBuf && (hitCount == 1)) { Af_key aso; if (af_setgkey (hitSet, 0, &aso) == -1) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("ruleExpandMacro")); return (NULL); } attrBuf = af_retattr (&aso, attrNameBuf); af_dropkey (&aso); } if (attrBuf) { if (*ptr == '$') ptr++; attrLen = strlen (attrBuf); needSpace (attrLen); strncpy (newPtr, attrBuf, attrLen); newPtr += attrLen; } else { attrLen = strlen (attrNameBuf); needSpace (attrLen+2); strncpy (newPtr, "$_", 2); newPtr += 2; strncpy (newPtr, attrNameBuf, attrLen); newPtr += attrLen; if (*ptr == '$') { ptr++; needSpace (1); *newPtr++ = '$'; } } } needSpace (1); *newPtr++ = '\0'; return (newString); } LOCAL char *ruleExpandCommand (str) char *str; { char *newString, *newPtr, *endPtr, *ptr = str; char resultBuf[10240]; size_t newSize = 0, maxSize = 256; int resultLen; FILE *fileDes; if ((newString = malloc (maxSize)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (NULL); } newPtr = newString; while ((*newPtr = *ptr)) { needSpace (1); if (*ptr != '`') { newPtr++; ptr++; continue; } ptr++; if ((endPtr = strchr (ptr, '`')) == NULL) { newPtr++; continue; } *endPtr = '\0'; if ((fileDes = popen (ptr, "r")) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "error during popen"); return (NULL); } if (fgets (resultBuf, 10240, fileDes) == NULL) { resultBuf[0] = '\0'; } resultBuf[10240-1] = '\0'; pclose(fileDes); resultLen = strlen (resultBuf); needSpace (resultLen); strncpy (newPtr, resultBuf, resultLen); newPtr += resultLen; *endPtr = '`'; ptr = endPtr+1; } return (newString); } /*====================================== * set new rules and restore old ones *======================================*/ EXPORT char *atCurRuleName () { return (bindRules[curEval->ruleTabIdx].name); } EXPORT int atBindSetRule (ruleName, targName, init) char *ruleName; char *targName; int init; /* initial rule setting if TRUE */ /* Returns rule status 0 - ok, 1-32 - rule error code, -1 internal error, -2 not found */ { /* set "ruleName" as version bind rule to be applied. This initializes the global variable "curEval" subsequently accessed by atBindRuleAlt. It realizes a stack of rules, represented as chained list, with "firstEval" as anchor and "curEval" as top. This stack has two reasons. First, a recursive evaluation due to "condexist|not|uniq" may use different selection rules, second the "rule" attribute may temporarily switch to another rule for the same name. In the first case, the "init" argument should be TRUE, indicating that this is the initial rule for the current selection. In the second case, "init" should be FALSE. */ char *rulePtr, *myRuleName; ProcRule *prevEval = curEval; int i; if (firstEval) { if ((curEval->next = (ProcRule *)malloc ((size_t) sizeof (ProcRule))) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (-1); } curEval = curEval->next; } else { if ((firstEval = (ProcRule *)malloc ((size_t) sizeof (ProcRule))) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (-1); } curEval = firstEval; } if ((myRuleName = malloc ((size_t) strlen (ruleName)+1)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); return (-1); } strcpy (myRuleName, ruleName); rulePtr = myRuleName; curEval->next = NULL; curEval->targName = targName; /* leave a marker on the stack, when a new evaluation starts. */ curEval->firstRule = init; /* Cut off arguments (in parenthesis) from the rule name. When there are no arguments, "rulePtr" will be NULL. Otherwise, "rulePtr" points to the open parenthesis in "myRuleName" which is replaced by a \0 rtemporarily. */ while (isgraph (*rulePtr) && (*rulePtr != '(')) rulePtr++; if (*rulePtr) { if (*rulePtr == '(') *rulePtr++ = '\0'; else { while (isspace (*rulePtr)) *rulePtr++ = '\0'; if (*rulePtr == '(') *rulePtr++ = '\0'; else rulePtr = NULL; } } else rulePtr = NULL; for (curEval->ruleTabIdx=ruleCount-1; curEval->ruleTabIdx>=0; curEval->ruleTabIdx--) { if (!strcmp (bindRules[curEval->ruleTabIdx].name, myRuleName)) { curEval->procAlt = bindRules[curEval->ruleTabIdx].altList; curEval->firstAlt = TRUE; break; } } if (curEval->ruleTabIdx < 0) { curEval = prevEval; if (curEval) { free (curEval->next); curEval->next = NULL; } else { free (firstEval); firstEval = NULL; } return (-2); } /* expect bindRules[curEval->ruleTabIdx].argNum arguments */ i=0; if (bindRules[curEval->ruleTabIdx].argNum && rulePtr) { while (1) { while (isspace (*rulePtr)) rulePtr++; curEval->ruleArgs[i++] = rulePtr; if (i == BIND_MAX_RULEARGS) break; while (isgraph (*rulePtr) && (*rulePtr != ',') && (*rulePtr != ')')) rulePtr++; while (isspace (*rulePtr)) *rulePtr++ = '\0'; if (!*rulePtr) break; if (*rulePtr == ')') { *rulePtr = '\0'; break; } *rulePtr++ = '\0'; } } /* initialize remaining arguments, if there are any */ for (;i < bindRules[curEval->ruleTabIdx].argNum; i++) curEval->ruleArgs[i] = ""; return (bindRules[curEval->ruleTabIdx].status); } EXPORT void atBindUnsetRule (abort) int abort; /* the abort argument says, if the whole selection is to be aborted -> (TRUE) all rules back to "firstRule" should be popped off the stack or just -> (FALSE) the last rule will be popped off. */ { if (curEval == firstEval) { free (firstEval); firstEval = curEval = NULL; } else { ProcRule *endPtr = firstEval, *basePtr = firstEval; while (endPtr->next->next) { endPtr = endPtr->next; if (endPtr->next->firstRule) basePtr = endPtr; } if (abort) curEval = basePtr; else curEval = endPtr; /* free rest of chained list */ endPtr = curEval->next; while (endPtr) { basePtr = endPtr; endPtr = endPtr->next; free (basePtr); } curEval->next = NULL; } } EXPORT char *atBindRuleAlt (hitSet) Af_set *hitSet; { char *tmpPattern; if (!curEval->firstAlt && curEval->procAlt) curEval->procAlt = curEval->procAlt->next; else curEval->firstAlt = FALSE; while (!curEval->procAlt && !curEval->firstRule) { /* if rule to be processed is done and there is a previous rule, restore it */ atBindUnsetRule (FALSE); curEval->procAlt = curEval->procAlt->next; } if (curEval->procAlt) { curEval->procPred = curEval->procAlt->predList; curEval->firstPred = TRUE; if (curEval->procAlt->pattern) { tmpPattern = curEval->procAlt->pattern; if (curEval->procAlt->info & BIND_PATTERN_RULE_MACRO) tmpPattern = ruleExpandMacro (tmpPattern, hitSet); if ((curEval->procAlt->info & BIND_PATTERN_SHAPE_MACRO) && (atBindExpandMacro)) tmpPattern = atBindExpandMacro (tmpPattern); if (curEval->procAlt->info & BIND_PATTERN_SHELL_COMMAND) tmpPattern = ruleExpandCommand (tmpPattern); return (tmpPattern); } else return ("*"); } else return (NULL); } EXPORT int atBindRulePred (arg1, arg2, hitSet) char **arg1; char **arg2; Af_set *hitSet; { char *tmpArg; if (!curEval->firstPred && curEval->procPred) curEval->procPred = curEval->procPred->next; else curEval->firstPred = FALSE; if (curEval->procPred) { tmpArg = curEval->procPred->args[0]; if (curEval->procPred->info & BIND_ARG1_RULE_MACRO) tmpArg = ruleExpandMacro (tmpArg, hitSet); if ((curEval->procPred->info & BIND_ARG1_SHAPE_MACRO) && (atBindExpandMacro)) tmpArg = atBindExpandMacro (tmpArg); if (curEval->procPred->info & BIND_ARG1_SHELL_COMMAND) tmpArg = ruleExpandCommand (tmpArg); *arg1 = tmpArg; tmpArg = curEval->procPred->args[1]; if (curEval->procPred->info & BIND_ARG2_RULE_MACRO) tmpArg = ruleExpandMacro (tmpArg, hitSet); if ((curEval->procPred->info & BIND_ARG2_SHAPE_MACRO) && (atBindExpandMacro)) tmpArg = atBindExpandMacro (tmpArg); if (curEval->procPred->info & BIND_ARG2_SHELL_COMMAND) tmpArg = ruleExpandCommand (tmpArg); *arg2 = tmpArg; return (curEval->procPred->position); } else return (-1); } shapetools-1.4pl6.orig/src/atfstk/bind_attr.c100444 2013 145 53753 5522254111 17367 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * bind_attr.c -- AtFS toolkit library (Version Binding) * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: bind_attr.c[7.0] Fri Jan 28 19:37:39 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "sttk.h" #include "atfstk.h" #include "bind.h" /*========================= * getAttr *=========================*/ LOCAL int getAttr (attrName) char *attrName; { int i; for (i = 0; atStdAttrTab[i].name; i++) { if (!(strcmp (attrName, atStdAttrTab[i].name))) return (atStdAttrTab[i].code); } return (-1); } /*========================= * atBindAttrAbsolute *=========================*/ EXPORT int atBindAttrAbsolute (set, attrName, attrValue) Af_set *set; char *attrName; char *attrValue; { int attrNum = getAttr (attrName), hits, bindType; Af_attrs reqAttrs; char *alias; af_initattrs (&reqAttrs); switch (attrNum) { case AT_CODE_ALIAS: if ((reqAttrs.af_udattrs[0] = malloc ((size_t) strlen (AT_ATTALIAS) + strlen(attrValue) + 2)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); af_dropset (set); return (0); } strcpy (reqAttrs.af_udattrs[0], AT_ATTALIAS); strcat (reqAttrs.af_udattrs[0], "="); if (attrValue) strcat (reqAttrs.af_udattrs[0], attrValue); reqAttrs.af_udattrs[1] = NULL; break; case AT_CODE_ATIME: if (attrValue && !(reqAttrs.af_atime = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher access date"); af_dropset (set); return (0); } break; case AT_CODE_AUTHOR: if (attrValue) atScanUser (attrValue, &reqAttrs.af_author); break; case AT_CODE_CACHEKEY: if ((reqAttrs.af_udattrs[0] = malloc ((size_t) strlen (AT_ATTCACHEKEY) + strlen(attrValue) + 2)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); af_dropset (set); return (0); } strcpy (reqAttrs.af_udattrs[0], AT_ATTCACHEKEY); strcat (reqAttrs.af_udattrs[0], "="); if (attrValue) strcat (reqAttrs.af_udattrs[0], attrValue); reqAttrs.af_udattrs[1] = NULL; break; break; case AT_CODE_CTIME: if (attrValue && !(reqAttrs.af_ctime = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher create date"); af_dropset (set); return (0); } break; case AT_CODE_GENERATION: if (attrValue) { if (!strcmp (attrValue, "busy")) reqAttrs.af_gen = AF_BUSYVERS; else reqAttrs.af_gen = atoi (attrValue); } break; case AT_CODE_HOST: if (attrValue) strcpy (reqAttrs.af_host, attrValue); break; case AT_CODE_LOCK: if (!attrValue) { Af_key tmpKey; int i; char *locker; for (i=af_nrofkeys(set)-1; i >= 0; i--) { af_setgkey (set, i, &tmpKey); locker = af_retattr (&tmpKey, AF_ATTLOCKER); if (!locker[0]) af_setposrmkey (set, i); af_dropkey (&tmpKey); } return (af_nrofkeys(set)); } atScanUser (attrValue, &reqAttrs.af_locker); break; case AT_CODE_LTIME: if (!attrValue) { Af_key tmpKey; int i; for (i=af_nrofkeys(set)-1; i >= 0; i--) { af_setgkey (set, i, &tmpKey); if (af_rettimeattr (&tmpKey, AF_ATTLTIME) == AF_NOTIME) af_setposrmkey (set, i); af_dropkey (&tmpKey); } return (af_nrofkeys(set)); } if (!(reqAttrs.af_ltime = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher lock date"); af_dropset (set); return (0); } break; case AT_CODE_MTIME: if (attrValue && !(reqAttrs.af_mtime = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher modification date"); af_dropset (set); return (0); } break; case AT_CODE_NAME: if (attrValue) strcpy (reqAttrs.af_name, attrValue); break; case AT_CODE_OWNER: if (attrValue) atScanUser (attrValue, &reqAttrs.af_owner); break; case AT_CODE_REVISION: if (attrValue) { if (!strcmp (attrValue, "busy")) reqAttrs.af_rev = AF_BUSYVERS; else reqAttrs.af_rev = atoi (attrValue); } break; case AT_CODE_SIZE: if (attrValue) reqAttrs.af_size = atoi (attrValue); break; case AT_CODE_STATE: if (attrValue && (reqAttrs.af_state = atScanStatus (attrValue)) == AF_NOSTATE) { atBindError = TRUE; strcpy (atBindErrorMsg, "unknown version state"); af_dropset (set); return (0); } break; case AT_CODE_STIME: if (attrValue && !(reqAttrs.af_stime = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher save date"); af_dropset (set); return (0); } break; case AT_CODE_SYSPATH: if (attrValue) strcpy (reqAttrs.af_syspath, attrValue); break; case AT_CODE_TYPE: if (attrValue) strcpy (reqAttrs.af_type, attrValue); break; case AT_CODE_VERSION: if (attrValue && !strcmp (attrValue, "busy")) { reqAttrs.af_gen = AF_BUSYVERS; reqAttrs.af_rev = AF_BUSYVERS; break; } if ((bindType = atScanBinding (attrValue ? attrValue : "", &alias, &reqAttrs.af_gen, &reqAttrs.af_rev, NULL)) == AT_BIND_DEFAULT) break; if (bindType == AT_BIND_VNUM) break; /* else assume version number alias (even if bindType is AT_BIND_RULE) */ if ((reqAttrs.af_udattrs[0] = malloc ((size_t) strlen (AT_ATTALIAS) + strlen(alias) + 2)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); af_dropset (set); return (0); } strcpy (reqAttrs.af_udattrs[0], AT_ATTALIAS); strcat (reqAttrs.af_udattrs[0], "="); if (attrValue) strcat (reqAttrs.af_udattrs[0], attrValue); reqAttrs.af_udattrs[1] = NULL; break; case -1: /* no standard attribute -- assume user defined attr */ if ((reqAttrs.af_udattrs[0] = malloc ((size_t) strlen(attrName) + strlen(attrValue ? attrValue : "") + 2)) == NULL) { atBindError = TRUE; strcpy (atBindErrorMsg, "not enough memory"); af_dropset (set); return (0); } strcpy (reqAttrs.af_udattrs[0], attrName); strcat (reqAttrs.af_udattrs[0], "="); if (attrValue) strcat (reqAttrs.af_udattrs[0], attrValue); reqAttrs.af_udattrs[1] = NULL; break; } if ((hits = af_subset (set, &reqAttrs, set)) == -1) { atBindError = TRUE; strcpy (atBindErrorMsg, af_errmsg ("atBindAttrAbsolute")); } if (reqAttrs.af_udattrs[0]) free (reqAttrs.af_udattrs[0]); return (hits); } /*========================= * atBindAttrRelative *=========================*/ LOCAL int dateCmp (date1, date2, op) time_t date1; time_t date2; int op; { switch (op) { case BIND_PRED_ATTRGE: return (date1 >= date2); case BIND_PRED_ATTRGT: return (date1 > date2); case BIND_PRED_ATTRLE: return (date1 <= date2); case BIND_PRED_ATTRLT: return (date1 < date2); case BIND_PRED_ATTRNOT: return (date1 != date2); } return (FALSE); } LOCAL int userCmp (user1, user2, op) Af_user *user1; Af_user *user2; int op; { switch (op) { case BIND_PRED_ATTRGE: if (strcmp (user1->af_username, user2->af_username) >= 0) return (TRUE); if (strcmp (user1->af_userdomain, user2->af_userdomain) >= 0) return (TRUE); break; case BIND_PRED_ATTRGT: if (strcmp (user1->af_username, user2->af_username) > 0) return (TRUE); if (strcmp (user1->af_userdomain, user2->af_userdomain) > 0) return (TRUE); break; case BIND_PRED_ATTRLE: if (strcmp (user1->af_username, user2->af_username) <= 0) return (TRUE); if (strcmp (user1->af_userdomain, user2->af_userdomain) <= 0) return (TRUE); break; case BIND_PRED_ATTRLT: if (strcmp (user1->af_username, user2->af_username) < 0) return (TRUE); if (strcmp (user1->af_userdomain, user2->af_userdomain) < 0) return (TRUE); break; case BIND_PRED_ATTRNOT: if (strcmp (user1->af_username, user2->af_username)) return (TRUE); if (strcmp (user1->af_userdomain, user2->af_userdomain)) return (TRUE); break; } return (FALSE); } LOCAL int intCmp (val1, val2, op) int val1; int val2; int op; { switch (op) { case BIND_PRED_ATTRGE: return (val1 >= val2); case BIND_PRED_ATTRGT: return (val1 > val2); case BIND_PRED_ATTRLE: return (val1 <= val2); case BIND_PRED_ATTRLT: return (val1 < val2); case BIND_PRED_ATTRNOT: return (val1 != val2); } return (FALSE); } LOCAL int versionCmp (gen1, rev1, gen2, rev2, op) int gen1; int rev1; int gen2; int rev2; int op; { switch (op) { case BIND_PRED_ATTRGE: if (gen1 > gen2) return (TRUE); if (gen1 == gen2) return (rev1 >= rev2); break; case BIND_PRED_ATTRGT: if (gen1 > gen2) return (TRUE); return (rev1 > rev2); case BIND_PRED_ATTRLE: if (gen1 < gen2) return (TRUE); if (gen1 == gen2) return (rev1 <= rev2); break; case BIND_PRED_ATTRLT: if (gen1 < gen2) return (TRUE); return (rev1 < rev2); case BIND_PRED_ATTRNOT: if (gen1 != gen2) return (TRUE); return (rev1 != rev2); } return (FALSE); } LOCAL int strValCmp (udaVal1, udaVal2, op) char *udaVal1; char *udaVal2; int op; { switch (op) { case BIND_PRED_ATTRGE: return (strcmp (udaVal1, udaVal2) >= 0); case BIND_PRED_ATTRGT: return (strcmp (udaVal1, udaVal2) > 0); case BIND_PRED_ATTRLE: return (strcmp (udaVal1, udaVal2) <= 0); case BIND_PRED_ATTRLT: return (strcmp (udaVal1, udaVal2) < 0); case BIND_PRED_ATTRNOT: return (strcmp (udaVal1, udaVal2) != 0); } return (FALSE); } EXPORT int atBindAttrRelative (set, attrName, attrValue, op) Af_set *set; char *attrName; char *attrValue; int op; { int attrNum = getAttr (attrName), i; Af_key tmpKey; time_t dateVal; Af_user userVal; int numVal; int bindType, genNo, revNo; char *alias, *origUdaVal; if (!attrValue) attrValue = ""; switch (attrNum) { case AT_CODE_ALIAS: alias = attrValue; bindType = AT_BIND_ALIAS; break; case AT_CODE_ATIME: if (!(dateVal = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher access date"); af_dropset (set); return (0); } break; case AT_CODE_AUTHOR: atScanUser (attrValue, &userVal); break; case AT_CODE_CACHEKEY: break; case AT_CODE_CTIME: if (!(dateVal = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher create date"); af_dropset (set); return (0); } break; case AT_CODE_GENERATION: if (attrValue) { if (!strcmp (attrValue, "busy")) numVal = AF_BUSYVERS; else numVal = atoi (attrValue); } else numVal = AF_NOVNUM; break; case AT_CODE_HOST: break; case AT_CODE_LOCK: atScanUser (attrValue, &userVal); break; case AT_CODE_LTIME: if (!(dateVal = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher lock date"); af_dropset (set); return (0); } break; case AT_CODE_MTIME: if (!(dateVal = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher modification date"); af_dropset (set); return (0); } break; case AT_CODE_NAME: break; case AT_CODE_OWNER: atScanUser (attrValue, &userVal); break; case AT_CODE_REVISION: if (attrValue) { if (!strcmp (attrValue, "busy")) numVal = AF_BUSYVERS; else numVal = atoi (attrValue); } else numVal = AF_NOVNUM; break; case AT_CODE_SIZE: if (attrValue) numVal = atoi (attrValue); else numVal = AF_NOSIZE; break; case AT_CODE_STATE: if ((numVal = atScanStatus (attrValue)) == AF_NOSTATE) { atBindError = TRUE; strcpy (atBindErrorMsg, "unknown version state"); af_dropset (set); return (0); } break; case AT_CODE_STIME: if (!(dateVal = stMktime (attrValue))) { atBindError = TRUE; strcpy (atBindErrorMsg, "cannot decipher save date"); af_dropset (set); return (0); } break; case AT_CODE_SYSPATH: break; case AT_CODE_TYPE: break; case AT_CODE_VERSION: if (!strcmp (attrValue, "busy")) { bindType = AT_BIND_VNUM; genNo = revNo = AF_BUSYVERS; } else bindType = atScanBinding (attrValue, &alias, &genNo, &revNo, NULL); break; case -1: /* no standard attribute -- assume user defined attr */ break; } for (i=af_nrofkeys(set)-1; i >= 0; i--) { (void) af_setgkey (set, i, &tmpKey); switch (attrNum) { case AT_CODE_ATIME: if (!dateCmp (af_rettimeattr (&tmpKey, AF_ATTATIME), dateVal, op)) af_setposrmkey (set, i); break; case AT_CODE_AUTHOR: if (!userCmp (af_retuserattr (&tmpKey, AF_ATTAUTHOR), &userVal, op)) af_setposrmkey (set, i); break; case AT_CODE_CACHEKEY: if ((origUdaVal = af_retattr (&tmpKey, AT_ATTCACHEKEY))) { if (!strValCmp (origUdaVal, attrValue, op)) af_setposrmkey (set, i); } else if (op != BIND_PRED_ATTRNOT) af_setposrmkey (set, i); break; case AT_CODE_CTIME: if (!dateCmp (af_rettimeattr (&tmpKey, AF_ATTCTIME), dateVal, op)) af_setposrmkey (set, i); break; case AT_CODE_GENERATION: if (!intCmp (af_retnumattr (&tmpKey, AF_ATTGEN), numVal, op)) af_setposrmkey (set, i); break; case AT_CODE_HOST: if (!strValCmp (af_retattr (&tmpKey, AF_ATTHOST), attrValue, op)); af_setposrmkey (set, i); break; case AT_CODE_LOCK: if (!userCmp (af_retuserattr (&tmpKey, AF_ATTLOCKER), &userVal, op)) af_setposrmkey (set, i); break; case AT_CODE_LTIME: if (!dateCmp (af_rettimeattr (&tmpKey, AF_ATTLTIME), dateVal, op)) af_setposrmkey (set, i); break; case AT_CODE_MTIME: if (!dateCmp (af_rettimeattr (&tmpKey, AF_ATTMTIME), dateVal, op)) af_setposrmkey (set, i); break; case AT_CODE_NAME: if (!strValCmp (af_retattr (&tmpKey, AF_ATTNAME), attrValue, op)); af_setposrmkey (set, i); break; case AT_CODE_OWNER: if (!userCmp (af_retuserattr (&tmpKey, AF_ATTOWNER), &userVal, op)) af_setposrmkey (set, i); break; case AT_CODE_REVISION: if (!intCmp (af_retnumattr (&tmpKey, AF_ATTREV), numVal, op)) af_setposrmkey (set, i); break; case AT_CODE_SIZE: if (!intCmp (af_retnumattr (&tmpKey, AF_ATTSIZE), numVal, op)) af_setposrmkey (set, i); break; case AT_CODE_STATE: if (!intCmp (af_retnumattr (&tmpKey, AF_ATTSTATE), numVal, op)) af_setposrmkey (set, i); break; case AT_CODE_STIME: if (!dateCmp (af_rettimeattr (&tmpKey, AF_ATTSTIME), dateVal, op)) af_setposrmkey (set, i); break; case AT_CODE_SYSPATH: if (!strValCmp (af_retattr (&tmpKey, AF_ATTSPATH), attrValue, op)); af_setposrmkey (set, i); break; case AT_CODE_TYPE: if (!strValCmp (af_retattr (&tmpKey, AF_ATTTYPE), attrValue, op)); af_setposrmkey (set, i); break; case AT_CODE_ALIAS: case AT_CODE_VERSION: switch (bindType) { case AT_BIND_DEFAULT: case AT_BIND_VNUM: if ((genNo == AF_NOVNUM) && (revNo == AF_NOVNUM)) break; if (genNo == AF_NOVNUM) { if (!intCmp (af_retnumattr (&tmpKey, AF_ATTREV), revNo, op)) af_setposrmkey (set, i); break; } if (revNo == AF_NOVNUM) { if (!intCmp (af_retnumattr (&tmpKey, AF_ATTGEN), genNo, op)) af_setposrmkey (set, i); break; } if (!versionCmp (af_retnumattr (&tmpKey, AF_ATTGEN), af_retnumattr (&tmpKey, AF_ATTREV), genNo, revNo, op)) af_setposrmkey (set, i); break; case AT_BIND_RULE: case AT_BIND_ALIAS: if ((origUdaVal = af_retattr (&tmpKey, AT_ATTALIAS))) { if (!strValCmp (origUdaVal, alias, op)) af_setposrmkey (set, i); } else if (op != BIND_PRED_ATTRNOT) af_setposrmkey (set, i); break; } break; case -1: /* no standard attribute -- assume user defined attr */ if ((origUdaVal = af_retattr (&tmpKey, attrName))) { if (!strValCmp (origUdaVal, attrValue, op)) af_setposrmkey (set, i); } else if (op != BIND_PRED_ATTRNOT) af_setposrmkey (set, i); break; } af_dropkey (&tmpKey); } return (af_nrofkeys(set)); } /*========================= * atBindAttrMinMax *=========================*/ EXPORT int atBindAttrMinMax (set, attrName, op) Af_set *set; char *attrName; int op; { int attrNum = getAttr (attrName); int maxSetPos = af_nrofkeys (set)-1, curSetPos = 0; int i, j, cmpCode; char *curUdaVal, *nextUdaVal; Af_key curKey, nextKey; Af_user curUserVal, *userPtr; if (maxSetPos < 1) /* set is empty or contains just one key */ return (maxSetPos+1); (void) af_setgkey (set, curSetPos++, &curKey); for (i=1; i <= maxSetPos; i++) { (void) af_setgkey (set, curSetPos, &nextKey); switch (attrNum) { case AT_CODE_ATIME: cmpCode = af_rettimeattr (&curKey, AF_ATTATIME) - af_rettimeattr (&nextKey, AF_ATTATIME); break; case AT_CODE_AUTHOR: userPtr = af_retuserattr (&curKey, AF_ATTAUTHOR); curUserVal = *userPtr; userPtr = af_retuserattr (&nextKey, AF_ATTAUTHOR); if (userCmp (&curUserVal, userPtr, BIND_PRED_ATTRLT)) cmpCode = -1; else if (userCmp (&curUserVal, userPtr, BIND_PRED_ATTRGT)) cmpCode = 1; else cmpCode = 0; break; case AT_CODE_CACHEKEY: cmpCode = strcmp (af_retattr (&curKey, AT_ATTCACHEKEY), af_retattr (&nextKey, AT_ATTCACHEKEY)); break; case AT_CODE_CTIME: cmpCode = af_rettimeattr (&curKey, AF_ATTCTIME) - af_rettimeattr (&nextKey, AF_ATTCTIME); break; case AT_CODE_GENERATION: cmpCode = af_retnumattr (&curKey, AF_ATTGEN) - af_retnumattr (&nextKey, AF_ATTGEN); break; case AT_CODE_HOST: cmpCode = 0; break; case AT_CODE_LOCK: userPtr = af_retuserattr (&curKey, AF_ATTLOCKER); curUserVal = *userPtr; userPtr = af_retuserattr (&nextKey, AF_ATTLOCKER); if (userCmp (&curUserVal, userPtr, BIND_PRED_ATTRLT)) cmpCode = -1; else if (userCmp (&curUserVal, userPtr, BIND_PRED_ATTRGT)) cmpCode = 1; else cmpCode = 0; break; case AT_CODE_LTIME: cmpCode = af_rettimeattr (&curKey, AF_ATTLTIME) - af_rettimeattr (&nextKey, AF_ATTLTIME); break; case AT_CODE_MTIME: cmpCode = af_rettimeattr (&curKey, AF_ATTMTIME) - af_rettimeattr (&nextKey, AF_ATTMTIME); break; case AT_CODE_NAME: cmpCode = 0; break; case AT_CODE_OWNER: userPtr = af_retuserattr (&curKey, AF_ATTOWNER); curUserVal = *userPtr; userPtr = af_retuserattr (&nextKey, AF_ATTOWNER); if (userCmp (&curUserVal, userPtr, BIND_PRED_ATTRLT)) cmpCode = -1; else if (userCmp (&curUserVal, userPtr, BIND_PRED_ATTRGT)) cmpCode = 1; else cmpCode = 0; break; case AT_CODE_REVISION: cmpCode = af_retnumattr (&curKey, AF_ATTREV) - af_retnumattr (&nextKey, AF_ATTREV); break; case AT_CODE_SIZE: cmpCode = af_retnumattr (&curKey, AF_ATTSIZE) - af_retnumattr (&nextKey, AF_ATTSIZE); break; case AT_CODE_STATE: cmpCode = af_retnumattr (&curKey, AF_ATTSTATE) - af_retnumattr (&nextKey, AF_ATTSTATE); break; case AT_CODE_STIME: cmpCode = af_rettimeattr (&curKey, AF_ATTSTIME) - af_rettimeattr (&nextKey, AF_ATTSTIME); break; case AT_CODE_SYSPATH: cmpCode = 0; break; case AT_CODE_TYPE: cmpCode = 0; break; case AT_CODE_ALIAS: case AT_CODE_VERSION: cmpCode = af_retnumattr (&curKey, AF_ATTGEN) - af_retnumattr (&nextKey, AF_ATTGEN); if (cmpCode == 0) cmpCode = af_retnumattr (&curKey, AF_ATTREV) - af_retnumattr (&nextKey, AF_ATTREV); break; case -1: /* no standard attribute -- assume user defined attr */ if (!(curUdaVal = af_retattr (&curKey, attrName))) { /* Uda non existent for current version -> delete cur vers */ af_setposrmkey (set, curSetPos-1); af_dropkey (&curKey); curKey = nextKey; if (i == maxSetPos) { /* at the end of the set delete last key too, if necessary */ af_setposrmkey (set, curSetPos-1); af_dropkey (&curKey); } continue; } if (!(nextUdaVal = af_retattr (&nextKey, attrName))) { /* Uda non existent for next version -> simulate smaller/bigger */ free (curUdaVal); if (op == BIND_PRED_ATTRMAX) cmpCode = 1; else if (op == BIND_PRED_ATTRMIN) cmpCode = -1; break; } cmpCode = strcmp (curUdaVal, nextUdaVal); free (curUdaVal); free (nextUdaVal); break; } switch (op) { case BIND_PRED_ATTRMAX: if (cmpCode < 0) { for (j = curSetPos-1; j >= 0; j--) af_setposrmkey (set, j); curSetPos = 1; af_dropkey (&curKey); curKey = nextKey; } else if (cmpCode > 0) { af_setposrmkey (set, curSetPos); af_dropkey (&nextKey); } else { curSetPos++; af_dropkey (&curKey); curKey = nextKey; } break; case BIND_PRED_ATTRMIN: if (cmpCode > 0) { for (j = curSetPos-1; j >= 0; j--) af_setposrmkey (set, j); curSetPos = 1; af_dropkey (&curKey); curKey = nextKey; } else if (cmpCode < 0) { af_setposrmkey (set, curSetPos); af_dropkey (&nextKey); } else { curSetPos++; af_dropkey (&curKey); curKey = nextKey; } break; } } af_dropkey (&curKey); return (af_nrofkeys (set)); } shapetools-1.4pl6.orig/src/atfstk/vbind.c100444 2013 145 12672 5537601306 16526 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * vbind.c -- Version Binding main program * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: vbind.c[7.0] Thu Mar 10 12:21:47 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "sttk.h" #include "atfstk.h" #include "bind.h" extern BindBaseline bindExact; LOCAL int dumpRules = FALSE; LOCAL int listRules = FALSE; LOCAL int testRules = FALSE; LOCAL int handleAlias (option, arg) char *option, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No version alias name -- '%s' ignored.", option); stLog (stMessage, ST_LOG_ERROR); return (1); } bindExact.baselineString = arg; bindExact.baselineType = AT_BIND_ALIAS; return (0); } LOCAL int handleDate (option, arg) char *option, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No date specified -- '%s' ignored.", option); stLog (stMessage, ST_LOG_ERROR); return (1); } if ((bindExact.baselineDate = stMktime (arg)) == 0) { sprintf (stMessage, "Invalid date specified -- '%s' ignored.", option); stLog (stMessage, ST_LOG_ERROR); return (1); } bindExact.baselineType = AT_BIND_DATE; return (0); } LOCAL int handleVersions (option, arg) char *option, *arg; { char *genPtr, *revPtr; if (!arg || !(*arg)) { sprintf (stMessage, "No version number specified -- '%s' ignored.", option); stLog (stMessage, ST_LOG_ERROR); return (1); } bindExact.baselineType = AT_BIND_VNUM; if (!strcmp (arg, "busy")) { bindExact.baselineGen = AF_BUSYVERS; bindExact.baselineRev = AF_BUSYVERS; return 0; } genPtr = arg; if ((revPtr = strchr (arg, '.'))) { *revPtr = '\0'; revPtr++; } bindExact.baselineGen = bindExact.baselineRev = AF_NOVNUM; if (genPtr && *genPtr) bindExact.baselineGen = atoi (genPtr); if (revPtr && *revPtr) bindExact.baselineRev = atoi (revPtr); return 0; } LOCAL int printVersion () { sprintf (stMessage, "This is %s version %s", stProgramName, atVersion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " using AtFS version %s", af_version()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " and Sttk version %s.", stVersion()); stLog (stMessage, ST_LOG_MSG); stExit (0); return (0); } static int usage(); static StOptDesc optDesc[] = { { "?", PCALL, usage, NULL, NULL }, { "alias", PCALL|PARG, handleAlias, NULL, NULL }, { "date", PCALL|PARG, handleDate, NULL, NULL }, { "help", PCALL, usage, NULL, NULL }, { "nomsg", PSWITCH|PSET, NULL, &atBindNoMsg, NULL }, { "ruledump", PSWITCH|PSET, NULL, &dumpRules, NULL }, { "ruleerr", PSWITCH|PSET, NULL, &atBindDisplayErrors, NULL }, { "rulelist", PSWITCH|PSET, NULL, &listRules, NULL }, { "ruletest", PSWITCH|PSET, NULL, &testRules, NULL }, { "version", PCALL, printVersion, NULL, NULL }, { "vnum", PCALL|PARG, handleVersions, NULL, NULL }, { NULL, 0, NULL, NULL, NULL }, }; LOCAL int usage() { stLog ("Usage:", ST_LOG_MSGERR); stShortUsage (stProgramName, optDesc, "names..."); atBindUsage (""); stExit (1); return (1); } /*================== * main *==================*/ int main (argc, argv) int argc; char **argv; { int tmpArgc, newArgc, i, j, retCode = 0; char *cp, **tmpArgv, **newArgv; Af_set *resultSet; Af_key tmpKey; stProgramName = (cp = strrchr (argv[0], '/')) ? ++cp : argv[0]; if (stParseArgs (argc, argv, &tmpArgc, &tmpArgv, optDesc)) stExit (1); if (atBindOptions (tmpArgc, tmpArgv, &newArgc, &newArgv)) stExit (1); if (listRules) { char **ruleList; if ((ruleList = atBindListRules ()) == NULL) { stLog (atBindErrorMsg, ST_LOG_ERROR); return (1); } i=0; while (ruleList[i]) { sprintf (stMessage, "%s", ruleList[i++]); stLog (stMessage, ST_LOG_MSG); } free (ruleList); } if (testRules) { for (i = 1; i < newArgc; i++) { if (atBindTestRule (newArgv[i])) { sprintf (stMessage, "%s -- ok.", newArgv[i]); } else { sprintf (stMessage, "%s -- not found.", newArgv[i]); retCode++; } stLog (stMessage, ST_LOG_MSG); } return (retCode); } for (i = 1; i < newArgc; i++) { if ((resultSet = atBindSet (newArgv[i], NULL, 0)) == NULL) { if (atBindError) { sprintf (stMessage, "(%s) %s", newArgv[i], atBindErrorMsg); stLog (stMessage, ST_LOG_ERROR); } retCode = 255; continue; } for (j=0; j> 16) & 0x0000FFFF) #define atRev(x) ((x) & 0x0000FFFF) int atSetVersAlias A((Af_key *aso, char *alias)); int atDelVersAlias A((Af_key *aso, char *alias)); /*** user.c ***/ int atUserValid A((Af_user *user)); void atScanUser A((char *userName, Af_user *resultUser)); char* atUserName A((Af_user *user)); uid_t atUserUid A((Af_user *user)); /*** uda.c ***/ struct atAttrTab { int code; char *name; char *atfsName; }; extern struct atAttrTab atStdAttrTab[]; char* atRetAttr A((Af_key *aso, char *attrName)); /* mode: AF_ADD, AF_DELETE, AF_REPLACE */ int atSetAttr A((Af_key *aso, char *attr, int mode)); int atSetAttrFile A((Af_key *aso, char *fileName)); char* atAttrName A((char *attr)); char* atAttrValue A((char *attr)); int atMatchAttr A((Af_key *aso, char *attr)); void atFreeAttr A((char *attrValue)); /*** citeattr.c */ #define AT_EXPAND_STRING 0 #define AT_EXPAND_FILE 1 int atExpandAttrs A((Af_key *aso, char *buf, size_t bufSize, void *dest, size_t destSize, int mode)); /*** read.c ***/ int atOpenExpand A((char *version, int expand_busy)) ; void atCloseExpand A((int desc)) ; int atReadExpand A((int desc, char *bufp, int size)) ; char *atGetWriteName A((int desc)) ; /*** network.c ***/ char* atNetworkPath A((Af_key *aso)); char* atLocalPath A((char *networkPath)); /*** lock.c ***/ #define AT_COMMENT_INTENT 1 /* comment type */ #define AT_COMMENT_DESCR 2 /* comment type */ #define AT_COMMENT_LOG 3 /* comment type */ #define AT_FROMSTDIN 01 /* mode */ #define AT_REUSE 02 /* mode */ #define AT_CONFIRM 04 /* mode */ int atSetComment A((Af_key *aso, int commentType, char *commentText, int mode)); int atUnlock A((Af_key *aso)); /*** cache.c ***/ char* atCacheKey A((Af_key *aso)); int atSaveCache A((Af_key *aso, Af_key *cachedAso, char *uniqAttr, int storeType)); /*** bind.c ***/ int atScanBinding A((char *binding, char **resultStr, int *resultGen, int *resultRev, time_t *resultDate)); int atBindOptions A((int argc, char **argv, int *newArgc, char *(*newArgv[]))); extern int atBindModeOption; int atBindSetArgv A((int *argc, char *(*argv[]))); void atBindUsage A((char *extraText)); Af_key* atBindVersion A((char *name, char *binding)); Af_set* atBindSet A((char *pattern, char *binding, int bindMode)); Af_set* atBindCache A((char *pattern, char *binding)); int atBindShowRules A((void)); char** atBindListRules A((void)); int atBindAddRule A((char *name, char *body, char *source, int srcLine)); int atBindTestRule A((char *name)); int atBindDelRule A((char *name)); int atBindRuleFile A((char *filename)); extern char *(*atBindExpandMacro)(); extern int atBindDisplayErrors; extern int atBindTrace; extern int atBindNoMsg; extern int atBindError; extern char atBindErrorMsg[]; /*** atfstk_version.c ***/ char* atVersion (); /*============== * constants *==============*/ /*** bind modes (for atBindSet) ***/ #define AT_BIND_UNIQUE 1 #define AT_BIND_SET 2 #define AT_BIND_LAST 3 #define AT_BIND_LASTSAVED 4 /*** bind types (returned by atScanBinding) ***/ #define AT_BIND_DEFAULT 1 #define AT_BIND_VNUM 2 #define AT_BIND_RULE 3 #define AT_BIND_ALIAS 4 #define AT_BIND_DATE 5 #define AT_BIND_CACHEKEY 6 #define AT_OK 0 #define AT_ERROR 1 #define AT_WARNING 2 #define AT_MSG 3 #define AT_NOSHELL 127 #define AT_ATTALIAS "__SymbolicName__" #define AT_ATTCLEAD "__Clead__" #define AT_ATTINTENT "__Intent__" #define AT_ATTLOG "__Log__" #define AT_ATTDESCR "__Description__" #define AT_ATTCACHEKEY "__CacheKey__" #define AT_STARTINTENT " Intention for change:\n" #define AT_EMPTYINTENT "--- no intent expressed ---" #define AT_STARTLOG " Change log:\n" #define AT_EMPTYLOG "--- empty log message ---" #define AT_STARTDESCR " Module description:\n" #define AT_EMPTYDESCR "--- empty description ---" #define AT_MAXATTRSIZE 10240 #define AT_MAXALIASLEN 1024 #define AT_CLEADMAXLEN 32 #define AT_CACHEKEYLEN 64 #define AT_DEFAULT_EDITOR "vi" /*** codes for predefined attributes ***/ #define AT_CODE_DESCRIPTION 0 #define AT_CODE_HEADER 1 #define AT_CODE_INTENT 2 #define AT_CODE_LOG 3 #define AT_CODE_ALIAS 4 #define AT_CODE_ATIME 5 #define AT_CODE_AUTHOR 6 #define AT_CODE_CACHEKEY 7 #define AT_CODE_CLEAD 8 #define AT_CODE_CTIME 9 #define AT_CODE_DSIZE 10 #define AT_CODE_GENERATION 11 #define AT_CODE_HOST 12 #define AT_CODE_LOCK 13 #define AT_CODE_LTIME 14 #define AT_CODE_MODE 15 #define AT_CODE_MTIME 16 #define AT_CODE_NAME 17 #define AT_CODE_NOTE 18 #define AT_CODE_OWNER 19 #define AT_CODE_PRED 20 #define AT_CODE_REVISION 21 #define AT_CODE_RTIME 22 #define AT_CODE_SELF 23 #define AT_CODE_SELFPATH 24 #define AT_CODE_SIZE 25 #define AT_CODE_STATE 26 #define AT_CODE_STIME 27 #define AT_CODE_SUCC 28 #define AT_CODE_SYSPATH 29 #define AT_CODE_TYPE 30 #define AT_CODE_UNIXNAME 31 #define AT_CODE_UNIXPATH 32 #define AT_CODE_VERSION 33 #define AT_CODE_VTIME 34 #define AT_CODE_XPOFF 35 #define AT_CODE_XPON 36 #endif /* _ATFSTKHDR_ */ shapetools-1.4pl6.orig/src/atfstk/bind.h100444 2013 145 7131 5414014751 16313 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * AtFStk -- Attribute Filesystem Toolkit Library * * bind.h * * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) * * $Header: bind.h[7.0] Tue Jun 29 16:16:14 1993 andy@cs.tu-berlin.de frozen $ */ /*============================= * constant definitions *=============================*/ #define BIND_RULES_FILENAME "BindRules" #define BIND_MAX_BINDING_LEN 256 #define BIND_MAX_RULEARGS 16 /*======================================== * flags and constant definitions *========================================*/ extern int atBindTrace; /*** predicate names ***/ #define BIND_PRED_ATTR 0 #define BIND_PRED_ATTREX 1 #define BIND_PRED_ATTRGE 2 #define BIND_PRED_ATTRGT 3 #define BIND_PRED_ATTRLE 4 #define BIND_PRED_ATTRLT 5 #define BIND_PRED_ATTRMAX 6 #define BIND_PRED_ATTRMIN 7 #define BIND_PRED_ATTRNOT 8 #define BIND_PRED_RULE 9 #define BIND_PRED_CONDEX 10 #define BIND_PRED_CONDEXPR 11 #define BIND_PRED_CONDNOT 12 #define BIND_PRED_CONDUNIQ 13 #define BIND_PRED_CONFIRM 14 #define BIND_PRED_CUT 15 #define BIND_PRED_MSG 16 /*============================== * type definitions *==============================*/ #define BIND_ARG1_RULE_MACRO 01 #define BIND_ARG1_SHAPE_MACRO 02 #define BIND_ARG1_SHELL_COMMAND 04 #define BIND_ARG2_RULE_MACRO 010 #define BIND_ARG2_SHAPE_MACRO 020 #define BIND_ARG2_SHELL_COMMAND 040 typedef struct predicate Predicate; struct predicate { int position; /* position in predicates list */ char *args[2]; int info; Predicate *next; }; #define BIND_PATTERN_RULE_MACRO 0100 #define BIND_PATTERN_SHAPE_MACRO 0200 #define BIND_PATTERN_SHELL_COMMAND 0400 typedef struct alternative Alternative; struct alternative { char *pattern; Predicate *predList; int info; Alternative *next; }; typedef struct { char *name; char *body; int argNum; char *argList[BIND_MAX_RULEARGS]; int status; Alternative *altList; char *fileName; int srcLine; } BindRule; typedef struct { int baselineType; char *baselineString; int baselineGen; int baselineRev; time_t baselineDate; } BindBaseline; /*============================== * function definitions *==============================*/ /*** bind_attr.c ***/ int atBindAttrAbsolute A((Af_set *set, char *attrName, char *attrValue)); int atBindAttrRelative A((Af_set *set, char *attrName, char *attrValue, int op)); int atBindAttrMinMax A((Af_set *set, char *attrName, int op)); /*** bind_rules.c ***/ int atBindInitRules A((void)); char *atCurRuleName A((void)); int atBindSetRule A((char *ruleName, char *targName, int init)); void atBindUnsetRule A((int abort)); char *atBindRuleAlt A((Af_set *hitSet)); int atBindRulePred A((char **arg1, char **arg2, Af_set *hitSet)); /*** bind_scan.c ***/ char *atBindPredName A((int pos)); int atBindPredCode A((int pos)); int atRuleNameScan A((BindRule *rule)); int atRuleScan A((BindRule *rule)); void atRuleDisplay A((BindRule *rule)); shapetools-1.4pl6.orig/src/atfstk/atfstk_vers.c100444 2013 145 205 5620172704 17702 0ustar dokoswtchar *atVersion () { static char release[] = "AtFStk-1.12 (Tue Aug 23 17:56:12 1994 by andy@cs.tu-berlin.de)"; return release; } shapetools-1.4pl6.orig/src/atfstk/Shapefile100444 2013 145 7033 5412604672 17057 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for AtFS toolkit library (atfstk) # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[7.0] Fri Jun 25 16:39:54 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds _all: all $(LIBTARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(PROGTARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) $(CC) -c $(CFLAGS) $(VERSIONFILE) localinstall: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) localinstall: MAINTARGET=localinstall ALLTARGETS=subsystems localinstalltargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/atfstk/Makefile100444 2013 145 33121 5425776215 16720 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for AtFS toolkit library (AtFStk) # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[7.0] Thu Jul 29 18:36:35 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/atfstk # A short name for this node system NODENAME = AtFStk # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = /home/stone/shape INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib INSTALLSHAPELIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib # special treatment due to problems in ShapeTools # installation procedure. LOCALLIBPATH may be redefined # from above. MYLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. PROGTARGET = vbind LIBTARGET = libAtFStk.a # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = atfstk_vers.c # source VERSIONOBJECT = atfstk_vers.o # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = # The regular source and header files. SOURCES = atfstk_lib.c attrs.c version.c user.c uda.c citeattr.c \ lock.c cache.c network.c read.c \ bind.c bind_options.c bind_scan.c bind_rules.c bind_attr.c \ vbind.c BindRules HEADERS = atfstk.h bind.h # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = vbind.1 MAN3 = atfstkintro.3 atattribute.3 atbind.3 atbindrule.3 atcache.3 \ atclass.3 atexpand.3 atlog.3 atnetwork.3 atprint.3 \ atread.3 atuser.3 atversion.3 MAN4 = MAN5 = MAN6 = MAN7 = bindrules.7 MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. LIBOBJECTS = atfstk_lib.o attrs.o version.o user.o uda.o citeattr.o \ lock.o cache.o network.o read.o \ bind.o bind_options.o bind_scan.o bind_rules.o bind_attr.o \ $(VERSIONOBJECT) PROGOBJECTS = vbind.o OBJECTS = $(LIBOBJECTS) $(PROGOBJECTS) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = $(MYLIBPATH)/libsttk.a $(MYLIBPATH)/libAtFS.a LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(LIBTARGET) $(PROGTARGET) $(LIBTARGET): $(LIBOBJECTS) -ar ruv $(LIBTARGET) $(LIBOBJECTS) @-($(RANLIB) $(LIBTARGET)) 2> /dev/null; true $(PROGTARGET): $(LOCALLIBS) $(PROGOBJECTS) $(LIBOBJECTS) $(CC) $(LDFLAGS) -o $(PROGTARGET) $(PROGOBJECTS) \ $(LIBOBJECTS) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(PROGTARGET) to $$i; \ ln $(PROGTARGET) $$i; \ done localinstalltargets: $(LOCALLIBPATH)/$(LIBTARGET) \ $(LOCALINCLUDEPATH)/atfstk.h $(PROGTARGET) $(LOCALLIBPATH)/$(LIBTARGET): $(LIBTARGET) @-echo "Copying $(LIBTARGET) to $(LOCALLIBPATH)"; \ if [ -f $(LOCALLIBPATH)/$(LIBTARGET) ] ;\ then \ mv -f $(LOCALLIBPATH)/$(LIBTARGET) \ $(LOCALLIBPATH)/$(LIBTARGET).old;\ fi; \ cp $(LIBTARGET) $(LOCALLIBPATH)/$(LIBTARGET); \ chmod $(INSTALLLIBMODE) $(LOCALLIBPATH)/$(LIBTARGET); \ ($(RANLIB) $(LOCALLIBPATH)/$(LIBTARGET)) 2> /dev/null; true $(LOCALINCLUDEPATH)/atfstk.h: atfstk.h @-echo "Copying atfstk.h to $(LOCALINCLUDEPATH)"; \ if [ -f $(LOCALINCLUDEPATH)/atfstk.h ] && \ [ ! -w $(LOCALINCLUDEPATH)/atfstk.h ]; \ then \ chmod u+w $(LOCALINCLUDEPATH)/atfstk.h; \ fi; \ cp atfstk.h $(LOCALINCLUDEPATH)/atfstk.h; \ chmod $(INSTALLINCMODE) $(LOCALINCLUDEPATH)/atfstk.h installtargets: $(INSTALLLIBPATH)/$(LIBTARGET) $(INSTALLINCPATH)/atfstk.h \ $(INSTALLBINPATH)/$(PROGTARGET) $(INSTALLSHAPELIBPATH)/BindRules $(INSTALLLIBPATH)/$(LIBTARGET): $(LIBTARGET) @-echo "installing $(LIBTARGET) in $(INSTALLLIBPATH)"; \ if [ -f $(INSTALLLIBPATH)/$(LIBTARGET) ] ;\ then \ mv -f $(INSTALLLIBPATH)/$(LIBTARGET) \ $(INSTALLLIBPATH)/$(LIBTARGET).old;\ fi; \ cp $(LIBTARGET) $(INSTALLLIBPATH)/$(LIBTARGET); \ chmod $(INSTALLLIBMODE) $(INSTALLLIBPATH)/$(LIBTARGET); \ ($(RANLIB) $(INSTALLLIBPATH)/$(LIBTARGET)) 2> /dev/null; true $(INSTALLBINPATH)/$(PROGTARGET): $(PROGTARGET) @-echo "installing $(PROGTARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(PROGTARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(PROGTARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(PROGTARGET); \ fi; \ cp $(PROGTARGET) $(INSTALLBINPATH)/$(PROGTARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(PROGTARGET); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(PROGTARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(PROGTARGET) $(INSTALLBINPATH)/$$i; \ done $(INSTALLINCPATH)/atfstk.h: atfstk.h @-echo "Installing atfstk.h in $(INSTALLINCPATH)"; \ if [ -f $(INSTALLINCPATH)/atfstk.h ] && \ [ ! -w $(INSTALLINCPATH)/atfstk.h ]; \ then \ chmod u+w $(INSTALLINCPATH)/atfstk.h; \ fi; \ cp atfstk.h $(INSTALLINCPATH)/atfstk.h; \ chmod $(INSTALLINCMODE) $(INSTALLINCPATH)/atfstk.h $(INSTALLSHAPELIBPATH)/BindRules: BindRules @-echo "Installing BindRules in $(INSTALLSHAPELIBPATH)"; \ if [ -f $(INSTALLSHAPELIBPATH)/BindRules ] && \ [ ! -w $(INSTALLSHAPELIBPATH)/BindRules ]; \ then \ chmod u+w $(INSTALLSHAPELIBPATH)/BindRules; \ fi; \ cp BindRules $(INSTALLSHAPELIBPATH)/BindRules; \ chmod $(INSTALLLIBMODE) $(INSTALLSHAPELIBPATH)/BindRules installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done noinstall: $(INSTALLBINPATH)/$(PROGTARGET) $(INSTALLSHAPELIBPATH)/BindRules # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(LIBTARGET) $(PROGTARGET) $(ALIASES) $(LIBOBJECTS) \ $(PROGOBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) localinstall: +localinstall $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +localinstall: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems localinstalltargets" \ MAINTARGET=localinstall \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" localinstall; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/atfstk/Dependencies100444 2013 145 5335 5405145556 17553 0ustar dokoswtatfstk_lib.o: ./atfstk.h atfstk_lib.o: $(BASE)/include/afsys.h atfstk_lib.o: $(BASE)/include/atfs.h atfstk_lib.o: $(BASE)/include/config.h atfstk_lib.o: atfstk_lib.c atfstk_vers.o: atfstk_vers.c attrs.o: ./atfstk.h attrs.o: $(BASE)/include/afsys.h attrs.o: $(BASE)/include/atfs.h attrs.o: $(BASE)/include/config.h attrs.o: attrs.c bind.o: ./atfstk.h bind.o: ./bind.h bind.o: $(BASE)/include/afsys.h bind.o: $(BASE)/include/atfs.h bind.o: $(BASE)/include/config.h bind.o: $(BASE)/include/sttk.h bind.o: bind.c bind_attr.o: ./atfstk.h bind_attr.o: ./bind.h bind_attr.o: $(BASE)/include/afsys.h bind_attr.o: $(BASE)/include/atfs.h bind_attr.o: $(BASE)/include/config.h bind_attr.o: $(BASE)/include/sttk.h bind_attr.o: bind_attr.c bind_options.o: ./atfstk.h bind_options.o: ./bind.h bind_options.o: $(BASE)/include/afsys.h bind_options.o: $(BASE)/include/atfs.h bind_options.o: $(BASE)/include/config.h bind_options.o: $(BASE)/include/sttk.h bind_options.o: bind_options.c bind_rules.o: ./atfstk.h bind_rules.o: ./bind.h bind_rules.o: $(BASE)/include/afsys.h bind_rules.o: $(BASE)/include/atfs.h bind_rules.o: $(BASE)/include/config.h bind_rules.o: $(BASE)/include/sttk.h bind_rules.o: bind_rules.c bind_scan.o: ./atfstk.h bind_scan.o: ./bind.h bind_scan.o: $(BASE)/include/afsys.h bind_scan.o: $(BASE)/include/atfs.h bind_scan.o: $(BASE)/include/config.h bind_scan.o: $(BASE)/include/sttk.h bind_scan.o: bind_scan.c cache.o: ./atfstk.h cache.o: $(BASE)/include/afsys.h cache.o: $(BASE)/include/atfs.h cache.o: $(BASE)/include/config.h cache.o: cache.c citeattr.o: ./atfstk.h citeattr.o: ./bind.h citeattr.o: $(BASE)/include/afsys.h citeattr.o: $(BASE)/include/atfs.h citeattr.o: $(BASE)/include/config.h citeattr.o: citeattr.c lock.o: ./atfstk.h lock.o: $(BASE)/include/afsys.h lock.o: $(BASE)/include/atfs.h lock.o: $(BASE)/include/config.h lock.o: $(BASE)/include/sttk.h lock.o: lock.c network.o: ./atfstk.h network.o: $(BASE)/include/afsys.h network.o: $(BASE)/include/atfs.h network.o: $(BASE)/include/config.h network.o: network.c read.o: ./atfstk.h read.o: $(BASE)/include/afsys.h read.o: $(BASE)/include/atfs.h read.o: $(BASE)/include/config.h read.o: read.c uda.o: ./atfstk.h uda.o: $(BASE)/include/afsys.h uda.o: $(BASE)/include/atfs.h uda.o: $(BASE)/include/config.h uda.o: $(BASE)/include/sttk.h uda.o: uda.c user.o: ./atfstk.h user.o: $(BASE)/include/afsys.h user.o: $(BASE)/include/atfs.h user.o: $(BASE)/include/config.h user.o: user.c vbind.o: ./atfstk.h vbind.o: ./bind.h vbind.o: $(BASE)/include/afsys.h vbind.o: $(BASE)/include/atfs.h vbind.o: $(BASE)/include/config.h vbind.o: $(BASE)/include/sttk.h vbind.o: vbind.c version.o: ./atfstk.h version.o: $(BASE)/include/afsys.h version.o: $(BASE)/include/atfs.h version.o: $(BASE)/include/config.h version.o: version.c shapetools-1.4pl6.orig/src/shape/ 40755 2013 145 0 5626416164 14746 5ustar dokoswtshapetools-1.4pl6.orig/src/shape/dkey.c100444 2013 145 17102 5574610501 16153 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - dkey.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: dkey.c[8.0] Mon Jun 6 15:09:55 1994 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: dkey.c[8.0] Mon Jun 6 15:09:55 1994 axel@cs.tu-berlin.de frozen $"; #endif /* * Handling of derivation key and appropriate data structures */ #include "shape.h" #define QUEUESIZE 64 LOCAL char *object_id (key) Af_key *key; { static char buffer[PATH_MAX]; char datebuf[12], *s; Bool from_cache = FALSE; buffer[0] = '\0'; strcat (buffer, af_retattr (key, AF_ATTUNIXNAME)); strcat (buffer, "["); if ((s = af_retattr (key, AT_ATTCACHEKEY))) { from_cache = TRUE; strcat (buffer, "#"); strcat (buffer, s); free (s); } else { sprintf (datebuf, "%ld", af_rettimeattr (key, AF_ATTMTIME)); strcat (buffer, datebuf); } if (!from_cache && (af_retnumattr (key, AF_ATTSTATE) != AF_BUSY)) { /* non busy versions are expanded by default */ if (!noexpflg) (void) strcat (buffer, "*"); } else { /* busy versions not expanded by default */ if (expflg) (void) strcat (buffer, "*"); } strcat (buffer, "]"); return buffer; } LOCAL char *dependent_ids (q, disl) DepQ *q; int *disl; { static char buffer[AT_MAXATTRSIZE]; Af_key *this = q->head; int curlen = 0; char *s; buffer[0] = '\0'; if (!q->dependent_queue_initialized) return buffer; while (this && (this <= q->tail)) { s = object_id (this++); curlen += strlen (s); if (curlen < AT_MAXATTRSIZE) strcat (buffer, s); else break; } *disl = curlen; return buffer; } LOCAL int init_dependent_queue (q) DepQ *q; { static Af_key nullkey; if (q->dependent_queue_initialized) return TRUE; if ((q->dependent_queue = (Af_key *)malloc (QUEUESIZE * sizeof (Af_key))) == (Af_key *)NULL) { stLog ("malloc", ST_LOG_ERROR); return FALSE; } q->head = q->tail = q->dependent_queue; *q->head = nullkey; q->current_max_dependents = QUEUESIZE; q->queued_dependents = 0; q->dependent_queue_initialized = TRUE; return TRUE; } LOCAL int grow_dependent_queue (q) DepQ *q; { unsigned int tail_offset = q->tail - q->dependent_queue; Af_key *queue_anchor = q->dependent_queue; if (!q->dependent_queue_initialized) { return init_dependent_queue(q); } if ((q->dependent_queue = (Af_key *)realloc ((char *)queue_anchor, 2 * q->current_max_dependents * sizeof (Af_key))) == (Af_key *)NULL) { q->dependent_queue = queue_anchor; return FALSE; } if (q->dependent_queue != queue_anchor) { q->head = q->dependent_queue; q->tail = q->dependent_queue + tail_offset; } q->current_max_dependents = q->current_max_dependents * 2; return TRUE; } EXPORT DepQ *new_DepQ () { DepQ *q; if ((q = (DepQ *)malloc (sizeof (DepQ))) == NULL) return (DepQ *)NULL; q->dependent_queue_initialized = FALSE; q->queue_changed = TRUE; return q; } EXPORT void drop_dependent_queue (q) DepQ *q; { if (!q) return; if (q->dependent_queue_initialized) { while (q->head <= q->tail) af_dropkey (q->head++); free (q->dependent_queue); free (q); } } EXPORT void append_dependent (key, q) Af_key *key; DepQ *q; { if (!q) return; q->queue_changed = TRUE; if (!q->dependent_queue_initialized && !init_dependent_queue(q)) { stLog ("Internal error: can't initialize dependent_queue", ST_LOG_ERROR); return; } if ((q->queued_dependents < q->current_max_dependents) || (grow_dependent_queue (q))) { if (q->queued_dependents) /* "tail" points to last element, exept when Q is empty */ *++(q->tail) = *key; else *q->tail = *key; q->queued_dependents++; return; } else { stLog ("Internal error: can't expand dependent_queue", ST_LOG_ERROR); return; } } #define KVERS "AV(1.0)" EXPORT char *make_derivation_key (current_rule, q) struct rules *current_rule; DepQ *q; { register char *buf_end, *peek, *buf_bound; register int i; int len; char edit_buffer[AT_MAXATTRSIZE], *dis, *dependent_ids(); static char *mts = ""; short is_implicit_rule; struct rules *implicit_target(); char **heritage; /* * This function finally builds the derivation key for the * current derivation. The produced key has the general * form . * The key is returned in static memory. The variable is "keybuffer". */ if (!q || !current_rule) return ""; if (!q->queue_changed) return q->keybuffer; q->keybuffer[0] = '\0'; buf_bound = &q->keybuffer[AT_MAXATTRSIZE - 1]; heritage = current_rule->heritage; /* keybuffer <- magic */ strcat (q->keybuffer, KVERS); /* keybuffer <- opt-ingredients */ dis = dependent_ids (q, &len); if ((len += strlen (KVERS)) < AT_MAXATTRSIZE) strcat (q->keybuffer, dis); else return mts; buf_end = q->keybuffer + len; if (buf_end < buf_bound) { strcat (q->keybuffer, ";"); buf_end++; } else return mts; /* production is made up of "{" opt-macro-defs "}">. */ /* first the production-key */ is_implicit_rule = (strchr (current_rule->name, '%') != NIL); if (!is_implicit_rule) { if (!current_rule->cmdlist || !current_rule->cmdlist->command || !*current_rule->cmdlist->command) { current_rule = implicit_target (current_rule->name); is_implicit_rule = TRUE; } if (!current_rule) return mts; heritage = current_rule->heritage; } /* ... now the opt-macro-defs */ if ((buf_end += 1) < buf_bound) strcat (q->keybuffer, "{"); else return mts; if (heritage) { for (i = 0; heritage[i]; i++) { Bool got_plus = FALSE; Bool got_open_paren = FALSE; peek = heritage[i]; while (*peek && (*peek != ')') && (buf_end < buf_bound)) { if (!got_plus) { if (*peek == '+') { got_plus = TRUE; ++peek; continue; } } if (!got_open_paren) { if (*peek == '(') { got_open_paren = TRUE; ++peek; continue; } } *buf_end = *peek; buf_end++; peek++; } if ((buf_end +1) >= buf_bound) return mts; /* let's assume we've seen the closing paren */ *buf_end++ = '{'; *buf_end = '\0'; strcpy (edit_buffer, heritage[i]); if (edit_buffer[0] == '+') { edit_buffer[0] = '$'; dis = expandmacro (edit_buffer); if ((buf_end += strlen (dis) + 1) >= buf_bound) return mts; strcat (q->keybuffer, dis); } else { /* f*ck it !!! */ } strcat (q->keybuffer, "}"); } } strcat (q->keybuffer, "};"); /* * opt-sequence-of-word is used to add additional parameters * to the derivation key. */ strcpy (edit_buffer, expandmacro ("$(HOSTTYPE)")); if (!*edit_buffer) strcpy (edit_buffer, expandmacro ("$(hosttype)")); if (!*edit_buffer) strcpy (edit_buffer, af_getdomain()); if ((buf_end += strlen (edit_buffer) +5) >= buf_bound) return mts; strcat (q->keybuffer, edit_buffer); q->queue_changed = FALSE; return q->keybuffer; } shapetools-1.4pl6.orig/src/shape/error.c100444 2013 145 16423 5570377154 16367 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - error.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) and Wolfgang Obst * * $Header: error.c[8.0] Tue May 24 15:20:33 1994 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: error.c[8.0] Tue May 24 15:20:33 1994 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" extern int af_errno; EXPORT void errexit(err, mess) int err; char *mess; { if (err != 14) { cleanup_links(link_reg); af_cleanup(); } switch (err) { case 1: /* ???? */ fprintf(stderr, "shape - multiple defined action for: %s\n", mess); exit(1); case 2: fprintf(stderr, "shape - unknown option: %s\n", mess); exit(1); case 3: if (!strcmp(mess,"love")) { fprintf(stderr,"Oh, what was it?"); sleep(2); fprintf(stderr," ."); sleep(2); fprintf(stderr,"."); sleep(2); fprintf(stderr,". "); fprintf(stderr,"I should remember it"); sleep(2); fprintf(stderr," ."); sleep(2); fprintf(stderr,"."); sleep(2); fprintf(stderr,". "); fprintf(stderr,"memory fault. coeur dumped."); exit(1); } if (!strcmp(mess,"future")) { fprintf(stderr,"Let me think "); sleep(2); fprintf(stderr,"."); sleep(2); fprintf(stderr,"."); sleep(2); fprintf(stderr,"."); sleep(2); fprintf(stderr," No future "); sleep(2); fprintf(stderr,"."); sleep(2); fprintf(stderr,"."); sleep(2); fprintf(stderr,"."); sleep(2); fprintf(stderr," definitely!!!\n"); exit(1); } if (!strcmp(mess,"me")) { fprintf(stderr,"shape - don't know how to shape you\n"); exit(1); } if (!strcmp(mess,"you")) { fprintf(stderr,"shape yourself!\n"); exit(1); } if (!strcmp(mess,"god")) { fprintf(stderr,"Don't know how to shave God\n"); exit(1); } if (!strcmp(mess,"the queen")) { fprintf(stderr,"Don't know how to shave the queen\n"); exit(1); } fprintf(stderr, "shape - don't know how to shape - %s\n", mess); exit(1); case 4: fprintf(stderr, "shape - unknown special macro in cmd: %s\n", mess); exit(1); case 5: fprintf(stderr, "shape - multiply defined selection rule: %s\n", mess); exit(1); case 6: fprintf(stderr, "shape - unknown standard predicate: %s\n", mess); exit(1); case 7: fprintf(stderr, "shape - error in variant section %s\n", mess); exit(1); case 8: fprintf(stderr, "shape - file not found: %s\n", mess); exit(1); case 9: fprintf(stderr, "shape - invalid gen/rev specification: %s\n", mess); exit(1); case 10: fprintf(stderr, "shape - error in: %s\n",mess); if ((af_errno != 0) && (strcmp("malloc",mess))) af_perror("AtFS reports"); exit(1); case 11: fprintf(stderr, "shape - no description file and no arguments\n"); exit(1); case 12: fprintf(stderr, "shape - cannot open file: %s\n", mess); exit(1); case 13: fprintf(stderr, "shape - error during execution; retcode: %s\n", mess); exit(1); case 14: fprintf(stderr, "shape - syntax error: %s\n", mess); break; case 15: fprintf(stderr, "shape - aborted due to syntactical error(s)\n"); exit(1); case 16: fprintf(stderr, "shape - invalid state: %s\n", mess); exit(1); case 17: fprintf(stderr, "shape - couldn't find appropriate version of %s.\n", mess); exit(1); case 18: /* not used */ fprintf(stderr, "shape - aborted!!!\n"); exit(1); case 19: fprintf(stderr, "shape - variant name not defined: %s\n", mess); exit(1); case 20: fprintf(stderr, "shape - can't link %s\n", mess); exit(1); case 21: fprintf(stderr, "shape - can't unlink %s\n", mess); exit(1); case 22: fprintf(stderr, "shape - can't link %s to tmpfile\n", mess); exit(1); case 23: fprintf(stderr, "shape - interrupted \n"); exit(1); case 24: fprintf(stderr, "shape - can't open include file: %s\n", mess); exit(1); case 25: fprintf(stderr, "shape - infinitely recursive macro caused by line: %s?\n", mess); exit(1); case 26: fprintf(stderr, "shape - invalid macrocitation within heritage field: %s\n",mess); exit(1); case 27: fprintf(stderr, "shape - too many %s\n", mess); exit(1); case 28: fprintf(stderr, "shape - forced stop :-(; couldn't find appropriate version for: %s\n", mess); exit(1); case 29: fprintf(stderr, "shape - attribute too long\n"); exit(1); case 30: fprintf(stderr, "shape - incompatible combination of variants (vclass error): %s\n", mess); exit(1); case 31: fprintf(stderr, "shape - syntax error in rule section (delimiter missing)\n"); exit(1); case 32: fprintf(stderr, "shape - unknown selection rule name: %s\n", mess); exit(1); case 33: fprintf(stderr, "shape - multiply defined variant name: %s\n", mess); exit(1); case 34: fprintf(stderr, "shape - choose -expandall *or* -expandnothing!\n"); exit(1); case 35: fprintf(stderr, "shape - argument %s for -confid is no target name\n",mess); exit(1); case 36: fprintf(stderr, "shape - too many arguments for -force\n"); exit(1); case 37: fprintf(stderr, "shape - too many variant definitions\n"); exit(1); case 38: fprintf(stderr, "shape - bad delimiter in rule section: %s\n", mess); exit(1); case 39: fprintf(stderr, "shape - multiply defined variant class: %s\n", mess); exit(1); case 40: fprintf (stderr, "shape - inifinte recursion: target `%s' depends on itself.\n", mess); exit (1); case 99: fprintf(stderr, "shape - not yet implemented: %s\n", mess); exit(1); default: fprintf(stderr, "shape - impossible error\n"); exit(1); } } EXPORT void warning (no, mess) int no; char *mess; { switch (no) { case 1: fprintf(stderr,"shape - warning: derived object not saved into derived object cache; no AtFS subdirectory\n"); return; case 2: fprintf(stderr,"shape - warning: target `%s' not remade because of errors\n", mess); return; case 3: fprintf(stderr,"shape - warning: defining macros via command line may cause the rebuilding of a different system than described in confid\n"); return; case 4: fprintf(stderr,"shape - warning: no AtFS subdirectory\n"); return; case 5: fprintf(stderr,"shape - warning: environment variable ATFSBPSIZ = 0?\n"); return; case 7: fprintf (stderr, "shape - warning: infinite loop: target `%s' depends on itself.\n", mess); return; default: fprintf (stderr, "%s.\n", mess); return; } } shapetools-1.4pl6.orig/src/shape/files.c100444 2013 145 67765 5524514045 16346 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - files.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: files.c[8.0] Thu May 19 13:58:14 1994 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: files.c[8.0] Thu May 19 13:58:14 1994 axel@cs.tu-berlin.de frozen $"; #endif #include #include "shape.h" EXPORT char actpath[MYMAXNAMLEN]; EXPORT char dollarplus[MYMAXNAMLEN]; EXPORT char *pathlist[MAXPATHLIST][2]; EXPORT int lastpath = 0; EXPORT char *curvpath[MAXVPATH] = {NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL, NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL}; EXPORT Af_attrs buft; LOCAL struct linked_list *confid_list; LOCAL struct rlist_entry { struct rules *rule_ptr; Bool has_commands; char *active_vars; } *rule_list; LOCAL int rlist_size = 0, rlist_level = 0; LOCAL void add_to_pathlist (name, path) char *name, *path; { char *namep = strrchr (name, '/'); if (lastpath >= MAXPATHLIST) return; if ((pathlist[lastpath][0] = malloc (MYMAXNAMLEN)) == NIL) return; strcpy (pathlist[lastpath][0], namep ? namep + 1 : name); if (!strcmp (path, curvpath[0])) { if ((pathlist[lastpath][1] = malloc(3)) == NIL) { free (pathlist[lastpath][0]); return; } strcpy (pathlist[lastpath][1], "&$"); } else { if ((pathlist[lastpath][1] = malloc(MYMAXNAMLEN)) == NIL) { free (pathlist[lastpath][0]); free (pathlist[lastpath][1]); return; } strcpy (pathlist[lastpath][1], path); strcat (pathlist[lastpath][1], "/"); strcat (pathlist[lastpath][1], pathlist[lastpath][0]); } lastpath++; } LOCAL Bool is_in_pathlist (raw_name, sought_name, full_path) char *raw_name, *sought_name; Bool full_path; { register int i; for(i = lastpath - 1; i >= 0; i--) { /* looking in pathlist if file already exists */ if (!strcmp (sought_name, pathlist[i][0])) { if (!strcmp (pathlist[i][1], "&$")) strcpy (actpath, curvpath[0]); else { if (pathlist[i][1][0] != '/') { strcpy (actpath, curvpath[0]); strcat (actpath, "/"); strcat (actpath, pathlist[i][1]); } else { strcpy (actpath, pathlist[i][1]); } if ((sought_name = strrchr (actpath, '/')) != NIL) *sought_name = '\0'; } if(full_path) { if (!strcmp (pathlist[i][1], raw_name)) { strcpy (actpath, pathlist[i][1]); if ((sought_name = strrchr (actpath, '/')) != NIL) *sought_name = '\0'; return TRUE; } if (!strcmp (raw_name, curvpath[0])) { strcpy (actpath, curvpath[0]); return TRUE; } } else { if ((pathlist[i][1][0] == '&') && (pathlist[i][1][1] == '$')) { strcpy (actpath, curvpath[0]); return TRUE; } else { strcpy (actpath, pathlist[i][1]); if ((sought_name = strrchr (actpath, '/')) != NIL) *sought_name = '\0'; return TRUE; } } } /* end if (!strcmp (sought_name, pathlist[i][0])) */ } /* end for (i = lastpath - 1; i >= 0; i--) */ return FALSE; } /*================ restore list ================== */ /* partially rewritten by andy@cs.tu-berlin.de -- 27. Jan. 92 */ LOCAL struct restoreItem { char *unixName; Af_key restoreKey; int restoreType; /* 0 = local, 1 = vpath, 2 = external */ struct restoreItem *next; } **restoreList; /* need one restore list for each recursion level */ LOCAL int maxResListDepth = 0; LOCAL void add_to_restorelist (restoreKey, unixName, restoreType) Af_key *restoreKey; char *unixName; int restoreType; { struct restoreItem *currentItem; if (depth >= maxResListDepth) { int i; if (maxResListDepth == 0) if((restoreList = (struct restoreItem **) malloc (16*sizeof(void *))) == (struct restoreItem **)0) errexit(10,"malloc"); else if((restoreList = (struct restoreItem **) realloc (restoreList, 16*sizeof(void *))) == (struct restoreItem **)0) errexit(10,"realloc"); for (i=maxResListDepth; inext) currentItem = currentItem->next; if ((currentItem->next = (struct restoreItem *) malloc (sizeof(struct restoreItem))) == (struct restoreItem *) 0) errexit(10,"malloc"); currentItem = currentItem->next; } if((currentItem->unixName = malloc((unsigned) (strlen(unixName) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(currentItem->unixName, unixName); currentItem->restoreKey = *restoreKey; currentItem->restoreType = restoreType; currentItem->next = (struct restoreItem *)0; } LOCAL void restore_vers (restoreKey, unixName, restoreType) Af_key *restoreKey; char *unixName; int restoreType; { extern int errno; FILE *atfs_fp, *tmp_fp; char tmpName[PATH_MAX], hiddenName[PATH_MAX]; char *buf, *at_getfilename(); Bool busy_exist; struct utimbuf rv_time; if (noexflg) /* don't execute commands (-n Option) */ return; /* creation of a temporary file for the revision to be restored */ if (restoreType == 2) /* external */ strcpy (tmpName, stTmpFile (af_retattr (restoreKey, AF_ATTSPATH))); else strcpy (tmpName, stTmpFile (".")); /* link, unlink, set busy */ if ((atfs_fp = af_open (restoreKey, "r")) == NULL) errexit(10,"af_open"); /* copy old revision into temp. file */ if ((buf = malloc((unsigned) af_retnumattr (restoreKey, AF_ATTSIZE))) == NIL) errexit(10,"malloc"); fread (buf, sizeof(char), (int) af_retnumattr (restoreKey, AF_ATTSIZE), atfs_fp); af_close(atfs_fp); if ((tmp_fp = fopen (tmpName, "w")) == NULL) errexit(10, "fopen; could not create tmpfile"); if(noexpflg) fwrite (buf, sizeof(char), (int) af_retnumattr (restoreKey, AF_ATTSIZE), tmp_fp); else atExpandAttrs (restoreKey, buf, af_retnumattr (restoreKey, AF_ATTSIZE), tmp_fp, 0, AT_EXPAND_FILE); free(buf); fclose(tmp_fp); /* save busy version into AtFS directory if necessary */ errno = 0; if (access (unixName, R_OK) == 0) { /* unix File already exists */ /* make name for real version that must be temporarily moved */ if (restoreType == 2) /* external */ strcpy (hiddenName, stTmpFile (af_retattr (restoreKey, AF_ATTSPATH))); else strcpy (hiddenName, stTmpFile (curvpath[0])); busy_exist = TRUE; if (link (unixName, hiddenName) != 0) { unlink (tmpName); errexit(20, unixName); } if (unlink (unixName) != 0) { unlink (tmpName); errexit(21, unixName); } } else { hiddenName[0] = '\0'; busy_exist = FALSE; } if (link (tmpName, unixName) != 0) errexit(22, unixName); if (unlink (tmpName) != 0) errexit(21, tmpName); rv_time.actime = af_rettimeattr (restoreKey, AF_ATTATIME); rv_time.modtime = af_rettimeattr (restoreKey, AF_ATTMTIME); if (utime (unixName, &rv_time) < 0) { perror ("shape -- warning: (restore_vers) can't set modification time.\n"); } register_link (unixName, hiddenName, busy_exist); if (af_retnumattr (restoreKey, AF_ATTSTATE) != AF_BUSY) busy_done = TRUE; } LOCAL Bool already_in_confid (key) Af_key *key; { char *name; register struct linked_list *clist; name = atRetAttr (key, AF_ATTBOUND); if (confid_list == (struct linked_list *) NIL) { if ((confid_list = (struct linked_list *) malloc (sizeof(struct linked_list))) == (struct linked_list *)NIL) errexit (10,"malloc"); if ((confid_list->string = malloc ((unsigned)(strlen (name)+ sizeof(char)))) == NIL) errexit (10,"malloc"); confid_list->nextstring = (struct linked_list *) NIL; strcpy (confid_list->string, name); return FALSE; } else { clist = confid_list; while (strcmp (name, clist->string)) { if (clist->nextstring != (struct linked_list *) NIL) clist = clist->nextstring; else break; } if (clist->nextstring != (struct linked_list *) NIL) return TRUE; if ((clist->nextstring = (struct linked_list *) malloc (sizeof(struct linked_list))) == (struct linked_list *) NIL) errexit (10,"malloc"); if((clist->nextstring->string = malloc ((unsigned) (strlen (name) + sizeof(char)))) == NIL) errexit (10,"malloc"); strcpy (clist->nextstring->string,name); clist->nextstring->nextstring = (struct linked_list *) NIL; return FALSE; } } LOCAL void write_confid (key, cid_mode) Af_key *key; int cid_mode; { char *netPathPrefix, *at; if (already_in_confid (key)) return; netPathPrefix = atNetworkPath (key); if ((at = strrchr (netPathPrefix, '@'))) { *at = '\0'; } if (af_retnumattr (key, AF_ATTSTATE) == AF_BUSY) { if (cid_mode == 0) { fprintf (cid,"\t%s[", atRetAttr (key, AF_ATTUNIXNAME)); fprintf (cid, "%s], ", atRetAttr (key, AF_ATTMTIME)); fprintf (cid, "msg (\"warning: using (yet unchanged) busy version of %s.\");\n", atRetAttr (key, AF_ATTUNIXNAME)); fprintf (cid,"\t%s[busy], ", atRetAttr (key, AF_ATTUNIXNAME)); fprintf (cid, "msg (\"warning: using busy version of %s (modified since baseline!).\");\n", atRetAttr (key, AF_ATTUNIXNAME)); fflush (cid); fprintf (stderr, "shape - warning: defining unsafe baseline. %s is a busy version.\n", atRetAttr (key, AF_ATTUNIXNAME)); return; } else { fprintf (cid, "\t%s[%s], ", netPathPrefix, atRetAttr (key, AF_ATTMTIME)); fprintf (cid, "msg (\"warning: using (yet unchanged) busy version of %s of %s.\");\n", netPathPrefix, atRetAttr (key, AF_ATTMTIME)); fprintf (cid,"\t%s[busy], ", netPathPrefix); fprintf (cid, "msg (\"warning: using busy version of %s (modified since baseline!).\");\n", netPathPrefix); fflush (cid); fprintf (stderr, "shape - warning: defining unsafe baseline. %s is a busy version.\n", netPathPrefix); return; } } if (cid_mode == 0) fprintf (cid,"\t%s", atRetAttr (key, AF_ATTBOUND)); else fprintf (cid, "\t%s", atNetworkPath (key)); if (af_retnumattr (key, AF_ATTSTATE) < AF_PUBLISHED) { fprintf (cid,",\n\tmsg (\"warning: %s had state", atRetAttr (key, AF_ATTBOUND)); fprintf (cid, " %s when baselined.\")", atRetAttr (key, AF_ATTSTATE)); fprintf(stderr,"shape - warning: %s had state", atRetAttr (key, AF_ATTBOUND)); fprintf (stderr, " %s when baselined.\n", atRetAttr (key, AF_ATTSTATE)); } fprintf (cid,";\n"); fflush (cid); } LOCAL void dump_rules (cidfile) FILE *cidfile; { register int i; for (i = 0; i < rlist_level; i++) { if (rule_list[i].active_vars) { char *var_name = stStrtok (rule_list[i].active_vars); while (var_name) { (void) activate_variant (var_name); var_name = stStrtok (NULL); } } dump_rule (cidfile, rule_list[i].rule_ptr, rule_list[i].has_commands); if (rule_list[i].active_vars) { char *var_name = stStrtok (rule_list[i].active_vars); while (var_name) { de_activate (var_name); var_name = stStrtok (NULL); } } } } LOCAL void dump_variant_classes (destination) FILE *destination; { /* * prints a list of all known variant class definitions to * the file passed in "destination". This must be an open * FILE. A variat definition is printed in correct Shapefile * syntax. */ register int vc_count = 0; (void) fputs ("#\n#\tVariant Class Definitions\n#\n\n", destination); while (variantClasses[vc_count].name) { print_variant_class (destination, &variantClasses[vc_count]); vc_count++; }; (void) fputs ("\n", destination); } LOCAL void dump_variant_definitions (destination) FILE *destination; { /* * print a list of all known variant definitions to the file * passed in "destination", which must point to an open FILE. * The definitions are printed in proper Shapefile variant * defintion syntax. */ register int vd_count = 0; (void) fputs ("#\n#\tVariant Definitions\n#\n\n", destination); while (variantDefs[vd_count].name) { print_variant_definition (destination, &variantDefs[vd_count]); vd_count++; }; } LOCAL void dump_variants (cidfile) FILE *cidfile; { dump_variant_classes (cidfile); dump_variant_definitions (cidfile); } LOCAL void free_rlist_entries () { register int i; for (i = 0; i < rlist_level; i++) { if (rule_list[i].active_vars) free (rule_list[i].active_vars); } } /* not used * * LOCAL void add_to_selmacro (fname) * char *fname; * { * if(fname[strlen(fname)-1] == ']') { * define_macro ("SELECTED_AtFS", fname, APPEND); * } * else { * define_macro ("SELECTED_FS", fname, APPEND); * } * } * * * LOCAL void notfounditem (dependent) * char *dependent; * { * static char depname[MYMAXNAMLEN]; * if(strcmp(dependent,depname)) * printf("%s\n", dependent); * strcpy(depname,dependent); * } * * LOCAL void write_select_list (key) * Af_key *key; * { * char *filename = atRetAttr (key, AF_ATTBOUND); * if(!nomsgflg) * printf ("%s\n", filename); * add_to_selmacro (filename); * } */ LOCAL char *path_to_net_id (path) char *path; { /* * compute the network id of the object referred to by * Result is returned in static memory. */ static char net_id[MYMAXNAMLEN], *empty_path = ""; Af_key *key; if (! (path && *path)) return empty_path; key = atBindVersion (path, ""); if (key) { (void) strcpy (net_id, atNetworkPath (key)); af_dropkey (key); return net_id; } else return empty_path; } LOCAL char *make_repository_id (path) char *path; { /* * compute the canonical network path name for the object pointed * to by . * Result is returned in static memory. */ char raw_repository_path[MYMAXNAMLEN], *at, *psuff, vbinding[MYMAXNAMLEN]; static char cooked_repository_path[MYMAXNAMLEN]; (void) sprintf (raw_repository_path, "%s/AtFS", path); (void) strcpy (raw_repository_path, path_to_net_id (raw_repository_path)); if (*raw_repository_path) { at = strrchr (raw_repository_path, '@'); psuff = strrchr (raw_repository_path, '/'); if (at) *at = ' '; if (psuff) *psuff = ' '; (void) sscanf (raw_repository_path, "%s AtFS %s", cooked_repository_path, vbinding); } else { (void) strcpy (raw_repository_path, path_to_net_id (path)); at = strrchr (raw_repository_path, '@'); if (at) *at = ' '; (void) sscanf (raw_repository_path, "%s %s", cooked_repository_path, vbinding); } return cooked_repository_path; } EXPORT Bool locate_object (name, mode) char *name; int mode; { /* * Try to locate a history or at least a regular file of the specified * name. In doing so, consider current vpath. If an object is found * write its path-prefix (i.e. not the name, just the path) into the * global variable "actpath" and return TRUE. If no object can be * found, return FALSE - "actpath" is undefined. * "mode" == ALL: check if "name" exists in any of BPOOL or SRC-R-KIVE * "mode" == NONE: ??? * "mode" == SOURCE: check if "name" exists in SRC-R-KIVE and nowhere else * "mode" == BINARY: check if "name" exists in BPOOL */ char bname[MYMAXNAMLEN], sysp[MYMAXNAMLEN], lname[MYMAXNAMLEN]; char current_path[MYMAXNAMLEN]; register char *px; register int i; #define YES 0 #define NO -1 int file_exists = NO, file_exists_in_src_rkive, file_exists_in_bpool; int ii; Af_attrs buf; Bool is_in_pathlist(), full_path = FALSE; if (!name || (name[0] == '\0')) return (FALSE); sysp[0] = '\0'; strcpy (lname, name); if ((px = strrchr (lname,'/'))) { full_path = TRUE; *px = '\0'; px++; } else px = lname; if ((mode != BINARY) && is_in_pathlist (lname, px, full_path)) return TRUE; strcpy (bname, name); if (strrchr (bname, '/')) { strcpy (sysp, af_afpath (bname)); } af_initattrs (&buf); strcpy (buf.af_name, af_afname (bname)); strcpy (buf.af_type, af_aftype (bname)); ii = 1; while (curvpath[ii]) ii++; i = ii - 1; /* "i" is index of last "vpath" element */ while ( i >= 0 ) { if (i) { /* still vpath entries to look through ... */ strcpy (current_path, expandmacro (curvpath[i])); if (!*current_path) break; if(*current_path != '/') { strcpy (buf.af_syspath, curvpath[0]); strcat (buf.af_syspath, "/"); strcat (buf.af_syspath, current_path); } else strcpy (buf.af_syspath, current_path); } else { /* i == 0 -- curvpath[0] points to build directory */ if (*sysp) strcpy (buf.af_syspath, sysp); else strcpy (buf.af_syspath, curvpath[0]); } if (mode == ALL) { file_exists_in_src_rkive = af_access (buf.af_syspath, buf.af_name, buf.af_type, AF_CLASS_SOURCE); file_exists_in_bpool = af_access (buf.af_syspath, buf.af_name, buf.af_type, AF_CLASS_DERIVED); if((file_exists_in_src_rkive == YES) || (file_exists_in_bpool == YES)) file_exists = YES; else file_exists = NO; } if (mode == NONE) file_exists = af_access (buf.af_syspath, buf.af_name, buf.af_type, AF_CLASS_SOURCE); if (mode == SOURCE) { file_exists = af_access (buf.af_syspath, buf.af_name, buf.af_type, AF_CLASS_DERIVED); if (file_exists == NO) file_exists = af_access (buf.af_syspath, buf.af_name, buf.af_type, AF_CLASS_SOURCE); else file_exists = NO; } if (mode == BINARY) file_exists = af_access(buf.af_syspath, buf.af_name, buf.af_type, AF_CLASS_DERIVED); if (file_exists == YES) { strcpy (actpath, buf.af_syspath); if (!full_path) add_to_pathlist (bname, buf.af_syspath); break; } i--; } /* end while ( i >= 0 ) */ return (file_exists == YES); #undef YES #undef NO } EXPORT Bool try_to_bind_version (dep, bind_rule, try_or_bind, bind_result) char *dep; char *bind_rule; Bool try_or_bind; BKey *bind_result; { /* * locate the repository location of the object named "dep", and * attempt to bind it to a version, implied by "bind_rule". If an * object can be bound, a pointer to it is stored in the BKey structure. * As a global side effect, all attributes of the bound object are stored * in the global attribute buffe "buft". */ Af_key *bound_key, *tmpKey; Bool objectExists, object_lives_in_vpath = FALSE, object_has_explicit_path = FALSE; char *atBindRule; int restoreType; bind_result->bk_isdefined = FALSE; if ((objectExists = locate_object (dep, ALL))) { if (strrchr (dep, '/') != NIL) { object_has_explicit_path = TRUE; } atBindExpandMacro = expandmacro; atBindRule = malloc (strlen (bind_rule ? bind_rule : "")+2); if (!atBindRule) { errexit (10, "malloc"); } *atBindRule = '\0'; strcat (atBindRule, bind_rule); strcat (atBindRule, ":"); chdir (actpath); if (D_flag) atBindTrace = TRUE; bound_key = atBindVersion (dep, atBindRule); chdir (curvpath[0]); if (bound_key) { bind_result->bk_key = *bound_key; bind_result->bk_isdefined = TRUE; af_allattrs (bound_key, &buft); af_freeattrbuf (&buft); if (!object_has_explicit_path) object_lives_in_vpath = strcmp (af_retattr (bound_key, AF_ATTSPATH), curvpath[0]); if(confid) { if(dep[0] == '/') write_confid (bound_key, 1); else write_confid (bound_key, 0); } /* If this version is found via vpath, we want it to be * "restored" to the current directory. Even if it is a * busy-version. If the version is non-busy, * we have to restore it anyway. */ if (object_lives_in_vpath) { restoreType = 1; /* vpath */ } else if (strrchr (dep, '/')) { restoreType = 2; /* explicit */ } else restoreType = 0; /* local */ if (object_lives_in_vpath || (af_retnumattr (bound_key, AF_ATTSTATE) != AF_BUSY ) || (expflg)) { add_to_restorelist (bound_key, dep, restoreType); return TRUE; } else { return TRUE; } } } reset_vclass(); if (!D_flag) { /* tracing already done */ atBindTrace = TRUE; chdir (actpath); tmpKey = atBindVersion (dep, atBindRule); af_dropkey (tmpKey); chdir (curvpath[0]); } errexit(17,dep); return FALSE; } EXPORT void init_confid (name) char *name; { char *hosttype = getenv ("HOSTTYPE"), *now = af_asctime(), *vp; if (now && *now) { char *nl = strchr (now, '\n'); if (nl && (*nl == '\n')) *nl = '\0'; } fprintf (cid, "########################################"); fprintf (cid, "########################################\n"); fprintf (cid, "######\n"); fprintf (cid, "###### Bound configuration for %s\n", name); fprintf (cid, "######\n"); fprintf (cid, "###### Date of creation: %s\n", now); fprintf (cid, "###### Created by: %s\n", atUserName (af_afuser (getuid ()))); fprintf (cid, "###### With: %s (%s)\n", stProgramName, version()); fprintf (cid, "######\n"); fprintf (cid, "###### Hostname: %s.%s", af_gethostname (), af_getdomain ()); if (hosttype) { fprintf (cid, " (a %s computer)\n", hosttype); } else { fprintf (cid, "\n"); } fprintf (cid, "###### Build directory: %s\n", curvpath[0]); fprintf (cid, "######\n"); fprintf (cid, "###### Repository base: %s\n", make_repository_id (curvpath[0])); vp = expandmacro ("$(vpath)"); if (vp && *vp) { char *var_repo; register char *c; c = strchr (vp, ':'); while (c) { *c = ' '; c = strchr (vp, ':'); } var_repo = stStrtok (vp); while (var_repo) { fprintf (cid, "###### %s\n", make_repository_id (var_repo)); var_repo = stStrtok (NULL); } } fprintf (cid, "######\n"); if (cmd_line_vars[0]) { register int cmdlv_count = 0; fprintf (cid, "###### The following variants were requested from the\n"); fprintf (cid, "###### command line: %s", cmd_line_vars[cmdlv_count]); cmdlv_count++; while (cmd_line_vars[cmdlv_count]) { fprintf (cid, ", %s", cmd_line_vars[cmdlv_count]); cmdlv_count++; } fputs ("\n", cid); } fprintf (cid, "######\n"); fprintf (cid, "###### To rebuild a program according to this bound\n"); fprintf (cid, "###### configuration, issue the command:\n"); fprintf (cid, "######\n"); fprintf (cid, "###### shape -rebuild %s\n", name); fprintf (cid, "######\n"); fprintf (cid, "########################################"); fprintf (cid, "########################################\n\n"); fprintf (cid, "vpath = %s\n", vp); fprintf (cid,"\n"); fprintf (cid,"bound_configuration_thread:-\n"); } #define RLSIZE 1024 EXPORT void add_rule_to_confid (rule) struct rules *rule; { register int i; char *active_vars; if (rule == NULL) return; /* if rule is already in list and variant context is the same, do nothing */ active_vars = active_variants (); for (i = 0; i < rlist_level; i++) { if (rule_list[i].rule_ptr == rule) if (!strcmp (rule_list[i].active_vars, active_vars)) return; } /* if list is full, expand it */ if (rlist_level == rlist_size) { if (rlist_size == 0) { rule_list = (struct rlist_entry *) malloc (RLSIZE * sizeof (struct rlist_entry)); if (!rule_list) errexit (10, "malloc"); rlist_size = RLSIZE * sizeof (struct rlist_entry); } else { struct rlist_entry *tmp = (struct rlist_entry *) realloc (rule_list, 2 * rlist_size); if (!tmp) errexit (10, "realloc"); rule_list = tmp; rlist_size *= 2; } } /* register rule */ rule_list[rlist_level].rule_ptr = rule; rule_list[rlist_level].active_vars = active_vars ? check_strdup (active_vars) : NULL; rule_list[rlist_level++].has_commands = (rule->cmdlist != NULL); } EXPORT void finish_confid() { fprintf (cid,"\t.\n"); fprintf (cid,"\n"); dump_variants (cid); dump_rules (cid); free_rlist_entries (); if (rule_list) free (rule_list); rlist_size = 0; rlist_level = 0; } EXPORT FILE *cmfopen( filename, mode, major_version,minor_version) char *filename; char *mode; /*ARGSUSED*/ int major_version; int minor_version; { char syspath[MYMAXNAMLEN]; Af_key key; FILE *fp; if (strrchr(filename,'/') == NIL) strcpy(syspath,curvpath[0]); else strcpy(syspath,af_afpath(filename)); if(af_crkey(syspath, af_afname(filename), af_aftype (filename),&key) == -1) errexit(10,"af_crkey"); else { fp = af_open(&key, mode); return (fp); } return((FILE *) NIL); } EXPORT void restore_all_vers() { struct restoreItem *currentItem; sb_ptr restored_objs_macro = sbnew (512); if (depth >= maxResListDepth) return; currentItem = restoreList[depth]; while(currentItem != (struct restoreItem *)0) { sbcat (restored_objs_macro, currentItem->unixName, strlen (currentItem->unixName)); sbcat (restored_objs_macro, " ", 1); restore_vers (¤tItem->restoreKey, currentItem->unixName, currentItem->restoreType); currentItem = currentItem->next; } define_macro ("RESTORED_OBJS", sbstr (restored_objs_macro), DYNAMIC); sbfree (restored_objs_macro); } EXPORT char *restored_object_id (unixname) char *unixname; { /* * Check whether an object with name "unixname" is in the restorelist, * return a string giving the actual location and id of the object. * The returned string format is as follows: if an object lives * somewhere in a vpath-subdirectory, the relative (to the build-dir) * pathname of the object is returned. To obtain the relative path, * we use the object's absolute path and skip the part of it that is * made up by the current directory's absolute path (plus the remaining * slash). This solution works only if vpath is actually a subdirectory * of the current dir. * If the object is a busy-file, just the object's name is used. If it's * a real version, bound version notation is used. */ static char roid[MYMAXNAMLEN]; struct restoreItem *currentItem; if (!(unixname && *unixname)) return (char *)NULL; if (depth >= maxResListDepth) return unixname; currentItem = restoreList[depth]; while(currentItem != (struct restoreItem *)0) { if (strcmp (unixname, currentItem->unixName) == 0) { Af_key *rkey = ¤tItem->restoreKey; Bool is_busy = af_retnumattr (rkey, AF_ATTSTATE) == AF_BUSY; switch (currentItem->restoreType) { case REGULAR: strcpy (roid, af_retattr (rkey, is_busy ? AF_ATTUNIXNAME : AF_ATTBOUND)); break; case VPATH: strcpy (roid, af_retattr (rkey, AF_ATTSPATH) + strlen (curvpath[0]) + 1); strcat (roid, "/"); strcat (roid, af_retattr (rkey, is_busy ? AF_ATTUNIXNAME : AF_ATTBOUND)); break; case EXTERNAL: strcpy (roid, af_retattr (rkey, AF_ATTSPATH)); strcat (roid, "/"); strcat (roid, af_retattr (rkey, is_busy ? AF_ATTUNIXNAME : AF_ATTBOUND)); break; default: fprintf (stderr, "internal error: wrong switch in `restored_object_id'.\n"); return (char *)NULL; } return roid; } currentItem = currentItem->next; } return unixname; } EXPORT void drop_restorelist () { struct restoreItem *currentItem, *lastItem; if (depth >= maxResListDepth) return; currentItem = restoreList[depth]; while(currentItem != (struct restoreItem *)0) { free (currentItem->unixName); lastItem = currentItem; currentItem = currentItem->next; free (lastItem); } restoreList[depth] = (struct restoreItem *)0; } shapetools-1.4pl6.orig/src/shape/hash.c100444 2013 145 17430 5416575155 16160 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - hash.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: hash.c[8.0] Wed Jul 7 18:32:58 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: hash.c[8.0] Wed Jul 7 18:32:58 1993 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" #define HASHSIZE 257 struct hash { unsigned short visited; unsigned short kind_of_substitution; /* see shape.h */ char *name; char *entry; struct linked_list *add_entries; struct hash *next; }; LOCAL struct hash hashTable[HASHSIZE]; EXPORT int hashval(name, tabsize) char *name; int tabsize; { register int hash = 0, i = 0; if (!(name && *name)) return 0; hash = name[0]; for(i = 1; name[i] != '\0'; i++) hash = ((hash * 32) + name[i]) % tabsize; return hash; } /* end hashval */ EXPORT void addHash (name, value, subst_kind) char *name; char *value; int subst_kind; { int hashValue = hashval (name, HASHSIZE); register struct hash *current; Bool current_is_new = TRUE; /* * Try to find existing entry for name in hash table */ current = &hashTable[hashValue]; /* * since additive macro defs are stored in any case in a special * entry of the struct hash structure, there is no need to protect * it from redefintions in the Shapefile */ if (subst_kind & APPEND) subst_kind &= ~FROM_CMDLINE; if (current->name) { while (current) { if (!strcmp (current->name, name)) /* found it */ { current_is_new = FALSE; break; } else if (current->next) { current = current->next; } else { current->next = (struct hash *)check_malloc (sizeof (struct hash)); current->next->entry = NULL; current->next->add_entries = NULL; current->next->next = NULL; current->next->name = NULL; current->next->visited = 0; current->next->kind_of_substitution = 0; current = current->next; break; } } } /* * "current" points to the correct (correctly linked) entry * in the hash table. * Now, see what needs to be done... */ if (current_is_new) { if (subst_kind & APPEND) { current->add_entries = (struct linked_list *)check_malloc (sizeof (struct linked_list)); current->add_entries->string = check_strdup (value); current->add_entries->nextstring = NULL; } else current->entry = check_strdup (value); current->name = check_strdup (name); current->kind_of_substitution = subst_kind; return; } /* * We have to deal with a redefinition or definition * enhancement case (+=). This is a bit more complicated * as this interacts with the macro definition semantics. */ if (subst_kind & APPEND) { struct linked_list *lp, *prev_lp; lp = prev_lp = current->add_entries; while (lp) { lp = lp->nextstring; if (lp) prev_lp = lp; } if (!prev_lp) { current->add_entries = (struct linked_list *)check_malloc (sizeof (struct linked_list)); current->add_entries->string = check_strdup (value); current->add_entries->nextstring = NULL; } else { prev_lp->nextstring = (struct linked_list *)check_malloc (sizeof (struct linked_list)); prev_lp->nextstring->string = check_strdup (value); prev_lp->nextstring->nextstring = NULL; } return; } if (subst_kind & FROM_CMDLINE) { /* almost always override existing defs */ if (current->entry) current->entry = check_realloc (current->entry, strlen(value) + sizeof(char)); else current->entry = check_malloc (strlen(value) + sizeof(char)); strcpy (current->entry, value); current->kind_of_substitution = subst_kind; return; } if ((current->kind_of_substitution & FROM_CMDLINE) && !(current->kind_of_substitution & APPEND)) return; if (current->entry) current->entry = check_realloc (current->entry, strlen(value) + sizeof(char)); else current->entry = check_malloc (strlen(value) + sizeof(char)); strcpy (current->entry, value); return; } /* end addHash */ #define LASTNAME_LEN 128 LOCAL struct hash *current_hash; LOCAL char lastname[LASTNAME_LEN], *lastentry = (char *)NIL; EXPORT char *getHash (name) char *name; { int hashValue = hashval (name, HASHSIZE); if (!name || !*name) return NIL; if (name && !strcmp (lastname ? lastname : "", name)) return lastentry; else strcpy (lastname, name); if (!hashTable[hashValue].name) { /* nothing found */ lastentry = NIL; return lastentry; } current_hash = &hashTable[hashValue]; while (current_hash) { register struct linked_list *lp; if (!strcmp (current_hash->name, name)) { /* found it */ lastentry = current_hash->entry; if (!lastentry) { lastentry = check_malloc (16); /* just something malloc'ed */ *lastentry = '\0'; } lp = current_hash->add_entries; while (lp) { if (lp->string && *lp->string) { lastentry = check_realloc (lastentry, strlen (lastentry) + strlen (lp->string) + 2); (void) strcat (lastentry, *lastentry ? " " : ""); (void) strcat (lastentry, lp->string); free (lp->string); } { struct linked_list *old_lp = lp; lp = lp->nextstring; free (old_lp); } } current_hash->entry = lastentry; if (current_hash->add_entries) current_hash->add_entries = NULL; current_hash->visited = TRUE; if (current_hash->kind_of_substitution & ONCE) { char *expanded_entry; struct hash *cur_hash_bak = current_hash; char lastname_bak[LASTNAME_LEN], *lastentry_bak = lastentry; int cmd_subst_flg = no_comm_subst; (void) strcpy (lastname_bak, lastname); no_comm_subst = FALSE; expanded_entry = check_strdup (expandmacro (lastentry)); no_comm_subst = cmd_subst_flg; (void) strcpy (lastname, lastname_bak); current_hash = cur_hash_bak; lastentry = lastentry_bak; free (lastentry); lastentry = expanded_entry; current_hash->entry = lastentry; current_hash->kind_of_substitution &= ~ONCE; } return lastentry; } current_hash = current_hash->next; } lastentry = NIL; return lastentry; } EXPORT Bool visitedHash (name) char *name; { if (!name || !lastname) return FALSE; return ((name && !strcmp (lastname, name)) && lastentry && current_hash->visited); } EXPORT void clearHashVisited (name) char *name; { if (!name || !lastname) return; if ((name && !strcmp (lastname, name)) && lastentry) current_hash->visited = FALSE; return; } EXPORT void dump(fd) FILE *fd; { register int i; register struct hash *current; fprintf(fd,"# Macros:\n"); for(i = 0; i < HASHSIZE; i++) { if (hashTable[i].name) { current = &hashTable[i]; while(current != (struct hash *) NIL) { if((current->name[0] != '$') && (current->name[0] != '*') && (current->name[0] != '+') && (current->name[0] != '<') && (current->name[0] != '?') && (current->name[0] != '@')) { if(fd != stdout) { fprintf(fd,"%s = %s\n", current->name, current->entry); } else { fprintf(fd,"\t%s = %s\n", current->name, current->entry); } } current = current->next; } } } } /* end dump */ shapetools-1.4pl6.orig/src/shape/inherit.c100444 2013 145 22652 5430456735 16677 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - inherit.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: inherit.c[8.0] Fri Aug 6 19:12:40 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: inherit.c[8.0] Fri Aug 6 19:12:40 1993 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" extern int af_errno; LOCAL Bool finddep(rule,name) struct rules *rule; char *name; { register int i = 0; char *dependent; while(*(dependent = get_dep(rule,i))) { if (!strcmp(dependent,name)) return(TRUE); i++; } return(FALSE); } LOCAL Bool forbidden(syspath,name,type) char *syspath; char *name; char *type; { char fullname[MYMAXNAMLEN]; Bool bp = FALSE, nobp = FALSE; register struct rules *bpool, *nobpool; fullname[0] = '\0'; if (strcmp(syspath,curvpath[0])) { strcpy(fullname,syspath); strcat(fullname,"/"); strcat(fullname,name); } else { strcpy(fullname,name); } if (type && *type) { strcat(fullname,"."); strcat(fullname,type); } bpool = get_target (".BPOOL"); nobpool = get_target (".NOBPOOL"); if (bpool != (struct rules *) NIL) { bp = finddep(bpool,fullname); } else bp = TRUE; if (nobpool != (struct rules *) NIL) { nobp = finddep(nobpool,fullname); } if (bp && nobp) return(TRUE); if (bp && (!nobp)) return(FALSE); if ((!bp) && nobp) return(TRUE); if ((!bp) && (!nobp)) return(TRUE); /*NOTREACHED*/ return(FALSE); } LOCAL struct linked_key_list { char *string; Af_key done_key; struct linked_key_list *nextstring; } *done_list; /* This function should be part of AtFS ! */ LOCAL int af_dupkey (inkey, outkey) Af_key *inkey, *outkey; { if (afAccessAso (inkey, 0)) FAIL ("dropkey", "", AF_EINVKEY, ERROR); /* increase reference count in corresponding archive and in attrbuf */ afIncreaseAccess (inkey); *outkey = *inkey; return (AF_OK); } EXPORT void add_to_done_list (targ_path, done_key) char *targ_path; Af_key *done_key; { struct linked_key_list *c; static struct linked_key_list *l; if(done_list == (struct linked_key_list *) NIL) { done_list = (struct linked_key_list *) check_malloc (sizeof(struct linked_key_list)); c = l = done_list; done_list->nextstring = (struct linked_key_list *) NIL; } else { l->nextstring = (struct linked_key_list *) check_malloc(sizeof(struct linked_key_list)); c = l->nextstring; l = c; } c->nextstring = (struct linked_key_list *) NIL; c->string = check_strdup (targ_path); if (done_key) { if (af_dupkey (done_key, &c->done_key) < 0) af_perror ("af_dupkey"); } } EXPORT Bool stk_matchuda (udas, attr) char *udas, *attr; { char *start, *end; int attrlen; if (udas == (char *)NULL) return FALSE; if (attr == (char *)NULL) return FALSE; attrlen = strlen (attr); start = udas; do { end = strchr (start, '\n'); if (!end) end = start + strlen (start); if ((attrlen == end-start) && strncmp (start, attr, end-start) == 0) return TRUE; if (*end) { start = end+1; } else return FALSE; } while (*start); return FALSE; } EXPORT void save_targets (dep_rule, primary_target_name, q, primary_target_key, touch_time) struct rules *dep_rule; char *primary_target_name; DepQ *q; BKey *primary_target_key; time_t touch_time; { Af_key busykey, savekey; Af_attrs attrbuf; struct rules *this_rule = dep_rule; char *do_key, *syspath, name[NAME_MAX+1], type[NAME_MAX+1], *p; int major_version = AF_BUSYVERS, minor_version = AF_BUSYVERS, retcode; char savepath[MYMAXNAMLEN], *targetpath, *derivation_key; primary_target_key->bk_isdefined = FALSE; if (noexflg) return; if (dep_rule == (struct rules *)NULL) return; /* * This is handling of the special case, when a target (pseudo * or real) depends on nothing but a commandlist. In this case * reproduction of the target must be performed unconditionally. * The resulting target (in case it is a file) is stored in the * BPOOL (should be avoided) with an empty attribute. We have to * avoid restoration from BPOOL and have to set the existing * file to non-current. */ if (!q->dependent_queue_initialized && (dep_rule->cmdlist != (struct cmds *)NIL)) return; if (!q->dependent_queue_initialized && (dep_rule->heritage != (char **)NIL)) return; do_key = make_derivation_key (dep_rule, q); if (strrchr (primary_target_name, '/')) { strcpy (savepath, primary_target_name); p = strrchr (savepath, '/'); *p = '\0'; p++; primary_target_name = p; syspath = savepath; } else syspath = curvpath[0]; strcpy (name, primary_target_name); strcpy (type, af_aftype (name)); strcpy (name, af_afname (name)); if((derivation_key = malloc((unsigned) (strlen(do_key) + strlen (ATTRNAME) + 2))) == NIL) errexit(10,"malloc"); strcpy (derivation_key, ATTRNAME); strcat (derivation_key, "="); strcat (derivation_key, do_key); while (this_rule && !this_rule->saved) { this_rule->saved = TRUE; if (error_occ) { error_occ = FALSE; goto next_spin; } if (is_pattern (this_rule->name)) { int pathlen = strlen (af_afpath (this_rule->name)); strcpy (name, af_afname (primary_target_name)); strcat(name, suffix (this_rule->name)); if (pathlen) { targetpath = check_malloc (pathlen + strlen (name) + 2); (void) sprintf (targetpath, "%s/%s\0", af_afpath (this_rule->name), name); } else { targetpath = check_strdup (name); } strcpy (type, af_aftype (name)); strcpy (name, af_afname (name)); } else { strcpy (name, af_afname (this_rule->name)); strcpy (type, af_aftype (this_rule->name)); targetpath = check_strdup (this_rule->name); } if (af_getkey (syspath, name, type, major_version, minor_version, &busykey) == -1) goto next_spin; /* * I hope this is right. Should we return the key from * the bpool instead (if possible) ? */ if (!primary_target_key->bk_isdefined) { primary_target_key->bk_isdefined = TRUE; primary_target_key->bk_key = busykey; } if (af_allattrs (&busykey, &attrbuf) < 0) { af_perror ("save_targets"); } else if (attrbuf.af_mtime < touch_time) { /* * This case happens if an implicit rule specifies multiple * targets but not all of them are actually made, perhaps due * to optimizations in the tool script (e.g. the well-known * "yacc -d"-problem). We want to prevent caching of identical * derived (actually *not* re-derived) versions. */ char *busy_dkeys = af_retattr (&busykey, ATTRNAME); if (!stk_matchuda (busy_dkeys, do_key)) if ((af_setattr (&busykey,AF_ADD,derivation_key)) == -1) { af_perror ("save_targets"); } if (busy_dkeys) free (busy_dkeys); af_freeattrbuf (&attrbuf); goto next_spin; } af_freeattrbuf (&attrbuf); retcode = af_setattr (&busykey, AF_REPLACE, atCacheKey(&busykey)); if ((retcode == -1) && (af_errno == AF_ENOATFSDIR)) { warning (1, "while trying to set cachekey"); af_initattrs (&buft); af_dropkey (&busykey); goto next_spin; } if ((af_setattr (&busykey, AF_REPLACE, derivation_key)) == -1) { af_perror ("save_targets"); goto next_spin; } add_to_done_list (targetpath, &busykey); free (targetpath); if ((bpoolflg) || (nobpoolflg)) { if (!forbidden (syspath, name, type)) { if ((atSaveCache (&busykey, &savekey, NULL, AF_STORE_COMPLETE)) == -1) switch (af_errno) { case AF_ENOATFSDIR: warning (1,NIL); break; default: af_perror ("save_targets"); goto next_spin; } else { if (buft.af_gen != -1) { if ((af_svnum (&savekey, buft.af_gen, buft.af_rev)) == -1) { af_perror ("save_targets"); goto next_spin; } } else { if ((af_svnum (&savekey, AF_BUSYVERS, AF_BUSYVERS)) == -1) af_perror ("save_targets"); af_dropkey (&savekey); } } } } next_spin: this_rule = this_rule->next; } free (derivation_key); /* * We have to clean up our flags if "dep_rule" is a pattern rule. */ if (is_pattern (dep_rule->name)) for (this_rule = dep_rule; this_rule && this_rule->saved; this_rule = this_rule->next) this_rule->saved = FALSE; } EXPORT Bool already_in_done_list(targetname, done_key) char *targetname; Af_key *done_key; { struct linked_key_list *c; c = done_list; while(c != (struct linked_key_list *) NIL) { if(!strcmp(c->string,targetname)) { if (af_dupkey (&c->done_key, done_key) < 0) af_perror ("af_dupkey"); return(TRUE); } else c = c->nextstring; } return(FALSE); } shapetools-1.4pl6.orig/src/shape/macro.c100444 2013 145 42457 5574617264 16350 0ustar dokoswt/*$__copyright$*/ /* * ShapeTools/shape program - macro.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: macro.c[8.0] Mon Jun 6 15:09:08 1994 axel@cs.tu-berlin.de frozen $ */ /* Thanks to Steve Emerson (steve@unidata.ucar.edu) for the reimplementation of expandmacro() */ #ifndef lint static char *AtFSid = "$Header: macro.c[8.0] Mon Jun 6 15:09:08 1994 axel@cs.tu-berlin.de frozen $"; #endif #include #include "shape.h" #define INCLUDE1 "include " #define INCLUDE2 "include\t" #define IMPORT "IMPORT" #define MAXLINELENGTH 20000 #define MACRONAM 128 #define MACROVAL 1048 EXPORT char *environment_vars = NIL; EXPORT FILE *temp; EXPORT Bool shape_command = FALSE; LOCAL int macdepth; LOCAL char *get_variant_macro(name) char *name; /* get macro value for variant */ { Bool macro_defined = FALSE; register int j = 0; int this_var; struct vardef *this_vardef; char *p, *p1, *p2, *p3; char macro[2048]; static char retval[1024]; static char *BLUMENKOHL="bLuMeNkOhL"; retval[0] = '\0'; for (this_var = 0; this_var < variants_active; this_var++) { this_vardef = &variantDefs[activeVariants[this_var]]; if (this_vardef->name) { if ((!strcmp(name,"vpath")) && (this_vardef->vpath)) { if (retval[0] == '\0') { strcat(retval, this_vardef->vpath); macro_defined = TRUE; } else { strcat(retval, " "); strcat(retval, this_vardef->vpath); } continue; } if ((!strcmp(name, "vflags")) && (this_vardef->vflags)) { if (retval[0] == '\0') { strcat(retval, this_vardef->vflags); macro_defined = TRUE; } else { strcat(retval, " "); strcat(retval, this_vardef->vflags); } continue; } for(j = 0; j < MAXVMACROS; j++) { if (this_vardef->vmacros[j] == NIL) break; strcpy (macro, this_vardef->vmacros[j]); if (!*macro) break; p1 = strchr(macro, '='); p2 = strchr(macro, ' '); p3 = strchr(macro, '\t'); if (p2 == NIL) p2 = p1 + 1; if (p3 == NIL) p3 = p1 + 1; if (( p1 < p2) && (p1 < p3)) p = p1; if (( p2 < p1) && (p2 < p3)) p = p2; if (( p3 < p2) && (p3 < p1)) p = p3; *p = '\0'; p1++; if (!strcmp(name, macro)) { while((*p1 == ' ') || (*p1 == '\t') || (*p1 == '=')) p1++; if(retval[0] == '\0') { strcat(retval,p1); macro_defined = TRUE; } else { strcat(retval," "); strcat(retval,p1); } } } } } if(macro_defined) return(retval); else return(BLUMENKOHL); } LOCAL char *cleaned (string) char *string; { static char *result_str = NIL; char *p; register int i; p = string; i = 0; if (result_str) result_str = check_realloc (result_str, (unsigned)(strlen (string)+1)); else result_str = check_malloc ((unsigned)(strlen (string)+1)); while (p && *p && isspace(*p)) p++; while (*p) { if (isspace (*p)) { result_str[i] = (*p == '\n' && !*(p+1)) ? '\0' : ' '; while (p && *p && isspace(*p)) p++; i++; } else { result_str[i] = *p; p++; i++; } } result_str[i--] = '\0'; while (isspace(result_str[i])) { result_str[i] = '\0'; i--; } return result_str; } #define RESBUF_SIZE 10240 LOCAL char *call_popen (str) char *str; { char *x, *y, *result; # define end_result (result + result_bytes) FILE *fd; register int i,j; int result_size = 0, result_bytes = 0, nbytes = 0; y = check_strdup (str); if (strchr (str, '$')) x = check_strdup (expandmacro (y)); else x = check_strdup (y); j = 0; i = 0; y = check_realloc (y, strlen (x) + 1); while (x[i]) { if((x[i] == '$') && (x[i+1] == '$')) i++; else { y[j] = x[i]; i++; j++; } } y[j] = '\0'; if ((fd = popen(y,"r")) == (FILE *) NIL) errexit(10,"popen"); result = check_malloc (RESBUF_SIZE+1); result[0] = '\0'; result_size = RESBUF_SIZE; do { if ((nbytes = fread (end_result, sizeof(char), RESBUF_SIZE, fd)) == RESBUF_SIZE) { result = check_realloc (result, result_size + RESBUF_SIZE + 1); result_size += RESBUF_SIZE; } result_bytes += nbytes; } while (!feof (fd)); *end_result = '\0'; pclose (fd); free (x); free (y); return cleaned (result); } LOCAL void insertvpath(string) char *string; { register char *p; register int i; for(i = 1; (p = strchr(string,':')) != NIL; i++) { *p = '\0'; if((*string != '/') && (strchr(string,'$') == NIL)) { if ((curvpath[i] = malloc((unsigned) (strlen(string) + strlen(curvpath[0]) + 3 * sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(curvpath[i],curvpath[0]); strcat(curvpath[i],"/"); if ((*string == '.') && (*(string+1) == '/')) { string += 2; } else { if ((*string == '.') && (*(string+1) == '.') && (*(string+2) == '/')) { *string += 3; } } strcat(curvpath[i],string); } else { if ((curvpath[i] = malloc((unsigned) (strlen(string) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(curvpath[i],string); } p++; string = p; } if((p == NIL) && (string != NIL)) { if((*string != '/') && (strchr(string,'$') == NIL)) { if((curvpath[i] = malloc((unsigned) (strlen(string) + strlen(curvpath[0]) + 2 * sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(curvpath[i],curvpath[0]); strcat(curvpath[i],"/"); if ((*string == '.') && (*(string+1) == '/')) { string += 2; } else { if ((*string == '.') && (*(string+1) == '.') && (*(string+2) == '/')) { *string += 3; } } strcat(curvpath[i],string); } else { { if((curvpath[i] = malloc((unsigned) (strlen(string) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(curvpath[i],string); } } } } LOCAL char *mirror_string (original) char *original; { /* * write the string, pointed to by original backwards into a * buffer that is allocated on the heap. A pointer to the * buffer is returned. It's the responsibility of the caller * to free the associated memory. * If original is empty or a NULL pointer, a NULL pointer is * returned. */ register int i, j; int olen; char *lanigiro; if (! (original && *original)) return NULL; olen = strlen (original); lanigiro = check_malloc (olen + 1); for ( i = 0, j = olen -1; j >= 0; i++, j--) { lanigiro[i] = original[j]; } lanigiro[olen] = '\0'; return lanigiro; } LOCAL char *substitute_string (subject, old, new) char *subject, *old, *new; { /* * replace all occurrences of substring "old" in each token in * "subject" by string "new". Return a pointer to a statically * allocated string that is the result of this operation. */ int subject_len, result_len, old_len, new_len; char *result, *dlo, *wen, *tecjbus, *tluser; register char *p, *s; register int i, j; if (subject == NULL) return ""; else subject_len = strlen (subject); old_len = old ? strlen (old) : 0; new_len = new ? strlen (new) : 0; result_len = subject_len + 1; if ((old_len == 0) || (old_len > subject_len)) { strcpy (result, subject); return result; } /* * mirror all participating strings. The corresponding * pointer variables have the names of their originals backwards, * i.e. old -> dlo etc. */ dlo = mirror_string (old); wen = mirror_string (new); if (wen == NULL) { wen = check_strdup (""); } tecjbus = mirror_string (subject); tluser = check_malloc (subject_len +1); p = tecjbus; s = dlo; j = 0; while (*p) { i = 0; while (*s && (*(p+i) == *s)) { s++; i++; } if (j+new_len >= result_len) { if ((tluser = (char *)realloc (tluser, j+new_len+subject_len) ) == (char *)NULL) errexit (10, "realloc"); result_len = j+new_len+subject_len; } if (*s) { tluser[j++] = *p++; } else { char *oldp; p += old_len; oldp = p; /* save position. the skipped text must be appended.. */ /* advance p to beginning of next token */ while (*p && !isspace(*p)) p++; while (*p && isspace(*p)) p++; tluser[j] = '\0'; strcat (tluser, wen); j += new_len; strncat (tluser, oldp, p - oldp); j += p - oldp; } s = dlo; } tluser[j] = '\0'; if (dlo) free (dlo); if (wen) free (wen); if (tecjbus) free (tecjbus); result = mirror_string (tluser); if (tluser) free (tluser); return result; } LOCAL Bool chk_strsub (subject, old, new) char *subject, **old, **new; { /* * Check if the string "subject" is of the form "str1=str2" where * str1 must be non-empty. If "subject" does have this form, * allocate space sufficient to hold "str1" and "str2" * respectively. Copy str1 and str2 to these memory areas and * assign "old" to "str1" and "new" to "str2". Return TRUE. * If "subject doesn't match this form, leave the outbound * parameters "old" and "new" untouched. Return FALSE. */ char *str1; register char *p; if (subject == (char *)NULL) return FALSE; p = subject; while (*p && (*p != '=')) p++; if (*p == '=') { if (p == subject) return FALSE; str1 = (char *)check_malloc ((p-subject)+1); strncpy (str1, subject, p-subject); *(str1+(p-subject)) = '\0'; p++; *old = check_strdup (expandmacro (str1)); *new = check_strdup (expandmacro (p)); return TRUE; } return FALSE; } EXPORT char *get_next_item(string) char *string; { register char *p1; if ((p1 = strchr(string,' ')) != NIL) { *p1 = '\0'; return string; } else return string; } LOCAL void get_macrodefs_from_env () { sb_ptr imports; char *imp_macro = expandmacro ("$(IMPORT)"), *thisdef, testmac[MACRONAM+3], *envval; int macl = imp_macro ? strlen (imp_macro) : 0; imports = sbnew (macl); imports = sbcpy (imports, imp_macro, macl); if (!(sbstr (imports) && *sbstr (imports))) return; thisdef = stStrtok (sbstr (imports)); while (thisdef) { strcpy (testmac, "$("); strcat (testmac, thisdef); strcat (testmac, ")"); if (!envflg && *expandmacro (testmac)) { /* macro defined in Shapefile */ thisdef = stStrtok ((char *)NULL); continue; } envval = getenv (thisdef); define_macro (thisdef, envval, DYNAMIC); thisdef = stStrtok ((char *)NULL); } } EXPORT void define_macro (name, value, mtype) char *name, *value; int mtype; { char *mt_val = ""; register char *lptr; if (!(name && *name)) return; if (!value) value = mt_val; while (*value && isspace (*value)) value++; lptr = value; while (*lptr) lptr++; if (lptr > value) lptr--; while (*lptr && isspace (*lptr)) lptr--; if (*lptr) *(lptr+1) = '\0'; if (!strcmp(name,"RECDEPTH")) { rec_do_depth = atoi(value); } addHash (name, value, mtype); if (!strcmp(name,"VPATH")) insertvpath(value); if (!strcmp(name,"IMPORT")) get_macrodefs_from_env(); /* macros are immediately defined */ } #define LEFT_PAREN '(' #define RIGHT_PAREN ')' #define LEFT_BRACE '{' #define RIGHT_BRACE '}' EXPORT char* expandmacro(inpstring) char *inpstring; /* Input string to be command- and * macro-expanded */ { char *p; /* Position in cmd_buf */ char *base; /* Scan start in string */ sb_ptr cmd_buf = sbnew(1024); /* Cmd-expansion buffer */ sb_ptr mac_buf = sbnew(1024); /* Mac-expansion buffer */ sb_ptr name = sbnew(64); /* Macro name */ static sb_ptr fin_buf = 0; /* Final string-buffer */ Bool string_substitution = FALSE; char *old, *new; /* Pointers for str subst. */ if (mac_buf == 0 || cmd_buf == 0 || name == 0) errexit(10, "sbnew"); /* * Allocate final string-buffer if necessary. */ if (fin_buf == 0) if ((fin_buf = sbnew(1024)) == 0) errexit(10, "sbnew"); /* * Terminate if macro nested too deeply. */ if (++macdepth > 50) errexit(25, inpstring); if (no_comm_subst) { /* * No command-expansion allowed, just copy input string to * command-expansion buffer. */ if (sbcpy(cmd_buf, inpstring, strlen(inpstring)) == 0) errexit(10, "sbcpy"); } else { /* * Command-expand input string into command-expansion buffer. */ char *p1; /* Points to initial '`' in input string */ /* * Loop through input string -- expanding each command-invocation * in turn. */ for (base = inpstring; (p1 = strchr(base, '`')) != 0; ) { char *p2 = strchr(p1+1, '`'); if (p2 == 0) { int len = strlen(base); if (sbcat(cmd_buf, base, len) == 0) errexit(10, "sbcat"); base += len; } else if ((p1 > base && p1[-1] == '\\') || p2[-1] == '\\') { if (sbcat(cmd_buf, base, p2+1-base) == 0) errexit(10, "sbcat"); base = p2 + 1; } else { char *expcomm; *p2 = '\0'; expcomm = call_popen (p1+1); *p2 = '`'; if (sbcat(cmd_buf, base, p1-base) == 0) errexit(10, "sbcat"); if (sbcat(cmd_buf, expcomm, strlen(expcomm)) == 0) errexit(10, "sbcat"); base = p2 + 1; } } /* command-subst loop */ if (sbcat(cmd_buf, base, strlen(base)) == 0) errexit(10, "sbcat"); } /* command-subst enabled */ /* * Loop through command-expanded string -- expanding each macro in turn. */ for (base = sbstr(cmd_buf); (p = strchr(base, '$')) != 0; ) { /* * Place head of string (up to current position) in macro-expansion * buffer. */ if (sbcat(mac_buf, base, p-base) == 0) errexit(10, "sbcat"); if (p[1] == '@' || /* Special macro found */ p[1] == '#' || p[1] == '?' || p[1] == '<' || p[1] == '*' || p[1] == '$' || p[1] == '+') { /* * Special macro: just copy to buffer. */ if (sbcat(mac_buf, p, 2) == 0) errexit(10, "sbcat"); base = p + 2; } else { /* single '$' found */ /* * Extract name of non-special macro. */ if (p[1] == LEFT_PAREN || p[1] == LEFT_BRACE) { /* * ()- or {}-enclosed macro: */ char *start = p + 2; char klauf = p[1]; char klazu = p[1] == LEFT_PAREN ? RIGHT_PAREN : RIGHT_BRACE; /* * Macroname is terminated either by closing paren * or by string susbstitution expression */ p = start; while (*p && (*p != klazu) && (*p != ':')) p++; if (sbcpy(name, start, p-start) == 0) errexit(10, "sbcpy"); if (strcmp(sbstr(name), "SHAPE") == 0 || strcmp(sbstr(name), "MAKE") == 0) { shape_command = TRUE; } if (*p == ':') { register char *closer; int level = 1; base = p + 1; while (*p && level) { if (*p == klauf) level++; if (*p == klazu) level--; if (level) p++; } if (*p) { *p = '\0'; string_substitution = chk_strsub (base, &old, &new); *p = klazu; } } if (*p == '\0') { base = p; } else { base = p + 1; } } else { /* * Single-character macro: */ sbcpy(name, p+1, 1); base = p + 2; } /* * Expand non-empty, non-special macro. */ if (sblen(name) > 0) { char *variant_macro = 0; if (curvar[0] != 0) { char *get_variant_macro(); variant_macro = get_variant_macro(sbstr(name)); if (strcmp(variant_macro, "bLuMeNkOhL") != 0) { char *mist = expandmacro(variant_macro); if (string_substitution) { char *cooked_string; cooked_string = substitute_string (mist, old, new); if (sbcat (mac_buf, cooked_string, strlen (cooked_string)) == 0) errexit (10, "sbcat"); if (cooked_string) free (cooked_string); } else { if (sbcat (mac_buf, mist, strlen (mist)) == 0) errexit (10, "sbcat"); } } } if (variant_macro == 0 || !strcmp(variant_macro,"bLuMeNkOhL")){ char *value, *expandedValue; if (!visitedHash (sbstr(name))) { if ((value = getHash (sbstr(name)))) { expandedValue = expandmacro (value); clearHashVisited (sbstr(name)); if (string_substitution) { char *cooked_string; cooked_string = substitute_string (expandedValue, old, new); if (sbcat (mac_buf, cooked_string, strlen (cooked_string)) == 0) errexit (10, "sbcat"); if (cooked_string) free (cooked_string); } else { if (sbcat(mac_buf, expandedValue, strlen(expandedValue)) == 0) errexit(10, "sbcat"); } } } else { /* recursive macro */ errexit (25, sbstr (name)); } } if (string_substitution) { if (old) free (old); if (new) free (new); string_substitution = FALSE; } } /* non-empty macro name */ } /* single '$' found */ } /* macro substitution loop */ /* * Append remaining, trailing stuff to macro-expansion buffer. */ if (sbcat(mac_buf, base, strlen(base)) == 0) errexit(10, "sbcat"); /* * Copy macro-expansion buffer to final string-buffer. */ if (sbcpy(fin_buf, sbstr(mac_buf), sblen(mac_buf)) == 0) errexit(10, "sbcpy"); /* * Free temporary string-buffers. */ sbfree(cmd_buf); sbfree(mac_buf); sbfree(name); macdepth--; return sbstr(fin_buf); } EXPORT void echo_macro(name) char *name; { char macr[32]; strcpy(¯[0],"$("); strcat(¯[0],name); strcat(¯[0],")"); printf("%s\n", expandmacro(macr)); } shapetools-1.4pl6.orig/src/shape/main.c100444 2013 145 20522 5426266242 16150 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - main.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: main.c[8.0] Sat Jul 31 19:15:40 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: main.c[8.0] Sat Jul 31 19:15:40 1993 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" #define MAXCMDTARGETS 32 extern FILE *temp; EXPORT char rbfile[MYMAXNAMLEN]; EXPORT char prev_dir[MYMAXNAMLEN]; EXPORT int main_gen = AF_BUSYVERS; EXPORT int main_rev = AF_BUSYVERS; EXPORT char *suffs; EXPORT char shapeflags[2048]; LOCAL char *filenames[] = {"Shapefile", "shapefile", "Makefile", "makefile"}; LOCAL char *stdmacros[] = { "ASFLAGS=","AS=as", "SHELL=/bin/sh", "RFLAGS=","FFLAGS=","FC=f77","M2FLAGS=", "M2C=m2c","PFLAGS=","PC=pc","CFLAGS=", "CC=cc","LDFLAGS=","LD=ld","LFLAGS=", "LEX=lex","YFLAGS=","YACC=yacc", "MAKE=shape $(MAKEFLAGS)", "SHAPE=shape $(MAKEFLAGS)", "$=$$", "SHAPEFLAGS=$(MAKEFLAGS)", "SELECTED_AtFS=", "SELECTED_FS=", "RESTORED_OBJS=", "@=$@", "?=$?", "<=$<", "*=$*", "+=$+", (char *)NULL}; EXPORT struct linked_list *shapefiles = (struct linked_list *) NIL; /* list of names of files from command line via the -f option */ LOCAL struct linked_list *shfiles; EXPORT char *cmdtargets[MAXCMDTARGETS]; /* list of target form the command line */ EXPORT char *cmd_line_vars[MAXCMDLINEVARS]; /* variant names activated from command line */ EXPORT int rec_do_depth; EXPORT char *newarg[64]; EXPORT int newargc; LOCAL Bool synterrflg = FALSE; EXPORT Bool Oldsuffs = FALSE; EXPORT Bool Newsuffs = FALSE; EXPORT void cleanup () { cleanup_links(link_reg); af_cleanup(); } #ifdef DEBUG_MALLOC LOCAL unsigned long tl_data_start = 0, histid0, histid1, histid2; LOCAL FILE *leak_log = NULL; LOCAL init_trace_leak () { tl_data_start = malloc_size(&histid0); histid1 = histid0; leak_log = fopen ("Shape_Leak.log", "w"); fprintf (leak_log, "Memory usage profile for %s\n", stProgramName); fprintf (leak_log, "==================================\n"); fprintf (leak_log, "Initial amount of allocated memory: %d bytes.\n", tl_data_start); } EXPORT void dssize (location, aux) char *location, *aux; { static unsigned long oldmbytes; unsigned long cursize = malloc_size (&histid2); fprintf (leak_log, "%s%s%s - %d bytes allocated (gained %d).\n", location, (aux && *aux) ? " " : "", (aux && *aux) ? aux : "", cursize, cursize - oldmbytes); fflush (leak_log); } #endif EXPORT int main(argc, argv) int argc; char **argv; { int newac = 0; Bool cmd_line_macro_def = FALSE; char **newav; sb_ptr strbuf = sbnew(128); register int i, k = 0; char *xxx, *cp; char atfsdir[PATH_MAX]; #ifdef DEBUG_MALLOC init_trace_leak (); #endif if (strbuf == 0) errexit(10, "sbnew"); rebuildflg = FALSE; bpoolflg = TRUE; rec_do_depth = 1; if ((curvpath[0] = malloc(PATH_MAX + 2)) == NIL) errexit(10,"malloc"); getcwd(curvpath[0], PATH_MAX + 2); catch_sigs(); *shapeflags = '\0'; for (i = 0; i < MAXCMDLINEVARS; i++) { cmd_line_vars[i] = (char *)NULL; } stProgramName = (cp = strrchr (argv[0], '/')) ? ++cp : argv[0]; /* make prog-name available to entire program */ if (argc != 1) { if(stParseArgs (argc, argv, &newac, &newav, odesc)) { stShortUsage(stProgramName, odesc, ""); exit(1); } } if (!echoflg) { strcpy(prev_dir,curvpath[0]); strcpy(atfsdir,curvpath[0]); strcat(atfsdir,"/AtFS"); if(af_access(af_afpath(atfsdir),af_afname(atfsdir),af_aftype(atfsdir),AF_CLASS_SOURCE) != 0) { strcpy(atfsdir,curvpath[0]); strcat(atfsdir,"/AFS"); if(af_access(af_afpath(atfsdir),af_afname(atfsdir),af_aftype(atfsdir), AF_CLASS_SOURCE) != 0) { warning(4,NIL); } } } if((xxx = strrchr (prev_dir,'/')) != NIL) *xxx = '\0'; init_ruletab(); newargc = newac; for(i = 1; i < newac; i++) newarg[i] = newav[i]; for (i = 0; stdmacros[i]; i++) { char *macbuf = check_strdup (stdmacros[i]); char *val; val = strchr (macbuf, '='); *val++ = '\0'; define_macro (macbuf, val, DYNAMIC); if (macbuf) free (macbuf); } { char buf[16]; (void) sprintf (buf, "%d", getpid()); define_macro ("SHAPEPID", buf, DYNAMIC | FROM_CMDLINE); define_macro ("SHAPEVERSION", stStrtok (version ()), DYNAMIC | FROM_CMDLINE); define_macro ("LOGNAME", atUserName (af_afuser (getuid ())), DYNAMIC | FROM_CMDLINE); } sbfree(strbuf); add_stdrules(); /* make command line macros known */ for (i = 1; i < newac; i++) { if (strchr(newav[i],'=')) { char *macbuf = check_strdup (newav[i]); char *val; int mactype; cmd_line_macro_def = TRUE; val = strchr (macbuf, '='); switch (*(val-1)) { case '+': mactype = APPEND; *(val-1) = '\0'; break; case ':': mactype = ONCE; *(val-1) = '\0'; break; default: mactype = DYNAMIC; break; } *val++ = '\0'; define_macro (macbuf, val, mactype | FROM_CMDLINE); if (macbuf) free (macbuf); } else { if ((cmdtargets[k] = malloc((unsigned) (strlen(newav[i]) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(cmdtargets[k++],newav[i]); cmdtargets[k] = NIL; } } if (!rebuildflg) { if (fileflg) { shfiles = shapefiles; while(shfiles != (struct linked_list *) NIL) { int open_ok = 0; open_ok += parse_file (shfiles->string); shfiles = shfiles->nextstring; if (parse_errors) { errexit (15, NIL); } if (!open_ok) { errexit (11, NIL); } } } else { int open_ok = 0; for ( i = 0; i <= 3; i++) { if ((open_ok = parse_file (filenames[i]))) break; } if (parse_errors) errexit (15, NIL); } } else { if (parse_file (rbfile)) { if (parse_errors) errexit (15, NIL); } else { errexit (8, rbfile); } } if (!echoflg || Var_flag) { fclose(temp); } commit_definitions (); /* make parsed definitions seen */ define_macro ("MAKEFLAGS", shapeflags, DYNAMIC); if (echoflg && !Var_flag) { echo_macro(echomac); exit(0); } if(rebuildflg && cmd_line_macro_def) warning(3, NIL); if (synterrflg == TRUE) errexit(15,NIL); ruleend(); adjust_stdrules(suffs); if(envflg) get_env_vals(); if(environment_vars != NIL) free(environment_vars); for (i = 0; cmd_line_vars[i] && (i < MAXCMDLINEVARS); i++) { if (!is_varname (cmd_line_vars[i])) { char *msg = malloc (strlen (cmd_line_vars[i]) + strlen (" is not a variant name") + sizeof (char)); if (msg == (char *)NULL) errexit (10, "malloc"); strcpy (msg, cmd_line_vars[i]+1); strcat (msg, " is not a variant name"); warning (99, msg); free (msg); } } if(echoflg) { echo_macro(echomac); exit(0); } if (printflg) { dump (stdout); /* dumping macros */ ruledump (stdout); /* dumping targets, dependents & commands, resp. */ exit (0); } #ifdef DEBUG_MALLOC dssize ("Before", "produce"); #endif produce(); #ifdef DEBUG_MALLOC dssize ("After", "produce"); #endif if (debugflg) { dump(stdout); /* dumping macros */ ruledump(stdout); /* dumping targets, dependents & commands, resp. */ } cleanup (); exit(0); } EXPORT void get_env_vals() { register char *p, *name, *enventry; if(environment_vars == NIL) return; p = environment_vars; while ((*p == ' ') || (*p == '\t')) p++; while((name = get_next_item(p))) { if (strcmp(p,"") == 0) break; p = strchr(p,'\0'); p++; while ((*p == ' ') || (*p == '\t')) p++; if ((enventry = getenv(name)) != NIL) { define_macro (name, enventry, DYNAMIC); } } } shapetools-1.4pl6.orig/src/shape/misc.c100444 2013 145 10441 5416575112 16154 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - misc.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: misc.c[8.0] Wed Jul 7 18:33:06 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: misc.c[8.0] Wed Jul 7 18:33:06 1993 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" /* Struct for registering links */ EXPORT struct linkreg *link_reg = (struct linkreg *) NIL; LOCAL struct linkreg *last_link; LOCAL char *types[] = { "generation", /* 0 int */ "revision", /* 1 int */ "state", /* 2 short */ "author", /* 3 short */ "group", /* 4 short */ "version", /* 5 char * */ "variant", /* 6 char * */ "syspath", /* 7 char * */ "host", /* 8 char * */ "locker", /* 9 char * */ "owner", /* 10 char * */ "0"}; /* 99 default = char * (for userdefined attributes */ EXPORT char *states[] = { "busy", "saved", "proposed", "published", "accessed", "frozen", "0"}; EXPORT int get_attr_type (name) char *name; { register int i = 0; if (name == NIL) return(99); while(strcmp(types[i],"0") != 0) { if((strcmp(types[i],name) == 0)) return(i); i++; } return(99); } LOCAL struct linkreg *init_linkreg() { register struct linkreg *lreg = (struct linkreg *) NIL; if ((lreg = (struct linkreg *) malloc(sizeof(struct linkreg))) == (struct linkreg *) NIL) errexit(10,"malloc"); if((lreg->fn = malloc(MYMAXNAMLEN)) == NIL) errexit(10,"malloc"); if((lreg->newfn = malloc(MYMAXNAMLEN)) == NIL) errexit(10,"malloc"); lreg->fn[0] = '\0'; lreg->newfn[0] = '\0'; lreg->next = (struct linkreg *) NIL; return(lreg); } EXPORT void register_link (fn, newfn, busy_exist) char *fn; char *newfn; Bool busy_exist; { if (link_reg == (struct linkreg *) NIL) { link_reg = init_linkreg(); strcpy(link_reg->fn, fn); strcpy(link_reg->newfn, newfn); link_reg->busy_exist = busy_exist; last_link = link_reg; } else { last_link->next = init_linkreg(); last_link = last_link->next; strcpy(last_link->fn, fn); strcpy(last_link->newfn, newfn); last_link->busy_exist = busy_exist; } } EXPORT void cleanup_links (cur_link) struct linkreg *cur_link; { if(cur_link != (struct linkreg *) NIL) { cleanup_links(cur_link->next); } if(cur_link != (struct linkreg *) NIL) { if (unlink(cur_link->fn) != 0) fprintf(stderr, "shape - warning: can't unlink temporarily restored version %s\n", cur_link->fn); if (cur_link->busy_exist) { if (link (cur_link->newfn, cur_link->fn) != 0) { fprintf(stderr, "shape - warning: can't restore original busy version of %s\n", cur_link->fn); fprintf(stderr, "\t\t original file available as %s !\n", cur_link->newfn); } else { if (unlink(cur_link->newfn) != 0) fprintf(stderr, "shape - warning: can't unlink temporary file %s\n", cur_link->newfn); } } } } EXPORT void free_linklist() { /* not yet implemented */ /* should free memory of linklist */ ; } EXPORT Bool is_in_forcelist(name) char *name; { register int i = 0; while(forcelist[i] != NIL) { if (!strcmp(forcelist[i],name)) return(TRUE); i++; } return(FALSE); } EXPORT int D_debug(name,type,at) /*ARGSUSED*/ char *name, *type, *at; { printf("shape - %s does not bear the appropriate attributes or does not exist\n", name); return(0); } shapetools-1.4pl6.orig/src/shape/produce.c100444 2013 145 62666 5575323271 16705 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - produce.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: produce.c[8.1] Wed Jun 8 13:09:06 1994 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: produce.c[8.1] Wed Jun 8 13:09:06 1994 axel@cs.tu-berlin.de frozen $"; #endif #include #include "shape.h" #define MAXCMDLENGTH 10240 LOCAL Bool error_happened = FALSE, simple_done = FALSE; LOCAL time_t touch_time; EXPORT Bool error_occ = FALSE; EXPORT Bool no_comm_subst = FALSE; typedef enum { Ok, Fail, Abort } TargetCode; /* used by make_target */ EXPORT char rbrule[64]; EXPORT char rbtarg[64]; EXPORT char ruleset[32]; EXPORT Bool busy_done = FALSE; EXPORT int depth; LOCAL Bool reallydone = FALSE; #define IMPLICIT 0 #define EXPLICIT 1 LOCAL void mark_all_done(cur) struct rules *cur; { struct rules *c; int i; if (is_pattern (cur->name)) return; if(cur->done == rec_do_depth) return; cur->done++; i = cur->done; c = cur->next; while((c != (struct rules *) NIL) && (c->done < i)) { if(simple_done) c->done++; else { if(locate_object (c->name, ALL)) c->done++; } c = c->next; } } LOCAL char *cooked_dep (current, base, nth, depkind) struct rules *current; char *base; int nth, depkind; { static char curdep[MYMAXNAMLEN]; char *this_dependent; if (*(this_dependent = get_dep (current, nth))) { if (depkind == IMPLICIT) { char *percent = stem (current->name, base); (void) strcpy (curdep, subst_char (this_dependent, '%', percent)); } else strcpy (curdep, this_dependent); } else *curdep = '\0'; return curdep; } LOCAL char *name_prefix (full_name) char *full_name; { /* * Treat "raw_name" as some sort of object_ID (e.g. pathname, bound * version ID etc.) and try to cut out the name prefix. If the name * prefix is undefined, an empty string will be returned. The found * prefix otherwise. */ static char this_prefix[MYMAXNAMLEN]; char raw_name[MYMAXNAMLEN]; char *last_slash, *last_dot, *last_open_bracket; this_prefix[0] = '\0'; if (full_name) { strcpy (raw_name, full_name); last_slash = strrchr (raw_name, '/'); last_dot = strrchr (raw_name, '.'); last_open_bracket = strrchr (raw_name, '['); if (last_open_bracket && (last_open_bracket > last_slash)) { /* assume bound version notation */ *last_open_bracket = '\0'; last_dot = strrchr (raw_name, '.'); } /* now we have a regular filename */ if ((last_dot > raw_name) && (last_dot > last_slash)) /* We do have a real prefix ... */ *last_dot = '\0'; strcpy (this_prefix, last_slash ? last_slash + 1 : raw_name); } return this_prefix; } LOCAL void reset_pathlist() { register int i; for (i = 1; pathlist[i][0] != NIL; i++) { pathlist[i][0] = NIL; pathlist[i][1] = NIL; lastpath = 1; } if (pathlist[0][1] != NIL) { if (!strcmp(pathlist[0][1],"&$")) { pathlist[0][0] = NIL; pathlist[0][1] = NIL; lastpath = 0; } } } LOCAL void cl_variants (vdepth, vcuri) int vdepth, vcuri; { register int vardepi; vcuri--; for (vardepi = vdepth; vardepi >= 0; vardepi--) { de_activate (curvar[vcuri-vardepi]); strcpy (curvar[vcuri-vardepi], ""); reset_pathlist (); } } LOCAL char *expand_command (cmd, cur, rel_dep) char *cmd; struct rules *cur; char *rel_dep; { char curdep[512], hhh[64], hhh2[64]; char comm[MAXCMDLENGTH], *common_prefix, *p, *hhhp, *hhh2p; register int i = 0, j = 0, k = 0; while(cmd[i] != '\0') { if((cmd[i] == '\\') && (cmd[i+1] == '`')) i++; if ((cmd[i] == '\\') && (cmd[i+1] == '%')) { comm[j++] = cmd[++i]; i++; } if((cmd[i] != '$') && (cmd[i] != '%')) { comm[j] = cmd[i]; i++; j++; } else { switch (cmd[i+1]) { case '@': if (!is_pattern (cur->name)) { comm[j] = '\0'; strcat(comm, cur->name); j = j + strlen(cur->name); i = i + 2; } else { comm[j] = '\0'; strcpy(hhh,rel_dep); hhhp = strrchr(hhh,'.'); if (hhhp != NIL) { hhhp[0] = '\0'; } strcpy(hhh2, cur->name); hhh2p = strrchr(hhh2,'.'); if (hhh2p) strcat(hhh,hhh2p); strcat(comm, hhh); j = j + strlen(hhh); i = i + 2; } break; case '#': { char target_name_prefix[MYMAXNAMLEN]; struct rules *use_rule; if (is_pattern (cur->name)) use_rule = cur; else use_rule = implicit_target (cur->name); strcpy (target_name_prefix, name_prefix (rel_dep)); k = 1; if (use_rule) { strcpy (curdep, cooked_dep (use_rule, rel_dep, 0, IMPLICIT)); } else { strcpy (curdep, get_dep (cur, 0)); } while (*curdep) { comm[j] = '\0'; if((curdep[0] != '+') && (!atBindTestRule(curdep))) { char *roid; roid = restored_object_id (curdep); if ((k > 1) && roid) strcat (comm, " "); strcat (comm, roid ? roid : ""); j = j + (roid ? (strlen (roid) + ((k > 1) ? 1 : 0)) : 0); } if (use_rule) { strcpy (curdep, cooked_dep (use_rule, rel_dep, k++, IMPLICIT)); } else { strcpy (curdep, get_dep (cur, k++)); } } } i = i + 2; break; case '?': if (*get_dep(cur,0)) { Bool target_is_pattern = is_pattern (cur->name); k = 1; strcpy(curdep, cooked_dep (cur, target_is_pattern ? rel_dep : NULL, 0, target_is_pattern ? IMPLICIT : EXPLICIT)); while (*curdep) { comm[j] = '\0'; if ((curdep[0] != '+') && (!atBindTestRule (curdep))) { strcat (comm, curdep); j = j + strlen (curdep); } strcpy (curdep, cooked_dep (cur, target_is_pattern ? rel_dep : NULL, k++, target_is_pattern ? IMPLICIT: EXPLICIT)); if (*curdep) { strcat(comm," "); j++; } } } i = i + 2; break; case '<': if (*get_dep(cur,0)) { Bool target_is_pattern = is_pattern (cur->name); k = 1; strcpy(curdep, cooked_dep (cur, target_is_pattern ? rel_dep : NULL, 0, target_is_pattern ? IMPLICIT : EXPLICIT)); while (*curdep) { comm[j] = '\0'; if ((curdep[0] != '+') && (!atBindTestRule (curdep))) { strcat (comm, curdep); j = j + strlen(curdep); break; } strcpy (curdep, cooked_dep (cur, target_is_pattern ? stem (cur->name, rel_dep) : NULL, k++, target_is_pattern ? IMPLICIT: EXPLICIT)); } } i = i + 2; break; case '*': case '.': case ' ': if (!is_pattern (cur->name)) { if ((common_prefix = malloc((unsigned) (strlen(cur->name) + 1))) == NIL) errexit(10,"malloc"); strcpy(common_prefix, cur->name); if ((p = strrchr(common_prefix,'.')) != NIL) { p[0] = '\0'; } comm[j] = '\0'; strcat(comm, common_prefix); j = j + strlen(common_prefix); if (cmd[i+1] == '*') i = i + 2; else i++; } else { char *st = stem (cur->name, rel_dep); comm[j] = '\0'; strcat(comm, st); j += st ? strlen(st) : 0; i += (cmd[i+1] == '*') ? 2 : 1; } break; case '(': errexit(99,"output translation $(name:str1=str2)"); /* ???? output translation, not yet implemented */ break; case '$': comm[j] = '$'; j++; i = i+2; break; default: if(cmd[i] == '%') /* single suffix rule */ { char *st = stem (cur->name, rel_dep); comm[j] = '\0'; strcat(comm, st); j += st ? strlen(st) : 0; i += (cmd[i+1] == '*') ? 2 : 1; } else { comm[j] = cmd[i]; j++; i++; } break; } } } comm[j] = '\0'; if (comm[0] == '\0') strcpy(comm,cmd); return(comm); } LOCAL void execute(cmd, itp) char *cmd, *itp; { int retcode = 0; Bool ignflg = FALSE, silflg = FALSE; char *rc; silflg = silentflg; while (isspace(*cmd)) cmd++; if (!*cmd) return; /* empty commands aren't executed */ again: switch (*cmd) { case '@': silflg = TRUE; cmd++; goto again; case '-': ignflg = TRUE; cmd++; goto again; default: if (noexflg && !shape_command) { printf("%s\n", cmd); fflush(stdout); reallydone = TRUE; shape_command = FALSE; return; } } /* printf("malloc_verify: %d\n", malloc_verify()); */ if (!silflg || ((noexflg))) { printf("%s%s\n", noexflg ? "" : "shape - executing: ", cmd); fflush(stdout); } if (!noexflg || shape_command) { reallydone = TRUE; retcode = stCallCmd (itp, cmd); if (retcode < 0) { switch (retcode) { case CMDPROC_EMPTY: stLog ("No Shell", ST_LOG_ERROR); break; case NO_MORE_CORE: stLog ("Not enough memory", ST_LOG_ERROR); break; case FORK_FAILED: stLog ("Couldn't fork", ST_LOG_ERROR); break; case PIPE_FAILED: stLog ("Couldn't open pipe to command interpreter", ST_LOG_ERROR); break; case WAIT_ERROR: stLog ("Couldn't wait for command", ST_LOG_ERROR); break; case EXEC_FAILED: stLog ("Unable to load command interpreter", ST_LOG_ERROR); break; case CHILD_KILLED: stLog ("Child process died from an accident", ST_LOG_ERROR); break; case WRITE_FAILED: stLog ("Command interpreter doesn't read", ST_LOG_ERROR); break; case NO_PROGRAM: stLog ("Couldn't find command interpreter", ST_LOG_ERROR); break; } } simple_done = TRUE; if (retcode != 0) { if(ignflg == FALSE) { error_happened = TRUE; error_occ = TRUE; } if ((rc = malloc (10 * sizeof(char))) == NIL) errexit(10,"malloc"); sprintf (rc, "%d", retcode); if (!(ignflg || goflg)) errexit(13,rc); } } shape_command = FALSE; } LOCAL Bool execute_commands (current, rel_dep, q, made_key) struct rules *current; char *rel_dep; DepQ *q; BKey *made_key; { register struct cmds *curcmd; char *expcmd, x_command[MAXCMDLENGTH], fname[MYMAXNAMLEN], command_processor[MYMAXNAMLEN]; if (rel_dep) strcpy (fname, rel_dep); if (current) curcmd = current->cmdlist; if (curcmd) { restore_all_vers (); strcpy (command_processor, expandmacro ("$(SHELL)")); while (curcmd) { if (curcmd->command) { no_comm_subst = TRUE; strcpy (x_command, expandmacro (curcmd->command)); no_comm_subst = FALSE; if ((expcmd = malloc (MAXCMDLENGTH)) == NIL) errexit(10,"malloc"); strcpy (expcmd, expand_command (x_command, current, fname)); execute (expcmd, command_processor); free (expcmd); } else break; curcmd = curcmd->nextcmd; } if (simple_done) { mark_all_done (current); simple_done = FALSE; } save_targets (current, fname, q, made_key, touch_time); } cleanup_links (link_reg); free_linklist (); link_reg = (struct linkreg *) NIL; return TRUE; } LOCAL Bool try_recache (do_name, do_key, dep_rule, key_from_cache) char *do_name, *do_key; struct rules *dep_rule; BKey *key_from_cache; { Af_set bset; Af_attrs buf; Af_key bkey, key1, restorekey; int object_is_cached, busy_version_exists; char type[MYMAXNAMLEN], sysp[MYMAXNAMLEN], *retrv_attr; key_from_cache->bk_isdefined = FALSE; if (!locate_object (do_name, ALL)) return FALSE; /* * This is handling of the special case, when a target (pseudo * or real) depends on nothing but a commandlist. In this case * reproduction of the target must be performed unconditionally. * The resulting target (in case it is a file) is stored in the * BPOOL (should be avoided) with an empty attribute. We have to * avoid restoration from BPOOL and have to set the existing * file to non-current. */ if ((do_key == NIL) || (*do_key == '\0')) { if ((dep_rule->deplist == (char *)NIL) && (dep_rule->cmdlist != (struct cmds *)NIL)) return FALSE; } af_initattrs(&buf); buf.af_gen = AF_BUSYVERS; buf.af_rev = AF_BUSYVERS; strcpy (type, af_aftype (do_name)); strcpy (sysp, af_afpath (do_name)); if(sysp[0] != '\0') strcpy (buf.af_syspath, sysp); else strcpy (buf.af_syspath, curvpath[0]); strcpy (buf.af_name, af_afname (do_name)); strcpy (buf.af_type, af_aftype (do_name)); if (forceflg) { if (is_in_forcelist (do_name)) { if (D_flag) printf ("shape - must reshape %s (caused by -force)\n", do_name); return FALSE; } } if (D_flag) printf ("shape - recache %s:\n looking for key: %s.\n\n", do_name, do_key); busy_version_exists = (af_getkey (buf.af_syspath, af_afname (do_name), af_aftype (do_name), AF_BUSYVERS, AF_BUSYVERS, &key1) > -1); if (busy_version_exists && (retrv_attr = af_retattr (&key1, ATTRNAME))) { if (stk_matchuda (retrv_attr, do_key)) { /* * Double-check, if this is really the busy version we need ! * If the derived object has been rederived with other tools * than shape (e.g. make), the derived object's contents may * have changed but the derivation key is still the same... * To make things sure we check the busy version's mtime against * the mtime that was stored in the cachekey when the object was * created.. */ char *ap = af_retattr (&key1, AT_ATTCACHEKEY); Af_attrs busy_attrs; if (ap && (af_allattrs (&key1, &busy_attrs) > -1)) { char *auxp = strchr (ap, '.'); if (auxp) *auxp = '\0'; if (busy_attrs.af_mtime == atol (ap)) { key_from_cache->bk_key = key1; key_from_cache->bk_isdefined = TRUE; af_freeattrbuf (&busy_attrs); free (retrv_attr); free (ap); if (D_flag) printf ("shape - recache %s:\n got the busyversion.\n\n", do_name); return TRUE; } } if (ap) free (ap); } if (retrv_attr) free (retrv_attr); } /* * ASSERT: Either there is no un-cached busyversion, or it has not * the attributes we're looking for. */ buf.af_gen = AF_NOVNUM; buf.af_rev = AF_NOVNUM; if ((retrv_attr = malloc ((unsigned)(strlen (do_key) + strlen (ATTRNAME) + 2))) == NIL) errexit(10,"malloc"); strcpy (retrv_attr, ATTRNAME); strcat (retrv_attr, "="); strcat (retrv_attr, do_key); buf.af_udattrs[0] = retrv_attr; buf.af_udattrs[1] = NIL; if ((object_is_cached = af_cachefind (&buf, &bset)) == -1) errexit (10, "af_cachefind"); if (!object_is_cached) { if (af_dropset (&bset) == -1) errexit (10, "af_dropset"); free (retrv_attr); if (D_flag) { printf ("shape - recache %s:\n failed!\n\n", do_name); printf ("shape - recache %s: the derived object cache is:\n", do_name); buf.af_udattrs[0] = NIL; if ((object_is_cached = af_cachefind (&buf, &bset)) == -1) { printf (" unaccessible. This is an error!\n\n"); } else { int i, nkeys = af_nrofkeys (&bset); if (nkeys == 0) printf (" empty.\n\n"); else { for (i = 0; i < nkeys; i++) { char *a; af_setgkey (&bset, i, &bkey); a = af_retattr (&bkey, ATTRNAME); printf (" %s\n", a); free (a); af_dropkey (&bkey); } af_dropset (&bset); printf ("\n"); } } } if (busy_version_exists && (af_dropkey (&key1) == -1)) af_perror ("try_recache"); return FALSE; } else { if (D_flag) printf ("shape - recache %s:\n got one!\n\n", do_name); if (af_setgkey (&bset, 0, &bkey) == -1) errexit (10,"af_setgkey"); if (!noexflg) { if (af_restore (&bkey, &restorekey) == -1) errexit (10,"af_restore"); printf ("... %s%s%s[%s] restored from derived object cache\n", buf.af_name, (buf.af_type && buf.af_type[0]) ? "." : "", buf.af_type ? buf.af_type : "", af_retattr (&bkey, AT_ATTCACHEKEY)); } else printf ("... %s%s%s[%s] found in derived object cache (not restored)\n", buf.af_name, (buf.af_type && buf.af_type[0]) ? "." : "", buf.af_type ? buf.af_type : "", af_retattr (&bkey, AT_ATTCACHEKEY)); key_from_cache->bk_key = bkey; key_from_cache->bk_isdefined = TRUE; if (af_dropset (&bset) == -1) errexit (10, "af_dropset"); if (buf.af_udattrs[0]) free (buf.af_udattrs[0]); /* implicitly freeing "retrv_attr" */ return TRUE; } } LOCAL Bool abort_this_try (targ) char *targ; { char messg[80]; if (goflg) { sprintf (messg, "shape - don't know how to shape %s", targ); warning (0, messg); return FALSE; } errexit (3, targ); /* NOTREACHED */ return FALSE; } static TargetCode make_target(); LOCAL Bool try_to_make_target (targ, sr, force, made_object_key) char *targ; char *sr; Bool force; BKey *made_object_key; { #ifdef DEBUG_MALLOC dssize ("In try_make, ", targ); #endif switch (make_target (targ, sr, made_object_key)) { case Ok: return TRUE; case Fail: return FALSE; case Abort: return abort_this_try (targ); } return FALSE; } LOCAL TargetCode make_target (targ, sr, made_object_key) char *targ; char *sr; BKey *made_object_key; { register struct rules *current; char *lastcurdep = NULL; char *curdep = NULL, *curselrule = NULL; char *this_dependent; Bool err_happ = FALSE; Bool lbusy_done = FALSE; BKey bkey; DepQ *new_DepQ(), *deriv_key_deps = new_DepQ(); int dep = 0, var_depth = -1; # define free_depvars { if (curdep) free (curdep); \ if (curselrule) free (curselrule); \ if (lastcurdep) free (lastcurdep); } lastcurdep = check_strdup (""); made_object_key->bk_isdefined = FALSE; if (already_in_done_list (targ, &made_object_key->bk_key)) { made_object_key->bk_isdefined = TRUE; drop_dependent_queue (deriv_key_deps); free_depvars; return Ok; } if (depth > MAXDEPTH) { drop_dependent_queue (deriv_key_deps); warning (7, targ); free_depvars; return Fail; } depth++; if (!(current = get_target (targ))) { /* * We don't have a rule to produce "targ", so it must be * a source object. If not - give up ! */ if (!locate_object (targ, ALL)) { depth--; drop_dependent_queue (deriv_key_deps); free_depvars; return Abort; } else { if (strcmp (targ, lastcurdep)) { if (try_to_bind_version (targ, sr, BIND_IT, &bkey)) { free (lastcurdep); lastcurdep = check_strdup (targ); depth--; drop_dependent_queue (deriv_key_deps); free_depvars; return Ok; } else { if (D_flag) D_debug (targ, NIL, NIL); depth--; drop_dependent_queue (deriv_key_deps); free_depvars; return Fail; } } else { depth--; drop_dependent_queue (deriv_key_deps); free_depvars; return Fail; } } } /**/ /* ASSERT: current != NIL ; "targ" is name of a derived object */ /**/ dep = 0; lbusy_done = busy_done; /* * Now, all the dependents of the current target are examined and * requested. */ curselrule = check_strdup (sr); reset_dep_list (current); if (confid) { add_rule_to_confid (current); } if (*(this_dependent = get_dep (current, dep))) { if (atBindTestRule (this_dependent)) { if((!ruleflg) || (depth > 1)) { free (curselrule); curselrule = check_strdup (this_dependent); } dep++; } while (is_varname (this_dependent = get_dep (current, dep))) { var_depth += activate_variant (this_dependent); dep++; } } curdep = check_strdup (get_dep (current, dep)); if (*curdep) dep++; /* * skip bogus variant activations (coming from empty expanding var macros) */ while (!strcmp (curdep, "+")) if (*get_dep (current, dep)) { free (curdep); curdep = check_strdup (get_dep (current, dep++)); } else *curdep = '\0'; if (is_pattern (current->name)) { dep--; free (curdep); curdep = check_strdup (cooked_dep (current, targ, dep++, IMPLICIT)); } else if ((current->cmdlist == (struct cmds *)NIL) || (current->cmdlist->command == (char *)NIL)) { add_defaults (targ, current); if (!*curdep) { free (curdep); curdep = check_strdup (get_dep (current, dep++)); } } while (*curdep) { struct rules *dep_is_derivable = get_target (curdep); Bool dep_exists = locate_object (curdep, ALL); if (!strcmp (curdep, lastcurdep)) goto next_dep; if (!dep_is_derivable && dep_exists && (strcmp (curdep, lastcurdep))) { free (lastcurdep); lastcurdep = check_strdup (curdep); #ifdef DEBUG_MALLOC dssize ("Vor bind_version, ", curdep); #endif try_to_bind_version (curdep, curselrule, BIND_IT, &bkey); #ifdef DEBUG_MALLOC dssize ("Nach bind_version, ", curdep); #endif if (bkey.bk_isdefined) append_dependent (&bkey.bk_key, deriv_key_deps); else { try_to_make_target (curdep, sr, TRUE, &bkey); /* basically produces an Abort! */ depth--; free_depvars; return Abort; } } else { if (dep_is_derivable && try_to_make_target (curdep, curselrule, TRUE, &bkey)) { if (error_happened) { err_happ = TRUE; error_happened = FALSE; } if (bkey.bk_isdefined) append_dependent (&bkey.bk_key, deriv_key_deps); } else { abort_this_try (curdep); depth--; cl_variants (var_depth, variants_active); drop_dependent_queue (deriv_key_deps); mark_all_done (current); free_depvars; return Fail; } } next_dep: free (curdep); curdep = check_strdup (cooked_dep (current, targ, dep++, is_pattern (current->name) ? IMPLICIT : EXPLICIT)); } /* end while (*curdep) */ /* * At this point all dependents of "targ" are either bound to * an appropriate source version or have been derived. Now we * can see whether "targ" needs to be made. */ mark_all_done (current); if (err_happ) { drop_dependent_queue (deriv_key_deps); cl_variants (var_depth, variants_active); depth--; free_depvars; return Fail; } if (locate_object (targ, ALL) && try_recache (targ, make_derivation_key (current, deriv_key_deps), current, made_object_key)) { add_to_done_list (targ, &made_object_key->bk_key); drop_dependent_queue (deriv_key_deps); drop_restorelist (); cl_variants (var_depth, variants_active); depth--; free_depvars; return Ok; } else { if (D_flag) printf ("shape - initially making %s\n", targ); if (execute_commands (current, targ, deriv_key_deps, made_object_key)) { drop_dependent_queue (deriv_key_deps); drop_restorelist (); cl_variants (var_depth, variants_active); depth--; free_depvars; return Ok; } else { drop_dependent_queue (deriv_key_deps); cl_variants (var_depth, variants_active); depth--; free_depvars; return Fail; } } } EXPORT void produce () { register int k = 0; char *comm; BKey produced_object; char *initial_selection = ""; int tfd = open ("...__tt", O_RDONLY | O_CREAT, S_IRUSR); struct stat sbuf; touch_time = time ((time_t *)0); /* used in execute_commands */ if (tfd >= 0) { unlink ("...__tt"); fstat (tfd, &sbuf); close (tfd); if (abs (touch_time - sbuf.st_ctime) >1) { fprintf (stderr, "shape -- WARNING: possible clock discrepancy between host and NFS server.\n"); } } else { fprintf (stderr, "shape -- WARNING: can't create files in `.'.\n"); } shape_command = FALSE; if (cmdtargets[0] == NIL) comm = firsttarget; else comm = cmdtargets[k++]; if ((nostdfile) && (!fileflg) && (cmdtargets[0] == NIL)) errexit(11,NIL); if (!rebuildflg) { if (ruleflg) { if (atBindTestRule (ruleset)) initial_selection = ruleset; else errexit(32,ruleset); } } else initial_selection = rbrule; if (!rebuildflg) { Bool build_success = TRUE; while (comm != NIL) { char bct_name[MYMAXNAMLEN]; Bool spin_success; depth = 0; if (confid) { (void) strcpy (bct_name, comm); (void) strcat (bct_name, ".bct"); if ((cid = fopen (bct_name, "w")) == NULL) errexit(12, bct_name); stRegisterFile (bct_name); init_confid (comm); } spin_success = try_to_make_target (comm, initial_selection, TRUE, &produced_object); if (spin_success && !reallydone) printf("shape - `%s' is up to date\n", comm); else if (!spin_success) warning (2, comm); build_success = build_success && spin_success; if (confid) { finish_confid (); fclose (cid); stUnRegisterFile (bct_name); } if (comm != firsttarget) comm = cmdtargets[k++]; else comm = NIL; } } else { Bool build_success; depth = 0; build_success = try_to_make_target (rbtarg, initial_selection, TRUE, &produced_object); if (build_success && !reallydone && !rebuildflg) printf("shape - `%s' is up to date\n", rbtarg); else if (reallydone) printf("shape - `%s' rebuilt according to bound configuration.\n", rbtarg); else if (!build_success) warning (2, rbtarg); } } shapetools-1.4pl6.orig/src/shape/rule.c100444 2013 145 122216 5570377166 16226 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - rule.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) and Wolfgang Obst * * $Header: rule.c[8.0] Tue May 24 15:19:17 1994 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: rule.c[8.0] Tue May 24 15:19:17 1994 axel@cs.tu-berlin.de frozen $"; #endif /* intermixing of implicit "." rules and normal targets is *not* allowed */ #include #include "shape.h" #define RULETABSIZE 257 #define MAXRULELENGTH 2048 EXPORT struct rules *ruletab[RULETABSIZE]; EXPORT char *firsttarget; LOCAL char *special_target[] = { ".BPOOL", ".DEFAULT", ".IGNORE", ".NOBPOOL", ".SILENT", ".SUFFIXES", (char *) 0 } ; LOCAL Bool oldrule; LOCAL Bool doublecolon; LOCAL int depnr, targnr, cmdnr, heritnr; LOCAL char *targfield[MAXTARGS], *depfield[MAXDEPS], *cmdfield[MAXCMDS]; LOCAL char *heritfield[MAXHERIT]; #define LINELEN 128 #define copy_token(source, dest) { register char *s = source, \ *d = dest; \ while (*s && !isspace(*s)) \ *d++ = *s++; \ *d = '\0'; } #define advance(tok) { while (*tok && !isspace(*tok)) tok++; \ while (*tok && isspace(*tok)) tok++; } #define skip_leading_space(tok) { while (*tok && isspace(*tok)) tok++; } LOCAL Bool is_macro (token) char *token; { register char *tc = token; while (*tc && !isspace (*tc) && !(*tc == '$')) tc++; return *tc == '$'; } LOCAL char *get_token_from_deplist (dep_rule, nth, junk) struct rules *dep_rule; int nth; int junk; /* unused; kept for compatibility during testing */ { /* * Returns "nth" token from the list of dependents in the * dependency rule "dep_rule". Macros are not expanded. */ static struct rules *last_rule; static int last_token_number; static char nth_dependent[PATH_MAX]; static Bool got_token = FALSE; char *this_token; int this_token_position = 0; if (!dep_rule) return NIL; if (!dep_rule->deplist) return NIL; if ((last_rule == dep_rule) && (nth == last_token_number)) return got_token ? nth_dependent : NIL; else { last_rule = dep_rule; last_token_number = nth; got_token = FALSE; } this_token = dep_rule->deplist; skip_leading_space (this_token); do { if (nth == this_token_position) { if (*this_token) { copy_token (this_token, nth_dependent); got_token = TRUE; /* * special treatment for "./targets" */ if (nth_dependent[0] == '.') if (nth_dependent[1] == '/') { register char *s1 = nth_dependent, *s2 = nth_dependent + 2; while ((*s1++ = *s2++)); } return nth_dependent; } else return NIL; } else { advance (this_token); this_token_position++; } } while (*this_token); return NIL; } LOCAL char *expand_token (tok) char *tok; { char tokbuf[LINELEN]; copy_token (tok, tokbuf); return expandmacro (tokbuf); } LOCAL char *insert_expansion (baseaddr, position, insertion) char **baseaddr, *position, *insertion; { char tokbuf[LINELEN], *base = *baseaddr; unsigned int replacement_offset = position - base, trailer_length, replace_length, replacement_length, new_base_length; char *new_base, *hook; copy_token (position, tokbuf); replace_length = strlen (tokbuf); trailer_length = strlen (position + replace_length); replacement_length = strlen (insertion); new_base_length = replacement_offset + replacement_length + trailer_length+1; if ((new_base = malloc (new_base_length)) == NIL) return position; strncpy (new_base, base, replacement_offset); new_base[replacement_offset] = '\0'; strcat (new_base, insertion); strcat (new_base, position + replace_length); if ((hook = realloc (base, new_base_length)) == NIL) { free (new_base); return position; } else { *baseaddr = hook; base = *baseaddr; } strcpy (base, new_base); position = base + replacement_offset; free (new_base); return position; } LOCAL char *get_src_name(name) char *name; { static char fname[MYMAXNAMLEN]; struct rules *dep_rule; char *f_suffix, *d_suffix, *dep; if (!name) return NIL; dep_rule = get_target (name); if (!dep_rule) return NIL; dep = get_token_from_deplist (dep_rule, 0, 0); if (!is_pattern (dep)) return dep; strcpy(fname,name); f_suffix = strrchr (fname, '.'); d_suffix = strchr (dep, '.'); if (f_suffix) *f_suffix = '\0'; if (d_suffix) strcat (fname, d_suffix); return fname; } LOCAL Bool is_old_rule(string) char *string; { if (strchr(string,'/') != NIL) return(FALSE); if ((string[0] == '.') && (strchr(string+2,'.') != NIL)) return(TRUE); else return(FALSE); } LOCAL void overload_stdrule(k) int k; { register int i; for(i = 0; implicit_suffs[i] != -1; i++) { if((strcmp(stdruletab[implicit_suffs[i]]->name,targfield[k]) == 0) && (strcmp(get_dep(stdruletab[implicit_suffs[i]],0), depfield[1]) == 0)) { implicit_suffs[i] = lastrule; return; } } implicit_suffs[lastrule] = lastrule; } LOCAL int convert_comm(j,suff) int j; char *suff; { char newcomm[1024]; register char *p,*p2; register int i; Bool mod = FALSE; p = cmdfield[j]; i = 0; if(strchr(cmdfield[j],'$') == NIL) return(0); while(*p != '\0') { if(*p != '$') { newcomm[i] = *p; p++; i++; newcomm[i] = '\000'; } else { switch(*(p+1)) { case '*': mod = TRUE; newcomm[i] = '%'; i++; newcomm[i] = '\0'; p = p+2; break; case '<': mod = TRUE; p2 = suff; while(*p2 != '\0') { newcomm[i] = *p2; p2++; i++; } p = p+2; break; default: newcomm[i] = '$'; i++; p++; break; } } } if(!mod) return(0); newcomm[i] = '\0'; if((cmdfield[j] = realloc(cmdfield[j], (unsigned)(strlen(newcomm) + sizeof(char)))) == NIL) errexit(10,"realloc"); strcpy(cmdfield[j],newcomm); return(0); } LOCAL void convertrule(i) int i; { char *p; register int j; p = strrchr (targfield[i],'.'); while ((p != NULL) && (*p == '.')) p--; if (p != NULL) { *++p = '\0'; p++; } if ((depfield[1] = malloc((unsigned) (strlen(targfield[i]) + 3))) == NIL) errexit(10,"malloc"); strcpy(depfield[1],"%"); strcat(depfield[1],targfield[i]); if((targfield[1] = malloc((unsigned) (strlen(p) + 3))) == NIL) errexit(10,"malloc"); strcpy(targfield[1],"%."); strcat(targfield[1],p); targnr = 1; depnr = 1; for(j = 1; j <= cmdnr; j++) convert_comm(j,depfield[1]); } EXPORT void ruledef(string) char *string; { register int i = 0, k = 0; int i2 = 0; char klazu; char t[MAXRULELENGTH], string2[MAXRULELENGTH]; targnr = 0; depnr = 0; cmdnr = 0; heritnr = 0; while(string[i] != ':') i++; i2 = i; strncpy(string2,string,i + 1); string2[i+1] = '\0'; i = 0; while(string2[i] != ':') { while((string2[i] != ' ') && (string2[i] != '\t') && (string2[i] != ':')) { t[k] = string2[i]; i++; k++; } t[k] = '\0'; targnr++; if (targnr > MAXTARGS) errexit(27, "targets"); if ((targfield[targnr] = malloc((unsigned) strlen(t) + 1)) == NIL) errexit(10,"malloc"); strcpy(targfield[targnr], t); k = 0; while((string2[i] == ' ') || (string2[i] == '\t')) i++; } i = i2; if (string[i+1] == ':') { doublecolon = TRUE; i = i + 2; } else i++; while((string[i] != '\0') && (string[i] != ';') && (string[i] != ':')) { while((string[i] == ' ') || (string[i] == '\t') || (string[i] == '\\')) { if ((string[i] == '\\') && (string[i+1] == '\n')) i = i+2; else i++; } while((string[i] != ' ') && (string[i] != '\t') && (string[i] != ';') && (string[i] != '\0') && (string[i] != ':') && (string[i] != '\\')) { t[k] = string[i]; i++; k++; } t[k] = '\0'; if (k != 0) { depnr++; if (depnr > MAXDEPS) errexit(27, "dependents"); if ((depfield[depnr] = malloc((unsigned) strlen(t) + 1)) == NIL) errexit(10,"malloc"); strcpy(depfield[depnr],t); } k = 0; } while((string[i] == ' ') || (string[i] == '\t')) i++; /* heritage */ k = 0; if (string[i] == ':') { i++; while (string[i]) { while(isspace(string[i])) i++; if (!string[i]) break; if (string[i] != '+') errexit(26, &string[i]); switch (string[i+1]) { case '(': klazu = ')'; break; case '{': klazu = '}'; break; default: klazu = ' '; } while (string[i] != klazu) { t[k] = string[i]; i++; k++; if (string[i] == '\0') errexit(26,&string[i]); } t[k] = string[i]; k++; i++; t[k] = '\0'; heritnr++; if (heritnr > MAXHERIT) errexit(27, "iherits"); if ((heritfield[heritnr] = malloc((unsigned) strlen(t) + 1)) == NIL) errexit(10,"malloc"); strcpy(heritfield[heritnr],t); k = 0; } } /* commands on ruledef line */ if( string[i] == ';') { i++; while( (string[i] != '\0')) { t[k] = string[i]; i++; k++; } t[k] = '\0'; cmdnr++; if (cmdnr > MAXCMDS) errexit(27, "commands"); if ((cmdfield[cmdnr] = malloc((unsigned) strlen(t) + 1)) == NIL) errexit(10,"malloc"); if (t[strlen(t)-1] == '\n') t[strlen(t)-1] = '\0'; strcpy(cmdfield[cmdnr], t); } } EXPORT void rulecont(string) char *string; { /* only commands have been found */ cmdnr++; if(cmdnr > MAXCMDS) errexit(27, "commands"); if ((cmdfield[cmdnr] = malloc ((unsigned) strlen(string) + 1)) == NIL) errexit(10,"malloc"); if (string[strlen(string)-1] == '\n') string[strlen(string)-1] = '\0'; strcpy(cmdfield[cmdnr], string); } EXPORT void ruleend() { struct rules *current, *previous; struct rules *first_target, *next_target; struct cmds *curcmd; register int i = 0, j = 0; int kkk = 0, xx = 0, ss = 0, hasht = 0, targs = 0; Bool src_found = FALSE; char *p, *srcname, *get_token_from_deplist(); Bool std_rule = FALSE, found = FALSE; if(targnr == 0) return; if(!strcmp(targfield[1],".SILENT")) silentflg = TRUE ; if(!strcmp(targfield[1],".BPOOL")) bpoolflg = TRUE; if(!strcmp(targfield[1],".NOBPOOL")) nobpoolflg = TRUE; if(!strcmp(targfield[1],".IGNORE")) ignoreflg = TRUE; if ((is_old_rule(targfield[1])) && (depfield[1] == NULL) && (strcmp(targfield[1],".SUFFIXES") != 0)) { oldrule = TRUE; targs = targnr; for(i = 1; i <= targs; i++) { if (is_old_rule(targfield[i])) { if (targfield[i] != NIL) convertrule(i); } ruleend(); } oldrule = FALSE; return; } for(i = 1; i <= targnr; i++) { p = strchr(targfield[i],'%'); if (is_pattern (p)) { std_rule = TRUE; break; } } for(i = 1; i <= targnr; i++) { found = FALSE; if(!std_rule) { hasht = hashval(targfield[i], RULETABSIZE); if ( ruletab[hasht] == (struct rules *) NIL) { if((current = ruletab[hasht] = (struct rules *) malloc( sizeof(struct rules))) == (struct rules *)NIL) errexit(10,"malloc"); memset (current, 0, sizeof (struct rules)); } else { current = ruletab[hasht]; if ((!strcmp(ruletab[hasht]->name, targfield[i])) && (strcmp(ruletab[hasht]->name, ".SUFFIXES")) && (current->doublecolon == FALSE) && (doublecolon == FALSE) && (ruletab[hasht]->cmdlist != (struct cmds *) NIL) && (cmdfield[1] != NIL)) errexit(1, targfield[i]); if((!strcmp(current->name,targfield[i])) && ((cmdfield[0] == NIL) || (current->cmdlist == (struct cmds *) NIL))) { found = TRUE; } while((current != (struct rules *) NIL) && (!found)) { if((strcmp(current->name,targfield[i]) == 0) && ((cmdfield[0] == NIL) || (current->cmdlist == (struct cmds *) NIL))) { found = TRUE; break; } else { previous = current; current = current->nextrule; } } if(found) { if ((strcmp(current->name, targfield[i]) == 0) && (strcmp(ruletab[hasht]->name, ".SUFFIXES") != 0) && (ruletab[hasht]->cmdlist != (struct cmds *) NIL) && (current->doublecolon == FALSE) && (doublecolon == FALSE) && (cmdfield[1] != NIL)) errexit(1, targfield[i]); if ((strcmp(current->name, ".SUFFIXES")) == 0) { if (depnr == 0) /* delete suffix list */ { current->deplist = NIL; } else { if (current->deplist == NIL) { if ((current->deplist = malloc((unsigned) 1)) == NIL) errexit(10,"malloc"); current->deplist[0] = '\0'; } for (kkk = 1; kkk <= depnr; kkk++) { if ((current->deplist = realloc(current->deplist, (unsigned) (strlen(depfield[kkk]) + strlen(current->deplist) + 3))) == NIL) errexit(10,"realloc"); strcat(current->deplist," "); strcat(current->deplist, depfield[kkk]); } } } } if (!found) { if((previous->nextrule = current = (struct rules *) malloc(sizeof(struct rules))) == (struct rules *) NIL) errexit(10,"malloc"); memset (current, 0, sizeof (struct rules)); } } } else { lastrule++; if((current = stdruletab[lastrule] = (struct rules *) malloc( sizeof(struct rules))) == (struct rules *) NIL) errexit(10,"malloc"); memset ((char *)current, 0, sizeof (struct rules)); overload_stdrule(i); implicit_suffs[lastrule+1] = -1; stdruletab[lastrule+1] = (struct rules *) NIL; } if (!found) { if((current->name = malloc( (unsigned) strlen( targfield[i] ) + 1)) == NIL) errexit(10,"malloc"); strcpy(current->name, targfield[i]); current->targetlist[0] = NIL; current->heritage[0] = NIL; } current->done = 0; if (doublecolon) current->doublecolon = TRUE; else current->doublecolon = FALSE; if(i == 1) { first_target = current; next_target = current; current->next = (struct rules *)NIL; current->saved = FALSE; } else { if(cmdnr >= 1) { next_target->next = current; next_target = current; } } if((i == 1) && (firsttarget == NIL) && !is_pattern (current->name) && ! is_old_rule(current->name) && ! is_special_target(current->name)) firsttarget = current->name; if(!found) { current->deplist = NIL; current->cmdlist = (struct cmds *) NIL; current->nextrule = (struct rules *) NIL; } if ((depnr > 0) && (!found)) { if ((current->firstdep = malloc((unsigned) (strlen(depfield[1]) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(current->firstdep, depfield[1]); } if (found) { xx = 0; while (get_token_from_deplist (current, xx, 0)) xx++; } for(j = xx+1; j <= xx+depnr; j++) { for(ss = 0; get_token_from_deplist(current,ss,0) != NIL; ss++) { if (!strcmp(get_token_from_deplist(current,ss,0),depfield[j-xx])) { src_found = TRUE; break; } } if(!src_found) { if(current->deplist == NIL) { if((current->deplist = malloc( (unsigned) (strlen (depfield[j-xx]) + 1))) == NIL) errexit(10,"malloc"); strcpy(current->deplist,depfield[j-xx]); } else { if ((current->deplist = realloc(current->deplist, (unsigned) (strlen(current->deplist) + (strlen(depfield[j-xx]))) + 3)) == NIL) errexit(10,"realloc"); strcat(current->deplist," "); strcat(current->deplist, depfield[j-xx]); } } src_found = FALSE; } /* get standard dependent */ if (!is_pattern (current->name)) { if((srcname = get_src_name(current->name)) != NIL) { for(ss = 0; get_token_from_deplist(current,ss,0) != NIL; ss++) { if(!strcmp(srcname,get_token_from_deplist (current,ss,0))) { src_found = TRUE; break; } } if (!src_found) { if (current->deplist == NIL) { if((current->deplist = malloc( (unsigned) (strlen(srcname) + 1))) == NIL) errexit(10,"malloc"); strcpy(current->deplist,srcname); } else { if((current->deplist = realloc(current->deplist, (unsigned) (strlen(srcname) + strlen(current->deplist) + 3))) == NIL) errexit(10,"realloc"); strcat(current->deplist," "); strcat(current->deplist,srcname); } } src_found = FALSE; } } if (heritnr > 0) { j = 0; while(current->heritage[j] != NIL) j++; for (j = j+1; j <= heritnr; j++) { if((current->heritage[j-1] = malloc((unsigned) (strlen(heritfield[j]) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(current->heritage[j-1], heritfield[j]); } current->heritage[j-1] = NIL; } if(std_rule) { for (j = 1; j <= targnr; j++) { if((current->targetlist[j-1] = malloc((unsigned) (strlen(targfield[j]) + 1))) == NIL) errexit(10,"malloc"); strcpy(current->targetlist[j-1],targfield[j]); } current->targetlist[j-1] = NIL; current->next = (struct rules *) NIL; } if (cmdnr > 0) { if ((curcmd = current->cmdlist = (struct cmds *) malloc( sizeof( struct cmds))) == (struct cmds *) NIL) errexit(10,"malloc"); for (j = 1; j <= cmdnr; j++) { if((curcmd->command = malloc( (unsigned) strlen (cmdfield[j]) + 1)) == NIL) errexit(10,"malloc"); strcpy(curcmd->command, cmdfield[j]); if (j != cmdnr) { if((curcmd = curcmd->nextcmd = (struct cmds *) malloc( sizeof( struct cmds))) == (struct cmds *) NIL) errexit(10,"malloc"); } else curcmd->nextcmd = (struct cmds *) NIL; } } if((targnr > 1) && (cmdnr > 0)) current->next = first_target; else current->next = (struct rules *) NIL; } doublecolon = FALSE; if (!oldrule) { targnr = 0; targfield[1] = NIL; depnr = 0; depfield[1] = NIL; cmdnr = 0; cmdfield[1] = NIL; heritnr = 0; heritfield[1] = NIL; } } /* end ruleend */ LOCAL struct rules *make_rule_object (target_name, dependent_list, ingredient_macro_list, command_list) char *target_name; struct stringlist *dependent_list, *ingredient_macro_list, *command_list; { struct rules *new_rule, *bucket_tail = (struct rules *)NULL; int hash_index = hashval (target_name, RULETABSIZE); struct rules *this_rule = ruletab[hash_index]; Bool rule_already_defined = FALSE; sb_ptr dep_list; while (this_rule) { if (strcmp (this_rule->name, target_name)) { bucket_tail = this_rule; this_rule = this_rule->nextrule; continue; } else { /* rule is already defined somehow - add deps if necessary */ struct stringlist *this_dependent = dependent_list; char *this_old_dependent; sb_ptr old_dependent_list = check_sbnew (MYMAXNAMLEN); Bool dep_already_known = FALSE; rule_already_defined = TRUE; check_sbcat (old_dependent_list, ruletab[hash_index]->deplist); while (this_dependent->string) { this_old_dependent = stStrtok (sbstr (old_dependent_list)); while (this_old_dependent) { if (strcmp (this_dependent->string, this_old_dependent)) { this_old_dependent = stStrtok ((char *)NULL); continue; } else { dep_already_known = TRUE; break; } } if (!dep_already_known) { old_dependent_list = check_sbcat (old_dependent_list, this_dependent->string); } this_dependent = this_dependent->next; } free (ruletab[hash_index]->deplist); ruletab[hash_index]->deplist = sbstr (old_dependent_list); free (old_dependent_list); } } if (rule_already_defined) return NULL; new_rule = (struct rules *) check_malloc (sizeof (struct rules)); new_rule = memset (new_rule, 0, (sizeof (struct rules))); new_rule->name = check_strdup (target_name); dep_list = check_sbnew (MYMAXNAMLEN); { struct stringlist *this_dependent; for (this_dependent = dependent_list; this_dependent; this_dependent = this_dependent->next) { dep_list = check_sbcat (dep_list, this_dependent->string); dep_list = check_sbcat (dep_list, " "); } } new_rule->deplist = sbstr (dep_list); free (dep_list); new_rule->firstdep = check_strdup (dependent_list->string); return NULL; } /* FINISH ME / 13.4.93 */ LOCAL void link_related_rule_objects (rule_name_list) char *rule_name_list; { } LOCAL void insert_rule_object (new_rule) struct rules *new_rule; { } LOCAL char *trim (base, trim_from) char *base, *trim_from; { /* * Prefixes of that are identical to * are removed from the beginning of */ register char *p = base, *q; do { q = trim_from; while (*q && (*p == *q)) { p++; q++; } } while (!*q); return p; } LOCAL Bool test_path (path) char *path; { /* * returns TRUE if * a) "path" is just a file name without a path prefix * b) "path" has a path prefix, and the prefix points to * an existing and searchable directory. * returns FALSE otherwise. */ char *cp_path, *slash; if (path == NULL) return FALSE; cp_path = check_strdup (path); slash = strrchr (cp_path, '/'); if (!slash) return TRUE; *slash = '\0'; /* test for existence by cd-ing to directory. If success, go back */ if (chdir (cp_path) < 0) return FALSE; chdir (curvpath[0]); return TRUE; } LOCAL Bool is_suffix_pattern (pattern) char *pattern; { /* * check whether a given name of an implicit (pattern) rule * is in suffix normal form (SNF). If it is in SNF, return * TRUE. Return FALSE otherwise. * SNF is optional path, immediately followed by '%', immediately * followed by an optional period-separated suffix. * The suffix shall not contain any more period chars. */ char *percent; char *period; if (pattern == NULL) return FALSE; percent = strrchr (pattern, '%'); period = strrchr (pattern, '.'); if (percent == NULL) return TRUE; /* check for leading stuff */ if ((percent > pattern) && (*(percent-1) != '/') && !isspace (*(percent-1))) return FALSE; /* If leading stuff is a path prefix, we need not consider it */ switch (*(percent+1)) { case '\0': return TRUE; case '.': return (percent+1) == period; default: return isspace(*(percent+1)); } } EXPORT char *subst_char (template, s_char, substitution) char *template; char s_char; char *substitution; { /* * this function substitutes all occurrences of 's_char' in 'template' * with 'substitution'. * The modified string is returned in static memory. * If no occurrence of 's_char' in 'template' is found, 'template' * is returned. */ static char result_str[MYMAXNAMLEN]; char *c1, *c2; c1 = template; c2 = strchr (c1, s_char); if (c2 == NULL) return template; (void) strncpy (result_str, c1, c2-c1); result_str[c2-c1] = '\0'; (void) strcat (result_str, substitution ? substitution : ""); c1 = c2+1; c2 = strchr (c1, s_char); while (c2) { (void) strncat (result_str, c1, c2-c1); result_str[c2-c1] = '\0'; (void) strcat (result_str, substitution ? substitution : ""); c1 = c2+1; c2 = strchr (c1, s_char); } (void) strcat (result_str, c1); return result_str; } EXPORT char *escape_char (template, s_char) char *template; char s_char; { /* * this function escapes all occurrences of 's_char' in 'template' * by prefixing it with a '\' character. * The modified string is returned in static memory. * If no occurrence of 's_char' in 'template' is found, 'template' * is returned. */ static char result_str[MYMAXNAMLEN]; char interim[MYMAXNAMLEN], s_str[3]; char *c1, *c2; c1 = template; c2 = strchr (c1, s_char); if (c2 == NULL) return template; (void) strcpy (interim, template); s_str[0] = '\\'; s_str[1] = s_char; s_str[2] = '\0'; c2 = interim + (c2-c1); c1 = interim; (void) strncpy (result_str, c1, c2-c1); result_str[c2-c1] = '\0'; (void) strcat (result_str, s_str); c1 = c2+1; c2 = strchr (c1, s_char); while (c2) { (void) strncat (result_str, c1, c2-c1); (void) strcat (result_str, s_str); c1 = c2+1; c2 = strchr (c1, s_char); } (void) strcat (result_str, c1); return result_str; } EXPORT void make_derivation_rule (target_list, dependent_list, ingredient_macro_list, command_list) struct stringlist *target_list, *dependent_list, *ingredient_macro_list, *command_list; { sb_ptr expanded_targets; struct stringlist *this_token = target_list; struct rules *new_derivation_rule; char cur_tok[MYMAXNAMLEN], *next_tok; if (!(target_list && target_list->string && *target_list->string)) return; expanded_targets = check_sbnew (MYMAXNAMLEN); while (this_token) { if (is_macro (this_token->string)) { expanded_targets = check_sbcat (expanded_targets, expandmacro (this_token->string)); } else { expanded_targets = check_sbcat (expanded_targets, this_token->string); } expanded_targets = check_sbcat (expanded_targets, " "); this_token = this_token->next; } next_tok = sbstr (expanded_targets); copy_token(next_tok, cur_tok); while (*cur_tok) { new_derivation_rule = make_rule_object (cur_tok, dependent_list, ingredient_macro_list, command_list); insert_rule_object (new_derivation_rule); advance(next_tok); copy_token(next_tok, cur_tok); } link_related_rule_objects (sbstr (expanded_targets)); sbfree (expanded_targets); } EXPORT void dump_rule (dest, rule, dump_commands) FILE *dest; struct rules *rule; Bool dump_commands; { struct cmds *this_cmd; register int i; char *deps, *this_dep; if (rule == NULL) return; for (i = 0; rule->targetlist[i] && (i < MAXHERIT); i++) { fprintf (dest, "%s ", rule->targetlist[i]); } fprintf (dest, "%s:", rule->targetlist[0] ? "" : rule->name); deps = expandmacro (rule->deplist); this_dep = stStrtok (deps); if (atBindTestRule (this_dep)) this_dep = stStrtok (NULL); while (this_dep) { fprintf (dest, " %s", trim (this_dep, "./")); this_dep = stStrtok (NULL); } fprintf (dest, "\n"); if (!dump_commands) return; this_cmd = rule->cmdlist; while (this_cmd) { if (this_cmd->command && *this_cmd->command) fprintf (dest, "\t%s\n", expandmacro (this_cmd->command)); this_cmd = this_cmd->nextcmd; } } EXPORT void ruledump(fd) FILE *fd; { register struct rules *cur; register struct cmds *ccmd; register int i, k; char *pp = NIL; for(i = 0; i< RULETABSIZE; i++) { if (ruletab[i] != (struct rules *) NIL) { cur = ruletab[i]; while( cur != (struct rules *) NIL) { if(fd == stdout) fprintf(fd,"%s\n", cur->name); else fprintf(fd,"%s", cur->name); if (fd == stdout) fprintf(fd," depends on:"); else fprintf(fd,":"); if(cur->deplist != NIL) { if(atBindTestRule(get_dep(cur,0))) { pp = strchr(cur->deplist,' '); if(pp != NIL) { pp++; fprintf(fd," %s",pp); } } else fprintf(fd," %s",cur->deplist); } if(fd == stdout) fprintf(fd,"\n"); if (cur->heritage[0] != NIL) { if(fd == stdout) fprintf(fd," inherits:"); else fprintf(fd," :"); } k = 0; while (cur->heritage[k] != NIL) { fprintf(fd," %s", cur->heritage[k]); k++; } fprintf(fd,"\n"); ccmd = cur->cmdlist; if (ccmd == '\0') ccmd = (struct cmds *) NIL; if(fd == stdout) fprintf(fd," commands:\n"); while (ccmd != (struct cmds *) NIL) { if(ccmd->command != NIL) fprintf(fd,"%s\n", ccmd->command); ccmd = ccmd->nextcmd; } fprintf(fd,"\n"); cur = cur->nextrule; } } } for(i = 0; i <= lastrule; i++) { cur = stdruletab[i]; if(fd == stdout) fprintf(fd,"%s\n", cur->name); else fprintf(fd,"%s", cur->name); if (fd == stdout) fprintf(fd," depends on:"); else fprintf(fd," :"); fprintf(fd," %s",cur->deplist); if (fd == stdout) fprintf(fd,"\n"); k = 0; if (fd == stdout) fprintf(fd," inherits:"); else fprintf(fd," :"); while (cur->heritage[k] != NIL) { fprintf(fd," %s", cur->heritage[k]); k++; } fprintf(fd,"\n"); ccmd = cur->cmdlist; if (fd == stdout) fprintf(fd," commands:\n"); while (ccmd != (struct cmds *) NIL) { if(ccmd->command != NIL) fprintf(fd,"%s\n", ccmd->command); ccmd = ccmd->nextcmd; if (ccmd == '\0') ccmd = (struct cmds *) NIL; } fprintf(fd,"\n"); } fflush(fd); } /* end ruledump */ EXPORT void adjust_stdrules(suffs) char *suffs; { /* empty */; } EXPORT void init_ruletab() { memset((char *) ruletab, 0, 257 * sizeof(struct rules *)); } EXPORT void reset_dep_list (dep_rule) struct rules *dep_rule; { if (dep_rule->_deplist_buffer) free (dep_rule->_deplist_buffer); if (dep_rule->deplist) dep_rule->_deplist_buffer = check_strdup (dep_rule->deplist); else dep_rule->_deplist_buffer = NULL; } EXPORT char *get_dep (dep_rule, nth) struct rules *dep_rule; int nth; { /* * Returns "nth" dependent from the list of dependents in the * dependency rule "dep_rule". * Principle is: for each token that has a lower token number than * "nth", check if it is a macro, and expand it if needed. * Proceed through tokens in expanded macro. If tokens in expanded * macro are exhausted, proceed as before ..... */ static struct rules *last_rule; static int last_token_number; static char nth_dependent[PATH_MAX]; static Bool got_token = FALSE; char **expand_string, *this_token, *m, *expand_token(), *insert_expansion(); int this_token_position = 0; if (!dep_rule) return ""; if (!dep_rule->deplist) return ""; expand_string = dep_rule->_deplist_buffer ? &(dep_rule->_deplist_buffer) : &(dep_rule->deplist); if ((last_rule == dep_rule) && (nth == last_token_number)) return got_token ? nth_dependent : ""; else { last_rule = dep_rule; last_token_number = nth; got_token = FALSE; } this_token = *expand_string; skip_leading_space (this_token); do { if (nth == this_token_position) { if (!is_macro (this_token)) { if (*this_token) { copy_token (this_token, nth_dependent); got_token = TRUE; /* * special treatment for "./targets" */ if (nth_dependent[0] == '.') if (nth_dependent[1] == '/') { register char *s1 = nth_dependent, *s2 = nth_dependent + 2; while ((*s1++ = *s2++)); } return nth_dependent; } else return ""; } else { m = expand_token (this_token); this_token = insert_expansion (expand_string, this_token, m); skip_leading_space (this_token); continue; } } if (!is_macro (this_token)) { advance (this_token); this_token_position++; } else { m = expand_token (this_token); this_token = insert_expansion (expand_string, this_token, m); skip_leading_space (this_token); } } while (*this_token); return ""; } EXPORT void add_defaults (targ, rule) char *targ; struct rules *rule; { /* * Make sure that the "primary dependent" of a target (e.g. "foo.c" * for target "foo.o" actually appears in the dependents list. * This is necessary, because there are often various explicit * dependencies in a Shape/Makefile but the most basic dependency * is not specified, because it's the default. * * First, find applicable default rule for "targ". Then construct * a regular Shapefile dependency from the pattern rule and the * "targ" name. Having the rule formed, it is passed to shape's * rule definition machinery. */ char default_dependency_line[2 * PATH_MAX], targ_edit[PATH_MAX], *this_target, *suff; struct rules *implicit_target(), *default_rule = implicit_target (targ); register int i; register char *line_end, *deplist; if (!default_rule) default_rule = get_target (".DEFAULT"); if (!default_rule) return; if (confid) add_rule_to_confid (default_rule); rule->cmdlist = default_rule->cmdlist; for (i = 0; (i < MAXHERIT) && default_rule->heritage[i]; i++) rule->heritage[i] = default_rule->heritage[i]; /* * make target part ... */ default_dependency_line[0] = '\0'; for (i = 0; (i < MAXHERIT) && (this_target = default_rule->targetlist[i]); i++) { if (is_pattern (this_target)) { targ_edit[0] = '\0'; strcat (targ_edit, targ); suff = suffix (targ_edit); if ((suff != targ_edit) && *suff) *suff = '\0'; suff = suffix (this_target); if (suff != this_target) strcat (targ_edit, suff); strcat (default_dependency_line, targ_edit); } else strcat (default_dependency_line, this_target); strcat (default_dependency_line, " "); } strcat (default_dependency_line, ": "); /* * make dependents part.... */ targ_edit[0] = '0'; strcpy (targ_edit, targ); suff = suffix (targ_edit); if ((suff != targ_edit) && *suff) *suff = '\0'; line_end = default_dependency_line; while (*line_end) line_end++; deplist = default_rule->deplist; while (deplist && *deplist) { if (*deplist == '%') { *line_end = '\0'; strcat (default_dependency_line, targ_edit); while (*line_end) line_end++; deplist++; } else *line_end++ = *deplist++; } *line_end = '\0'; /* * make additional dependency known to shape... */ ruledef (default_dependency_line); ruleend (); reset_dep_list (rule); return; } EXPORT Bool is_special_target(string) char * string ; { int i ; for (i = 0; special_target[i]; i++) { if (!strcmp(string, special_target[i])) return TRUE ; } return FALSE ; } EXPORT Bool is_pattern (string) char * string; { /* * recognize implicit rules that use the pattern notation */ if (!string) return FALSE; if (string[0] == '%') return TRUE; if (strchr (string, '%')) return TRUE; return FALSE; } #define STEMLEN 128 EXPORT char *stem (pattern, string) char *pattern, *string; { /* * Match "string" against "pattern" (consists of '%' and a possibly * empty constant string) and returns the substring of string that * matched the wildcard character. If "string" didn't match, NULL * is returned. */ register char *p1, *p2, *q1, *q2; unsigned int l; static char wild_stem[STEMLEN]; if (!(pattern && string && *pattern && *string)) return NULL; if (strchr (string, '%')) { fprintf (stderr, "String to match (%s) must not be a pattern.\n", string); return NULL; } p1 = pattern; p2 = string; while (*p1 && (*p1 == *p2)) { p1++ ; p2++; } if ((*p1 == *p2) && (*p1 == '\0')) { /* pattern and string are identical */ strcpy (wild_stem, string); return wild_stem; } q1 = pattern + ((l = strlen (pattern)) ? l-1 : 0); q2 = string + ((l = strlen (string)) ? l-1 : 0); while (*q1 == *q2) { q1--; q2--; } if ((p1 == q1) && (*q1 == '%')) { q2++; strncpy (wild_stem, p2, q2 - p2); wild_stem[q2 - p2] = '\0'; return wild_stem; } else return NULL; } EXPORT char *rule_id (rule) struct rules *rule; { struct rules *this_ruletab_entry, *canonical_rule = rule; static char edit_buffer[32], *canonical_name; int hasht, hasht_ext = 0; if (!rule) return ""; canonical_name = rule->name; if (rule->next) { /* find "canonical" (lexically first) name in rule group */ struct rules *this_rule = rule->next; while (this_rule && (this_rule != rule)) { /* cyclic list ! */ if (strcmp (canonical_name, this_rule->name) > 0) { canonical_name = this_rule->name; canonical_rule = this_rule; } this_rule = this_rule->next; } } hasht = hashval(canonical_name, RULETABSIZE); this_ruletab_entry = ruletab[hasht]; while (this_ruletab_entry && (this_ruletab_entry != canonical_rule)) { this_ruletab_entry = this_ruletab_entry->nextrule; hasht_ext++; } if (this_ruletab_entry == NULL) warning (100, "make_derivation_key: inconsistent rule parameters"); if (hasht_ext) sprintf (edit_buffer, "%d.%d", hasht, hasht_ext); else sprintf (edit_buffer, "%d", hasht); return edit_buffer; } EXPORT struct rules *get_target (targ) char *targ; { int hasht; register struct rules *current = (struct rules *) NIL; /* * Find and return the production rule for the specified target. */ if (!*targ) return((struct rules *) NIL); if (!test_path (targ)) return NULL; hasht = hashval (targ, RULETABSIZE); if (ruletab[hasht] != (struct rules *) NIL) { current = ruletab[hasht]; while ((current != (struct rules *) NIL ) && (strcmp (targ, current->name) != 0)) { /* look through hash chain */ current = current->nextrule; } } if ((current) && (strcmp(targ, current->name) == 0)) return current; /* * Either there is no rule for hashval(targ), or the rule * doesn't match, i.e. hashval(targ) is accidentally the same as * for some explicit target. We have to look for std rule . */ return implicit_target (targ); } EXPORT struct rules *implicit_target (targ) char *targ; { char *p = NIL, *percent, *pathprefix; char fname[MYMAXNAMLEN], targrule_names[2][MYMAXNAMLEN], *targrulename = targrule_names[0], *targrulename_with_path = targrule_names[1]; register int i, j, k; Bool match_found = FALSE, prerequisites_available = TRUE; /* * Find and return the applicable implicit production rule for * the specified target. * Before a rule is returned as applicable, "implicit_target" makes * sure that we know rules to produce all dependents of "targ". */ if (!*targ) return((struct rules *) NIL); /* First, build the names for the sought rule */ strcpy (fname, targ); p = strrchr (fname, '.'); while ((p != NULL) && (*p == '.')) p--; if ((p != NULL) && (*(p+1) == '.')) p++; pathprefix = af_afpath (targ); /* build rule names */ if (*pathprefix) (void) sprintf (targrulename_with_path, "%s/%c%s%s", pathprefix, '%', p ? "." : "", p ? p+1 : ""); else { targrulename_with_path[0] = '\0'; } (void) sprintf (targrulename, "%c%s%s", '%', p ? "." : "", p ? p+1 : ""); /* * If we have a target with a relative path prefix, we shall first * try to find an implicit rule with a corresponding relative path * part. If no such rule exists, try to find a rule without a path part. */ for (k = 1; k >= 0; k--) { char *trn = targrule_names[k]; if (trn[0] == (char) NULL) continue; for (i = lastrule; i >= 0; i--) { if (implicit_suffs[i] == -1) continue; prerequisites_available = TRUE; match_found = FALSE; if (!is_suffix_pattern (stdruletab[implicit_suffs[i]]->name)) { register char *c; char *cleaned_pattern = stdruletab[implicit_suffs[i]]->name, *rpat, *rmsg; for (c = "\\.*[]|+?^$()"; *c; c++) { cleaned_pattern = escape_char (cleaned_pattern, *c); } # define MATCHALL ".*" rpat = check_strdup (subst_char (cleaned_pattern, '%', MATCHALL)); cleaned_pattern = check_malloc (strlen (rpat) + 3); cleaned_pattern[0] = '^'; cleaned_pattern[1] = '\0'; (void) strcat (cleaned_pattern, rpat); (void) strcat (cleaned_pattern, "$"); free (rpat); rpat = cleaned_pattern; rmsg = re_comp (rpat); free (rpat); if (re_exec (targ)) { /* * The rule name matches our target. Now let's extract * the substring that matched our wildcard. */ percent = stem (stdruletab[implicit_suffs[i]]->name, targ); match_found = TRUE; } } else if (strcmp (trn, stdruletab[implicit_suffs[i]]->name) == 0) { /* * We have found an implicit rule that matches our target. * Now, construct the implicit dependent object(s) name(s) * by substituting the '%' character with the filename-stem * of targ. Then, see if a corresponding object can be located * or derived. */ percent = stem (trn, targ); match_found = TRUE; } if (match_found) { for (j = 0; *get_dep (stdruletab[implicit_suffs[i]], j); j++) { Bool object_derivable, object_exists; static int depth; char *depname = check_strdup (subst_char (get_dep (stdruletab[implicit_suffs[i]], j), '%', percent)); if (depth > MAXDEPTH) { char wrng[MYMAXNAMLEN + 18]; strcpy (wrng, "(implicit "); strcat (wrng, stdruletab[implicit_suffs[i]]->name); strcat (wrng, ") "); strcat (wrng, depname); errexit (40, wrng); } depth++; object_derivable = (Bool) get_target (depname); depth--; object_exists = locate_object (depname, SOURCE); free (depname); prerequisites_available = prerequisites_available && ( object_derivable || object_exists); } /* end for */ if (prerequisites_available) return stdruletab[implicit_suffs[i]]; } /* end if (match_found) */ } /* end for (i >= 0 ) */ } /* end for (k >= 0) */ return (struct rules *) NIL; } shapetools-1.4pl6.orig/src/shape/shapeopt.c100444 2013 145 22156 5416575030 17051 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - shapeopt.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: shapeopt.c[8.0] Wed Jul 7 18:33:14 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: shapeopt.c[8.0] Wed Jul 7 18:33:14 1993 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" EXPORT char cfname[MYMAXNAMLEN]; EXPORT char echomac[32]; EXPORT char *forcelist[10]; EXPORT FILE *cid; EXPORT Bool debugflg; EXPORT Bool D_flag; EXPORT Bool Var_flag; EXPORT Bool envflg; EXPORT Bool fileflg; EXPORT Bool nostdfile; EXPORT Bool ignoreflg; EXPORT Bool goflg; EXPORT Bool noexflg; EXPORT Bool printflg; EXPORT Bool ruleflg; EXPORT Bool silentflg; EXPORT Bool stdinflg; EXPORT Bool confid; EXPORT Bool rebuildflg; EXPORT Bool expflg; EXPORT Bool noexpflg; EXPORT Bool echoflg; EXPORT Bool nomsgflg; EXPORT Bool novclassflg; EXPORT Bool bpoolflg; EXPORT Bool nobpoolflg; EXPORT Bool forceflg; LOCAL int h_d_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { debugflg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_D_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { D_flag = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_e_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { envflg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_f_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { struct linked_list *shfiles; if (!strcmp(arg,"")) return(1); fileflg = TRUE; if (strcmp(arg,"-") == 0) stdinflg = TRUE; else { if (shapefiles == (struct linked_list *) NIL) { if ((shapefiles = (struct linked_list *) malloc(sizeof(struct linked_list))) == (struct linked_list *) NIL) errexit(10,"malloc"); if ((shapefiles->string = malloc((unsigned) strlen(arg) + sizeof(char))) == NIL) errexit(10,"malloc"); strcpy(shapefiles->string,arg); shapefiles->nextstring = (struct linked_list *) NIL; } else { shfiles = shapefiles; while( shfiles->nextstring != (struct linked_list *) NIL) shfiles = shfiles->nextstring; if((shfiles->nextstring = (struct linked_list *) malloc(sizeof(struct linked_list))) == (struct linked_list *) NIL) errexit(10,"malloc"); shfiles = shfiles->nextstring; if ((shfiles->string = malloc((unsigned) strlen(arg) + sizeof(char))) == NIL) errexit(10,"malloc"); strcpy(shfiles->string, arg); shfiles->nextstring = (struct linked_list *) NIL; } } return(0); } LOCAL int h_force_option(opt,arg) /*ARGSUSED*/ char *opt; char *arg; { int i = 0; forceflg = TRUE; while(forcelist[i] != NIL) { if (i == 10) errexit(36, NIL); i++; } if ((forcelist[i] = malloc((unsigned) (strlen(arg) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(forcelist[i],arg); strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); strcat (shapeflags, arg); strcat (shapeflags, " "); return (0); } LOCAL int h_h_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { return(1); } LOCAL int h_i_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { ignoreflg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_k_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { goflg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_n_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { noexflg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_nomsg_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { nomsgflg = TRUE; atBindNoMsg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_novclass_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { novclassflg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_p_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { printflg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_r_option(opt,arg) /*ARGSUSED*/ char *opt; char *arg; { implicit_suffs[0] = -1; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_R_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { ruleflg = TRUE; strcpy(ruleset,arg); strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); strcat (shapeflags, arg); strcat (shapeflags, " "); return(0); } LOCAL int h_s_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { silentflg = TRUE; stQuietFlag = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_version_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { printf("shape - Version %s\n", version()); printf("AtFS version %s\n", af_version()); printf("AtFS toolkit lib %s\n", atVersion()); exit(0); } LOCAL int h_expandall_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { if (noexpflg) errexit(34,NIL); expflg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_expandnothing_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { if(expflg) errexit(34,NIL); noexpflg = TRUE; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); return(0); } LOCAL int h_echo_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { echoflg = TRUE; strcpy(echomac,arg); return(0); } LOCAL int h_V_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { static int nvars = 0; Bool addplus = FALSE; char *vnp; /* activate a variant from the command line */ if (nvars == MAXCMDLINEVARS) { warning (99, "Too many variant activations from command line"); return 1; } if (!(arg && *arg)) { warning (99, "Usage: shape -V "); return 1; } if (*arg != '+') addplus = TRUE; if ((vnp = (char *)malloc (strlen (arg) + (addplus ? 2 : 1))) == NULL) errexit (10, "malloc"); if (addplus) strcpy (vnp, "+"); else *vnp = '\0'; strcat (vnp, arg); cmd_line_vars[nvars++] = vnp; strcat (shapeflags, "-"); strcat (shapeflags, opt); strcat (shapeflags, " "); strcat (shapeflags, arg); strcat (shapeflags, " "); Var_flag = TRUE; return 0; } LOCAL int h_confid_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { confid = TRUE; return 0; } LOCAL int h_rebuild_option(opt, arg) /*ARGSUSED*/ char *opt; char *arg; { strcpy (rbrule, "bound_configuration_thread"); if ((strrchr (arg, '[') == NIL)) { strcpy (rbtarg, arg); strcpy (rbfile, arg); strcat (rbfile, ".bct"); } else { char *p; strcpy (rbfile, arg); strcpy (rbtarg, arg); if ((p = strchr (rbtarg, '.')) != NIL) *p = '\0'; } rebuildflg = TRUE; return 0; } EXPORT StOptDesc odesc[] = { { "d", PSWITCH, h_d_option, NULL, NULL }, { "D", PSWITCH, h_D_option, NULL, NULL }, { "e", PSWITCH, h_e_option, NULL, NULL }, { "f", PARG, h_f_option, NULL, NULL }, { "force", PARG, h_force_option, NULL, NULL }, { "h", PSWITCH, h_h_option, NULL, NULL }, { "i", PSWITCH, h_i_option, NULL, NULL }, { "k", PSWITCH, h_k_option, NULL, NULL }, { "n", PSWITCH, h_n_option, NULL, NULL }, { "nomsg", PSWITCH, h_nomsg_option, NULL, NULL }, { "novclass", PSWITCH, h_novclass_option, NULL, NULL }, { "p", PSWITCH, h_p_option, NULL, NULL }, { "r", PSWITCH, h_r_option, NULL, NULL }, { "R", PARG, h_R_option, NULL, NULL }, { "s", PSWITCH, h_s_option, NULL, NULL }, { "V", PARG, h_V_option, NULL, NULL }, { "version", PSWITCH, h_version_option, NULL, NULL }, { "confid", PSWITCH, h_confid_option, NULL, NULL }, { "bct", PSWITCH, h_confid_option, NULL, NULL }, { "rebuild", PARG, h_rebuild_option, NULL, NULL }, { "xpon", PSWITCH, h_expandall_option, NULL, NULL }, { "xpoff", PSWITCH, h_expandnothing_option, NULL, NULL }, { "echo", PARG, h_echo_option, NULL, NULL }, { (char *) NULL, 0, NULL, NULL, NULL } }; shapetools-1.4pl6.orig/src/shape/sighand.c100444 2013 145 4232 5416575020 16615 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - sighand.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: sighand.c[8.0] Wed Jul 7 18:33:17 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: sighand.c[8.0] Wed Jul 7 18:33:17 1993 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" EXPORT void catch_sigs () { /* * Setup signal handlers for various signals. Previous handlers * are saved. On receipt of a signal, the * original handler for this signal will be invoked after specified * action has been taken. */ Sigret_t die2(), die8(), die10(), die11(), die15(); signal (SIGINT, die2); signal (SIGFPE, die8); signal (SIGBUS, die10); signal (SIGSEGV, die11); signal (SIGTERM, die15); } Sigret_t die2 () { signal(SIGINT,SIG_IGN); errexit(23,"\0"); } Sigret_t die8 () { signal(SIGINT,SIG_IGN); fprintf(stderr, "Oh! Oh! .... this was a floating exception -- goodbye.\n"); af_cleanup (); cleanup_links(link_reg); exit (1); } Sigret_t die10 () { fprintf(stderr, "Oh! Oh! .... this was a buserror -- goodbye.\n"); fprintf(stderr, "Dumping core.\n"); af_cleanup (); cleanup_links(link_reg); kill (getpid(), SIGQUIT); } Sigret_t die11 () { signal(SIGINT,SIG_IGN); fprintf(stderr, "Oh! Oh! .... this was a segmentation violation -- goodbye.\n"); fprintf(stderr, "Dumping core.\n"); af_cleanup (); cleanup_links(link_reg); kill (getpid(), SIGQUIT); } Sigret_t die15 () { signal(SIGINT,SIG_IGN); af_cleanup(); cleanup_links(link_reg); exit(1); } shapetools-1.4pl6.orig/src/shape/std.c100444 2013 145 21437 5505372111 16013 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - std.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) and Wolfgang Obst * * $Header: std.c[8.0] Mon Dec 20 19:52:39 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: std.c[8.0] Mon Dec 20 19:52:39 1993 axel@cs.tu-berlin.de frozen $"; #endif /* reearrangement of suffixes ??? */ /* implicit predefined rules with more than one target ??? */ #include "shape.h" #define STDRULETABSIZE 64 #define MAXIMPLICIT STDRULETABSIZE EXPORT struct rules *stdruletab[STDRULETABSIZE]; EXPORT int lastrule; /* char *stdsuff = ".o .c .c~ .mod .mod~ .sym .def .def~ .p .p~ .f .f~ .F .F~ .r .r~ .y .y~ .l .l~ .s .s~ .sh .sh~ .h .h~ "; */ /* .x~ suffixes are not supported */ EXPORT char *stdsuff = ".o .c .mod .sym .def .a .p .f .F .r .y .l .s .sh .h"; EXPORT char *shaperules = "%.o:%.c %.o:%.l %.o:%.y %.o:%.s %.o:%.r %.o:%.F %.o:%.f %.o:%.mod %.o:%.p %.c:%.l %.c:%.y %.sym:%.def %.a:%.c %:%.sh %:%.r %:%.F %:%.f %:%.p %:%.mod %:%.c "; EXPORT int implicit_suffs[MAXIMPLICIT] = {19, /* 19 .c */ 18, /* 18 .mod */ 17, /* 17 .p */ 16, /* 16 .f */ 15, /* 15 .F */ 14, /* 14 .r */ 13, /* 13 .sh */ 0, /* 12 .c.a */ 9, /* 11 .def.sym */ 2, /* 10 .y.c */ 1, /* 9 .l.c */ 11, /* 8 .p.o */ 10, /* 7 .mod.o */ 8, /* 6 .f.o */ 7, /* 5 .F.o */ 6, /* 4 .r.o */ 5, /* 3 .s.o */ 4, /* 2 .y.o */ 3, /* 1 .l.o */ 12, /* 0 .c.o */ -1 }; LOCAL char *stdrules[] = { /* ".c.a", "\t$(CC) -c $(CFLAGS) $(vflags) $<", "\tar rv $@ $*.o", "\trm -f $*.o", */ "%.a", /* 0 */ "%.c", "+(CC)", "+(CFLAGS)", "+(vflags)", "\t@echo shape - executing: $(CC) -c $(CFLAGS) $#;", "\t@$(CC) $(CFLAGS) -E %.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.c\\(\".*\\)$$;\\1$#\\2;' > %.i;", "\t@$(CC) -c $(CFLAGS) %.i;", "\t@rm %.i;", "\tar rv %.a %.o", "\trm -f %.o", /* ".l.c", "\t$(LEX) $(LFLAGS) $<", "\tmv lex.yy.c $@", */ "%.c", /* 1 */ "%.l", "+(LEX)", "+(LFLAGS)", "\t$(LEX) $(LFLAGS) %.l", "\tmv lex.yy.c %.c", /* ".y.c", "\t$(YACC) $(YFLAGS) $<", "\tmv y.tab.c $@", */ "%.c", /* 2 */ "%.y", "+(YACC)", "+(YFLAGS)", "\t$(YACC) $(YFLAGS) %.y", "\tmv y.tab.c %.c", /* ".l.o", "\t$(LEX) $(LFLAGS) $<", "\t$(CC) $(CFLAGS) $(vflags) -c lex.yy.c", "\trm lex.yy.c", "\tmv lex.yy.o $@", */ "%.o", /* 3 */ "%.l", "+(LEX)", "+(LFLAGS)", "+(CC)", "+(CFLAGS)", "+(vflags)", "\t@echo shape - executing: $(LEX) $(LFLAGS) $#;", "\t@$(LEX) $(LFLAGS) %.l", "\t@$(CC) $(CFLAGS) -E lex.yy.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.l\\(\".*\\)$$;\\1$#\\2;' > lex.yy.i;", "\t@echo shape - executing: $(CC) $(CFLAGS) $(vflags) -c lex.yy.c", "\t@$(CC) $(CFLAGS) $(vflags) -c lex.yy.i", "\trm lex.yy.c", "\t@rm lex.yy.i", "\tmv lex.yy.o %.o", /* ".y.o", "\t$(YACC) $(YFLAGS) $<", "\t$(CC) $(CFLAGS) $(vflags) -c y.tab.c", "\trm y.tab.c", "\tmv y.tab.o $@", */ "%.o", /* 4 */ "%.y", "+(YACC)", "+(YFLAGS)", "+(CC)", "+(CFLAGS)", "+(vflags)", "\t@echo shape - executing: $(YACC) $(YFLAGS) $#;", "\t@$(YACC) $(YFLAGS) %.y", "\t@$(CC) $(CFLAGS) -E y.tab.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.y\\(\".*\\)$$;\\1$#\\2;' > y.tab.i;", "\t@echo shape - executing: $(CC) $(CFLAGS) $(vflags) -c y.tab.c", "\t@$(CC) $(CFLAGS) $(vflags) -c y.tab.i", "\trm y.tab.c", "\t@rm y.tab.i", "\tmv y.tab.o %.o", /* ".s.o", "\t$(AS) $(ASFLAGS) -o $@ $<", */ "%.o", /* 5 */ "%.s", "+(AS)", "+(ASFLAGS)", "\t$(AS) $(ASFLAGS) -o %.o %.s", /* ".r.o", "\t$(FC) $(RFLAGS) $(FFLAGS) -c $<", */ "%.o", /* 6 */ "%.r", "+(FC)", "+(RFLAGS)", "+(FFLAGS)", "\t$(FC) $(RFLAGS) $(FFLAGS) -c %.r", /* ".F.o", "\t$(FC) $(FFLAGS) -c $<", */ "%.o", /* 7 */ "%.F", "+(FC)", "+(FFLAGS)", "\t$(FC) $(FFLAGS) -c %.F", /* ".f.o", "\t$(FC) $(FFLAGS) -c $<", */ "%.o", /* 8 * */ "%.f", "+(FC)", "+(FFLAGS)", "\t$(FC) $(FFLAGS) -c %.f", /* ".def.sym", "\t$(M2C) $(M2FLAGS) $<", */ "%.sym", /* 9 */ "%.def", "+(M2C)", "+(M2FLAGS)", "\t$(M2C) $(M2FLAGS) %.def", /* ".mod.o", "\t$(M2C) $(M2FLAGS) $<", */ "%.o", /* 10 */ "%.mod", "+(M2C)", "+(M2FLAGS)", "\t$(M2C) $(M2FLAGS) %.mod", /* ".p.o", "\t$(PC) $(PFLAGS) -c $<", */ "%.o", /* 11 */ "%.p", "+(PC)", "+(PFLAGS)", "\t$(PC) $(PFLAGS) -c %.p", #ifdef NOVGDB /* ".c.o", "\t$(CC) $(CFLAGS) $(vflags) -c $<", */ "%.o", /* 12 */ "%.c", "+(CC)", "+(CFLAGS)", "+(vflags)", "\t@echo shape - executing: $(CC) -c $(CFLAGS) %.c;", "\t@$(CC) -c $(CFLAGS) %.c;", "\t@rm %.i;", #else /* NOVGDB */ /* ".c.o", "\t$(CC) $(CFLAGS) $(vflags) -c $<", */ "%.o", /* 12 */ "%.c", "+(CC)", "+(CFLAGS)", "+(vflags)", "\t@echo shape - executing: $(CC) -c $(CFLAGS) $#;", "\t@$(CC) $(CFLAGS) -E %.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.c\\(\".*\\)$$;\\1$#\\2;' > %.i;", "\t@$(CC) -c $(CFLAGS) %.i;", "\t@rm %.i;", #endif /* NOVGDB */ /* ".sh", "\tcat $< >$@; chmod +x $@", */ "%", /* 13 */ "%.sh", "\tcat %.sh >%; chmod +x %", /* ".r", "\t$(FC) $(RFLAGS) $(FFLAGS) $(LDFLAGS) $< -o $@", */ "%", /* 14 */ "%.r", "+(FC)", "+(RFLAGS)", "+(FFLAGS)", "+(LDFLAGS)", "\t$(FC) $(RFLAGS) $(FFLAGS) $(LDFLAGS) %.r -o %", /* ".F", "\t$(FC) $(FFLAGS) $(LDFLAGS) $< -o $@", */ "%", /* 15 */ "%.F", "+(FC)", "+(FFLAGS)", "+(LDFLAGS)", "\t$(FC) $(FFLAGS) $(LDFLAGS) %.F -o %", /* ".f", "\t$(FC) $(FFLAGS) $(LDFLAGS) $< -o $@", */ "%", /* 16 */ "%.f", "+(FC)", "+(FFLAGS)", "+(LDFLAGS)", "\t$(FC) $(FFLAGS) $(LDFLAGS) %.f -o %", /* ".p", "\t$(PC) $(PFLAGS) $(LDFLAGS) $< -o $@", */ "%", /* 17 */ "%.p", "+(PC)", "+(PFLAGS)", "+(LDFLAGS)", "\t$(PC) $(PFLAGS) $(LDFLAGS) %.p -o %", /* ".mod", "\t$(M2C) $(M2FLAGS) $(LDFLAGS) $< -e $@ -o $@", */ "%", /* 18 */ "%.mod", "+(M2C)", "+(M2FLAGS)", "+(LDFLAGS)", "\t$(M2C) $(M2FLAGS) $(LDFLAGS) %.mod -e % -o %", /* ".c", "\t$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@", */ "%", /* 19 */ "%.c", "+(CC)", "+(CFLAGS)", "+(LDFLAGS)", "\t@echo shape - executing: $(CC) $(CFLAGS) $# -o %;", "\t@$(CC) $(CFLAGS) -E %.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.c\\(\".*\\)$$;\\1$#\\2;' > %.i;", "\t@$(CC) $(CFLAGS) $(LDFLAGS) %.i -o %;", "\t@rm %.i;", /* ".SUFFIXES:", ".o",".c",".c~",".mod",".mod~",".sym",".def",".def~",".p",".p~",".f",".f~",".F",".F~",".r",".r~",".y",".y~",".l",".l~",".s",".s~",".sh",".sh~",".h",".h~", */ "0" }; LOCAL struct cmds *newcmds() { register struct cmds *reval; reval = (struct cmds *) malloc(sizeof (struct cmds)); if (!reval) errexit(10,"malloc"); reval->nextcmd = (struct cmds *) 0; reval->command = (char *)0; return reval; } EXPORT void add_stdrules() { register int i = 0, j = 0, k = 0; register struct cmds *comm; while(strcmp(stdrules[i],"0") != 0) { if (is_pattern (stdrules[i])) { if((stdruletab[k] = (struct rules *) malloc( sizeof(struct rules))) == (struct rules *) NIL) errexit(10,"malloc"); memset ((char *)stdruletab[k], 0, sizeof (struct rules)); stdruletab[k]->name = stdrules[i]; stdruletab[k]->next = (struct rules *)NIL; i++; } if(stdrules[i][0] != '\t') { while ((stdrules[i][0] != '\t') && (stdrules[i][0] != '+') && (strcmp(stdrules[i],"0") != 0)) { stdruletab[k]->deplist = stdrules[i]; stdruletab[k]->firstdep = stdrules[i]; i++; } } if (stdrules[i][0] == '+') { j = 0; while (stdrules[i][0] == '+') { stdruletab[k]->heritage[j] = stdrules[i]; i++; j++; } stdruletab[k]->heritage[j] = NIL; } else stdruletab[k]->heritage[0] = NIL; if (stdrules[i][0] == '\t') { comm = stdruletab[k]->cmdlist = newcmds(); if (stdrules[i][0] == '\t') do { comm->command = stdrules[i]; comm->nextcmd = newcmds(); comm = comm->nextcmd; i++; } while (stdrules[i][0] == '\t'); stdruletab[k]->targetlist[0] = stdruletab[k]->name; stdruletab[k]->targetlist[1] = NIL; } k++; } stdruletab[k] = (struct rules *) NIL; lastrule = k - 1; } shapetools-1.4pl6.orig/src/shape/strbuf.c100444 2013 145 11065 5405656434 16536 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - strbuf.c * * by Steve Emerson (steve@unidata.ucar.edu) * * $Header: strbuf.c[8.0] Thu Jun 10 18:29:55 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: strbuf.c[8.0] Thu Jun 10 18:29:55 1993 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" typedef struct str_buf { char *buf; /* Malloc(3)ed string buffer. NUL terminated. */ int len; /* Current string-length. Excludes NUL. */ int max; /* Maximum possible string-length. Excludes NUL. */ } str_buf; /* * Insure that a string-buffer can contain a string of the given size. * This is done by increasing the size of a string-buffer * via a geometric progression based on the golden ratio (which I happen * to like) until it can hold the specified number of characters. */ static str_buf* sbinsure(sb, len) str_buf *sb; /* String-buffer */ int len; /* Number of characters to insure */ { if (sb != NULL) { if (len > sb->max) { if (sb->buf == NULL) { sb->buf = malloc((unsigned)(len+1)); if(sb->buf == NIL) errexit(10,"malloc"); } else { int n = sb->max + 1; while (n < len+1) n *= 1.618034; /* Golden ratio (approx.) */ sb->buf = realloc(sb->buf, (unsigned)n); if(sb->buf == NIL) errexit(10,"realloc"); len = n - 1; } if (sb->buf == NULL) { sb = NULL; } else { sb->max = len; } } } return sb; } /* * Clear a string-buffer. */ static str_buf* sbclear(sb) str_buf *sb; /* String-buffer */ { if (sb != NULL) { sb->buf = NULL; sb->len = 0; sb->max = 0; } return sb; } /* * Copy a string to a string-buffer. The string buffer will expand as * necessary to accomodate the input string. On failure, it will return * NULL. */ str_buf* sbcpy(sb, string, len) str_buf *sb; /* String-buffer */ char *string; /* String to be copied */ int len; /* Length of string. Excludes NUL */ { if (sb != NULL) { if (sbinsure(sb, len) == NULL) return NULL; if (string == NULL) { sb->buf[0] = 0; sb->len = 0; } else { strncpy(sb->buf, string, len); sb->len = len; } } return sb; } /* * Initialize a string-buffer. */ str_buf* sbinit(sb, string, len) str_buf *sb; /* String-buffer */ char *string; /* Initial string */ int len; /* String length */ { return sbcpy(sbclear(sb), string, len); } /* * Instantiate a string-buffer. Returns NULL on failure. The specified, * initial, maximum string length doesn't count the terminating NUL. */ str_buf* sbnew(max) int max; /* Initial maximum string length */ { str_buf *sb; if((sb = (str_buf*)malloc((unsigned)sizeof(str_buf))) == (str_buf *)NIL) errexit(10,"malloc"); return sbinsure(sbclear(sb), max); } /* * Free a string-buffer. */ void sbfree(sb) str_buf *sb; /* String-buffer */ { if (sb != NULL) { if (sb->buf != NULL) free(sb->buf); free((char*)sb); } } /* * Append a string to a string-buffer. The string-buffer will expand as * necessary to accomodate the catenated string. The function returns NULL * on failure. */ str_buf* sbcat(sb, string, len) str_buf *sb; /* String-buffer */ char *string; /* String to be appended */ int len; /* Length of string. Excludes NUL */ { if (sb != NULL) { if (sbinsure(sb, sb->len+len) == NULL) return NULL; strncpy(sb->buf+sb->len, string, len); sb->len += len; } return sb; } /* * Return a pointer to a string-buffer's string. The string is guaranteed * to be NUL terminated. */ char* sbstr(sb) str_buf *sb; /* String-buffer */ { if (sb == NULL) return NULL; if (sb->buf != NULL) sb->buf[sb->len] = 0; return sb->buf; } /* * Return the length of a string-buffer's string. Excludes the terminating * NUL. */ int sblen(sb) str_buf *sb; /* String-buffer */ { return sb == NULL ? 0 : sb->buf == NULL ? 0 : sb->len; } shapetools-1.4pl6.orig/src/shape/varsec.c100444 2013 145 24376 5566652045 16527 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - varsec.c * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) and Wolfgang Obst * * $Header: varsec.c[8.0] Thu May 19 13:58:27 1994 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: varsec.c[8.0] Thu May 19 13:58:27 1994 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" EXPORT struct vardef variantDefs[MAXVARDEFS]; EXPORT char *curvar[MAXVARIANTS] = {"","","","","","","","", "","","","","","","","", "","","","","","","","", "","","","","","","",""}; EXPORT struct varclass variantClasses[MAXVCLASS]; EXPORT int lastVariantDef = 0; EXPORT int variants_active = 0; EXPORT int activeVariants[MAXVARIANTS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; LOCAL int vardef_position (); LOCAL Bool attrvar (); EXPORT void vardef_end () { if (variantDefs[lastVariantDef].name) { register int i; for (i = 0; cmd_line_vars[i] && (i < MAXCMDLINEVARS); i++) { if (strcmp (cmd_line_vars[i]+1, variantDefs[lastVariantDef].name)) continue; activate_variant (cmd_line_vars[i]); } } } EXPORT void vclassdef (name, varnames) char *name; struct stringlist *varnames; { register int k, l; struct stringlist *nextvar; k = 0; while (variantClasses[k].name) { if (!strcmp (variantClasses[k].name, name)) errexit (39, name); k++; if (k == MAXVCLASS) errexit (27, "vclass definitions"); } variantClasses[k].name = check_strdup (name); variantClasses[k].active = -1; l = 0; nextvar = varnames; while (nextvar && nextvar->string) { variantClasses[k].variants[l] = check_strdup (nextvar->string); l++; nextvar = nextvar->next; } variantClasses[k].variants[l] = NIL; } EXPORT Bool check_vclass(varname) char *varname; { register int i = 0, j = 0; while (variantClasses[i].name) { j = 0; while (variantClasses[i].variants[j] != NIL) { if (strcmp (variantClasses[i].variants[j],varname) == 0) { if ((variantClasses[i].active != -1) && (variantClasses[i].active != j)) { if (novclassflg) { stLog (" incompatible variant combination with ", ST_LOG_WARNING | ST_LOG_NONL); stLog (varname, ST_LOG_MSGERR | ST_LOG_NONL); stLog (", vclass ", ST_LOG_MSGERR | ST_LOG_NONL); stLog (variantClasses[i].name, ST_LOG_MSGERR); } else return FALSE; } variantClasses[i].active = j; } j++; } i++; } if (!variantClasses[i].name) return TRUE; /*NOTREACHED*/ return FALSE; } EXPORT void reset_vclass() { register int i = 0; while (variantClasses[i].name) { variantClasses[i].active = -1; i++; } } EXPORT Bool is_varname (string) char *string; { char *p; if(string == NIL) return(FALSE); if(string[0] != '+') return(FALSE); else if (string[1] == '\0') return(TRUE); p = &string[1]; return (vardef_position (p) > -1); } EXPORT int activate_variant (varname) char *varname; { char lvarname[64]; int curi, new_activations = 0, varpos; if (varname && (*varname == '+')) strcpy (lvarname, varname+1); else return new_activations; curi = 0; while (curi < variants_active) { if (!strcmp (curvar[curi], lvarname)) return new_activations; curi++; if (curi == MAXVARIANTS) errexit (37,NIL); } if ((curvar[curi] = malloc ((unsigned) (strlen (lvarname) + sizeof (char)))) == NIL) errexit (10,"malloc"); varpos = vardef_position (lvarname); if ( varpos > -1 ) { activeVariants[variants_active] = varpos; variants_active++; new_activations = 1; strcpy (curvar[curi], lvarname); attrvar (lvarname, NIL, (Af_set *) NIL); } return new_activations; } EXPORT void de_activate (varname) char *varname; { register int i = 0, j; int varpos = vardef_position (varname); struct vardef *this_vardef = (void *)NIL; if (varpos < 0) return; this_vardef = &variantDefs[varpos]; while(variantClasses[i].name) { if ((variantClasses[i].active != -1) && (!strcmp(variantClasses[i].variants[variantClasses[i].active], varname))) variantClasses[i].active = -1; i++; } for ( j = 0; j < variants_active; j++ ) { if (activeVariants[j] == varpos) { register int k; for (k = j; k < variants_active; k++) { activeVariants[k] = activeVariants[k+1]; } variants_active--; activeVariants[variants_active] = -1; } } if (this_vardef->vpath) { /* * The following block (kind of) fixes a bug * that leads to eventual corruption of the curvpath * variable. However, the fix introduces a new bug: * the vpath element of a de_activated variant is * completely wiped out, even if another, still * active variant has the same vpath. We hope that * this case is unlikely. */ register int yucc, urgh; /* yes, YUCC! URGH! */ for (yucc = 0; curvpath[yucc] && (yucc < MAXVPATH); yucc++) { if (strcmp (this_vardef->vpath, curvpath[yucc])) continue; if (yucc == MAXVPATH-1) { curvpath[yucc] = NIL; } else { for (urgh = yucc+1; curvpath[urgh-1]; urgh++) curvpath[urgh-1] = curvpath[urgh]; yucc--; } } } } EXPORT char *active_variants () { /* * returns a space separated list of all currently active variants. * The value is maintained as static memory. */ static sb_ptr varbuf; char *av; register int i; if (!varbuf) varbuf = sbnew (1); varbuf = sbinit (varbuf, "", 0); for (i = 0; i < variants_active; i++) { varbuf = sbcat (varbuf, i ? " +" : "+", 1); varbuf = sbcat (varbuf, curvar[i], strlen (curvar[i])); } av = (av=sbstr (varbuf)) ? check_strdup (av) : av; sbfree (varbuf); return av; } EXPORT void print_variant_class (dest, vcdef_p) FILE * dest; struct varclass * vcdef_p; { /* * print a Shapefile variant class definition to the file pointed to * by "dest". "dest" must point to an open FILE. The pointer to * the variant class definition structure shall be non-nil, and shall * contain a valid variant class definition. */ register int v_count = 0; register char * vn_p; if ((vcdef_p == NULL) || (vcdef_p->name == NULL)) return; (void) fprintf (dest, "vclass %s ::= (", vcdef_p->name); if ((vn_p = vcdef_p->variants[v_count])) { (void) fputs (vn_p, dest); v_count++; } while ((vn_p = vcdef_p->variants[v_count])) { (void) fprintf (dest, ", %s", vn_p); v_count++; } (void) fputs (")\n", dest); } EXPORT void print_variant_definition (dest, vardef_p) FILE * dest; struct vardef * vardef_p; { /* * print the full Shapefile variant definition to the file pointed to * by "dest". "dest" must point to an open FILE. The pointer to * the variant definition structure shall be non-nil, and shall * contain a valid variant definition. */ register int vm_count = 0; register char * vm_p; if ((vardef_p == NULL) || (vardef_p->name == NULL)) return; (void) fprintf (dest, "%s:+\n", vardef_p->name); (void) fprintf (dest, "\tvflags = %s\n", (vm_p = vardef_p->vflags) ? vm_p : ""); (void) fprintf (dest, "\tvpath = %s\n", (vm_p = vardef_p->vpath) ? vm_p : ""); while ((vm_p = vardef_p->vmacros[vm_count])) { (void) fprintf (dest, "\t%s\n", vm_p); vm_count++; } fputs ("\n", dest); } EXPORT void print_variant_names (destination) FILE * destination; { /* * print a list with the names of all known variants to the * file pointed to by "destination". */ register int vd_count = 0; register char * varname_p; (void) fputs ("#\n#\tVariant Definitions\n#\n\n", destination); if ((varname_p = variantDefs[vd_count].name)) { (void) fputs (varname_p, destination); vd_count++; }; while ((varname_p = variantDefs[vd_count].name)) { (void) fputs (" ", destination); (void) fputs (varname_p, destination); vd_count++; }; (void) fputs ("\n", destination); } LOCAL int vardef_position (varname) char *varname; { register int k = 0; if(varname == NIL) return -1; while ((k < MAXVARDEFS) && variantDefs[k].name) { if (!strcmp(variantDefs[k].name, varname)) return k; k++; } return -1; } LOCAL Bool attrvar(name, value, set) char *name; /*ARGSUSED*/ char *value; Af_set *set; { /* set variant path & variant flags */ register int varpos = vardef_position (name), i = 0; register char *ind; char pathlist[PATH_MAX]; if (check_vclass(name) != TRUE) errexit(30,name); if (varpos < 0) errexit (19, name); while (curvpath[i] != NIL) i++; if (variantDefs[varpos].vpath != NIL) { strcpy (pathlist, variantDefs[varpos].vpath); while(( ind = strchr(pathlist,':')) != NIL) { *ind = '\0'; if((pathlist[0] == '.') && (pathlist[1] == '.')) { if((curvpath[i] = malloc((unsigned) (strlen(prev_dir) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(curvpath[i],prev_dir); } else { if ((curvpath[i] = malloc((unsigned) (strlen(pathlist) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(curvpath[i],pathlist); } ind++; strcpy(pathlist,ind); i++; } if((pathlist[0] == '.') && (pathlist[1] == '.')) { if((curvpath[i] = malloc((unsigned) (strlen(prev_dir) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(curvpath[i],prev_dir); } else { if ((curvpath[i] = malloc((unsigned) (strlen(pathlist) + sizeof(char)))) == NIL) errexit(10,"malloc"); strcpy(curvpath[i],pathlist); } } return TRUE; } shapetools-1.4pl6.orig/src/shape/parser.c100444 2013 145 101706 5430516401 16532 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - pa.c * * by Juergen.Nickelsen@cs.tu-berlin.de * * $Header: parser.c[8.0] Fri Aug 6 20:12:26 1993 nickel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: parser.c[8.0] Fri Aug 6 20:12:26 1993 nickel@cs.tu-berlin.de frozen $"; #endif #include #include #include "shape.h" #include "parser.h" #include "mfiles.h" /* This variable is exported: */ int parse_errors = 0 ; /* number of parse_errors */ #ifdef DEBUG int dump_parsed_definitions ; #endif /* local declarations and definitions */ /* several string literals and their length: */ #define STRING_LENGTH(s) (sizeof(s) - 1) /* ONLY for literals! */ #define INCLUDE_STRING "include" #define INCLUDE_LENGTH STRING_LENGTH(INCLUDE_STRING) #define VCLASS_STRING "vclass" #define VCLASS_LENGTH STRING_LENGTH(VCLASS_STRING) #define VCLASS_SEPARATOR "::=" #define VCLSEP_LENGTH STRING_LENGTH(VCLASS_SEPARATOR) #define RULESEC_STRING "RULE-SECTION" #define RULESEC_LENGTH STRING_LENGTH(RULESEC_STRING) #define VARSEC_STRING "VARIANT-SECTION" #define VARSEC_LENGTH STRING_LENGTH(VARSEC_STRING) #define ENDSEC_STRING "END-" #define ENDSEC_LENGTH STRING_LENGTH(ENDSEC_STRING) /* constants for the type of a top-level line */ #define UNKNOWN_LINE 0 /* not recognized */ #define VCLASS_LINE 1 /* vclass definition */ #define DEPRULE_LINE 2 /* dependency rule */ #define VARDEF_LINE 3 /* variant definition */ #define MACRO_LINE 4 /* macro definition with = */ #define ADDMAC_LINE 5 /* macro definition with += */ #define SUBMAC_LINE 6 /* macro definition with -= */ #define VARMAC_LINE 7 /* macro definition with := */ #define SELRULE_LINE 8 /* selection rule */ #define RULESEC_LINE 9 /* beginning of rule section */ #define VARSEC_LINE 10 /* beginning of variant section */ #define INCLUDE_LINE 11 /* "include" line */ #define DOUBLEC_LINE 12 /* line with double colon */ /* Constants for parse_selection_rule() and parse_variant_definition(): * Has definition been found in a SECTION (old style) or not. */ #define IN_SECTION 1 #define NO_SECTION 0 /* possible components of selection rule or variant names, this is * essentially [0-9_A-Za-z] */ #define RULE_OR_VAR_NAME_COMPONENTS \ "0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" /* local Functions */ static int recognize_line A((char **linep, struct stringlist **name_list_p)) ; static void skip_over_rulebody A((void)) ; static char *get_variant_name A((char **linep)) ; static struct stringlist *collect_names A((char **linep)) ; static void parse_rule_or_var_section A((char *line)) ; static void parse_macro_definition A((char *line, int type, struct stringlist *name_list)) ; static void parse_vclass_definition A((char *line)) ; static void parse_dependency_rule A((char *line, struct stringlist *name_list)) ; static int end_of_section A((char *line, char *section)) ; static void parse_selection_rule A((char *line, struct stringlist *name_list, int in_section)) ; static void variant_section_body A((char *line)) ; static void rule_section_body A((char *line)) ; static void parse_variant_definition A((char *line, struct stringlist *name_list, int in_section)) ; static void parse_include_statement A((char *line)) ; static int rule_or_variant_body A((char *line)) ; static void clean_from_comment A((char *line)) ; static void clean_selrule_from_comment A((char *line)) ; /* local Variables */ static MFILE *currentmf ; static jmp_buf jmp_toplevel ; /* int parse_file(filename): toplevel parse funtion */ int parse_file(filename) char *filename ; { /* It does: - read in the specified file with mf_readin() - for each line at the top-level do the following: - skip over leading blanks - look at the first character of the line. It may indicate a comment line, an empty line, or a line beginning with TAB, which is not allowed at top-level. - call recognize_line() to determine the type of a non-empty line. recognize_line() also reads the "names" (target, rule, variant, or macro names) it encounters before seeing a "magic token" which identifies the line. - call the appropriate parse function for this line. This function may read more lines. - if an error is found, a parse function may jump back to the top-level with longjmp() (usually called by parsing_error()). The entry point is saved in jmp_toplevel. The current MFILE * and jmp_toplevel are global to this module in order to be accessible by the other parse functions. In case of an recursive invokation of parse_file() by parse_include_statement() they are saved in local variables of parse_include_statement(). */ char *line ; /* pointer to current line */ int line_type ; /* type of line */ char *line_begin ; /* save ptr to beginning of line */ struct stringlist *name_list ; /* list of "names" collected * before type of line is * determined */ #ifdef DEBUG dump_parsed_definitions = getenv("SHAPE_PARSER_DUMP") ; #endif /* check if standard input is to be parsed */ if (strcmp(filename, "-")) { currentmf = mf_readin(filename) ; } else { currentmf = mf_readin_stdin() ; } if (currentmf == NULL) { /* mf_readin() failed */ return FALSE ; } /* jump target for parsing_error() */ setjmp(jmp_toplevel) ; /* top-level loop */ while ((line = mf_nextline(currentmf))) { line_begin = line ; line = skip_over_blanks(line) ; switch (*line) { /* look at first character */ case '#': /* comment or RULE- or VARIANT-SECTION */ if (*(line + 1) == '%') { parse_rule_or_var_section(line) ; } /* else comment: ignore */ break ; case '\t': /* tab at beginning only in rule or * variant bodies allowed (or line * must be empty) */ line = skip_over_whitespace(line) ; if (*line != '\0' && *line != '#') { parsing_error("line with tab character at top-level", line, NULL) ; } break ; case '\0': /* empty line */ break ; default: line_type = recognize_line(&line, &name_list) ; /* line now points to first character after magic token, * name_list contains names found up to that point in * correct order. */ clean_from_comment(line) ; switch (line_type) { case UNKNOWN_LINE: parsing_error("line not recognized", line_begin, NULL) ; break ; case VCLASS_LINE: parse_vclass_definition(line) ; break ; case DEPRULE_LINE: parse_dependency_rule(line, name_list) ; break ; case VARDEF_LINE: parse_variant_definition(line, name_list, NO_SECTION) ; break ; case MACRO_LINE: parse_macro_definition(line, ' ', name_list) ; break ; case ADDMAC_LINE: parse_macro_definition(line, '+', name_list) ; break ; case SUBMAC_LINE: parse_macro_definition(line, '-', name_list) ; break ; case VARMAC_LINE: parse_macro_definition(line, ':', name_list) ; break ; case SELRULE_LINE: parse_selection_rule(line, name_list, NO_SECTION) ; break ; case INCLUDE_LINE: parse_include_statement(line) ; break ; case DOUBLEC_LINE: parsing_warning("double colon treated as single colon", line, NULL) ; parse_dependency_rule(line, name_list) ; break ; default: fatal("This can't happen", "invalid line type at top-level") ; } } } return TRUE ; } /* parse functions for top-level items */ /* parse an include file */ static void parse_include_statement(line) char *line ; { char *includefilenames ; /* rest of line after "include" */ MFILE *save_mf ; /* to save currentmf in */ jmp_buf save_jmpbuf ; /* to save jmp_toplevel in */ int retval ; /* return value of parse_file() */ struct stringlist *name_list ; /* names of include files to parse */ struct stringlist *curname ; /* current include file to parse */ char incpath[PATH_MAX]; /* construct include file name here */ char *st_env ; /* ST_ENV environment */ line = skip_over_whitespace(line) ; includefilenames = expandmacro(line) ; name_list = collect_names(&includefilenames) ; if (name_list == NULL) { parsing_warning("name of include file(s) missing", line, line) ; } else { /* save global state */ memcpy (save_jmpbuf, jmp_toplevel, sizeof(jmp_buf)) ; save_mf = currentmf ; /* iterate through name_list */ for (curname = name_list; curname != NULL; curname = curname->next) { retval = parse_file(curname->string) ; if (retval == FALSE) { /* try to look for file in standard shape include path */ if ((st_env = getenv(ST_ENV)) != 0) { strcpy(incpath, st_env) ; strcat(incpath, ST_ENV_SHAPELIB) ; strcat(incpath, "/") ; strcat(incpath, curname->string) ; /* try again */ retval = parse_file(incpath) ; } } if (retval == FALSE) { currentmf = save_mf ; parsing_warning("could not open include file", line, curname->string) ; } } free_stringlist(name_list) ; /* restore global state */ currentmf = save_mf ; memcpy (jmp_toplevel, save_jmpbuf, sizeof(jmp_buf)) ; } } /* parse dependency rule. Target names are in name_list. */ static void parse_dependency_rule(line, name_list) char *line ; struct stringlist *name_list ; { struct stringlist *targets = NULL ; /* targets of rule */ struct stringlist *deps = NULL ; /* dependents of rule */ struct stringlist *macros = NULL ; /* macros targets depend on */ struct stringlist *cmds = NULL ; /* shell commands to build */ /* names of targets are in name_list, *if* */ if (name_list == NULL) { parsing_error("dependency rule must begin with target", line, NULL) ; } targets = name_list ; /* dependents are following */ deps = collect_names(&line) ; /* line may now point to second ':', then collect macros * the target depends on */ if (*line == ':') { line++ ; macros = collect_names(&line) ; } /* line must point to command, comment, or end of line now */ switch (*line) { case ';': /* first command line */ if (skip_over_whitespace(line + 1) != '\0') { cmds = push_stringlist(line + 1, cmds, 0) ; } break ; case '#': /* "virtual" end of line... */ case '\0': /* and the real one */ break ; default: parsing_error("Syntax error in dependency rule", line, NULL) ; } /* collect command lines for shell script. The shell script ends * on a non-comment line that does not begin with a TAB. */ while ((line = mf_nextline(currentmf)) != NULL) { char *first_nonblank = skip_over_whitespace(line) ; if (*line != '\t' && *first_nonblank != '#') { break ; /* end of shell script */ } /* give only lines with real commands to the shell */ if (*first_nonblank != '\0' && *first_nonblank != '#') { cmds = push_stringlist(line, cmds, 0) ; } } /* make first non-command line next to be read if ! EOF */ if (line != NULL) { mf_prevline(currentmf) ; } /* cmds are in still in reverse order! */ cmds = revert_stringlist(cmds) ; queue_dependency_rule(targets, deps, macros, cmds) ; } /* collect the names (usually of targets or dependants) from a string. * Returned is a stringlist with the names in correct order. * Stops at the first character which is neither namecomponent nor * whitespace. The pointer linep points to is set to the position * where collect_names() stopped collecting. */ static struct stringlist *collect_names(linep) char **linep ; /* pointer to pointer to string */ { struct stringlist *names = NULL ; /* list of names */ struct stringlist *last = NULL ; /* last member */ struct stringlist *tmp ; while (strlen(*linep)) { /* something is left */ *linep = skip_over_whitespace(*linep) ; /* stop here if no name is found */ if (is_no_namecomponent(**linep)) { break ; } /* append name to list */ tmp = (struct stringlist *) check_malloc(sizeof(struct stringlist)) ; if (last == NULL) { last = names = tmp ; } else { last->next = tmp ; last = last->next ; } last->next = NULL ; last->string = get_name(linep) ; last->freeable = 1 ; } return names ; } /* parse selection rule */ static void parse_selection_rule(line, name_list, in_section) char *line ; /* line with head of rule */ struct stringlist *name_list ; /* list with name of selection rule */ int in_section ; { sb_ptr sb ; /* buffer for selection predicates */ int src_line_no; /* pos. of sel.rule head in input file */ char *src_filename_ptr; /* pointer to name of cur. input file */ char src_filename_buf[PATH_MAX]; char *pretty_header; /* "pretty-print" selection rule header */ { sb_ptr head_buf; struct stringlist *next_str; head_buf = check_sbnew (SB_LENGTH); for (next_str = name_list; next_str; next_str = next_str->next) { head_buf = check_sbcat (head_buf, next_str->string); } pretty_header = check_strdup (sbstr (head_buf)); sbfree (head_buf); } /* * consider header syntactically correct, if it either consists * of a single name, or a single name, followed by a parenthesized * parameter list. In the latter case, it will suffice, if the first * non-white-space character after the name is a '(', and the last * character is a ')'. */ { register char *open_paren = pretty_header, *close_paren; while (open_paren && *open_paren && (*open_paren != '(') && !isspace (*open_paren)) open_paren++; while (open_paren && *open_paren && isspace (*open_paren)) open_paren++; close_paren = open_paren; while (close_paren && *close_paren) close_paren++; if (close_paren && (*close_paren == '\0') && (close_paren > pretty_header)) { close_paren--; while (*close_paren && isspace(*close_paren)) close_paren--; } if (open_paren && *open_paren && (*open_paren != '(')) { parsing_error ("rule name with optional argument list required", line, NULL); } if (open_paren && *open_paren && close_paren && *close_paren && (*close_paren != ')')) { parsing_error ("rule name with optional argument list required", line, NULL); } } mf_locate (line, &src_filename_ptr, &src_line_no); (void) strcpy (src_filename_buf, src_filename_ptr); /* check if text follows */ line = skip_over_whitespace(line) ; if (*line != '\0') { parsing_error("newline expected after selection rule header", line, NULL) ; } sb = check_sbnew(SB_LENGTH) ; /* prepare string buffer for rule body */ /* collect rule body lines */ while ((line = mf_nextline(currentmf)) != NULL) { if (in_section ? rule_or_variant_body(line) : *line == '\t') { clean_selrule_from_comment(line) ; sb = check_sbcat(sb, line) ; } else { break ; } } /* ... and feed them to vbind. */ queue_selection_rule(pretty_header, sbstr(sb), src_filename_buf, src_line_no); free(name_list) ; free(sb) ; /* recover from look-ahead */ if (line != NULL) { mf_prevline(currentmf) ; } } static int rule_or_variant_body(line) char *line ; { /* In a section there are three ytpes of lines: 1. empty or comment-only line (possibly end of section) --> return FALSE 2. body of rule or variant --> return TRUE 3. header of rule or variant, this is something like "^[ \t]+[_0-9a-zA-Z]+[ \t]+:[ \t]+\(#.*\)*$" --> return FALSE 4. vclass definition, beginning with "[ \t]vclass[ \t]" --> return FALSE The choice between 2. and 3. is difficult. I decide to return TRUE if the header pattern is not matched. */ char *word_beginning ; /* beginning of first word in line */ line = skip_over_whitespace(line) ; if (*line == '\0' || *line == '#') { /* empty or comment-only */ return FALSE ; } word_beginning = line ; while (*line != '\0' && strchr(RULE_OR_VAR_NAME_COMPONENTS, *line)) { /* skip over possible header */ line++ ; } if (line - word_beginning == VCLASS_LENGTH && (*line == '\t' || *line == ' ') && !strncmp(word_beginning, VCLASS_STRING, VCLASS_LENGTH)) { /* is a vclass definition */ return FALSE ; } line = skip_over_whitespace(line) ; if (*line != ':') { return TRUE ; /* does not match header pattern */ } /* if nothing but comment follows, header pattern is matched */ line = skip_over_whitespace(line + 1) ; if (*line == '\0' || *line == '#') { return FALSE ; /* matched */ } return TRUE ; /* not matched */ } /* parse variant definition */ static void parse_variant_definition(line, name_list, in_section) char *line ; /* line with variant name */ struct stringlist *name_list ; /* must contain only variant name */ int in_section ; { char *variant_name ; struct stringlist *macro_list = NULL ; /* list of macros for variant */ if (name_list == NULL || name_list->next != NULL) { parsing_error("exactly one variant name required", line, NULL) ; } /* check if text follows */ line = skip_over_whitespace(line) ; if (*line != '\0') { parsing_error("newline expected after variant definition header", line, NULL) ; } variant_name = name_list->string ; free(name_list) ; /* feed macro definitions to shape */ while ((line = mf_nextline(currentmf)) != NULL) { if (in_section ? rule_or_variant_body(line) : *line == '\t') { clean_from_comment(line) ; macro_list = push_stringlist(skip_over_whitespace(line), macro_list, 0) ; } else { break ; } } queue_variant_definition(variant_name, macro_list) ; /* recover from look-ahead */ if (line != NULL) { mf_prevline(currentmf) ; } } /* parse rule- or variant-section */ static void parse_rule_or_var_section(line) char *line ; { char *section_name ; /* pointer to name of section */ /* functions to parse the body of a * rule resp. variant section */ void (*body_parser)A((char *line)) ; /* pointer to hold the address * of the appropriate routine */ char *backup = line ; /* line before current. Must have an initial * value because it is given as argument to * parsing_error() even if no line has been * read here (in case of EOF) */ jmp_buf save_jmpbuf ; /* save state of top-level loop */ line = skip_over_whitespace(line + 2) ; section_name = get_name(&line) ; /* get name of section */ if (!strcmp(section_name, RULESEC_STRING)) { /* this is a rule section */ body_parser = rule_section_body ; } else if (!strcmp(section_name, VARSEC_STRING)) { /* this is a variant section */ body_parser = variant_section_body ; } else { return ; /* must be comment */ } /* a section has its own top-level, so it needs * an own recovery point for parsing_error() */ memcpy (save_jmpbuf, jmp_toplevel, sizeof(jmp_buf)) ; setjmp(jmp_toplevel) ; /* section top-level loop */ do { line = mf_nextline(currentmf) ; if (line == NULL) { /* end of file reached */ /* restore global state */ memcpy (jmp_toplevel, save_jmpbuf, sizeof(jmp_buf)) ; parsing_error("end of file in section", backup, section_name) ; } backup = line ; line = skip_over_whitespace(line) ; /* skip empty and comment lines */ switch (*line) { case '\0': case '#': break ; case '\t': parsing_error("line beginning with TAB at top-level", line, section_name) ; break ; default: (*body_parser)(line) ; } } while (!end_of_section(line, section_name)) ; free(section_name) ; /* restore global state */ memcpy (jmp_toplevel, save_jmpbuf, sizeof(jmp_buf)) ; } /* parse a body part of a rule section */ static void rule_section_body(line) char *line ; { struct stringlist *name_list = NULL ; /* get name of rule */ name_list = push_stringlist(get_name(&line), name_list, 1) ; line = skip_over_whitespace(line) ; if (*line != ':' || *skip_over_whitespace(++line) != '\0') { parsing_error("syntax error in selection rule header", line, NULL) ; } parse_selection_rule(line, name_list, IN_SECTION) ; } /* parse a body part of a variant section */ static void variant_section_body(line) char *line ; { char *name ; /* variant name or "vclass" */ struct stringlist *name_list ; /* to feed it to * parse_variant_definition() */ name = get_name(&line) ; /* variant name or "vclass" */ if (!strcmp(name, VCLASS_STRING)) { parse_vclass_definition(line) ; } else { name_list = push_stringlist(name, NULL, 1) ; line = skip_over_whitespace(line) ; if (*line != ':' || *skip_over_whitespace(++line) != '\0') { parsing_error("syntax error in variant definition header", line, NULL) ; } parse_variant_definition(line, name_list, IN_SECTION) ; } } /* determine if line is the end line of section */ static int end_of_section(line, section) char *line ; /* line with possible "#% END-..." */ char *section ; /* name of section as string */ { if (strncmp(line, "#%", 2)) { return FALSE ; /* no "#%" at beginning */ } line = skip_over_whitespace(line + 2) ; if (strncmp(line, ENDSEC_STRING, ENDSEC_LENGTH)) { return FALSE ; /* no "END-" */ } if (strncmp(line + 4, section, strlen(section))) { return FALSE ; /* name of appropriate section missing */ } line = skip_over_name(line) ; if (*line != '\0' && !isspace(*line)) { return FALSE ; /* no whitespace after name of section */ } line = skip_over_whitespace(line) ; if (*line != '\0') { parsing_warning("trailing text on end-section line ignored", line, section) ; } return TRUE ; /* it IS the end of the section (at last) */ } /* parse_macro_definition(char *line, char type): parse macro definition */ static void parse_macro_definition(line, type, name_list) char *line ; char type ; struct stringlist *name_list ; { int mac_def_type = DYNAMIC; if (name_list == NULL || name_list->next != NULL) { parsing_error("exactly one macro name required", line, NULL) ; } switch (type) { case '-': parsing_error("macros with \"-=\" not yet supported", line, NULL) ; break ; case ':': mac_def_type = ONCE; break ; case '+': mac_def_type = APPEND; break ; case ' ': break ; } define_macro(name_list->string, line, mac_def_type) ; free_stringlist(name_list) ; } /* parse vclass definition. "vclass" has been eaten by recognize_line() */ static void parse_vclass_definition(line) char *line ; { char *name ; /* name of vclass */ struct stringlist *elems = NULL ; /* list of elements */ name = get_name(&line) ; /* get name of vclass */ line = skip_over_whitespace(line) ; if (strncmp(line, VCLASS_SEPARATOR, VCLSEP_LENGTH)) { /* "::=" */ parsing_error("Syntax error in vclass definition", line, NULL) ; } line += VCLSEP_LENGTH ; line = skip_over_whitespace(line) ; if (*line != '(') { parsing_error("\"(\" expected in vclass definition", line, NULL) ; } line++ ; /* get first element (at least one must be present) */ elems = push_stringlist(get_variant_name(&line), elems, 1) ; line = skip_over_whitespace(line) ; /* continue until ')' is seen */ while (*line != ')') { if (*line == ',') { line = skip_over_whitespace(++line) ; elems = push_stringlist(get_variant_name(&line), elems, 1) ; line = skip_over_whitespace(line) ; } else { parsing_error("syntax error in vclass definition", line, "\")\" or \",\" expected") ; } } /* feed definition to shape */ queue_vclass_definition(name, elems) ; if (*skip_over_whitespace(++line)) { parsing_warning("trailing text after vclass definition ignored", line, NULL) ; } } /* The following function is different from the other "skip_over_"s * because it is intended to throw away information. */ static void skip_over_rulebody() { char *line ; /* line to be read */ /* This is only a bad guess. Since the bodies of selection * rule definitions in rule sections and of variant definitions * in variant sections need not begin with a tab, we may lose here. * This will result in lots of complaints about syntactically wrong * ruledef and vardef headers (which are no headers). * But to make this of somewhat general purpose, I decide * to make this tradeoff. * For all things outside sections this works ok. */ while ((line = mf_nextline(currentmf)) != NULL && *line == '\t') ; if (line != NULL) { mf_prevline(currentmf) ; } } /* parsing_error(char *message, char *ptr, char *option): give * error message, skip any lines beginning with tabs and * jump to recovery point. extern int parse_errors is incremented. */ void parsing_error(message, ptr, option) char *message ; /* error message */ char *ptr ; /* pointer to error position */ char *option ; /* additional message */ { char *fname ; /* name of file error occured in */ int lineno ; /* number of line */ parse_errors++ ; /* increment number of detected errors */ /* locate position of error */ if (mf_locate(ptr, &fname, &lineno)) { fprintf(stderr, "%s:%d: ", fname, lineno) ; } /* give message */ fprintf(stderr, "%s parse error: %s", stProgramName, message) ; if (option) { fprintf(stderr, " (%s)", option) ; } fprintf(stderr, "\n") ; #ifdef DEBUG /* determine column where the error was detected */ line = mf_thisline(currentmf, lineno) ; fprintf(stderr, " Column %d\n", ptr - line) ; /* counts from 0 */ #endif /* throw away anything that is not top-level */ skip_over_rulebody() ; /* jump to top-level loop */ longjmp(jmp_toplevel, 1) ; } /* issue a warning */ void parsing_warning(message, ptr, option) char *message ; /* warning message */ char *ptr ; /* pointer to place */ char *option ; /* additional message */ { char *fname ; /* name of file place is in */ int lineno ; /* number of line */ /* locate place */ if (mf_locate(ptr, &fname, &lineno)) { fprintf(stderr, "%s:%d: ", fname, lineno) ; } /* issue warning */ fprintf(stderr, "%s parse warning: %s", stProgramName, message) ; if (option) { fprintf(stderr, " (%s)", option) ; } fprintf(stderr, "\n") ; } /* tries to recognize the type of a top-level line. * *name_list_p contains a list of names found before the token that * determines the line type. * *linep points to the first character *after* this token. * We don't need to recognize RULESEC_LINE or VARSEC_LINE, because * these would have been detected earlier in the top-level loop. */ static int recognize_line(linep, name_list_p) char **linep ; struct stringlist **name_list_p ; { char *line = *linep ; /* pointer into line */ struct stringlist *name_list = NULL ; /* list of names read */ sb_ptr sb ; /* buffer to collect a name */ char in_quote = 0 ; /* if non-zero: current wuoting character */ int paren_level = 0 ; /* level of nested parentheses we're in */ int line_type = UNKNOWN_LINE ; /* don't know yet... */ /* "include" or "vclass" at beginning of line * overrides all other line types, * so we can return immediately */ if (!strncmp(line, INCLUDE_STRING, INCLUDE_LENGTH) && isspace(*(line + INCLUDE_LENGTH))) { *linep = line + INCLUDE_LENGTH ; line_type = INCLUDE_LINE ; *name_list_p = NULL ; return line_type ; } else if (!strncmp(line, VCLASS_STRING, VCLASS_LENGTH) && isspace(*(line + VCLASS_LENGTH))) { *linep = line + VCLASS_LENGTH ; line_type = VCLASS_LINE ; *name_list_p = NULL ; return line_type ; } /* In the other case we have to look at each character. * Each character that is not whitespace or part of the * magic token is saved in a string buffer. If whitespace is * found, the string buffer is pushed to the name list. * * This can *not* be done with get_name(), since some of the * characters in the magic tokens are valid name components. */ sb = check_sbnew(SB_LENGTH) ; /* prepare string buffer */ /* iterate over line while we don't know the type */ while (*line && line_type == 0) { /* handle quoted strings */ if (in_quote) { if (*line == in_quote) { in_quote = 0 ; } else { sb = check_sbaddc(sb, *line) ; } } else { switch (*line) { case '(': paren_level++ ; sb = check_sbaddc(sb, *line) ; break ; case ')': if (paren_level <= 0) { parsing_error("unexpected close parentheses", line, NULL) ; } paren_level-- ; sb = check_sbaddc(sb, *line) ; break ; case '\'': case '\"': case '`': in_quote = *line ; break ; default: if (paren_level > 0) { sb = check_sbaddc(sb, *line) ; } else { switch (*line) { case '#': *line = '\0' ; break ; case '-': /* perhaps -= macro */ if (*(line + 1) == '=') { line_type = SUBMAC_LINE ; line++ ; } else { sb = check_sbaddc(sb, *line) ; } break ; case '+': /* perhaps += macro */ if (*(line + 1) == '=') { line_type = ADDMAC_LINE ; line++ ; } else { sb = check_sbaddc(sb, *line) ; } break ; case ':': /* dependency rule, vclass definition, * := macro, selection rule, or variant * definition */ switch (*(line + 1)) { case ':': /* vclass or :: rule */ if (*(line + 2) == '=') { line_type = VCLASS_LINE ; line += 2 ; } else { line_type = DOUBLEC_LINE ; line++ ; } break ; case '=': /* := macro */ line_type = VARMAC_LINE ; line++ ; break ; case '+': /* variant definition */ line_type = VARDEF_LINE ; line ++ ; break ; case '-': /* selection rule */ line_type = SELRULE_LINE ; line++ ; break ; default: /* dependency rule */ line_type = DEPRULE_LINE ; } break ; case '=': /* normal macro */ line_type = MACRO_LINE ; break ; case ' ': /* ends a name */ case '\t': /* if a name is in the string buffer, * save it to the name list */ if (sblen(sb) > 0) { /* the string is not unquote()ed since the * quotes are already removed */ name_list = push_stringlist(sbstr(sb), name_list, 1) ; free(sb) ; /* prepare new string buffer */ sb = check_sbnew(SB_LENGTH) ; } break ; default: sb = check_sbaddc(sb, *line) ; } } } } line++ ; } /* save last name to name list */ if (sblen(sb) > 0) { name_list = push_stringlist(sbstr(sb), name_list, 1) ; free(sb) ; } else { sbfree(sb) ; } /* name list is backwards yet */ *name_list_p = revert_stringlist(name_list) ; *linep = line ; /* any open quotes? */ if (in_quote) { char quote_char[2] ; quote_char[0] = in_quote ; quote_char[1] = '\0' ; free_stringlist(name_list) ; parsing_error("non-terminated quoting at end of line", line, quote_char) ; } /* any open parentheses? */ if (paren_level > 0) { parsing_error("missing close parentheses at end of line", line, NULL) ; } return line_type ; } /* This function differs from get_name in that commas and parentheses * are not allowed in variant names. */ static char *get_variant_name(linep) char **linep ; { char *name_end, *name_beg ; name_beg = skip_over_whitespace(*linep) ; name_end = skip_over_name_with_stop(name_beg, ",()") ; if (name_beg == name_end) { parsing_error("name or macro expected", *linep, NULL) ; } *linep = name_end ; return check_strndup(name_beg, name_end - name_beg) ; } /* clean trailing comments from a selection rule line * quting doesn't matter here, only parentheses */ static void clean_selrule_from_comment(line) char *line ; { int paren_level = 0 ; /* number of nested () pairs */ while (*line != '\0') { switch (*line) { case '(': paren_level++ ; break ; case ')': paren_level-- ; break ; case '#': if (paren_level <= 0) { *line = '\0' ; return ; } break ; default: ; } line++ ; } } /* clean trailing comments from a line */ static void clean_from_comment(line) char *line ; { while (*line != '\0') { if (*line == '#') { *line = '\0' ; return ; } if (isspace(*line)) { line = skip_over_whitespace(line) ; } else if (is_no_namecomponent(*line)) { line++ ; } else { line = skip_over_name(line) ; } } } /* EOF */ shapetools-1.4pl6.orig/src/shape/mfiles.c100444 2013 145 26051 5416300737 16503 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - mfiles.c * implements memory file. A memory file is completely * read into a buffer. All operations work on that buffer. * * by Juergen.Nickelsen@cs.tu-berlin.de * * $Header: mfiles.c[8.0] Tue Jul 6 15:46:00 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: mfiles.c[8.0] Tue Jul 6 15:46:00 1993 axel@cs.tu-berlin.de frozen $"; #endif #include "shape.h" #include "mfiles.h" #include "parser.h" /* list of all MFILE structures */ static MFILE *mf_structlist = NULL ; /* internal functions */ static void mf_do_read A((MFILE *mf, int fd)) ; static void mf_split_lines A((MFILE *mf)) ; static MFILE *mf_struct_alloc A((char *fname)) ; static int mf_open A((char *fname, FILE **fpp)) ; static void mf_readin_special A((MFILE *mf, int handle)) ; static MFILE *mf_readin_nosplit A((char *fname)) ; static MFILE *mf_struct_alloc(fname) char *fname; { MFILE *mf ; mf = (MFILE *) check_malloc(sizeof(MFILE)) ; mf->mf_name = check_strdup(fname) ; mf->mf_buffer = NULL ; mf->mf_lbeg = NULL ; mf->mf_lines = 0 ; mf->mf_curline = -1 ; mf->mf_end = NULL ; mf->mf_next = mf_structlist ; mf_structlist = mf ; return mf ; } /* Kill an MFILE buffer pointed to by mf. Releases all memory associated with this buffer. */ void mf_kilbuf(mf) MFILE *mf; { MFILE *tmp ; if (mf == mf_structlist) { mf_structlist = mf->mf_next ; } else { for (tmp = mf_structlist; tmp->mf_next != NULL; tmp = tmp->mf_next) { if (tmp->mf_next == mf) { tmp->mf_next = mf->mf_next ; } } if (tmp->mf_next == NULL) { #ifdef DEBUG fatal("freeing spurious buffer", mf->mf_name) ; #endif return ; /* not found in our list */ } } free(mf->mf_name) ; free(mf->mf_buffer) ; free(mf->mf_lbeg) ; free(mf) ; } /* Kill all MFILE buffers. */ void mf_killall() { MFILE *tmp, *next ; for (tmp = mf_structlist, next = mf_structlist->mf_next; tmp != NULL; tmp = tmp->mf_next, next = next->mf_next) { free(tmp->mf_name) ; free(tmp->mf_buffer) ; free(tmp->mf_lbeg) ; free(tmp) ; } } /* Read standard input into MFILE buffer */ MFILE *mf_readin_stdin() { MFILE *mf ; mf = mf_struct_alloc("Standard Input") ; mf_readin_special(mf, 0) ; mf_split_lines(mf) ; return mf ; } static void mf_readin_special(mf, handle) MFILE *mf ; int handle ; { unsigned long buffer_size ; /* current size of buffer */ unsigned long increment ; /* */ unsigned long read_ret ; /* return value of read(2) */ unsigned long total ; /* no of bytes read in, next read() goes to this offset */ buffer_size = INITIAL_BUFFER_SIZE ; increment = INITIAL_BUFFER_SIZE ; mf->mf_buffer = check_malloc(INITIAL_BUFFER_SIZE) ; total = 0 ; do { if ((read_ret = read(handle, mf->mf_buffer + total, buffer_size - total)) == -1) { fatal_perror(mf->mf_name) ; } total += read_ret ; if (total > 3 * buffer_size / 4) { increment = increment * 4 / 3 ; mf->mf_buffer = check_realloc(mf->mf_buffer, buffer_size + increment) ; buffer_size += increment ; } } while (read_ret > 0); mf->mf_buffer = check_realloc(mf->mf_buffer, total + 1) ; mf->mf_end = mf->mf_buffer + total ; *(mf->mf_end) = '\0' ; } /* Read file fname into an MFILE buffer */ MFILE *mf_readin(fname) char *fname; { MFILE *mf ; /* struct holding buffer information */ mf = mf_readin_nosplit(fname) ; if (mf != NULL) { mf_split_lines(mf) ; } return mf ; } /* Read file fname into an MFILE buffer without splitting into lines */ static MFILE *mf_readin_nosplit(fname) char *fname; { MFILE *mf ; /* struct holding buffer information */ unsigned long fsize ; /* size of the file */ int fd ; /* file descriptor to read from */ struct stat statbuf ; FILE *in ; /* *this* must be closed instead of fd */ if ((fd = mf_open(fname, &in)) == -1) { return NULL ; } else { if (fstat(fd, &statbuf) == -1) { fatal_perror(fname) ; } mf = mf_struct_alloc(fname) ; if (S_ISREG(statbuf.st_mode)) { fsize = statbuf.st_size ; mf->mf_buffer = check_malloc(fsize + 1) ; mf->mf_end = mf->mf_buffer + fsize ; *(mf->mf_end) = '\0' ; mf_do_read(mf, fd) ; } else { /* if it is not a regular file, we don't know the size */ mf_readin_special(mf, fd) ; } fclose(in) ; } return mf ; } /* Open file fname, return file descriptor. Pointer to FILE structure is written into place filepp points to. */ static int mf_open(fname, filepp) FILE **filepp ; char *fname ; { Af_key *key ; /* key for af_open() */ if (!(key = atBindVersion (fname, ""))) return -1; if ((*filepp = af_open(key, "r")) == NULL) { /* This must be an error because AtFS promised it could * open the file by giving us a key */ af_perror(fname) ; fatal("AtFS error", NULL) ; } return fileno(*filepp) ; } /* Read the contents of the file fd is a descriptor to into buffer mf. Space for the file contents is already allocated. */ static void mf_do_read(mf, fd) MFILE *mf; int fd ; { unsigned long left ; /* bytes left to read */ unsigned long read_ret ; /* return value of read(2) */ char *next_here ; /* next read(2) goes here */ left = mf->mf_end - mf->mf_buffer ; next_here = mf->mf_buffer ; while (left > 0) { if ((read_ret = read(fd, next_here, left)) == -1) { fatal_perror(mf->mf_name) ; } left -= read_ret ; next_here += read_ret ; } } /* Split the file buffer mf into lines. Newlines are replaced by null bytes, backslash/newline sequences are replaced by two blanks. Pointers to the original line beginnings are written into mf->mf_lbeg[]. mf->mf_lbeg[mf->mf_lines] points to the first character past the last line, i.e. mf->mf_end. The size of this array is written into mf->mf_lines. */ static void mf_split_lines(mf) MFILE *mf; { /* for the sake of efficiency backslash-newline pairs make * continuation lines even inside comments, i.e. *always* */ unsigned long enoli ; /* estimated number of lines */ unsigned long lines ; /* actual number of lines */ char *bufptr ; /* pointer into buffer */ char *oldbufptr ; /* copy of bufptr */ #define CHARS_PER_LINE 15 enoli = (mf->mf_end - mf->mf_buffer) / CHARS_PER_LINE + 1 ; /* perhaps... */ mf->mf_lbeg = (char **) check_malloc(enoli * sizeof(char *)) ; bufptr = mf->mf_buffer ; lines = 0 ; while (bufptr < mf->mf_end) { /* bufptr gets incremented in the switch */ mf->mf_lbeg[lines++] = bufptr ; /* get beg. of current line */ if (lines >= enoli) { /* extend array of pointers */ enoli *= 2 ; mf->mf_lbeg = (char **) check_realloc((char *) mf->mf_lbeg, enoli * sizeof(char *)) ; } oldbufptr = bufptr ; if ((bufptr = strchr(bufptr, '\n')) == NULL) { bufptr = oldbufptr ; break ; /* no newline to end of buffer */ } if (*(bufptr - 1) == '\\') { /* continuation line */ *(bufptr - 1) = ' ' ; *bufptr++ = ' ' ; } else { *bufptr++ = '\0' ; } } if (bufptr + strlen(bufptr) != mf->mf_end) { fatal("Nullbyte in file", mf->mf_name) ; } mf->mf_lbeg = (char **) check_realloc((char *) mf->mf_lbeg, (lines + 1) * sizeof(char *)) ; mf->mf_lbeg[lines] = mf->mf_end ; mf->mf_lines = lines ; } /* The current line is set to the next line. A pointer to the beginning of this line is returned. */ char *mf_nextline(mf) MFILE *mf; { int line = mf->mf_curline ; if (line < 0) { /* if current position is before the beginning of the file, * go to the first line */ line = 0 ; } else { do { if (++line >= mf->mf_lines) { /* end of file reached */ return NULL ; } /* beginning of a real line (not original) * is only after a null byte */ } while (*(mf->mf_lbeg[line] - 1) != '\0') ; } mf->mf_curline = line ; return mf->mf_lbeg[line] ; } /* The current line is set to the previous line. A pointer to the beginning of this line is returned. */ char *mf_prevline(mf) MFILE *mf; { int line = mf->mf_curline ; if (--line < 0) { /* kind of "virtual" position before the beginning */ mf->mf_curline = -1 ; } else { /* look for the beginning of a "real" line. A real line * beginning if found if it is the beginning of the buffer * or otherwise has a null byte in the previous position. */ while (line > 0 && *(mf->mf_lbeg[line] - 1) != '\0') { line-- ; } mf->mf_curline = line ; } return line >= 0 ? mf->mf_lbeg[line] : NULL ; } /* Return a pointer to the specified line in mf. */ char *mf_thisline(mf, lineno) MFILE *mf; int lineno ; { return mf->mf_lbeg[lineno - 1] ; } /* The file name and line number ptr points into are written into *pfilename and *plineno. If ptr does not point into an MFILE buffer, 0 is returned, 1 on success. */ int mf_locate(ptr, pfilename, plineno) char *ptr ; char **pfilename ; int *plineno ; { MFILE *mf ; int lineno ; /* go through mf_structlist and try to locate ptr */ for (mf = mf_structlist; mf != NULL; mf = mf->mf_next) { if ((lineno = mf_locate_in(mf, ptr)) > 0) { *plineno = lineno ; if (pfilename != NULL) { *pfilename = mf->mf_name ; } return 1 ; } } return 0 ; } /* The line number ptr points into in the buffer of mf is returned. If ptr does not point into the buffer of mf, -1 is returned. */ int mf_locate_in(mf, ptr) MFILE *mf ; char *ptr ; { unsigned long here ; unsigned long upper ; unsigned long lower ; /* check bounds first */ if (ptr >= mf->mf_buffer && ptr <= mf->mf_end) { upper = mf->mf_lines - 1 ; lower = 0 ; /* kind of binary search */ while (lower <= upper) { here = (lower + upper) / 2 ; if (ptr > mf->mf_lbeg[here]) { if (ptr < mf->mf_lbeg[here + 1]) { /* in THIS line */ return here + 1 ; } else { lower = here + 1 ; } } else if (ptr < mf->mf_lbeg[here]) { upper = here ; } else { return here + 1 ; } } } return -1 ; } /* set the current line of mf to the line ptr points to. If ptr does not point into the buffer of mf, a fatal error is raised. */ void mf_setline(mf, ptr) MFILE *mf ; char *ptr ; { int lineno ; /* number of line ptr points to */ lineno = mf_locate_in(mf, ptr) ; if (lineno < 0) { fatal("ptr not in mf", mf->mf_name) ; } mf->mf_curline = lineno - 1 ; /* mf_locate_in() returns user level line numbers, not an index in mf_lbeg */ } /*EOF*/ shapetools-1.4pl6.orig/src/shape/utils.c100444 2013 145 21027 5405657373 16373 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - utils.c * * by Juergen.Nickelsen@cs.tu-berlin.de * * $Header: utils.c[8.0] Thu Jun 10 18:30:02 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: utils.c[8.0] Thu Jun 10 18:30:02 1993 axel@cs.tu-berlin.de frozen $"; #endif #include #include #include "shape.h" #include "parser.h" /* * The memory management functions do the following: allocate, check * if result is valid, initialize fields if necessary */ /*** raw allocators ***/ /* allocate memory and check */ char *check_malloc(size) unsigned size ; { char *tmp ; tmp = malloc(size) ; if (tmp == NULL) { fatal(NOMORECORE, NULL) ; } return tmp ; } /* reallocate memory and check */ char *check_realloc(ptr, size) char *ptr ; unsigned size ; { char *tmp ; tmp = realloc(ptr, size) ; if (tmp == NULL) { fatal(NOMORECORE, NULL) ; } return tmp ; } /*** string functions ***/ /* like strdup, but only n characters * the resulting string is null padded, freeable */ char *check_strdup(s) char *s ; { char *tmp = check_malloc(strlen(s) + 1) ; strcpy(tmp, s) ; return tmp ; } /* like strdup, but only n characters * the resulting string is null padded, freeable */ char *check_strndup(s, n) char *s ; int n ; { char *tmp = check_malloc(n + 1) ; strncpy0(tmp, s, n) ; return tmp ; } /* safe strncpy with null padding but no return value */ void strncpy0(s1, s2, n) char *s1, *s2 ; int n ; { strncpy(s1, s2, n) ; s1[n] = '\0' ; } sb_ptr check_sbcat(sb, string) sb_ptr sb ; char *string ; { if ((sb = sbcat(sb, string, strlen(string))) == NULL) { fatal(NOMORECORE, NULL) ; } return sb ; } /* add one character to a string buffer */ sb_ptr check_sbaddc(sb, c) sb_ptr sb ; char c ; { if ((sb = sbcat(sb, &c, 1)) == NULL) { fatal(NOMORECORE, NULL) ; } return sb ; } sb_ptr check_sbnew(len) int len ; { sb_ptr sb ; if ((sb = sbnew(len)) == NULL) { fatal(NOMORECORE, NULL) ; } return sb ; } /* allocate a struct stringlist. This struct is pushed on list * with contents str. */ struct stringlist *push_stringlist(str, list, freeable) char *str ; /* string value */ struct stringlist *list ; /* list to push struct on */ int freeable ; /* if non-zero, string can be freed */ { struct stringlist *s ; /* pointer to allocated list */ s = (struct stringlist *) check_malloc(sizeof(struct stringlist)) ; s->string = str ; /* set string value */ s->freeable = freeable ; /* for free_stringlist() */ s->next = list ; /* put in front of list */ return s ; /* return head of new list */ } /* revert a stringlist. This is necessary for rule.cmds, * since the commands are added with push_stringlist(). */ struct stringlist *revert_stringlist(strlp) struct stringlist *strlp ; { struct stringlist *tmp, *new ; new = NULL ; /* initialize new list */ while (strlp != NULL) { /* put head of old list to * head of new list */ tmp = strlp->next ; strlp->next = new ; new = strlp ; strlp = tmp ; } return new ; } /* free all elements of a stringlist */ void free_stringlist(strlist) struct stringlist *strlist ; { struct stringlist *tmp ; while (strlist != NULL) { tmp = strlist ; strlist = strlist->next ; if (tmp->freeable) { free(tmp->string) ; } free(tmp) ; } } /*** errors and warnings ***/ /* print fatal error message and exit */ void fatal(message, message2) char *message ; char *message2 ; { fprintf(stderr, "%s fatal error: %s", stProgramName, message) ; if (message2 != NULL) fprintf(stderr, " (%s)", message2) ; fputc('\n', stderr) ; #ifdef DEBUG abort() ; #else cleanup() ; exit(3) ; #endif } /* specials for the parser */ /* char *skip_over_XXX(char *p): skip over item XXX */ char *skip_over_blanks(p) char *p ; { while (*p == ' ') p++ ; return p ; } /* stops at NUL byte */ char *skip_over_whitespace(p) char *p ; { while (*p && isspace(*p)) p++ ; return p ; } /* skip over a name or macro reference */ char *skip_over_name(p) char *p ; { return skip_over_name_with_stop(p, "") ; } /* skip over a name or macro reference. Stops at notnamecomponents * and at characters in stop */ char *skip_over_name_with_stop(p, stop) char *p ; char *stop ; /* additional characters to stop at */ { char in_quote = 0 ; /* initially outside of quoting */ int ignore_parens ; /* if non-zero, don't do paren matching */ int parenth_level = 0 ; /* initially no parantheses */ ignore_parens = strchr(stop, ')') || strchr(stop, '(') ; /* loop over string */ while (*p) { switch (*p) { case '\"': /* quoting character encountered */ case '\'': case '`': /* backquote counts as quoting here */ if (in_quote) { if (in_quote == *p) { /* end of quoting */ in_quote = 0 ; } } else { /* beginning of quoting */ in_quote = *p ; } break ; case '(': /* if parentheses are to be ignored, we have to fall * through to the "default:" label. This looks pretty ugly, * I know! */ if (!ignore_parens) { parenth_level++ ; break ; } case ')': if (!ignore_parens) { if (parenth_level <= 0) { parsing_error("unmatched closing parenthesis", p, NULL) ; } parenth_level-- ; break ; } default: if (!in_quote && (is_no_namecomponent(*p) || strchr(stop, *p)) && (ignore_parens || parenth_level == 0)) { /* return if: * - outside of quoting * - all parentheses closed (or ignored) * - character is * - no namecomponent * - or is stop character */ return p ; /* points at first character after name */ } } p++ ; } /* quoting must be terminated at end of line */ if (in_quote) { parsing_error("non-terminated quoting at end of line", p - 1, NULL) ; } /* all parentheses must be matched */ if (!ignore_parens && parenth_level != 0) { parsing_error("mismatched parenthesis", p, NULL) ; } return p ; } /* copies a name after point *linep points to a string * and returns a pointer to the allocated string. *linep is incremented * to point to the first character after the name. * Any quoting is removed from the name. * macro references are treated as names. */ char *get_name(linep) char **linep ; /* pointer to pointer to string */ { char *name_beg ; /* pointer to beginning of name */ char *name_end ; /* pointer to end of name */ name_beg = skip_over_whitespace(*linep) ; name_end = skip_over_name(name_beg) ; if (name_beg == name_end) { parsing_error("name or macro expected", *linep, NULL) ; } *linep = name_end ; return unquote(check_strndup(name_beg, name_end - name_beg)) ; } /* remove pairs of quoting characters from string. The quoting characters * are already guaranteed to be matching by skip_over_name(). * The unquoting is done in place, but the address of the string * is also returned. */ char *unquote(string) char *string ; { int distance = 0 ; /* distance to move folling characters */ char in_quote = 0 ; /* character of current quoting */ char *from ; /* place to copy characters from... */ char *to ; /* ... and to. */ to = from = string ; while (*from) { if (in_quote) { if (*from == in_quote) { from++ ; in_quote = 0 ; distance++ ; } else { *to++ = *from++ ; } } else { if (*from == '\'' || *from == '\"') { in_quote = *from ; from++ ; distance++ ; } else { *to++ = *from++ ; } } } *to = '\0' ; #ifdef DEBUG if (distance != from - to) { fatal("wrong distance in unquote()", "Hmm...") ; } #endif return string ; } /* int is_no_namecomponent(char c) */ char notnamecomponents[] = "#:;= " ; /* may become a macro eventually */ /* is true for NUL character */ int is_no_namecomponent(c) long c ; { return (int) strchr(notnamecomponents, c) ; } /*EOF*/ shapetools-1.4pl6.orig/src/shape/queues.c100444 2013 145 22235 5414074252 16531 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - queues.c * * by Juergen.Nickelsen@cs.tu-berlin.de * * $Header: queues.c[8.0] Tue Jun 29 19:57:47 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef lint static char *AtFSid = "$Header: queues.c[8.0] Tue Jun 29 19:57:47 1993 axel@cs.tu-berlin.de frozen $"; #endif #include #include "shape.h" #include "parser.h" struct deprule { struct stringlist *macros ; /* list of macros target depends on */ struct stringlist *deps ; /* list of dependants */ struct stringlist *targets ;/* list of targets */ struct stringlist *cmds ; /* list of commands */ struct deprule *next ; /* pointer to next rule */ } ; static struct deprule *deprulelist = NULL ; /* list of all dependency rules */ static struct deprule *lastdeprule = NULL ; /* pointer to last entry */ struct selrule { /* selection rule */ char *name ; /* name of rule */ char *body ; /* body of rule */ char *src_file; /* name of src file containing rule */ int src_lineno; /* lineno of rule-head */ struct selrule *next ; /* pointer to next rule */ } ; static struct selrule *selrulelist = NULL ; static struct selrule *lastselrule = NULL ; struct vclassdef { char *name ; struct stringlist *elements ; struct vclassdef *next ; } ; void queue_dependency_rule (targets, deps, macros, cmds) struct stringlist *targets ; struct stringlist *deps ; struct stringlist *macros ; struct stringlist *cmds ; { struct deprule *rule ; rule = (struct deprule *) check_malloc(sizeof(struct deprule)) ; rule->targets = targets ; rule->deps = deps ; rule->macros = macros ; rule->cmds = cmds ; if (lastdeprule == NULL) { lastdeprule = deprulelist = rule ; } else { lastdeprule->next = rule ; lastdeprule = lastdeprule->next ; } lastdeprule->next = NULL ; } void queue_selection_rule(name, body, src_filename, src_lineno) char *name ; char *body ; char *src_filename; int src_lineno; { struct selrule *rule ; rule = (struct selrule *) check_malloc(sizeof(struct selrule)) ; rule->name = name ; rule->body = body ; rule->src_lineno = src_lineno; rule->src_file = check_strdup (src_filename); if (lastselrule == NULL) { lastselrule = selrulelist = rule ; } else { lastselrule->next = rule ; lastselrule = lastselrule->next ; } lastselrule->next = NULL ; } /* Insert a variant definition into Shape's data structures. */ void queue_variant_definition(name, macros) char *name ; struct stringlist *macros ; { /* variant definitions are not really queued, since we need them * as early as macro definitions. They are directly written * into Shape's data structures instead. */ struct stringlist *mac ; /* loops over the "macros" list */ struct stringlist *pr_mac ; /* loops over the "macros" list, but * one behind mac. Used for freeing the * stringlist struct. */ int curvdef ; /* loops over variantDefs[] */ int curmdef ; /* loops over variantDefs[curvdef].vmacros[] */ /* Look for empty slot in variantDefs[]. * If a variant definition with the same name is found, * this is considered an error. */ for (curvdef = 0; variantDefs[curvdef].name != NULL && curvdef < MAXVARDEFS; curvdef++) { if (!strcmp (variantDefs[curvdef].name, name)) { /* variant name already defined */ errexit (33, name) ; /* I'll kill him later for 33... */ } } if (curvdef == MAXVARDEFS) { /* variant table overflow */ errexit (27, "variant definitions") ; } /* vardef_end() uses this variable */ lastVariantDef = curvdef ; /* Now we have a free slot in variantDefs[curvdef], * so initialize name, vpath, vflags, and vmacros fields */ variantDefs[curvdef].name = name ; variantDefs[curvdef].vpath = NULL ; variantDefs[curvdef].vflags = NULL ; for(curmdef = 0; curmdef < MAXVMACROS; curmdef++) { variantDefs[curvdef].vmacros[curmdef] = NULL ; } /* mark next slot as last+1 with NULL in .name */ variantDefs[curvdef + 1].name = NULL ; /* now insert macro definitions for this variant * macros "vpath" and "vflags" get special treatment */ curmdef = 0 ; /* number of current macro definition */ for (mac = macros, pr_mac = NULL; mac != NULL; pr_mac = mac, mac = mac->next) { char *macname ; /* name of macro */ char *macptr ; /* pointer into macro definition */ char *macval ; /* pointer to macro value */ if (pr_mac != NULL) { free(pr_mac) ; /* free previous struct stringlist */ } /* get name of macro */ macptr = mac->string ; macname = get_name(&macptr) ; /* macptr points to position after name now */ macptr = skip_over_whitespace(macptr) ; /* this shodul be more general some time: check for * "=", "-=", "+=", ":=" */ if (*macptr != '=') { parsing_error("\"=\" expected in variant definition", macptr, name) ; } macval = macptr = skip_over_whitespace(macptr + 1) ; /* macptr and macval now point to macro value */ /* check for special macros vpath and vflags if there is a value */ if (*macval && !strcmp(macname, "vpath")) { char *cp ; /* keep value to free it later */ /* This is a very simple heuristic: * if vpath has only one component and this is "..", * use prev_dir instead */ if (!strcmp((cp = get_name(&macval)), "..") && /* macval now points behind the first component */ *skip_over_whitespace(macval) == '\0') { variantDefs[curvdef].vpath = check_strdup(prev_dir) ; } else { /* macval's value is useless now, so use macptr */ variantDefs[curvdef].vpath = macptr ; } free(cp) ; } else if (*macval && !strcmp(macname, "vflags")) { variantDefs[curvdef].vflags = macval ; } else { /* So this is a "real" variant macro -- * do we still have a free macro slot? */ if (curmdef >= MAXVMACROS) { fatal("too many variant macro definitions", name) ; } /* now insert definition */ variantDefs[curvdef].vmacros[curmdef++] = mac->string ; } free(macname) ; } free(pr_mac) ; vardef_end() ; /* This is a hook from which this variant * may already be activated */ } void queue_vclass_definition(name, elements) char *name ; struct stringlist *elements ; { /* vclass definitions are not really queued, since we need them * as early as macro definitions */ vclassdef(name, elements) ; free_stringlist(elements) ; } void commit_selrule_definitions() { struct selrule *srule, *prev_srule = NULL ; int backup = atBindDisplayErrors; /* selection rules */ atBindDisplayErrors = TRUE; for (srule = selrulelist; srule != NULL; srule = srule->next) { atBindAddRule(srule->name, srule->body, srule->src_file, srule->src_lineno) ; free(srule->name) ; free(srule->body) ; if (prev_srule != NULL) free(prev_srule) ; prev_srule = srule ; } atBindDisplayErrors = backup; if (prev_srule != NULL) free(prev_srule) ; lastselrule = selrulelist = NULL ; } void commit_deprule_definitions() { struct deprule *drule, *prev_drule = NULL ; /* dependency rules */ for (drule = deprulelist; drule != NULL; drule = drule->next) { sb_ptr sb ; /* string buffer to accumulate rule */ struct stringlist *tmp ; /* pointer into rulep->targets, * rulep->deps, and rulep->cmds */ sb = check_sbnew(SB_LENGTH) ; /* copy targets to string buffer */ for (tmp = drule->targets; tmp != NULL; tmp = tmp->next) { char *xtmp = expandmacro (tmp->string); while (xtmp && *xtmp && isspace(*xtmp)) xtmp++; sb = check_sbcat(sb, xtmp) ; sb = check_sbcat(sb, " ") ; } /* separator */ sb = check_sbcat(sb, ": ") ; /* copy dependants to string buffer */ for (tmp = drule->deps; tmp != NULL; tmp = tmp->next) { sb = check_sbcat(sb, tmp->string) ; sb = check_sbcat(sb, " ") ; } if (drule->macros) { sb = check_sbcat(sb, ": ") ; for (tmp = drule->macros; tmp != NULL; tmp = tmp->next) { sb = check_sbcat(sb, tmp->string) ; sb = check_sbcat(sb, " ") ; } } /* give rule to shape */ ruledef(sbstr(sb)) ; sbfree(sb) ; /* add commands to rule */ for (tmp = drule->cmds; tmp != NULL; tmp = tmp->next) { rulecont(tmp->string) ; } ruleend() ; free_stringlist(drule->targets) ; free_stringlist(drule->deps) ; free_stringlist(drule->macros) ; free_stringlist(drule->cmds) ; if (prev_drule != NULL) free(prev_drule) ; prev_drule = drule ; } if (prev_drule != NULL) free(prev_drule) ; lastdeprule = deprulelist = NULL ; } void commit_definitions() { commit_selrule_definitions() ; commit_deprule_definitions() ; } shapetools-1.4pl6.orig/src/shape/shape.h100444 2013 145 24062 5524512733 16332 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - shape.h * * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) * * $Header: shape.h[8.0] Tue May 24 15:21:21 1994 axel@cs.tu-berlin.de frozen $ */ typedef int Bool; #define TEST_ONLY 0 #define BIND_IT 1 #define ALL 0 #define SOURCE 1 #define BINARY 2 #define NONE 3 #define NIL ((char *) 0) #define MYMAXNAMLEN 256 /* Restore Types */ #define REGULAR 0 #define VPATH 1 #define EXTERNAL 2 #include "atfs.h" #include "atfstk.h" #include "sttk.h" #include "strbuf.h" struct linked_list { char *string; struct linked_list *nextstring; }; struct list { int (*selfunc)(); char *parn; char *parv; int i; struct list *cont; }; struct cmds { char *command; struct cmds *nextcmd; }; #define ATTRNAME "__DerivationKey__" #define DRV_TIME "__DTime__" #define MAXDEPTH 64 #define MAXPATHLIST 256 #define MAXVPATH 16 #define MAXTARGS 128 #define MAXHERIT 32 #define MAXDEPS 256 #define MAXCMDS 32 struct rules { char *name; struct rules *next; Af_set date; int done; Bool doublecolon; Bool saved; char *firstdep; /* possibly selection rule name */ char *deplist; char *_deplist_buffer; char *heritage[MAXHERIT]; char *targetlist[MAXHERIT]; struct cmds *cmdlist; struct rules *nextrule; }; typedef struct { Bool bk_isdefined; Af_key bk_key; } BKey; typedef struct { int dependent_queue_initialized; Af_key *dependent_queue, *head, *tail; char keybuffer[AT_MAXATTRSIZE]; int queued_dependents, current_max_dependents; int queue_changed; } DepQ; #define suffix(s) (strrchr (s, '.') ? strrchr (s, '.') : "") #define STD_ATTRS 10 struct linkreg { char *fn; char *newfn; Bool busy_exist; struct linkreg *next; }; #define MAXVARIANTS 32 #define MAXVMACROS 32 #define MAXVCLASS 64 #define MAXVARDEFS 64 #define MAXCMDLINEVARS 32 #define MAXACTVAR 32 struct vardef { char *name; char *vmacros[MAXVMACROS]; char *vflags; char *vpath; }; struct varclass { char *name; int active; char *variants[MAXVARIANTS]; }; struct stringlist { /* generic list of strings */ char *string ; int freeable ; /* if non-zero, string can be freed */ struct stringlist *next ; } ; #define MAXPREDS 256 /* * Module interface section (Prototypes) */ /* error.c */ void errexit A((int err, char *mess)); void warning A((int err, char *mess)); /* files.c */ extern Af_attrs buft; extern char *pathlist[MAXPATHLIST][2]; extern int lastpath; extern char *curvpath[]; extern char actpath[]; extern char dollarplus[]; Bool locate_object A((char *name, int mode)); Bool try_to_bind_version A((char *dep, char *bind_rule, Bool try_or_bind, BKey *bind_result)); void init_confid A((char *name)); void add_rule_to_confid A((struct rules *rule)); void finish_confid A((void)); FILE *cmfopen A((char *filename, char *mode, int major_version, int minor_version)); void restore_all_vers A((void)); char *restored_object_id A((char *unixname)); void drop_restorelist A((void)); /* main.c */ extern char rbfile[]; extern char prev_dir[]; extern int main_gen; extern int main_rev; extern char *suffs; extern char shapeflags[]; extern struct linked_list *shapefiles; extern char *cmdtargets[]; extern char *cmd_line_vars[MAXCMDLINEVARS]; extern int rec_do_depth; extern char *newarg[]; extern int newargc; extern Bool Oldsuffs; extern Bool Newsuffs; void cleanup A((void)); void get_env_vals A((void)); /* dkey.c */ DepQ *new_DepQ A((void)); void drop_dependent_queue A((DepQ *q)); void append_dependent A((Af_key *key, DepQ *q)); char *make_derivation_key A((struct rules *current_rule, DepQ *q)); /* produce.c */ extern Bool error_occ; extern Bool no_comm_subst; extern char rbrule[]; extern char rbtarg[]; extern char ruleset[]; extern Bool busy_done; extern int depth; struct rules *get_target A((char *targ)); struct rules *implicit_target A((char *targ)); void produce A((void)); /* pa.c */ int parse_file A((char *filename)) ; extern int parse_errors ; /* number of parse errors */ void parsing_error A((char *message, char *ptr, char *option)) ; void parsing_warning A((char *message, char *ptr, char *option)) ; /* utils.c */ /* exports from utils.c */ char *skip_over_blanks A((char *line)) ; char *skip_over_whitespace A((char *line)) ; char *skip_over_name A((char *line)) ; char *get_name A((char **line)) ; struct stringlist *push_stringlist A((char *str, struct stringlist *list, int freeable)) ; int is_no_namecomponent A((long c)) ; char *skip_over_name_with_stop A((char *p, char *stop)) ; struct stringlist *revert_stringlist A((struct stringlist *strlp)) ; char *unquote A((char *string)) ; char *check_malloc A(( unsigned size )); char *check_realloc A(( char *ptr, unsigned size )); char *check_strdup A(( char *s )); char *check_strndup A(( char *s, int n )); void strncpy0 A(( char *s1, char *s2, int n )); sb_ptr check_sbcat A(( sb_ptr sb, char *string )); sb_ptr check_sbaddc A(( sb_ptr sb, int c )); sb_ptr check_sbnew A(( int len )); void free_stringlist A(( struct stringlist *strlist )); void fatal A(( char *message, char *message2 )); /* queues.c */ void queue_dependency_rule A((struct stringlist *targets, struct stringlist *deps, struct stringlist *macros, struct stringlist *cmds)) ; void queue_selection_rule A((char *name, char *body, char *src_filename, int src_lineno)) ; void queue_variant_definition A((char *name, struct stringlist *macros)) ; void queue_vclass_definition A((char *name, struct stringlist *elements)) ; void commit_definitions A((void)) ; void commit_selrule_definitions A((void)) ; void commit_deprule_definitions A((void)) ; /* macro.c: */ extern char *environment_vars; extern FILE *temp; extern Bool shape_command; char *get_next_item A((char *string)); void define_macro A((char *name, char *value, int mtype)); char *expandmacro A((char *inpstring)); void echo_macro A((char *name)); /* shapeopt.c */ extern char cfname[]; extern char echomac[]; extern char *forcelist[]; extern FILE *cid; extern Bool debugflg; extern Bool D_flag; extern Bool Var_flag; extern Bool selectflg; extern Bool notfoundflg; extern Bool noretrvflg; extern Bool instflg; extern Bool restflg; extern Bool envflg; extern Bool fileflg; extern Bool nostdfile; extern Bool ignoreflg; extern Bool goflg; extern Bool noexflg; extern Bool printflg; extern Bool questflg; extern Bool ruleflg; extern Bool silentflg; extern Bool touchflg; extern Bool stdinflg; extern Bool confid; extern Bool rebuildflg; extern Bool stopflg; extern Bool tunixflg; extern Bool logflg; extern Bool expflg; extern Bool noexpflg; extern Bool echoflg; extern Bool nomsgflg; extern Bool novclassflg; extern Bool bpoolflg; extern Bool nobpoolflg; extern Bool forceflg; extern StOptDesc odesc[]; /* rule.c */ extern struct rules *ruletab[]; extern char *firsttarget; void ruledef A((char *string)); void rulecont A((char *string)); void ruleend A((void)); void dump_rule A((FILE *dest, struct rules *rule, Bool dump_commands)); void ruledump A((FILE *fd)); void adjust_stdrules A((char *suffs)); void init_ruletab A((void)); void reset_dep_list A((struct rules *dep_rule)); char *get_dep A((struct rules *dep_rule, int nth)); void add_defaults A((char *targ, struct rules *rule)); Bool is_special_target A((char *string)); Bool is_pattern A((char *string)); char *stem A((char *pattern, char *string)); char *subst_char A((char *template, char s_char, char *substitution)); /* std.c */ extern struct rules *stdruletab[]; extern int lastrule; /* index of last std rule */ extern char *stdsuff; extern char *shaperules; extern int implicit_suffs[]; void add_stdrules A((void)); /* selrule.c */ void selruledef_preds A((char *string)); void selruledef_name A((char *string)); Bool is_selrule_name A((char *name)); /* inherit.c */ Bool stk_matchuda A((char *udas, char *attr)); void save_targets A((struct rules *dep_rule, char *primary_target_name, DepQ *q, BKey *primary_target_key, time_t touch_time)); Bool already_in_done_list A((char *targetname, Af_key *done_key)); void add_to_done_list A((char *targ_path, Af_key *done_key)); /* misc.c */ extern struct linkreg *link_reg; extern char *states[]; int get_attr_type A((char *name)); void register_link A((char *fn, char *newfn, Bool busy_exist)); void cleanup_links A((struct linkreg *cur_link)); void free_linklist A((void)); Bool is_in_forcelist A((char *name)); int D_debug A((char *name, char* type, char *at)); /* varsec.c */ extern struct vardef variantDefs[]; extern char *curvar[]; extern int variants_active; extern int activeVariants[]; extern struct varclass variantClasses[]; extern int lastVariantDef; void vardef_end A((void)); void vclassdef A((char *name, struct stringlist *varnames)); Bool check_vclass A((char *varname)); void reset_vclass A((void)); Bool is_varname A((char *string)); int activate_variant A((char *varname)); void de_activate A((char *varname)); char *active_variants A(()); void print_variant_class A((FILE * dest, struct varclass * vcdef_p)); void print_variant_names A((FILE * destination)); void print_variant_definition A((FILE * dest, struct vardef * vardef_p)); /* hash.c */ #define DYNAMIC 01 #define APPEND 02 #define ONCE 04 #define FROM_CMDLINE 0100 int hashval A((char *name, int tabsize)); void addHash A((char *name, char *value, int mode)); char *getHash A((char *name)); Bool visitedHash A((char *name)); void clearHashVisited A((char *name)); void dump A((FILE *fd)); /* sighand.c */ void catch_sigs A((void)); /* version.c */ char *version A((void)); shapetools-1.4pl6.orig/src/shape/strbuf.h100444 2013 145 4063 5344662443 16522 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - strbuf.c * * by Steve Emerson (steve@unidata.ucar.edu) * * $Header: strbuf.h[8.0] Tue Mar 2 15:02:03 1993 shape@cs.tu-berlin.de frozen $ */ #ifndef STRING_BUFFER_HEADER_INCLUDED #define STRING_BUFFER_HEADER_INCLUDED /* * String-buffer data-type. */ typedef struct str_buf *sb_ptr; /* * String-buffer interface: */ /* Instantiate a string-buffer. Returns NULL on failure. The specified, * initial, maximum string length doesn't count the terminating NUL. */ extern sb_ptr sbnew A((int max)); /* Initialize an existing string-buffer. */ extern sb_ptr sbinit A((sb_ptr sb, char *string, int len)); /* Free a string-buffer. */ extern void sbfree A((sb_ptr sb)); /* Copy a string to a string-buffer. The string buffer will expand as * necessary to accomodate the input string. On failure, it will return * NULL. */ extern sb_ptr sbcpy A((sb_ptr sb, char *string, int len)); /* Append a string to a string-buffer. The string-buffer will expand as * necessary to accomodate the catenated string. The function returns NULL * on failure. */ extern sb_ptr sbcat A((sb_ptr sb, char *string, int len)); /* Return a pointer to a string-buffer's string. The string is guaranteed * to be NUL terminated. */ extern char *sbstr A((sb_ptr sb)); /* Return the length of a string-buffer's string. Excludes the terminating * NUL. */ extern int sblen A((sb_ptr sb)); #endif /* !STRING_BUFFER_HEADER_INCLUDED */ shapetools-1.4pl6.orig/src/shape/parser.h100444 2013 145 2305 5405653541 16503 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - parser.h * * by Juergen.Nickelsen@cs.tu-berlin.de * * $Header: parser.h[8.0] Thu Jun 10 18:30:06 1993 axel@cs.tu-berlin.de frozen $ */ #ifndef NULL #define NULL 0 #endif #define NOMORECORE "no more core" #define SB_LENGTH 128 /* initial length of string buffer * for dependency rules etc. */ #ifdef DEBUG extern int dump_parsed_definitions ; #endif extern int errno ; /* I want to handle ... */ extern char *sys_errlist[] ; /* ... these strings by myself */ #define fatal_perror(string) fatal(sys_errlist[errno], string) shapetools-1.4pl6.orig/src/shape/mfiles.h100444 2013 145 2751 5344663221 16471 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - mfiles.h * * by Juergen.Nickelsen@cs.tu-berlin.de * * $Header: mfiles.h[8.0] Tue Mar 2 15:02:19 1993 shape@cs.tu-berlin.de frozen $ */ #ifndef __MFILES_H #define __MFILES_H #define STDIN_NAME "Standard Input" /* Name used for standard input */ #define INITIAL_BUFFER_SIZE 8192 /* initial buffer size for reading from special file or stdin */ typedef struct MFILE__ { char *mf_name ; /* filename */ char *mf_buffer ; /* pointer to mfile buffer */ char **mf_lbeg ; /* array of original line beginnings */ int mf_lines ; /* number of lines */ int mf_curline ;/* current line */ char *mf_end ; /* end of buffer */ struct MFILE__ *mf_next ; /* pointer to next, don't use! */ } MFILE ; #include "mffuncs.h" #endif /* __MFILES_H */ shapetools-1.4pl6.orig/src/shape/mffuncs.h100444 2013 145 11256 5416575464 16706 0ustar dokoswt/* * This file was automatically generated by version 1.7 of cextract. * Manual editing not recommended. * * Created: Wed Jul 7 18:35:00 1993 */ #ifndef __CEXTRACT__ #if __STDC__ /* Copyright (C) 1993 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - mfiles.c * implements memory file. A memory file is completely * read into a buffer. All operations work on that buffer. * * by Juergen.Nickelsen@cs.tu-berlin.de * * $Header: mfiles.c[4.25] Tue Jul 6 15:46:00 1993 axel@cs.tu-berlin.de proposed $ */ /* Kill an MFILE buffer pointed to by mf. Releases all memory associated with this buffer. */ void mf_kilbuf ( MFILE *mf ); /* Kill all MFILE buffers. */ void mf_killall ( void ); /* Read standard input into MFILE buffer */ MFILE *mf_readin_stdin ( void ); /* Read file fname into an MFILE buffer */ MFILE *mf_readin ( char *fname ); /* The current line is set to the next line. A pointer to the beginning of this line is returned. */ char *mf_nextline ( MFILE *mf ); /* The current line is set to the previous line. A pointer to the beginning of this line is returned. */ char *mf_prevline ( MFILE *mf ); /* Return a pointer to the specified line in mf. */ char *mf_thisline ( MFILE *mf, int lineno ); /* The file name and line number ptr points into are written into *pfilename and *plineno. If ptr does not point into an MFILE buffer, 0 is returned, 1 on success. */ int mf_locate ( char *ptr, char **pfilename, int *plineno ); /* The line number ptr points into in the buffer of mf is returned. If ptr does not point into the buffer of mf, -1 is returned. */ int mf_locate_in ( MFILE *mf, char *ptr ); /* set the current line of mf to the line ptr points to. If ptr does not point into the buffer of mf, a fatal error is raised. */ void mf_setline ( MFILE *mf, char *ptr ); #else /* __STDC__ */ /* Copyright (C) 1993 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools/shape program - mfiles.c * implements memory file. A memory file is completely * read into a buffer. All operations work on that buffer. * * by Juergen.Nickelsen@cs.tu-berlin.de * * $Header: mfiles.c[4.25] Tue Jul 6 15:46:00 1993 axel@cs.tu-berlin.de proposed $ */ /* Kill an MFILE buffer pointed to by mf. Releases all memory associated with this buffer. */ void mf_kilbuf (/* MFILE *mf */); /* Kill all MFILE buffers. */ void mf_killall (/* void */); /* Read standard input into MFILE buffer */ MFILE *mf_readin_stdin (/* void */); /* Read file fname into an MFILE buffer */ MFILE *mf_readin (/* char *fname */); /* The current line is set to the next line. A pointer to the beginning of this line is returned. */ char *mf_nextline (/* MFILE *mf */); /* The current line is set to the previous line. A pointer to the beginning of this line is returned. */ char *mf_prevline (/* MFILE *mf */); /* Return a pointer to the specified line in mf. */ char *mf_thisline (/* MFILE *mf, int lineno */); /* The file name and line number ptr points into are written into *pfilename and *plineno. If ptr does not point into an MFILE buffer, 0 is returned, 1 on success. */ int mf_locate (/* char *ptr, char **pfilename, int *plineno */); /* The line number ptr points into in the buffer of mf is returned. If ptr does not point into the buffer of mf, -1 is returned. */ int mf_locate_in (/* MFILE *mf, char *ptr */); /* set the current line of mf to the line ptr points to. If ptr does not point into the buffer of mf, a fatal error is raised. */ void mf_setline (/* MFILE *mf, char *ptr */); #endif /* __STDC__ */ #endif /* __CEXTRACT__ */ shapetools-1.4pl6.orig/src/shape/version.c100444 2013 145 204 5575345160 16646 0ustar dokoswtchar *version () { static char release[] = "shape_CM-4.9 (Tue Aug 23 17:57:17 1994 by axel@cs.tu-berlin.de)"; return release; } shapetools-1.4pl6.orig/src/shape/Shapefile100444 2013 145 6674 5423513260 16667 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for shape # # Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[8.0] Thu Jul 22 15:31:39 1993 axel@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man all:+ MAINTARGET=all ALLTARGETS=subsystems targets install:+ MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean:+ MAINTARGET=clean ALLTARGETS=subsystems doclean my_gnu:+ CC=gcc -traditional -Wall macro-ext:+ vpath=macro-ext IMPORT= NEED_STATUS # Variant activation for normal builds and installation builds #_all: all $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) +$(MISCVAR) #$(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) # $(CC) -c $(CFLAGS) $(VERSIONFILE) $(VERSIONOBJECT): $(VERSIONFILE) $(CC) -c $(CFLAGS) $(VERSIONFILE) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) disttar: $(COMPONENTS) tar cvf shape-dist.tar $(COMPONENTS) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. Dependencies=Dependencies include $(Dependencies) # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. #.BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) shapetools-1.4pl6.orig/src/shape/Makefile100444 2013 145 23552 5522263501 16516 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for shape # # Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[8.0] Fri Jan 28 20:28:08 1994 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/shape # A short name for this node system NODENAME = shape_CM # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = #SWITCHES = -DMEMDEBUG # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = $(BASE) INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. TARGET = shape # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = version.c # source VERSIONOBJECT = version.o # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = # The regular source and header files. # VARSRC and VAROBJ will be overridden by certain variants as appropriate SOURCES = dkey.c error.c files.c hash.c inherit.c macro.c main.c \ misc.c produce.c rule.c shapeopt.c \ sighand.c std.c strbuf.c varsec.c \ parser.c mfiles.c utils.c queues.c $(VARSRC) HEADERS = shape.h strbuf.h parser.h mfiles.h mffuncs.h $(VARHDR) # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = shape.1 MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. OBJECTS = main.o hash.o dkey.o macro.o rule.o files.o error.o \ produce.o std.o varsec.o misc.o sighand.o \ shapeopt.o inherit.o strbuf.o \ mfiles.o utils.o queues.o parser.o $(VERSIONOBJECT) \ $(VAROBJ) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = gcc -traditional CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = $(VARLIBS) $(LOCALLIBPATH)/libAtFStk.a\ $(LOCALLIBPATH)/libsttk.a $(LOCALLIBPATH)/libAtFS.a LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(TARGET) $(TARGET): $(LOCALLIBS) $(VARLIBS) $(OBJECTS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LOCALLIBS) $(VARLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET) to $$i; \ ln $(TARGET) $$i; \ done # Construction of a library would look like: #$(TARGET): $(OBJECTS) # ar ruv $(TARGET) $(OBJECTS); \ # $(RANLIB) $(TARGET) installtargets: $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$(TARGET): $(TARGET) @-echo "installing $(TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET); \ fi; \ cp $(TARGET) $(INSTALLBINPATH)/$(TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$$i; \ done installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/shape/Dependencies100444 2013 145 10544 5417345137 17375 0ustar dokoswtdkey.o: ./shape.h dkey.o: ./strbuf.h dkey.o: $(BASE)/include/afsys.h dkey.o: $(BASE)/include/atfs.h dkey.o: $(BASE)/include/atfstk.h dkey.o: $(BASE)/include/config.h dkey.o: $(BASE)/include/sttk.h dkey.o: dkey.c error.o: ./shape.h error.o: ./strbuf.h error.o: $(BASE)/include/afsys.h error.o: $(BASE)/include/atfs.h error.o: $(BASE)/include/atfstk.h error.o: $(BASE)/include/config.h error.o: $(BASE)/include/sttk.h error.o: error.c files.o: ./shape.h files.o: ./strbuf.h files.o: $(BASE)/include/afsys.h files.o: $(BASE)/include/atfs.h files.o: $(BASE)/include/atfstk.h files.o: $(BASE)/include/config.h files.o: $(BASE)/include/sttk.h files.o: files.c hash.o: ./shape.h hash.o: ./strbuf.h hash.o: $(BASE)/include/afsys.h hash.o: $(BASE)/include/atfs.h hash.o: $(BASE)/include/atfstk.h hash.o: $(BASE)/include/config.h hash.o: $(BASE)/include/sttk.h hash.o: hash.c inherit.o: ./shape.h inherit.o: ./strbuf.h inherit.o: $(BASE)/include/afsys.h inherit.o: $(BASE)/include/atfs.h inherit.o: $(BASE)/include/atfstk.h inherit.o: $(BASE)/include/config.h inherit.o: $(BASE)/include/sttk.h inherit.o: inherit.c macro.o: ./shape.h macro.o: ./strbuf.h macro.o: $(BASE)/include/afsys.h macro.o: $(BASE)/include/atfs.h macro.o: $(BASE)/include/atfstk.h macro.o: $(BASE)/include/config.h macro.o: $(BASE)/include/sttk.h macro.o: macro.c main.o: ./shape.h main.o: ./strbuf.h main.o: $(BASE)/include/afsys.h main.o: $(BASE)/include/atfs.h main.o: $(BASE)/include/atfstk.h main.o: $(BASE)/include/config.h main.o: $(BASE)/include/sttk.h main.o: main.c mfiles.o: ./mffuncs.h mfiles.o: ./mfiles.h mfiles.o: ./parser.h mfiles.o: ./shape.h mfiles.o: ./strbuf.h mfiles.o: $(BASE)/include/afsys.h mfiles.o: $(BASE)/include/atfs.h mfiles.o: $(BASE)/include/atfstk.h mfiles.o: $(BASE)/include/config.h mfiles.o: $(BASE)/include/sttk.h mfiles.o: mfiles.c misc.o: ./shape.h misc.o: ./strbuf.h misc.o: $(BASE)/include/afsys.h misc.o: $(BASE)/include/atfs.h misc.o: $(BASE)/include/atfstk.h misc.o: $(BASE)/include/config.h misc.o: $(BASE)/include/sttk.h misc.o: misc.c parser.o: ./mffuncs.h parser.o: ./mfiles.h parser.o: ./parser.h parser.o: ./shape.h parser.o: ./strbuf.h parser.o: $(BASE)/include/afsys.h parser.o: $(BASE)/include/atfs.h parser.o: $(BASE)/include/atfstk.h parser.o: $(BASE)/include/config.h parser.o: $(BASE)/include/sttk.h parser.o: parser.c produce.o: ./shape.h produce.o: ./strbuf.h produce.o: $(BASE)/include/afsys.h produce.o: $(BASE)/include/atfs.h produce.o: $(BASE)/include/atfstk.h produce.o: $(BASE)/include/config.h produce.o: $(BASE)/include/sttk.h produce.o: produce.c queues.o: ./parser.h queues.o: ./shape.h queues.o: ./strbuf.h queues.o: $(BASE)/include/afsys.h queues.o: $(BASE)/include/atfs.h queues.o: $(BASE)/include/atfstk.h queues.o: $(BASE)/include/config.h queues.o: $(BASE)/include/sttk.h queues.o: queues.c rule.o: ./shape.h rule.o: ./strbuf.h rule.o: $(BASE)/include/afsys.h rule.o: $(BASE)/include/atfs.h rule.o: $(BASE)/include/atfstk.h rule.o: $(BASE)/include/config.h rule.o: $(BASE)/include/sttk.h rule.o: rule.c shapeopt.o: ./shape.h shapeopt.o: ./strbuf.h shapeopt.o: $(BASE)/include/afsys.h shapeopt.o: $(BASE)/include/atfs.h shapeopt.o: $(BASE)/include/atfstk.h shapeopt.o: $(BASE)/include/config.h shapeopt.o: $(BASE)/include/sttk.h shapeopt.o: shapeopt.c sighand.o: ./shape.h sighand.o: ./strbuf.h sighand.o: $(BASE)/include/afsys.h sighand.o: $(BASE)/include/atfs.h sighand.o: $(BASE)/include/atfstk.h sighand.o: $(BASE)/include/config.h sighand.o: $(BASE)/include/sttk.h sighand.o: sighand.c std.o: ./shape.h std.o: ./strbuf.h std.o: $(BASE)/include/afsys.h std.o: $(BASE)/include/atfs.h std.o: $(BASE)/include/atfstk.h std.o: $(BASE)/include/config.h std.o: $(BASE)/include/sttk.h std.o: std.c strbuf.o: ./shape.h strbuf.o: ./strbuf.h strbuf.o: $(BASE)/include/afsys.h strbuf.o: $(BASE)/include/atfs.h strbuf.o: $(BASE)/include/atfstk.h strbuf.o: $(BASE)/include/config.h strbuf.o: $(BASE)/include/sttk.h strbuf.o: strbuf.c utils.o: ./parser.h utils.o: ./shape.h utils.o: ./strbuf.h utils.o: $(BASE)/include/afsys.h utils.o: $(BASE)/include/atfs.h utils.o: $(BASE)/include/atfstk.h utils.o: $(BASE)/include/config.h utils.o: $(BASE)/include/sttk.h utils.o: utils.c varsec.o: ./shape.h varsec.o: ./strbuf.h varsec.o: $(BASE)/include/afsys.h varsec.o: $(BASE)/include/atfs.h varsec.o: $(BASE)/include/atfstk.h varsec.o: $(BASE)/include/config.h varsec.o: $(BASE)/include/sttk.h varsec.o: varsec.c version.o: version.c shapetools-1.4pl6.orig/src/vc/ 40755 2013 145 0 5626416447 14262 5ustar dokoswtshapetools-1.4pl6.orig/src/vc/atfsit/ 40755 2013 145 0 5626416211 15541 5ustar dokoswtshapetools-1.4pl6.orig/src/vc/atfsit/atfsit.c100444 2013 145 36413 5373727503 17331 0ustar dokoswt/* * shapeTools -- atfsit * * $Header: atfsit.c[4.0] Tue May 11 15:52:13 1993 andy@cs.tu-berlin.de frozen $ * * derived from: * rcsit -- Prepare files for RCS. rcsit puts the correct headings * at the top of files to prepare them for RCS headings * and log tracking. * * Michael Cooper (mcooper@usc-oberon.arpa) * University Computing Services, USC * * 9-16-85 * */ #include #include "config.h" char *atfsit_version(); #define LENGTH 512 /* length of line */ #define TRUE 1 #define FALSE 0 #ifdef DEBUG int debugon = TRUE; #else int debugon = FALSE; #endif static char *progname; /* program name */ static char *rcsdir; /* * Messages to be printed for the user. */ static char *msg_name; static char *m_stdc = "Standard C", *m_stdcflg = "Standard C with compile flags", *m_include = "C Include", *m_fortran = "Fortran", *m_elisp = "Emacs Lisp", *m_make = "Makefile", *m_shape = "Shapefile", *m_shell = "Shell Script", *m_manual = "Manual"; /* * The headers to put at the beginning of the file(s). * Notice that the words Header and Log do not appear here * because RCS will put in the keyword substitutions when rcsit.c * is co'ed. */ static char *header; #ifdef RCSIT static char *h_stdc = "#ifndef lint\nstatic char *RCSid = \"$%s$\";\n#endif\n/*\n * $%s$\n */\n\n"; static char *h_stdcflg = "#ifndef lint\nstatic char *RCSid = \"$%s$\";\n#ifdef CFFLGS\n\ static char *ConfFlg = CFFLGS;\n\t/* should be defined from within\ Makefile */\n#endif\n#endif\n/*\n * $%s$\n */\n\n"; #else static char *h_stdc = "#ifndef lint\nstatic char *AtFSid = \"$%s$\";\n#endif\n/*\n * $%s$\n */\n\n"; static char *h_stdcflg = "#ifndef lint\nstatic char *AtFSid = \"$%s$\";\n#ifdef CFFLGS\n\ static char *ConfFlg = CFFLGS;\n\t/* should be defined from within\ Makefile */\n#endif\n#endif\n/*\n * $%s$\n */\n\n"; #endif static char *h_include = "/*\n * $%s$\n *\n * $%s$\n */\n\n"; static char *h_make = "#\n# $%s$\n#\n# $%s$\n#\n"; static char *h_shape = "#\n# $%s$\n#\n# $%s$\n#\n"; static char *h_elisp = ";;\n;; $%s$\n;; $%s$\n;;\n"; static char *h_manual = "...\n... $%s$\n... \n... $%s$\n...\n"; static char *h_fortran = "c\nc $%s$\nc\nc $%s$\nc\n"; /* * Template file names */ static char *template_c = ".template.c"; /* .c template */ static char *template_h = ".template.h"; /* .h template */ static char *template_f = ".template.f"; /* .f template */ static char *template_man = ".template.man"; /* man template */ static char *template_make = ".template.make"; /* make template */ static char *template_shape = ".template.shape"; /* shape template */ static char *template_elisp = ".template.el"; /* elisp template */ static char *template_sh = ".template.sh"; /* sh script template */ static char *tpath; /* path to template */ static char tfile[BUFSIZ]; /* template file */ static char tbuf[BUFSIZ]; /* current tfile */ /* * Command line flags */ int Iflag = FALSE; /* run ci(1) or save(1) */ int rcsflag = FALSE; /* run rcs(1) or vadm(1) */ int aflag = TRUE; /* do auto guess */ int dflag = TRUE; /* creat RCS or AtFS dir. */ int qflag = FALSE; /* be quiet! */ int cflag = FALSE; /* std c file */ int fflag = FALSE; /* fortran file */ int Fflag = FALSE; /* insert C-Flags header */ int pflag = FALSE; /* pascal file */ int eflag = FALSE; /* elisp file */ int Sflag = FALSE; /* Shapefile */ int hflag = FALSE; /* include file */ int sflag = FALSE; /* shell script */ int mflag = FALSE; /* Makefile */ int Mflag = FALSE; /* manual */ int tflag = FALSE; /* template flag */ int atfsit = FALSE; /* progam called as "atfsit" */ /* * debug - print (useless) debugging info. */ static void debug(msg) char *msg; { #ifdef DEBUG fprintf(stderr, msg); fputc('\n', stdout); #endif } /* * fatal - print error and then exit(1). */ static void fatal0(str) char *str; { fprintf(stderr, "%s: %s\n", progname, str); exit(1); } static void fatal1(format, str) char *format, *str; { char namefmt[100]; sprintf(namefmt, "%s: %s\n", progname, format); fprintf(stderr, namefmt, str); exit(1); } static void fatal2(format, str1, str2) char *format, *str1, *str2; { char namefmt[100]; sprintf(namefmt, "%s: %s\n", progname, format); fprintf(stderr, namefmt, str1, str2); exit(1); } /* * zap str with NULL's */ static void zap(str) char str[]; { int i, x; i = strlen(str); for(x = 0; x <= i; ) str[x++] = '\0'; } /* * set_flags - set & check flags */ static void set_flags() { if(cflag || eflag || hflag || mflag || Mflag || sflag || Sflag || fflag) { if(cflag) { msg_name = m_stdc; header = h_stdc; } if(eflag) { msg_name = m_elisp; header = h_elisp; } if (Fflag) { /* This is more than just cflag - axel@coma */ msg_name = m_stdcflg; header = h_stdcflg; } if(hflag) { msg_name = m_include; header = h_include; } if(mflag) { msg_name = m_make; header = h_make; } if(Mflag) { msg_name = m_manual; header = h_manual; } if(sflag) { msg_name = m_shell; header = h_make; } if(Sflag) { msg_name = m_shape; header = h_shape; } if(fflag) { msg_name = m_fortran; header = h_fortran; } } else { cflag = TRUE; set_flags(); } } /* * auto_guess - try and be intelligent and guess type of file * by looking at the suffix or the whole name * in the case of a makefile. */ static void auto_guess(file) char *file; { char *suffix; (suffix = strrchr(file, '.')) ? suffix++ : (suffix = ""); /* fixed by jmp@inesc */ if((strcmp(file, "makefile") == 0) || (strcmp(file, "Makefile") == 0) || (strcmp(file, "shapefile") == 0) || (strcmp(file, "Shapefile") == 0) || (strcmp(suffix, "mk") == 0)) { /* sys V std suffix */ mflag = TRUE; sflag = FALSE; Sflag = FALSE; cflag = FALSE; eflag = FALSE; hflag = FALSE; Mflag = FALSE; fflag = FALSE; } if((strcmp(suffix, "sh") == 0) || (strcmp(suffix, "csh") == 0)) { sflag = TRUE; Sflag = FALSE; cflag = FALSE; eflag = FALSE; hflag = FALSE; mflag = FALSE; Mflag = FALSE; fflag = FALSE; } if(strcmp(suffix, "c") == 0){ cflag = TRUE; eflag = FALSE; hflag = FALSE; mflag = FALSE; Mflag = FALSE; sflag = FALSE; Sflag = FALSE; fflag = FALSE; } if(strcmp(suffix, "el") == 0){ eflag = TRUE; cflag = FALSE; hflag = FALSE; mflag = FALSE; Mflag = FALSE; sflag = FALSE; Sflag = FALSE; fflag = FALSE; } if(strcmp(suffix, "h") == 0){ hflag = TRUE; cflag = FALSE; eflag = FALSE; mflag = FALSE; Mflag = FALSE; sflag = FALSE; Sflag = FALSE; fflag = FALSE; } if(strcmp(suffix, "f") == 0){ fflag = TRUE; hflag = FALSE; cflag = FALSE; eflag = FALSE; mflag = FALSE; Mflag = FALSE; sflag = FALSE; Sflag = FALSE; } if(strcmp(suffix, "S") == 0){ Sflag = TRUE; fflag = FALSE; hflag = FALSE; cflag = FALSE; eflag = FALSE; mflag = FALSE; Mflag = FALSE; sflag = FALSE; } if(isdigit(*suffix) != 0) { Mflag = TRUE; hflag = FALSE; cflag = FALSE; eflag = FALSE; mflag = FALSE; sflag = FALSE; Sflag = FALSE; fflag = FALSE; } set_flags(); if(!qflag || debugon) printf("Hmm. This file looks like a %s file.\n", msg_name); } /* * copy from -> to */ static void copy(from, to, mode) char *from; char *to; char *mode; { FILE *fdfrom, *fdto; char s[LENGTH]; if((fdfrom = fopen(from, "r")) == NULL) { fatal1("Cannot open %s for reading.",from); } if((fdto = fopen(to, mode)) == NULL) { fatal2("Cannot open %s for \"%s\".",to,mode); } while(fgets(s, sizeof(s), fdfrom) != NULL) fputs(s, fdto); fclose(fdfrom); fclose(fdto); } /* * checkfor(x, str) -- check for x in str. Return 1 (TRUE) if exists. * Otherwise 0 (FALSE). */ static int checkfor(x, str) char *x; char *str; { while(*str) { if(strcmp(str, x) == 0) return(TRUE); str++; } return(FALSE); } /* * lineprint - print msg in a nice line */ static void lineprint(msg) char *msg; { int len, left, right, x; len = strlen(msg); right = (75-len)/2; left = right; for(x = 0; x < right; ++x) fputc('-', stdout); printf("[ %s ]", msg); for(x = 0; x < left; ++x) fputc('-', stdout); fputc('\n', stdout); } /* * Run RCS's rcsprog on file with flags. */ static void rcs(rcsprog, file, flags) char *rcsprog; char *file; char *flags; { char buf[LENGTH]; char tmp[LENGTH]; if(!checkfor("q", flags) && qflag) flags = "q"; if(strcmp(flags, "") == 0) sprintf(buf, "%s %s", rcsprog, file); else sprintf(buf, "%s -%s %s", rcsprog, flags, file); sprintf(tmp,"Running ``%s''...\n", buf); debug(tmp); if(!qflag) { sprintf(tmp, "Start of ``%s''", buf); lineprint(tmp); } system(buf); if(!qflag) { sprintf(tmp, "End of ``%s''", buf); lineprint(tmp); } } /* * Run SHAPE/AtFS' vcprog on file with flags. */ static void atfs(vcprog, file, flags) char *vcprog; char *file; char *flags; { char buf[LENGTH]; char tmp[LENGTH]; if(strcmp(flags, "") == 0) sprintf(buf, "%s %s %s", vcprog, qflag ? "-q" : "", file); else sprintf(buf, "%s -%s %s %s", vcprog, flags, qflag ? "-q" : "", file); sprintf(tmp,"Running ``%s''...\n", buf); debug(tmp); if(!qflag) { sprintf(tmp, "Start of ``%s''", buf); lineprint(tmp); } system(buf); if(!qflag) { sprintf(tmp, "End of ``%s''", buf); lineprint(tmp); } } /* * checkdir - make RCS or AtFS directory if not present. */ static void checkdir() { if(access(atfsit ? "AtFS" : "RCS", 0) != 0){ if(!qflag || debugon) printf("Cannot find \"%s\" directory. Creating...\n", atfsit ? "AtFS" : "RCS"); if(strcmp(rcsdir, atfsit ? "AtFS" : "RCS") != 0) { if(symlink(rcsdir, atfsit ? "AtFS" : "RCS") != 0) fatal2("Symbolic link of %s to %s failed.", rcsdir, atfsit ? "AtFS" : "RCS"); } else { if(mkdir(rcsdir, 0755) != 0) fatal1("Cannot create \"%s\" directory.", rcsdir); } } } /* * get template names */ static void get_temp() { zap(tbuf); if(mflag) strcpy(tbuf, template_make); if(Mflag) strcpy(tbuf, template_man); if(hflag) strcpy(tbuf, template_h); if(cflag) strcpy(tbuf, template_c); if(eflag) strcpy(tbuf, template_elisp); if(sflag) strcpy(tbuf, template_sh); if(Sflag) strcpy(tbuf, template_shape); if(fflag) strcpy(tbuf, template_f); } int main(argc, argv) int argc; char *argv[]; { int x; char tmp[LENGTH]; char *file; char *flags; char tmpfile[32]; char *cp; FILE *fdtmp; progname = (cp = strrchr (argv[0], '/')) ? ++cp : argv[0]; if (strcmp ("rcsit", progname)) atfsit = TRUE; for (x = 1; x < argc; x++) { if (argv[x][0] != '-') break; switch (argv[x][1]) { case 'a': aflag = FALSE; break; case 'q': qflag = TRUE; break; case 'd': dflag = FALSE; break; case 'f': fflag = TRUE; break; case 'e': eflag = TRUE; break; case 'F': Fflag = TRUE; cflag = TRUE; /* Only for C-files yet */ break; case 'h': hflag = TRUE; break; case 's': sflag = TRUE; break; case 'S': Sflag = TRUE; break; case 'm': mflag = TRUE; break; case 'M': Mflag = TRUE; break; case 'i': case 'I': Iflag = TRUE; flags = &argv[x][2]; break; case 'r': case 'R': rcsflag = TRUE; flags = &argv[x][2]; break; case 't': tflag = TRUE; tpath = &argv[x][2]; break; case 'v': printf ("This is %s version %s.\n", progname, atfsit_version()); exit (0); break; case 'c': cflag = TRUE; break; default: fatal1("Unknown flag %s.",argv[x]); } } argc -= (x - 1); argv += (x - 1); if((hflag && (mflag || Mflag || cflag || eflag || Sflag)) || (mflag && (hflag || cflag || Mflag || eflag || Sflag)) || (Mflag && (cflag || hflag || mflag || eflag || Sflag)) || (Sflag && (cflag || hflag || mflag || eflag || Mflag)) || (eflag && (cflag || hflag || mflag || Mflag || Sflag)) || (cflag && (hflag || Mflag || mflag || eflag || Sflag))) { fatal0("Only ONE of -c,-e,-f,-m,-M,-h,-s,-S may be specified."); } if(Iflag && rcsflag) { fatal0("Only ONE of ``-i'' and ``-r'' may be specified."); } if(cflag || eflag || hflag || mflag || Mflag || fflag || sflag || Sflag) aflag = FALSE; if((rcsdir = getenv(atfsit ? "AtFSDIR" : "RCSDIR")) == NULL) rcsdir = atfsit ? "AtFS" : "RCS"; if(Iflag && dflag) checkdir(); /* Make RCS or AtFS directory for ci or save */ if((!tflag) && ((tpath = getenv ("TEMPLATES")) != NULL)) tflag = TRUE; /* fixed by axel@coma.uucp */ if((tpath == NULL) && /* fixed by jmp@inesc */ ((tpath = getenv("TEMPLATES")) == NULL)) if((tpath = getenv("HOME")) == NULL) fatal0("Cannot find environment variable HOME or TEMPLATE"); /* * make tmp file once. */ sprintf (tmpfile, "/tmp/%s%d", progname, getpid()); while (--argc) { /* Main loop */ file = *++argv; sprintf(tmp, "...file (*++argv) = %s...", file); debug(tmp); if(access(file, 4) != 0) fatal1("Cannot access %s. No read permission OR file does not exist.", file); if((fdtmp = fopen(tmpfile, "w")) == NULL) { fatal1("Cannot open tmpfile (%s).", tmpfile); } if(aflag) auto_guess(file); /* try and guess file type */ else set_flags(); /* check and set flags */ if(tflag) { /* * first get names of templates, then create * path name to it. */ get_temp(); sprintf(tfile, "%s/%s", tpath, tbuf); } if(access(tfile, 0) == 0 && tflag) { if(!qflag || debugon) printf("Adding %s header file to %s...", msg_name, file); copy(tfile, tmpfile, "w"); copy(file, tmpfile, "a"); } else { if(!qflag || debugon) printf( "Adding default header (%s format) to %s...", msg_name, file); /* * put the Keywords into header string */ if (atfsit) sprintf(tmp, header, "__Header", "__Log"); else sprintf(tmp, header, "Header", "Log"); fputs(tmp, fdtmp); /* * fclose'em, just in case. */ fclose(fdtmp); copy(file, tmpfile, "a"); } unlink(file); copy(tmpfile, file, "w"); unlink(tmpfile); if(!qflag || debugon) printf("done.\n"); if (Fflag && (!qflag || debugon)) fputs ("-> Don't forget to define CFFLGS on compiler commandline <-\n", stdout); if(Iflag){ if (atfsit) { atfs("save", file, flags); if(Mflag) atfs("vadm", file, "setc '... '"); else if (cflag) atfs("vadm", file, "setc ' * '"); else if (eflag) atfs("vadm", file, "setc ';; '"); else if (fflag) atfs("vadm", file, "setc 'c '"); else if (pflag) atfs("vadm", file, "setc ' * '"); else if (sflag) atfs("vadm", file, "setc '# '"); else if (Sflag) atfs("vadm", file, "setc '# '"); else if (mflag) atfs("vadm", file, "setc '# '"); else if (hflag) atfs("vadm", file, "setc ' * '"); } else { rcs("ci", file, flags); if(Mflag){ /* kludge to tell rcs about manuals */ rcs("rcs", file, "c'... '"); /* * kludge part 2 - if the user tried a ci * with a -l option, then the header is * messed up in the currently checked out * man file. So we have to co the file to * clean up the header. Plus we use the * -l option of co to insure file locking. */ if(checkfor("l", flags)){ unlink(file); rcs("co", file, "l"); } } } } if(rcsflag) if (atfsit) atfs("vadm", file, flags); else rcs("rcs", file, flags); } return (0); } shapetools-1.4pl6.orig/src/vc/atfsit/atfsitvers.c100444 2013 145 262 5522264740 20155 0ustar dokoswt/* * Prototype version procedure */ char *atfsit_version () { static char release[] = "atfsit-1.15 (Tue Aug 23 17:57:56 1994 by andy@cs.tu-berlin.de)"; return release; } shapetools-1.4pl6.orig/src/vc/atfsit/Shapefile100444 2013 145 6244 5414050531 17457 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for atfsit # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[4.0] Tue Jun 29 16:29:18 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/vc/atfsit/Makefile100444 2013 145 22311 5426221712 17311 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for atfsit # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[4.0] Fri Jul 30 17:39:32 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/vc/atfsit # A short name for this node system NODENAME = atfsit # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = $(BASE) INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. TARGET = atfsit # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = atfsitvers.c # source VERSIONOBJECT = atfsitvers.o # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = # The regular source and header files. SOURCES = atfsit.c HEADERS = # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = atfsit.1 MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. OBJECTS = atfsit.o $(VERSIONOBJECT) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(TARGET) $(TARGET): $(LOCALLIBS) $(OBJECTS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET) to $$i; \ ln $(TARGET) $$i; \ done installtargets: $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$(TARGET): $(TARGET) @-echo "installing $(TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET); \ fi; \ cp $(TARGET) $(INSTALLBINPATH)/$(TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$$i; \ done installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/vc/atfsit/Dependencies100444 2013 145 121 5205001605 20105 0ustar dokoswtatfsit.o: $(BASE)/include/config.h atfsit.o: atfsit.c atfsitvers.o: atfsitvers.c shapetools-1.4pl6.orig/src/vc/rcs2atfs/ 40755 2013 145 0 5626416243 16003 5ustar dokoswtshapetools-1.4pl6.orig/src/vc/rcs2atfs/afind.c100444 2013 145 4021 5414051653 17313 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * do something like opendir(), readdir(), closedir() * * Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) * * $Header: afind.c[3.0] Tue Jun 29 16:37:58 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "rcs2atfs.h" #include "functions.h" /* * initializes reading files from the specified directory. f_state keeps * the status information needed by afind_read() and afind_close(). */ int afind_init(dir, f_state) char *dir ; struct AFIND_STATE *f_state ; { Af_attrs attrs ; int found ; af_initattrs(&attrs) ; attrs.af_gen = attrs.af_rev = AF_BUSYVERS ; strcpy(attrs.af_syspath, dir) ; found = af_find(&attrs, &f_state->set) ; f_state->counter = 0 ; return found ; } /* * returns a filename from the directory with which f_state was initialized. * the returned string is freeable. If all names have been read, NULL is * returned */ char *afind_read(f_state) struct AFIND_STATE *f_state ; { Af_key key ; if (f_state->counter >= af_nrofkeys(&f_state->set)) { return NULL ; } af_setgkey(&f_state->set, f_state->counter++, &key) ; return check_strdup(af_retattr (&key, AF_ATTUNIXNAME)); } /* * completes reading files with afind, frees memory */ void afind_close(f_state) struct AFIND_STATE *f_state ; { af_dropset(&f_state->set) ; #ifdef DEBUG bzero(f_state, sizeof(struct AFIND_STATE)) ; #endif } /*EOF*/ shapetools-1.4pl6.orig/src/vc/rcs2atfs/main.c100444 2013 145 16040 5414051627 17203 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * main module of rcs2atfs * * Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) * * $Header: main.c[3.0] Tue Jun 29 16:38:02 1993 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "sttk.h" #include "rcs2atfs.h" #include "functions.h" char *progname ; /* for usage message etc. */ int warnings = 0 ; /* no. of warnings occurred (not used) */ int errors = 0 ; /* no. of errors occured */ bool use_pipe = true ; /* use pipe to shell */ bool recursive = false ; /* recursively descend dir.-tree */ bool keep_quiet = false ; /* don't issue warnings */ /* description of options for ParseArgs: * option string, whattodo, opt.function, var. to set, ??? */ static StOptDesc optDesc[] = { { "o", PCALL|PARG, read_out_name, NULL, NULL}, { "R", PSET, NULL, &recursive, NULL }, { "q", PSET, NULL, &keep_quiet, NULL }, { "version", PCALL, (int (*)()) echo_version, NULL,NULL}, { NULL, 0, NULL, NULL, NULL } } ; char *shellscript ; /* name of generated shell script */ /*ARGSUSED*/ int read_out_name(o, arg) char *o, *arg ; { shellscript = arg ; use_pipe = false ; return 0 ; } void usage() { (void) fprintf(stderr, "Usage: %s [-o outputfile] [-q] history ...\n", progname) ; (void) fprintf(stderr, " %s [-o outputfile] [-q] -R directory ...\n", progname) ; } /* main function (this should be obvious) */ int main(argc, argv) int argc ; char **argv ; { char *rcs_history ; /* name of RCS history to convert */ int nargc ; /* argc changed by ParseArgs */ char **nargv ; /* argv changed by ParseArgs() */ FILE *out ; /* shell commands are written here */ extern int pclose() ; extern int fclose() ; /* extract name of this program */ progname = strrchr(argv[0], '/') ; progname = (progname == NULL) ? argv[0] : progname + 1 ; #if defined(sun) && defined(DEBUG) /* call life saver */ malloc_debug(2) ; #endif /* sun, DEBUG */ /* parse argument list for option settings */ if (stParseArgs(argc, argv, &nargc, &nargv, optDesc) || nargc < 2) { usage() ; (void) exit(1); } /* determine command output */ if (use_pipe) { /* open pipe to Bourne Shell */ if ((out = popen(BOURNE_SHELL, "w")) == NULL) { fatal(POPEN_SHELL, sys_errlist[errno]) ; } } else { /* open output file for script */ if ((out = fopen(shellscript, "w")) == NULL) { fatal(sys_errlist[errno], shellscript) ; } /* insert some header into shell script (#!/bin/sh etc.) */ fprintf(out, SCRIPT_HEADER, "rcs2atfs-1.9") ; } /* repeat for all arguments */ *nargv++; /* skip command name */ while ((rcs_history = *nargv++) != NULL) { convert(rcs_history, out) ; } if (!keep_quiet) fprintf(out, "\necho Done.\n") ; fprintf(out, "exit\n") ; (use_pipe ? pclose : fclose) (out) ; return errors ; } /* convert fname, if recursive, maybe directory */ void convert(fname, out) char *fname ; FILE *out ; { struct RCSFILE *rcsfile ; /* to be returned by readin_rcsfile() */ char *newfname ; /* to construct a new filename */ char *dirname ; /* dir file resides in */ struct AFIND_STATE astate; /* state information for afind */ char *found_file ; /* file found by afind */ switch (file_type(fname)) { case f_plain: /* is a plain file */ if (recursive) { return ; /* comes from readdir if RCS archive * exists; we will get at it later */ } else { /* if not recursive: does a history exist? */ rcsfile = readin_rcsfile(fname) ; if (rcsfile != NULL) { if (atfs_exists(fname)) { error(AtFS_EXISTS, fname) ; } else { dirname = strip_last(fname) ; make_shell_script(dirname, rcsfile, out) ; (void) free(dirname) ; } free_rcsfile(rcsfile) ; } } break ; case f_dir: /* is a directory */ if (! recursive) { /* we ignore dirs if not recursive */ warning(NOT_RECURSIVE, fname) ; return ; } /* if recursive, we look into them */ if (afind_init(fname, &astate) == -1) { warning("", fname) ; af_perror(fname) ; return ; } while ((found_file = afind_read(&astate)) != NULL) { /* don't look at itself, parent, * and AtFS directories */ if (!strcmp(found_file, "..") || !strcmp(found_file, ".") || !strcmp(found_file, AF_SUBDIR) || !strcmp(found_file, "AFS")) { continue ; } newfname = addstr3(fname, "/", found_file) ; free(found_file) ; convert(newfname, out) ; free(newfname) ; } afind_close(&astate) ; break ; case f_rcs: /* is RCS archive file */ rcsfile = readin_rcsfile(fname) ; if (rcsfile != NULL) { dirname = strip_last(fname) ; if (dirname != NULL && file_type(dirname) == f_rcsdir) { /* is RCS archive in RCS directory */ char *tmp = dirname ; dirname = strip_last(dirname) ; free(tmp) ; } newfname = addstr3(dirname, "/", rcsfile->working_file) ; if (atfs_exists(newfname)) { error(AtFS_EXISTS, newfname) ; } else { make_shell_script(dirname, rcsfile, out) ; } free(dirname) ; free(newfname) ; free_rcsfile(rcsfile) ; } break ; case f_rcsdir: /* is RCS directory */ convert_rcsdir(fname, out) ; break ; default: ; /* can only be f_error, but that doesn't * matter anymore */ } } /* convert a directory named RCS */ void convert_rcsdir(rdir, out) char *rdir ; FILE *out ; { DIR *dirp ; /* for reading... */ struct dirent *dep ; /* ... directory entries */ struct RCSFILE *rcsfile ; /* to be returned by readin_rcsfile() */ char *basedir ; /* name of dir. RCS directory lies in */ char *rcs_archive ; /* name of RCS archive in rdir */ /* where is the working dir. of this RCS archive? */ basedir = strip_last(rdir) ; /* may be NULL */ if ((dirp = opendir(rdir)) == NULL) { warning(sys_errlist[errno], rdir) ; free(rdir) ; return ; } while ((dep = (struct dirent *)readdir(dirp))) { rcs_archive = addstr3(rdir, "/", dep->d_name) ; if (file_type(rcs_archive) == f_rcs) { /* convert only RCS archives */ rcsfile = readin_rcsfile(rcs_archive) ; if (rcsfile != NULL) { char *tmp = addstr3(basedir, "/", rcsfile->working_file) ; if (atfs_exists(tmp)) { error(AtFS_EXISTS, tmp) ; } else { make_shell_script(basedir, rcsfile, out) ; } free(tmp) ; free_rcsfile(rcsfile) ; } } free(rcs_archive) ; } if (basedir != NULL) free(basedir) ; closedir(dirp) ; } /*EOF*/ shapetools-1.4pl6.orig/src/vc/rcs2atfs/out.c100444 2013 145 10121 5462032721 17055 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * output module for rcs2atfs * * Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) * * $Header: out.c[3.1] Fri Oct 22 20:47:55 1993 nickel@cs.tu-berlin.de frozen $ */ #include "rcs2atfs.h" #include "functions.h" /* convert a single revision */ void convert_revision(out, wkfile, branches, rev, initial, comment_leader) FILE *out ; /* to shell script to write into */ char *wkfile ; /* name of working file */ bool branches ; /* branches exist */ struct RCSREV *rev ; /* revision struct */ bool initial ; /* this is the initial revision, * no locking required */ char *comment_leader ; /* comment leader string */ { struct SYMNAME *sym ; (void) fprintf(out, "\n\n# %s[%s]\n\n", wkfile, rev->number) ; if (!keep_quiet) { fprintf(out, "echo -n '[%s] '\n", rev->number) ; } /* lock previous version */ if (! initial) { fprintf(out, "vadm -q -lock %s \n", wkfile) ; } /* check out appropriate revision */ fprintf(out, "co -q -%s %s\n", rev->number, wkfile) ; /* set atime and mtime */ fprintf(out, "utime %ld %ld %s\n", rev->date, rev->date, wkfile) ; /* save as AtFS version with log message */ if (! branches) { /* we can only keep version numbers if no branches exist */ fprintf(out, "save -q -f -m \"%s\" %s[%s]\n", rev->log_message ? rev->log_message : "", wkfile, rev->number + 1) ; } else { fprintf(out, "save -q -f -m \"%s\" %s\n", rev->log_message, wkfile) ; } /* set comment leader */ fprintf(out, "vadm -q -setc \"%s\" %s\n", comment_leader, wkfile) ; /* set author */ fprintf(out, "vadm -q -chaut %s %s\n", rev->author, wkfile) ; /* set symbolic names */ for (sym = rev->symbolic_names; sym != NULL; sym = sym->next) { (void) fprintf(out, "vadm -q -symbolic %s %s\n", sym->symname, wkfile) ; } /* set state as AtFS-UDA */ fprintf(out, "vadm -q -setuda RCSstate='%s' %s\n", rev->state ? rev->state : "", wkfile) ; /* set RCS revision number as symbolic name */ fprintf(out, "vadm -q -symbolic %s %s\n", rev->number, wkfile) ; /* set AtFS state if RCS state is something known */ if (! strcmp(rev->state, "Stab")) { /* set state to proposed */ fprintf(out, "vadm -q -promote %s\n", wkfile) ; } else if (! strcmp(rev->state, "Rel")) { /* set state to published */ fprintf(out, "vadm -q -promote %s\n", wkfile) ; fprintf(out, "vadm -q -promote %s\n", wkfile) ; } } /* build shell script for converting the archive */ void make_shell_script(directory, rcsfile, out) char *directory ; struct RCSFILE *rcsfile ; FILE *out ; { struct RCSREV *rev ; char *wkfile = rcsfile->working_file ; /* change working directory */ if (directory != NULL) { fprintf(out, "(cd %s\n\n", directory) ; } /* insert messages */ if (!keep_quiet) { fprintf(out, "echo %s:\n\n", rcsfile->rcs_file) ; } /* create AtFS directory, don't complain if it exists */ fprintf(out, "mkdir %s 2> /dev/null\n", AtFSDIR) ; /* convert first revision (without locking) */ rev = rcsfile->revisions ; convert_revision(out, wkfile, rcsfile->branches, rev, true, rcsfile->comment_leader) ; /* other revisions */ for (rev = rev->next ; rev != NULL; rev = rev->next) { convert_revision(out, wkfile, rcsfile->branches, rev, false, rcsfile->comment_leader) ; } if (!keep_quiet) { fprintf(out, "echo\n") ; } if (directory != NULL) { fprintf(out, ")\n") ; } } /*EOF*/ shapetools-1.4pl6.orig/src/vc/rcs2atfs/readin.c100444 2013 145 33427 5414051551 17525 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * read in rlog output for rcs2atfs * * Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) * * $Header: readin.c[3.0] Tue Jun 29 16:38:11 1993 andy@cs.tu-berlin.de frozen $ */ #include "rcs2atfs.h" #include "functions.h" #include "sttk.h" /* read rlogin output into a struct RCSFILE */ struct RCSFILE *readin_rcsfile(fname) char *fname ; { char *rlog_command ; /* command to be executed in the pipe */ FILE *rlog_pipe ; /* pipe for rlog command */ char input_line[LINELENGTH + 1] ; /* line for reading from pipe */ bool file_separator_seen ; /* rlog output completely read? */ read_state_t read_state ; /* state of reader */ struct RCSFILE *rcsfile ; /* pointer to struct being filled */ bool use_old_line ; /* don't read a new line, use old one */ struct SYMNAME *symname_list ; /* lst of symbolic names */ /* open pipe to rlog command */ rlog_command = addstr(RLOG_COMMAND, fname) ; if ((rlog_pipe = popen(rlog_command, "r")) == NULL) { fatal(POPEN_RLOG, rlog_command) ; } free(rlog_command) ; rlog_command = NULL ; /* initialize variables for the reader */ symname_list = NULL ; /* no symbolic names yet */ rcsfile = new_rcsfile() ; /* malloc and initialize */ file_separator_seen = false ; /* end of rlog output not yet seen */ read_state = header ; /* reader is in the header */ use_old_line = false ; /* read a new line */ /* while loop terminates, when file separator has been seen * or no more input is available. If we have to use the line * previously read, we don't read a new one. */ while (! file_separator_seen && (use_old_line || fgets(input_line, LINELENGTH, rlog_pipe))) { /* if a new line has been read, we remove a trailing newline * character. If there is none, we skip the rest of the line. */ if (! use_old_line) { /* remove newline */ char *newline = strchr(input_line, '\n') ; if (newline != NULL) { *newline = '\0' ; } else { /* or throw away the rest of the line */ input_line[LINELENGTH] = '\0' ; while (fgetc(rlog_pipe) != '\n') ; } } else { /* must be false for the next run */ use_old_line = false ; } /* */ switch (read_state) { /* reader is in header of rlog output */ case header: /* checking for one-line fields */ if (!strncmp(input_line, K_rcsfile, strlen(K_rcsfile))) { rcsfile->rcs_file = check_strdup(input_line + strlen(K_rcsfile) + 1) ; } else if (!strncmp(input_line, K_wrkfile, strlen(K_wrkfile))) { char *wfile = check_strdup(input_line + strlen(K_wrkfile) + 1); /* Make sure NO path is left in rcsfile->working_file. * That's better than sometimes and sometimes not and I * don't know when. */ rcsfile->working_file = basename(wfile) ; free(wfile) ; } else if (!strncmp(input_line, K_comlead, strlen(K_comlead))) { char *tmp = check_strdup(input_line + strlen(K_comlead) + 1) ; *strrchr(tmp, '\"') = '\0' ; rcsfile->comment_leader = sh_quote(tmp) ; free(tmp) ; } else /* fields with more than one line require a status change. */ if (!strncmp(input_line, K_descr, strlen(K_descr))) { /* read description */ read_state = description ; } else if (!strncmp(input_line, K_locks, strlen(K_locks))) { read_state = locks ; /* grumble about locks */ } else if (!strncmp(input_line, K_alist, strlen(K_alist))) { /* ignore access list */ read_state = skip ; } else if (!strncmp(input_line, K_symnames, strlen(K_symnames))) { /* read symbolic names */ read_state = symnames ; } break ; case skip: /* skip over lines beginning with whitespace */ if (! isspace(input_line[0])) { /* switch back to "header" if line does not begin with whitespace and keep line in buffer. */ read_state = header ; use_old_line = true ; } break ; case locks: /* look at locks */ /* if line doesn't begin with whitespace, it is another field */ if (! isspace(input_line[0])) { read_state = header ; use_old_line = true ; break ; } rcsfile->locks = true ; warning(LOCKED_VERSIONS, rcsfile->rcs_file) ; break ; case symnames: /* read symbolic names */ { char *nbegin = input_line, *colon ; struct SYMNAME *symname ; int length ; /* if line doesn't begin with whitespace, it is another field */ if (! isspace(input_line[0])) { read_state = header ; use_old_line = true ; break ; } /* extract symbolic name and revision number */ while (isspace(*++nbegin)) ; colon = strchr(nbegin, ':') ; length = colon - nbegin ; if (colon == NULL) { error(NO_COLON, rcsfile->rcs_file) ; free_rcsfile(rcsfile) ; pclose(rlog_pipe) ; return NULL ; } symname = new_symname() ; symname->symname = check_malloc(length + 1) ; strncpy0(symname->symname, nbegin, length) ; symname->revision = check_strdup(colon + 2) ; symname->next = symname_list ; symname_list = symname ; } break ; case description: /* read description of RCS file */ /* if line is separator, it doesn't belong to the description */ if (! strcmp(input_line, K_revsep)) { read_state = revision1 ; break ; } /* allocate space for next line of description */ if (rcsfile->description == NULL) { rcsfile->description = check_calloc(strlen(input_line) + 2, 1) ; /* needs to be zeroed out initially */ } else { rcsfile->description = check_realloc(rcsfile->description, strlen(rcsfile->description) + strlen(input_line) + 2) ; } /* copy contents of line */ strcat(rcsfile->description, input_line) ; strcat(rcsfile->description, "\n") ; break ; case revision1: /* first line of a revision */ { char *scan, *scan2 ; struct RCSREV *rev ; /* consistency check */ if (strncmp(input_line, K_revision, strlen(K_revision))) { error(NO_REVISION, rcsfile->rcs_file) ; free_rcsfile(rcsfile) ; pclose(rlog_pipe) ; return NULL ; } /* copy contents into allocated RCSREV struct, insert * struct into list of revisions. */ rev = new_rcsrev() ; scan = input_line + strlen(K_revision) ; scan2 = scan ; while (*scan2 != '\0' && !isspace(*++scan2)) ; rev->number = check_malloc(scan2 - scan + 2) ; rev->number[0] = 'r' ; strncpy0(rev->number + 1, scan, scan2 - scan) ; rev->next = rcsfile->revisions ; rcsfile->revisions = rev ; rcsfile->no_of_revs++ ; read_state = revision2 ; } break ; case revision2: /* second line of revision */ { char *scan, *scan2, *datestring ; struct RCSREV *rev = rcsfile->revisions ; /* consistency check */ if (strncmp(input_line, K_date, strlen(K_date))) { error(NO_DATE, rcsfile->rcs_file) ; free_rcsfile(rcsfile) ; pclose(rlog_pipe) ; return NULL ; } /* extract and convert date */ scan = strchr(input_line, ';') ; scan2 = input_line + strlen(K_date) ; datestring = strndup(scan2, scan - scan2) ; rev->date = stMktime(datestring) ; free(datestring) ; while (isspace(*++scan)) ; /* consistency check */ if (strncmp(scan, K_author, strlen(K_author))) { error(NO_AUTHOR, rcsfile->rcs_file) ; free_rcsfile(rcsfile) ; pclose(rlog_pipe) ; return NULL ; } /* extract author field */ scan += strlen(K_author) ; scan2 = strchr(scan, ';') ; rev->author = check_malloc(scan2 - scan + 1) ; strncpy0(rev->author, scan, scan2 - scan) ; scan = scan2 + 1 ; while (isspace(*++scan)) ; /* consistency check */ if (strncmp(scan, K_state, strlen(K_state))) { error(NO_STATUS, rcsfile->rcs_file) ; free_rcsfile(rcsfile) ; pclose(rlog_pipe) ; return NULL ; } /* extract state */ scan +=strlen(K_state) ; scan2 = strchr(scan, ';') ; rev->state = check_malloc(scan2 - scan + 1) ; strncpy0(rev->state, scan, scan2 - scan) ; read_state = log_msg ; } break ; case log_msg: /* log message of revision */ { struct RCSREV *rev = rcsfile->revisions ; char *quoted_line ; /* input line after quoting \ and $ */ /* if line is revision separator or file separator, * log message is over */ if (!strcmp(input_line, K_revsep)) { read_state = revision1 ; break ; } if (!strcmp(input_line, K_filesep)) { read_state = header ; file_separator_seen = true ; break ; } /* perhaps it is a "branches" line */ if (!strncmp(input_line, K_branches, strlen(K_branches))) { if (! rcsfile->branches) { /* we haven't warned yet */ warning(BRANCHES, rcsfile->rcs_file) ; } rcsfile->branches = true ; break ; } /* quote \ and $ in input_line */ quoted_line = sh_quote(input_line) ; /* allocate space for log message */ if (rev->log_message == NULL) { /* I use calloc(3) bcause allocated space * must have a '\0' at the beginning for strcat(3) */ rev->log_message = check_calloc(strlen(quoted_line) + 2, 1) ; } else { rev->log_message = check_realloc(rev->log_message, strlen(rev->log_message) + strlen(quoted_line) + 2) ; } /* copy current line of log message */ strcat(rev->log_message, quoted_line) ; strcat(rev->log_message, "\n") ; } break ; default: /* this must never happen */ fatal(MIND_LOST, MUSTNOT) ; } } if (pclose(rlog_pipe) != 0) { error(RLOG_FAILED, fname) ; free_rcsfile(rcsfile) ; return NULL ; } if (! check_rcsfile(rcsfile)) { error(CHECK_FAILED, fname) ; free_rcsfile(rcsfile) ; return NULL ; } sort_revisions(rcsfile) ; apply_symnames(rcsfile, symname_list) ; return rcsfile ; } /* The name of the following two functions should have been * "compare_revisions_by_number" and "compare_revisions_by_date", but * I guess there still some compilers that treat only the first some * (10? 8? 6?) characters of an identifier as significant. (WHY?!) * These two are needed for qsort()ing an array of revision pointers. */ int number_compare_revisions(r1, r2) struct RCSREV **r1, **r2 ; { int r1maj, r1min, r2maj, r2min ; /* major and minor revision numbers * of revisions r1 and r2 */ if (sscanf((*r1)->number, "r%d.%d", &r1maj, &r1min) != 2 || sscanf((*r2)->number, "r%d.%d", &r2maj, &r2min) != 2) { fatal(REV_CORRUPT, MUSTNOT) ; } if (r1maj < r2maj) { return -1 ; } else if (r1maj > r2maj) { return 1 ; } else { /* so the majors must be equal */ if (r1min < r2min) { return -1 ; } else if (r1min > r2min) { return 1 ; } else { /* the minors, too */ return 0 ; } } } int date_compare_revisions(r1, r2) struct RCSREV **r1, **r2 ; { if ((*r1)->date < (*r2)->date) { return -1 ; } else if ((*r1)->date > (*r2)->date) { return 1 ; } else { return 0 ; } } /* sort revisions by revision number, if branches exist by date */ void sort_revisions(rcsfile) struct RCSFILE *rcsfile ; { struct RCSREV **pointers ; /* to store a pointer to every r. in */ struct RCSREV *rev ; /* pointer to a revision */ int (*compare)() ; /* for qsort() */ int i ; /* counter and index into pointers[] */ /* copy pointers to revisions into array */ pointers = (struct RCSREV **) check_malloc(sizeof(struct RCSREV *) * rcsfile->no_of_revs) ; for (rev = rcsfile->revisions, i = 0; rev != NULL; rev = rev->next, i++) { if (i == rcsfile->no_of_revs) { fatal(BAD_REVNO, MUSTNOT) ; } pointers[i] = rev ; } /* sort array */ compare = rcsfile->branches ? date_compare_revisions : number_compare_revisions ; qsort(pointers, i, sizeof(struct RCSREV *), compare) ; /* and hang to rcsfile structure */ rcsfile->revisions = NULL ; while (--i > -1) { pointers[i]->next = rcsfile->revisions ; rcsfile->revisions = pointers[i] ; } free(pointers) ; } /* check if all needed fields in rcsfile are present */ bool check_rcsfile(rcsfile) struct RCSFILE *rcsfile ; { struct RCSREV *rev ; int a ; if (rcsfile->working_file == NULL || rcsfile->comment_leader == NULL || rcsfile->revisions == NULL) { return false ; } for (rev = rcsfile->revisions; rev != NULL; rev = rev->next) { if (rev->number == NULL || sscanf(rev->number, "r%d.%d", &a, &a) != 2 || rev->author == NULL) { return false ; } } return true ; } /* apply symbolic names to apropriate revisions */ void apply_symnames(rcsfile, symname_list) struct RCSFILE *rcsfile ; struct SYMNAME *symname_list ; { struct RCSREV *rev ; struct SYMNAME *sym ; /* Yes, I know it is an O(n^2) algorithm, but I don't think * it is worth more effort. */ while (symname_list != NULL) { for (rev = rcsfile->revisions; rev != NULL; rev = rev->next) { if (!strcmp(rev->number + 1, symname_list->revision)) { sym = symname_list ; symname_list = symname_list->next ; sym->next = rev->symbolic_names ; rev->symbolic_names = sym ; break ; /* save a few nanoseconds */ } } if (rev == NULL) { /* for-loop came to an end */ warning(BOGUS_SYMNAME, symname_list->symname) ; symname_list = symname_list->next ; } } } /*EOF*/ shapetools-1.4pl6.orig/src/vc/rcs2atfs/utils.c100444 2013 145 21644 5414051512 17416 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * Utility functions for rcs2atfs * * Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) * * $Header: utils.c[3.0] Tue Jun 29 16:38:16 1993 andy@cs.tu-berlin.de frozen $ */ #include "rcs2atfs.h" #include "functions.h" #include /* * The memory mamagement functions do the following: allocate, check * if result is valid, initialize fields if necessary */ /*** raw allocators ***/ /* allocate memory and check */ char *check_malloc(size) unsigned size ; { char *tmp ; tmp = malloc(size) ; if (tmp == NULL) { fatal(NOMORECORE, NULL) ; } return tmp ; } /* reallocate memory and check */ char *check_realloc(ptr, size) char *ptr ; unsigned size ; { char *tmp ; tmp = realloc(ptr, size) ; if (tmp == NULL) { fatal(NOMORECORE, NULL) ; } return tmp ; } /* callocate memory and check */ char *check_calloc(nelem, elsize) unsigned nelem, elsize ; { char *tmp ; tmp = calloc(nelem, elsize) ; if (tmp == NULL) { fatal(NOMORECORE, NULL) ; } return tmp ; } /*** structure allocators ***/ /* allocate and initialize struct RCSFILE */ struct RCSFILE *new_rcsfile() { struct RCSFILE *new ; new = (struct RCSFILE *) check_malloc(sizeof(struct RCSFILE)) ; new->dirname = NULL ; new->rcs_file = NULL ; new->working_file = NULL ; new->locks = false ; new->comment_leader = NULL ; new->description = NULL ; new->revisions = NULL ; new->branches = false ; new->no_of_revs = 0 ; new->next = NULL ; return new ; } /* allocate and initialize struct RCSREV */ struct RCSREV *new_rcsrev() { struct RCSREV *new ; new = (struct RCSREV *) check_malloc(sizeof(struct RCSREV)) ; new->next = NULL ; new->number = NULL ; new->date = 0 ; new->author = NULL ; new->state = NULL ; new->log_message = NULL ; new->symbolic_names = NULL ; return new ; } /* allocate and initialize struct SYMNAME */ struct SYMNAME *new_symname() { struct SYMNAME *new ; new = (struct SYMNAME *) check_malloc(sizeof(struct SYMNAME)) ; new->next = NULL ; new->revision = NULL ; new->symname = NULL ; return new ; } /*** free structures ***/ /* free memory allocated for a struct RCSFILE */ void free_rcsfile(rp) struct RCSFILE *rp ; { (void) free(rp->rcs_file) ; (void) free(rp->working_file) ; (void) free(rp->comment_leader) ; (void) free(rp->description) ; (void) free_rev_chain(rp->revisions) ; (void) free((char *) rp) ; } /* free memory allocated for a chain of struct RCSREV */ void free_rev_chain(rp) struct RCSREV *rp ; { struct RCSREV *tmp ; while (rp) { tmp = rp ; rp = rp->next ; free_rcsrev(tmp) ; } } /* free memory allocated for a struct RCSREV */ void free_rcsrev(rp) struct RCSREV *rp ; { (void) free(rp->number) ; (void) free(rp->author) ; (void) free(rp->state) ; (void) free(rp->log_message) ; (void) free_symnames(rp->symbolic_names) ; } /* free memory allocated for a chain of struct SYMNAME */ void free_symnames(sp) struct SYMNAME *sp ; { struct SYMNAME *tmp ; while (sp) { tmp = sp ; sp = sp->next ; (void) free(tmp->symname) ; (void) free(tmp->revision) ; } } /*** string functions ***/ /* duplicate string with check */ char *check_strdup(s) char *s ; { char *new ; new = malloc(strlen(s) + 1) ; if (new == NULL) { fatal(NOMORECORE, NULL) ; } strcpy(new, s) ; return new ; } /* like strdup, but only n characters * the resulting string is null padded, freeable */ char *strndup(s, n) char *s ; int n ; { char *tmp = check_malloc(n + 1) ; strncpy0(tmp, s, n) ; return tmp ; } /* return a string concatenated from s1, s2, and s3. * The returned string is freeable. * Each argument may be NULL. If all are NULL, NULL is returned. */ char *addstr3(s1, s2, s3) char *s1, *s2, *s3 ; { if (s1 == NULL) { return addstr(s2, s3) ; } else if (s2 == NULL) { return addstr(s1, s3) ; } else if (s3 == NULL) { return addstr(s1, s2) ; } else { /* Wow! None is NULL! */ char *tmp = check_malloc(strlen(s1) + strlen(s2) + strlen(s3) + 1) ; strcpy(tmp, s1) ; strcat(tmp, s2) ; strcat(tmp, s3) ; return tmp ; } } /* return a string concatenated from s1 and s2. * The returned string is freeable. * Each argument may be NULL, if both, NULL is returned. */ char *addstr(s1, s2) char *s1, *s2 ; { if (s1 == NULL) { return s2 ; /* if s2 is also NULL, NULL is returned */ } else if (s2 == NULL) { return s1 ; } else { /* both not NULL */ char *tmp = check_malloc(strlen(s1) + strlen(s2) + 1) ; strcpy(tmp, s1) ; strcat(tmp, s2) ; return tmp ; } } /* safe strncpy with null padding but no return value */ void strncpy0(s1, s2, n) char *s1, *s2 ; int n ; { strncpy(s1, s2, n) ; s1[n] = '\0' ; } /* safe strncat with null padding but no return value */ void strncat0(s1, s2, n) char *s1, *s2 ; int n ; { int previous = strlen(s1) ; strncat(s1, s2, n) ; s1[previous + n] = '\0' ; } /*** errors and warnings ***/ /* print fatal error message and exit */ void fatal(message, message2) char *message ; char *message2 ; { (void) fprintf(stderr, "%s fatal error: %s", progname, message) ; if (message2 != NULL) fprintf(stderr, " (%s)", message2) ; fputc('\n', stderr) ; if (shellscript != NULL) { (void) unlink(shellscript) ; } (void) exit(3) ; } /* print error message */ void error(message, message2) char *message ; char *message2 ; { fprintf(stderr, "%s error: %s", progname, message) ; if (message2 != NULL) fprintf(stderr, " (%s)", message2) ; fputc('\n', stderr) ; errors++ ; } /* print warning message */ void warning(message, message2) char *message ; char *message2 ; { fprintf(stderr, "%s warning: %s", progname, message) ; if (message2 != NULL) fprintf(stderr, " (%s)", message2) ; fputc('\n', stderr) ; warnings++ ; } /*** miscellaneous stuff ***/ /* check for existence of an AtFS history for file fname */ bool atfs_exists(fname) char *fname ; { return ! af_access(af_afpath(fname), af_afname(fname), af_aftype(fname), AF_CLASS_SOURCE) ; } /* strip last component of pathname. * if pathname is NULL or doesn't contain a slash, NULL is returned. * returned string may be free()d later */ char *strip_last(pathname) char *pathname ; { char *dir = NULL ; char *slash ; if (pathname != NULL) { dir = check_strdup(pathname) ; slash = strrchr(dir, '/') ; if (slash == NULL) { free(dir) ; return NULL ; } *slash = '\0' ; } return dir ; } /* and now the opposite: return the last component of pathname. * returned string is free(3)able. */ char *basename(pathname) char *pathname ; { char *bnp ; /* ptr to basename */ bnp = strrchr(pathname, '/') ; if (bnp == NULL) { return check_strdup(pathname) ; } return check_strdup(++bnp) ; } /* return type of file: directory, normal file, RCS file, * RCS directory, error (not stat()able) */ filetype_t file_type(fname) char *fname ; { struct stat st ; if (stat(fname, &st) == -1) { switch (errno) { case EACCES: if (! recursive) { error(sys_errlist[errno], fname) ; } return f_error ; case EFAULT: fatal(sys_errlist[errno], MUSTNOT) ; case ENOENT: /* can be RCS working file without busy version */ return f_plain ; default: error(sys_errlist[errno], fname) ; } } if (S_ISDIR(st.st_mode)) { if (strlen(fname) == 3 && ! strcmp(fname, "RCS")) { return f_rcsdir ; } else if (! strcmp(fname + strlen(fname) - 4, "/RCS")) { return f_rcsdir ; } else { return f_dir ; } } else if (! strcmp(fname + strlen(fname) - 2, ",v")) { return f_rcs ; } else { return f_plain ; } } /* quote \, " and $ in text for use in the shell script quoted with " */ char *sh_quote(text) char *text ; { /* chunk of memory for quoted text */ char *tmp = check_malloc(strlen(text) * 2) ; /* it will NEVER get bigger */ /* pointer into chunk */ char *ptr = tmp ; /* copy text, looking for $ and \ */ while (*text != '\0') { if (*text == '\\' || *text == '$' || *text == '\"') { /* must quote with \ */ *ptr++ = '\\' ; } *ptr++ = *text++ ; } *ptr = '\0' ; tmp = check_realloc(tmp, strlen(tmp) + 1) ; return tmp ; } /*EOF*/ shapetools-1.4pl6.orig/src/vc/rcs2atfs/utime.c100444 2013 145 3270 5414051454 17361 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * set access time and mdification time of files * * Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) * * $Header: utime.c[3.0] Tue Jun 29 16:38:20 1993 andy@cs.tu-berlin.de frozen $ */ #include "config.h" #include void usage() ; int main(argc, argv) int argc ; char **argv ; { struct utimbuf utb ; int errors = 0 ; if (argc < 4) { /* Test number of arguments */ if (argc == 2 && ! strcmp(argv[1], "-version")) { (void) fputs("$Header: utime.c[3.0] Tue Jun 29 16:38:20 1993 andy@cs.tu-berlin.de frozen $\n", stdout) ; (void) exit(0) ; } usage() ; (void) exit(1) ; } /* Check and read time arguments */ if (sscanf(*++argv, "%ld", &utb.actime) != 1 || sscanf(*++argv, "%ld", &utb.modtime) != 1) { usage() ; (void) exit(1) ; } /* Set times of file arguments */ while (*++argv) { if (utime(*argv, &utb)) { (void) perror(*argv) ; errors++ ; } } /* return error code */ return errors ; } void usage() { fputs("Usage: utime atime mtime file ...\n", stderr) ; } shapetools-1.4pl6.orig/src/vc/rcs2atfs/functions.h100444 2013 145 23162 5367237030 20300 0ustar dokoswt/* * This file was automatically generated by version 1.7 of cextract. * Manual editing not recommended. * * Created: Tue Apr 27 16:07:20 1993 */ #ifndef __CEXTRACT__ #if __STDC__ /* * initializes reading files from the specified directory. f_state keeps * the status information needed by afind_read() and afind_close(). */ int afind_init ( char *dir, struct AFIND_STATE *f_state ); /* * returns a filename from the directory with which f_state was initialized. * the returned string is freeable. If all names have been read, NULL is * returned */ char *afind_read ( struct AFIND_STATE *f_state ); /* * completes reading files with afind, frees memory */ void afind_close ( struct AFIND_STATE *f_state ); /*ARGSUSED*/ int read_out_name ( char *o, char *arg ); void usage ( void ); /* main function (this should be obvious) */ int main ( int argc, char **argv ); /* convert fname, if recursive, maybe directory */ void convert ( char *fname, FILE *out ); /* convert a directory named RCS */ void convert_rcsdir ( char *rdir, FILE *out ); /* comment leader string */ void convert_revision ( FILE *out, char *wkfile, bool branches, struct RCSREV *rev, bool initial, char *comment_leader ); /* build shell script for converting the archive */ void make_shell_script ( char *directory, struct RCSFILE *rcsfile, FILE *out ); /* read rlogin output into a struct RCSFILE */ struct RCSFILE *readin_rcsfile ( char *fname ); /* The name of the following two functions should have been * "compare_revisions_by_number" and "compare_revisions_by_date", but * I guess there still some compilers that treat only the first some * (10? 8? 6?) characters of an identifier as significant. (WHY?!) * These two are needed for qsort()ing an array of revision pointers. */ int number_compare_revisions ( struct RCSREV **r1, struct RCSREV **r2 ); int date_compare_revisions ( struct RCSREV **r1, struct RCSREV **r2 ); /* sort revisions by revision number, if branches exist by date */ void sort_revisions ( struct RCSFILE *rcsfile ); /* check if all needed fields in rcsfile are present */ short check_rcsfile ( struct RCSFILE *rcsfile ); /* apply symbolic names to apropriate revisions */ void apply_symnames ( struct RCSFILE *rcsfile, struct SYMNAME *symname_list ); /* allocate memory and check */ char *check_malloc ( unsigned size ); /* reallocate memory and check */ char *check_realloc ( char *ptr, unsigned size ); /* callocate memory and check */ char *check_calloc ( unsigned nelem, unsigned elsize ); /* allocate and initialize struct RCSFILE */ struct RCSFILE *new_rcsfile ( void ); /* allocate and initialize struct RCSREV */ struct RCSREV *new_rcsrev ( void ); /* allocate and initialize struct SYMNAME */ struct SYMNAME *new_symname ( void ); /* free memory allocated for a struct RCSFILE */ void free_rcsfile ( struct RCSFILE *rp ); /* free memory allocated for a chain of struct RCSREV */ void free_rev_chain ( struct RCSREV *rp ); /* free memory allocated for a struct RCSREV */ void free_rcsrev ( struct RCSREV *rp ); /* free memory allocated for a chain of struct SYMNAME */ void free_symnames ( struct SYMNAME *sp ); /* duplicate string with check */ char *check_strdup ( char *s ); /* like strdup, but only n characters * the resulting string is null padded, freeable */ char *strndup ( char *s, int n ); /* return a string concatenated from s1, s2, and s3. * The returned string is freeable. * Each argument may be NULL. If all are NULL, NULL is returned. */ char *addstr3 ( char *s1, char *s2, char *s3 ); /* return a string concatenated from s1 and s2. * The returned string is freeable. * Each argument may be NULL, if both, NULL is returned. */ char *addstr ( char *s1, char *s2 ); /* safe strncpy with null padding but no return value */ void strncpy0 ( char *s1, char *s2, int n ); /* safe strncat with null padding but no return value */ void strncat0 ( char *s1, char *s2, int n ); /* print fatal error message and exit */ void fatal ( char *message, char *message2 ); /* print error message */ void error ( char *message, char *message2 ); /* print warning message */ void warning ( char *message, char *message2 ); /* check for existence of an AtFS history for file fname */ bool atfs_exists ( char *fname ); /* strip last component of pathname. * if pathname is NULL or doesn't contain a slash, NULL is returned. * returned string may be free()d later */ char *strip_last ( char *pathname ); /* and now the opposite: return the last component of pathname. * returned string is free(3)able. */ char *basename ( char *pathname ); /* return type of file: directory, normal file, RCS file, * RCS directory, error (not stat()able) */ filetype_t file_type ( char *fname ); /* quote \, " and $ in text for use in the shell script quoted with " */ char *sh_quote ( char *text ); /*EOF*/ void echo_version ( void ); #else /* __STDC__ */ /* * initializes reading files from the specified directory. f_state keeps * the status information needed by afind_read() and afind_close(). */ int afind_init (/* char *dir, struct AFIND_STATE *f_state */); /* * returns a filename from the directory with which f_state was initialized. * the returned string is freeable. If all names have been read, NULL is * returned */ char *afind_read (/* struct AFIND_STATE *f_state */); /* * completes reading files with afind, frees memory */ void afind_close (/* struct AFIND_STATE *f_state */); /*ARGSUSED*/ int read_out_name (/* char *o, char *arg */); void usage (/* void */); /* main function (this should be obvious) */ int main (/* int argc, char **argv */); /* convert fname, if recursive, maybe directory */ void convert (/* char *fname, FILE *out */); /* convert a directory named RCS */ void convert_rcsdir (/* char *rdir, FILE *out */); /* comment leader string */ void convert_revision (/* FILE *out, char *wkfile, bool branches, struct RCSREV *rev, bool initial, char *comment_leader */); /* build shell script for converting the archive */ void make_shell_script (/* char *directory, struct RCSFILE *rcsfile, FILE *out */); /* read rlogin output into a struct RCSFILE */ struct RCSFILE *readin_rcsfile (/* char *fname */); /* The name of the following two functions should have been * "compare_revisions_by_number" and "compare_revisions_by_date", but * I guess there still some compilers that treat only the first some * (10? 8? 6?) characters of an identifier as significant. (WHY?!) * These two are needed for qsort()ing an array of revision pointers. */ int number_compare_revisions (/* struct RCSREV **r1, struct RCSREV **r2 */); int date_compare_revisions (/* struct RCSREV **r1, struct RCSREV **r2 */); /* sort revisions by revision number, if branches exist by date */ void sort_revisions (/* struct RCSFILE *rcsfile */); /* check if all needed fields in rcsfile are present */ short check_rcsfile (/* struct RCSFILE *rcsfile */); /* apply symbolic names to apropriate revisions */ void apply_symnames (/* struct RCSFILE *rcsfile, struct SYMNAME *symname_list */); /* allocate memory and check */ char *check_malloc (/* unsigned size */); /* reallocate memory and check */ char *check_realloc (/* char *ptr, unsigned size */); /* callocate memory and check */ char *check_calloc (/* unsigned nelem, unsigned elsize */); /* allocate and initialize struct RCSFILE */ struct RCSFILE *new_rcsfile (/* void */); /* allocate and initialize struct RCSREV */ struct RCSREV *new_rcsrev (/* void */); /* allocate and initialize struct SYMNAME */ struct SYMNAME *new_symname (/* void */); /* free memory allocated for a struct RCSFILE */ void free_rcsfile (/* struct RCSFILE *rp */); /* free memory allocated for a chain of struct RCSREV */ void free_rev_chain (/* struct RCSREV *rp */); /* free memory allocated for a struct RCSREV */ void free_rcsrev (/* struct RCSREV *rp */); /* free memory allocated for a chain of struct SYMNAME */ void free_symnames (/* struct SYMNAME *sp */); /* duplicate string with check */ char *check_strdup (/* char *s */); /* like strdup, but only n characters * the resulting string is null padded, freeable */ char *strndup (/* char *s, int n */); /* return a string concatenated from s1, s2, and s3. * The returned string is freeable. * Each argument may be NULL. If all are NULL, NULL is returned. */ char *addstr3 (/* char *s1, char *s2, char *s3 */); /* return a string concatenated from s1 and s2. * The returned string is freeable. * Each argument may be NULL, if both, NULL is returned. */ char *addstr (/* char *s1, char *s2 */); /* safe strncpy with null padding but no return value */ void strncpy0 (/* char *s1, char *s2, int n */); /* safe strncat with null padding but no return value */ void strncat0 (/* char *s1, char *s2, int n */); /* print fatal error message and exit */ void fatal (/* char *message, char *message2 */); /* print error message */ void error (/* char *message, char *message2 */); /* print warning message */ void warning (/* char *message, char *message2 */); /* check for existence of an AtFS history for file fname */ bool atfs_exists (/* char *fname */); /* strip last component of pathname. * if pathname is NULL or doesn't contain a slash, NULL is returned. * returned string may be free()d later */ char *strip_last (/* char *pathname */); /* and now the opposite: return the last component of pathname. * returned string is free(3)able. */ char *basename (/* char *pathname */); /* return type of file: directory, normal file, RCS file, * RCS directory, error (not stat()able) */ filetype_t file_type (/* char *fname */); /* quote \, " and $ in text for use in the shell script quoted with " */ char *sh_quote (/* char *text */); /*EOF*/ void echo_version (/* void */); #endif /* __STDC__ */ #endif /* __CEXTRACT__ */ shapetools-1.4pl6.orig/src/vc/rcs2atfs/rcs2atfs.h100444 2013 145 13362 5414051412 20007 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * Header file for rcs2atfs, global data structures and variables * * Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) * * $Header: rcs2atfs.h[3.0] Tue Jun 29 16:38:24 1993 andy@cs.tu-berlin.de frozen $ */ #include #include #include "atfs.h" /* includes config.h */ /* * Constants */ #ifdef bool /* atfs.h defines this to short, */ #undef bool /* but I need it as int */ #endif typedef int bool ; #define false (0) #define true (1) #ifndef NULL #define NULL 0 #endif /* shell we call in a pipe */ #define BOURNE_SHELL "/bin/sh" /* name of AtFS directory */ #ifndef AtFSDIR #define AtFSDIR "AtFS" #endif /* reader state in readin.c */ typedef enum { header, /* in header of rlog output */ skip, /* skip lines beginning with whitespace */ locks, /* look at locks */ symnames, /* look at symbolic names */ description, /* look at description */ revision1, /* first line of revision */ revision2, /* second line of revision */ log_msg /* log message of revision or branches line */ } read_state_t ; /* type of a file */ typedef enum { f_plain, /* plain file */ f_rcs, /* RCS file (*,v) */ f_dir, /* directory */ f_rcsdir, /* directory named RCS */ f_error /* can't stat(2) file */ } filetype_t ; #define LINELENGTH 1024 /* Max. length of input line */ /* messages etc. */ #define RLOG_COMMAND "rlog " #define RLOG_FAILED "rlog command failed, file skipped" #define POPEN_RLOG "popen to rlog command failed" #define POPEN_SHELL "popen to shell failed" #define LOCKED_VERSIONS "locked version(s) exist" #define NO_COLON "colon after symbolic name missing, file skipped" #define NO_REVISION "\"revision\" not found, file skipped" #define NO_DATE "date not found, file skipped" #define NO_AUTHOR "author not found, file skipped" #define NO_STATUS "status not found, file skipped" #define MIND_LOST "Oops? Unknown reader state in readin_rcsfile!" #define CHECK_FAILED "rlog information missing, file skipped" #define BOGUS_SYMNAME "symbolic name to non-existent revision" #define NOMORECORE "no more core" #define AtFS_EXISTS "AtFS history exists, file skipped" #define NOT_RECURSIVE "-R flag not set, directory skipped" #define REV_CORRUPT "revision numbers corrupted!" #define MUSTNOT "this must not happen" #define BAD_REVNO "number of revisions is wrong!" #define BRANCHES "branches exist, can't keep revision numbers" #define CONTRADICT "You can't mean this.\n" /* * Strings in rlog output */ #define K_rcsfile "RCS file:" #define K_wrkfile "Working file:" #define K_head "head:" #define K_branch "branch:" #define K_locks "locks:" #define K_symnames "symbolic names:" #define K_comlead "comment leader: " #define K_descr "description:" #define K_revision "revision " #define K_locked "locked_by: " #define K_date "date: " #define K_author "author: " #define K_state "state: " #define K_alist "access list:" #define K_branches "branches: " #define K_revsep "----------------------------" #define K_filesep "=============================================================================" /* header for generated shell script */ #define SCRIPT_HEADER "#!/bin/sh\n\ # shell script generated by rcs2atfs\n\ # %s\n\ \n\ \n" /* * Structures */ /* structure for storing a symbolic name while reading rlog output */ struct SYMNAME { char *symname ; /* the symbolic name itself */ char *revision ; /* the revision number it belongs to */ struct SYMNAME *next ; /* pointer to next symname */ } ; /* structure containing information of an RCS revision */ struct RCSREV { struct RCSREV *next ; /* pointer to next r. */ char *number ; /* r. number (string!) */ time_t date ; /* date (of check-in?) */ char *author ; /* author of this r. */ char *state ; /* state of the r. (Exp, Stab, Rel,... */ char *log_message ; /* log message of the r. */ struct SYMNAME *symbolic_names ; /* symbolic names of this r. */ } ; /* structure containing header information of an RCS file */ struct RCSFILE { char *dirname ; /* name of dir. working file is in */ char *rcs_file ; /* name of RCS archive file */ char *working_file ; /* name of working file */ bool locks ; /* locks exist */ char *comment_leader ; /* comment leader string */ char *description ; /* descriptive text */ struct RCSREV *revisions ; /* list of revisions */ bool branches ; /* Branches exist */ int no_of_revs ; /* number of revisions */ struct rcsfile *next ; /* pointer to next rcsfile */ } ; /* struct afind_state is built by init_afind(), used by afind_next() */ struct AFIND_STATE { Af_set set ; int counter ; } ; /* * Variables */ extern char *progname ; /* name this program was called with */ extern int warnings ; /* no of warnings issued */ extern int errors ; /* no of errors encountered */ extern char *shellscript ; /* name of shellscript (if any) */ extern bool keep_quiet ; /* don't issue warnings */ extern bool recursive ; /* recursively descend directories */ extern int errno ; /* I want to handle ... */ extern char *sys_errlist[] ; /* ... these strings by myself */ /*EOF*/ shapetools-1.4pl6.orig/src/vc/rcs2atfs/version.c100444 2013 145 2347 5517473136 17740 0ustar dokoswt/* * $Header: version.c[1.9] Fri Jan 28 20:39:33 1994 andy@cs.tu-berlin.de frozen $ * version carrier of rcs2atfs * Log for /export/stone/shape/development/src/vc/rcs2atfs/version.c[1.9]: [1.1] Mon Feb 17 20:12:54 1992 nickel@cs.tu-berlin.de accessed [Mon Feb 17 19:49:51 1992] Intention for change: reduce number of gcc warnings Done. [1.2] Wed Mar 11 20:23:03 1992 nickel@cs.tu-berlin.de accessed [Wed Mar 11 20:22:53 1992] Intention for change: Delete include of time.h ...Done. [1.3] Mon Apr 27 18:23:20 1992 nickel@cs.tu-berlin.de accessed [1.4] Tue May 19 21:58:02 1992 nickel@cs.tu-berlin.de frozen [1.5] Wed Mar 3 13:30:57 1993 shape@cs.tu-berlin.de accessed [1.6] Tue Apr 27 16:26:26 1993 andy@cs.tu-berlin.de accessed [Tue Apr 27 16:02:22 1993] Intention for change: Use fputs instead of puts. [1.7] Fri Jul 9 20:04:27 1993 andy@cs.tu-berlin.de frozen [1.8] Tue Sep 7 18:47:44 1993 andy@cs.tu-berlin.de frozen [1.9] Fri Jan 28 20:39:33 1994 andy@cs.tu-berlin.de frozen */ #include #include "rcs2atfs.h" #include "functions.h" void echo_version() { if (!keep_quiet) { puts("rcs2atfs rcs2atfs-1.9 (Tue Aug 23 17:58:16 1994 by andy@cs.tu-berlin.de)") ; } exit(0) ; } /*EOF*/ shapetools-1.4pl6.orig/src/vc/rcs2atfs/Shapefile100444 2013 145 6275 5414051253 17722 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for rcs2atfs # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[3.0] Tue Jun 29 16:38:33 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds _all: all $(TARGET1) $(TARGET2): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/vc/rcs2atfs/Makefile100444 2013 145 26377 5426221773 17575 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for rcs2atfs # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[3.0] Fri Jul 30 17:44:17 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/vc/rcs2atfs # A short name for this node system NODENAME = rcs2atfs # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = $(BASE) INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. TARGET1 = rcs2atfs TARGET2 = utime TARGET = $(TARGET1) $(TARGET2) # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = version.c VERSIONOBJECT = version.o # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = # The regular source and header files. RSOURCES = afind.c main.c out.c readin.c utils.c USOURCES = utime.c SOURCES = $(RSOURCES) $(USOURCES) HEADERS = functions.h rcs2atfs.h # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = rcs2atfs.1 utime.1 MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. OBJECTS1 = afind.o main.o out.o readin.o utils.o $(VERSIONOBJECT) OBJECTS2 = utime.o OBJECTS = $(OBJECTS1) $(OBJECTS2) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = $(LOCALLIBPATH)/libsttk.a $(LOCALLIBPATH)/libAtFS.a LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) funcs: $(RSOURCES) rcs2atfs.h $(VERSIONFILE) touch functions.h cextract -I$(INCLUDEPATH) +scm -E -o new_functions.h $(RSOURCES) \ $(VERSIONFILE) mv new_functions.h functions.h tags: $(SOURCES) $(HEADERS) $(VERSIONFILE) etags $(SOURCES) $(HEADERS) $(VERSIONFILE) \ $(PARTIALRELEASEBASE)/src/atfs/*.c $(PARTIALRELEASEBASE)/src/atfstk/*.c # The final system building action. targets: $(TARGET1) $(TARGET2) $(TARGET1): $(LOCALLIBS) $(OBJECTS1) $(CC) $(LDFLAGS) -o $(TARGET1) $(OBJECTS1) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET1) to $$i; \ ln $(TARGET1) $$i; \ done $(TARGET2): $(LOCALLIBS) $(OBJECTS2) $(CC) $(LDFLAGS) -o $(TARGET2) $(OBJECTS2) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET2) to $$i; \ ln $(TARGET2) $$i; \ done # Construction of a library would look like: #$(TARGET): $(OBJECTS) # @ar ruv $(TARGET) $(OBJECTS); \ # ($(RANLIB) $(TARGET)) 2> /dev/null installtargets: $(INSTALLBINPATH)/$(TARGET1) $(INSTALLBINPATH)/$(TARGET2) $(INSTALLBINPATH)/$(TARGET1): $(TARGET1) @-echo "installing $(TARGET1) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET1) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET1) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET1); \ fi; \ cp $(TARGET1) $(INSTALLBINPATH)/$(TARGET1); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET1); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET1) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET1) $(INSTALLBINPATH)/$$i; \ done $(INSTALLBINPATH)/$(TARGET2): $(TARGET2) @-echo "installing $(TARGET2) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET2) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET2) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET2); \ fi; \ cp $(TARGET2) $(INSTALLBINPATH)/$(TARGET2); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET2); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET2) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET2) $(INSTALLBINPATH)/$$i; \ done # Installing a library #installtargets: $(INSTALLLIBPATH)/$(TARGET) installincludes # #$(INSTALLLIBPATH)/$(TARGET): $(TARGET) # @-echo "installing $(TARGET) in $(INSTALLLIBPATH)"; \ # if [ -f $(INSTALLLIBPATH)/$(TARGET) ] ;\ # then \ # mv -f $(INSTALLLIBPATH)/$(TARGET) \ # $(INSTALLLIBPATH)/$(TARGET).old;\ # fi; \ # cp $(TARGET) $(INSTALLLIBPATH)/$(TARGET); \ # chmod $(INSTALLLIBMODE) $(INSTALLLIBPATH)/$(TARGET); \ # ($(RANLIB) $(INSTALLLIBPATH)/$(TARGET)) 2> /dev/null installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/vc/rcs2atfs/Dependencies100444 2013 145 2071 5367236624 20414 0ustar dokoswtafind.o: ./functions.h afind.o: ./rcs2atfs.h afind.o: $(BASE)/include/afsys.h afind.o: $(BASE)/include/atfs.h afind.o: $(BASE)/include/config.h afind.o: afind.c main.o: ./functions.h main.o: ./rcs2atfs.h main.o: $(BASE)/include/afsys.h main.o: $(BASE)/include/atfs.h main.o: $(BASE)/include/config.h main.o: $(BASE)/include/sttk.h main.o: main.c out.o: ./functions.h out.o: ./rcs2atfs.h out.o: $(BASE)/include/afsys.h out.o: $(BASE)/include/atfs.h out.o: $(BASE)/include/config.h out.o: out.c readin.o: ./functions.h readin.o: ./rcs2atfs.h readin.o: $(BASE)/include/afsys.h readin.o: $(BASE)/include/atfs.h readin.o: $(BASE)/include/config.h readin.o: $(BASE)/include/sttk.h readin.o: readin.c utils.o: ./functions.h utils.o: ./rcs2atfs.h utils.o: $(BASE)/include/afsys.h utils.o: $(BASE)/include/atfs.h utils.o: $(BASE)/include/config.h utils.o: utils.c utime.o: $(BASE)/include/config.h utime.o: utime.c version.o: ./functions.h version.o: ./rcs2atfs.h version.o: $(BASE)/include/afsys.h version.o: $(BASE)/include/atfs.h version.o: $(BASE)/include/config.h version.o: version.c shapetools-1.4pl6.orig/src/vc/retrv/ 40755 2013 145 0 5626416266 15423 5ustar dokoswtshapetools-1.4pl6.orig/src/vc/retrv/retrv.c100444 2013 145 24644 5412065176 17047 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools Version Control System * * retrv.c - main program for "retrv" command * * by Axel.Mahler@cs.tu-berlin.de * and Andreas.Lampen@cs.tu-berlin.de * * $Header: retrv.c[6.0] Tue Jun 29 16:45:32 1993 andy@cs.tu-berlin.de frozen $ */ /* * Retrieve a previously saved version of a file. We orient us pretty much * towards the check-out operation of RCS. Retrieve determines the * archive name to be searched from the given file names. Unless otherwise * specified by the project context (-p), the archive is expected to * reside in the AtFS subdirectory. The retrieved version will be created * in the current directory. Retrieve tries to be careful if an * attempt is made to overwrite an existing busy-version: unless -f * is specified, retrv will ask the caller for permission. * If no busy version exists, one is created with the modes of the * formerly saved version. If one exists, it's modes are kept unless * -m is given. * There's a number of ways to specify which version should be retrieved. * With -V an explicit version can be selected. Another argument to -V * could be a symbolic name (hopefully unique). Alternatively, versions * can be selected by supplying certain attribute values to retrv, such as * the name of the author, the version state, a generation number or a * set of user defined attributes, possibly describing a variant. In case * that more than one version fits the desired attributes, the newest * of them is selected, unless -x (exact!) is specified. -V implies -x. */ #include "atfs.h" #include "atfstk.h" #include "sttk.h" void showAFile(), retrieveAFile(); /*==================== * global variables *====================*/ /* -?, -help */ EXPORT int copyFlag = FALSE; /* -c, -copy (retrv) */ EXPORT char *destPath = NULL; /* -dest (retrv) */ EXPORT int fixFlag = FALSE; /* -fix (retrv) */ EXPORT int forceFlag = FALSE; /* -f, -force (retrv) */ EXPORT char *intent = NULL; /* -i, -intent (retrv) */ EXPORT int lockFlag = FALSE; /* -l, -lock (retrv) */ /* -q, -quiet */ EXPORT int stdinFlag = FALSE; /* -stdin (retrv) */ /* -version */ EXPORT int expandFlag = TRUE; /* -xpoff */ EXPORT int vcatFlag = FALSE; EXPORT Af_key *newLock = NULL; LOCAL int nameCount; /*======================== * command line parsing *========================*/ LOCAL int handleDestPath (option, arg) char *option, *arg; { char *endPtr; struct stat iBuf; if (!arg || !(*arg)) { sprintf (stMessage, "No attributes file specified -- '%s' ignored.\n", option); stLog (stMessage, ST_LOG_ERROR); return (0); } if (destPath) { sprintf (stMessage, "Destination path already set to %s -- '%s' ignored.", arg, option); stLog (stMessage, ST_LOG_ERROR); return (0); } endPtr = &arg[strlen(arg) - 1]; while (*endPtr == '/') *endPtr-- = '\0'; if (stat (arg, &iBuf) < 0) { sprintf (stMessage, "Destination path %s does not exist -- '%s' ignored.", arg, option); stLog (stMessage, ST_LOG_ERROR); stExit (1); } if (!S_ISDIR(iBuf.st_mode)) { sprintf (stMessage, "Destination path %s is not a directory -- '%s' ignored.", arg, option); stLog (stMessage, ST_LOG_ERROR); stExit (1); } destPath = arg; return (0); } LOCAL int handleIntent (option, arg) char *option, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No intent message specified -- '%s' ignored.\n", option); stLog (stMessage, ST_LOG_ERROR); return (0); } if (!strcmp (arg, "-")) stdinFlag = TRUE; else intent = arg; return (0); } LOCAL int printVersion () { char *retrversion(); sprintf (stMessage, "This is %s version %s", stProgramName, retrversion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " using AtFStk version %s", atVersion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " AtFS version %s", af_version()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " and Sttk version %s.", stVersion()); stLog (stMessage, ST_LOG_MSG); stExit (0); return (0); } static int usage(); static StOptDesc optDesc[] = { { "?", PCALL, usage, NULL, NULL }, { "help", PCALL, usage, NULL, NULL }, { "q", PSWITCH|PSET, NULL, &stQuietFlag, NULL }, { "quiet", PSWITCH|PSET, NULL, &stQuietFlag, NULL }, { "version", PSWITCH, printVersion, NULL, NULL }, { "xpoff", PSWITCH|PCLEAR, NULL, &expandFlag, NULL }, { NULL, 0, NULL, NULL, NULL }, }; static StOptDesc retrvOptDesc[] = { { "c", PSWITCH|PSET, NULL, ©Flag, NULL }, { "copy", PSWITCH|PSET, NULL, ©Flag, NULL }, { "dest", PARG, handleDestPath, NULL, NULL }, { "fix", PSWITCH|PSET, NULL, &fixFlag, NULL }, { "f", PSWITCH|PSET, NULL, &forceFlag, NULL }, { "force", PSWITCH|PSET, NULL, &forceFlag, NULL }, { "i", PARG, handleIntent, NULL, NULL }, { "intent", PARG, handleIntent, NULL, NULL }, { "l", PSWITCH|PSET, NULL, &lockFlag, NULL }, { "lock", PSWITCH|PSET, NULL, &lockFlag, NULL }, { "q", PSWITCH|PSET, NULL, &stQuietFlag, NULL }, { "stdin", PSWITCH|PSET, NULL, &stdinFlag, NULL }, { NULL, 0, NULL, NULL, NULL }, }; LOCAL int usage() { stLog ("Usage:", ST_LOG_MSGERR); if (!strcmp (stProgramName, "vcat")) { stShortUsage (stProgramName, optDesc, "names..."); } else { stShortUsage (stProgramName, retrvOptDesc, ""); stShortUsage (" ", optDesc, "names..."); } atBindUsage (""); stExit (1); return (1); } /*============== * main *==============*/ LOCAL Sigret_t interrupt_action () /* is executed by appropriate signal handler */ { disableSig (SIGINT); if (newLock && !(stThisTransaction.tr_done)) { /* Try to unlock an eventually placed new lock */ atUnlock (newLock); } if (vcatFlag) stExit(1); if ((nameCount - stThisTransaction.tr_seqno) > 1) { sprintf (stMessage, "\ncompletely stop retrieving (%d files pending) ?", nameCount - stThisTransaction.tr_seqno); if (stAskConfirm (stMessage, "no")) { if (stThisTransaction.tr_done) { sprintf (stMessage, "\ntoo late, %s already restored", stThisTransaction.tr_fname); stLog (stMessage, ST_LOG_MSG); enableSig(); return; /* continue where we've been interrupted */ } sprintf (stMessage, "%s not restored", stThisTransaction.tr_fname); stLog (stMessage, ST_LOG_MSG); enableSig (); stCatchSigs (); /* see comment in save.c */ af_cleanup (); longjmp (stThisTransaction.tr_env, 1); } else { sprintf (stMessage, "%s not restored", stThisTransaction.tr_fname); stLog (stMessage, ST_LOG_MSG); stExit (1); } } else { sprintf (stMessage, "\n%s not restored", stThisTransaction.tr_fname); stLog (stMessage, ST_LOG_MSG); stExit (1); } } EXPORT int main (argc, argv) int argc; char **argv; { int tmpArgc, newArgc, i, j, k, retCode=0; char *cp, **tmpArgv, **newArgv, path[PATH_MAX], tmpStr[16]; Af_key curKey; Af_set *setPtr; stProgramName = (cp = strrchr (argv[0], '/')) ? ++cp : argv[0]; if (!strcmp (stProgramName, "vcat")) vcatFlag = TRUE; if ((argc < 2) && !vcatFlag) { usage (); stExit (1); } atBindModeOption = 0; if (atBindOptions (argc, argv, &newArgc, &newArgv)) stExit (1); if (stParseArgs (newArgc, newArgv, &tmpArgc, &tmpArgv, optDesc)) stExit (1); if (newArgc == 1) { stLog ("No name(s) given.", ST_LOG_MSGERR); stExit (1); } if (vcatFlag) { newArgc = tmpArgc; newArgv = tmpArgv; } else { if (stParseArgs (tmpArgc, tmpArgv, &newArgc, &newArgv, retrvOptDesc)) stExit (1); } if (lockFlag && destPath) { sprintf (stMessage, "No checkout with lock to distant directory %s.", destPath); stLog (stMessage, ST_LOG_ERROR); stExit (1); } if (fixFlag) lockFlag = TRUE; stInterruptAction = interrupt_action; stCatchSigs (); if (vcatFlag) { signal (SIGPIPE, interrupt_action); } nameCount = newArgc-1; k=0; stThisTransaction.tr_rc = 0; /* no arguments on the command line */ if ((newArgc == 1) && vcatFlag) showAFile ("", NULL); for (i = 1; i < newArgc; i++) { /* do version binding */ if (vcatFlag && !strcmp (newArgv[i], "-")) { /* This is a special case */ showAFile ("", NULL); continue; } if (!atBindModeOption) { if (vcatFlag) atBindModeOption = AT_BIND_LAST; /* default for vcat */ else atBindModeOption = AT_BIND_LASTSAVED; /* default for retrv */ } if ((setPtr = atBindSet (newArgv[i], NULL, atBindModeOption)) == NULL) { stLog (atBindErrorMsg, ST_LOG_ERROR); stExit (2); } if (af_nrofkeys (setPtr) == 0) { sprintf (stMessage, "%s: nothing found -- skipped.", newArgv[i]); stLog (stMessage, ST_LOG_MSGERR); retCode++; continue; } strcpy (path, af_afpath (newArgv[i])); for (j = 0; j < af_nrofkeys (setPtr); j++) { af_setgkey (setPtr, j, &curKey); if (!setjmp (stThisTransaction.tr_env)) { stThisTransaction.tr_seqno = k++; strcpy (stThisTransaction.tr_fname, af_retattr (&curKey, AF_ATTBOUND)); stThisTransaction.tr_done = FALSE; newLock = NULL; af_transaction (); if (vcatFlag) showAFile (path, &curKey); else retrieveAFile (path, &curKey); if (af_commit () < 0) { sprintf (stMessage, "Cannot save changes for %s%s%s -- %s.", path, path[0] ? "/" : "", af_retattr (&curKey, AF_ATTUNIXNAME), af_errmsg ("af_commit")); stLog (stMessage, ST_LOG_ERROR); retCode++; } } else { /* stThisTransaction was aborted */ retCode += stThisTransaction.tr_rc; af_abort (); } /* switch attribute expansion on */ /* $__xpoff$ */ tmpStr[0] = '\0'; atExpandAttrs (&curKey, "$__xpon$", 8, tmpStr, 16, AT_EXPAND_STRING); /* xpon */ af_dropkey (&curKey); } } if (nameCount > 1) stLog ("done.", ST_LOG_MSG); return (retCode); } shapetools-1.4pl6.orig/src/vc/retrv/doretrv.c100444 2013 145 37361 5520012621 17355 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools Version Control System * * doretrv.c - "retrv" command * * by Axel.Mahler@cs.tu-berlin.de * and Andreas.Lampen@cs.tu-berlin.de * * $Header: doretrv.c[6.2] Sun Jan 23 21:55:33 1994 axel@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "atfstk.h" #include "sttk.h" extern int copyFlag; extern char *destPath; extern int fixFlag; extern int forceFlag; extern char *intent; extern int lockFlag; extern int stdinFlag; extern int expandFlag; extern int vcatFlag; extern Af_key *newLock; extern int af_errno; /* permission status for retrieveAFile */ #define DOIT 01 #define DENIED 02 #define RECREATE 04 #define UNCHANGED 010 /*========================= * vcat *=========================*/ EXPORT void showAFile (path, aso) char *path; Af_key *aso; { FILE *versionFile; int nbytes; char *contentsBuf; /* an empty argument indicates, that "vcat" was called * withour arguments or with "-" as argument -> read from stdin */ if (!aso) { # define IOBUFLEN 2048 char iobuf[IOBUFLEN]; int cr, cw; stLog ("stdin", ST_LOG_MSGERR); while ((cr = fread (iobuf, sizeof (char), IOBUFLEN, stdin))) { cw = fwrite (iobuf, sizeof (char), cr, stdout); fflush (stdout); if (cw != cr) stLog ("Oops! Write error on stdout", ST_LOG_ERROR); } clearerr (stdin); return; } /* ToDo: show file */ if (!(versionFile = af_open (aso, "r"))) { stLog (af_errmsg ("af_open"), ST_LOG_ERROR); stAbortThis (TRUE); } if (path[0]) sprintf (stMessage, "%s/%s", path, af_retattr (aso, AF_ATTBOUND)); else sprintf (stMessage, "%s", af_retattr (aso, AF_ATTBOUND)); stLog (stMessage, ST_LOG_MSGERR); if ((contentsBuf = malloc ((unsigned) af_retnumattr (aso, AF_ATTSIZE)+1)) == NULL) { stLog ("Out of memory.", ST_LOG_ERROR); stAbortThis (TRUE); } nbytes = fread (contentsBuf, sizeof (char), af_retnumattr (aso, AF_ATTSIZE), versionFile); contentsBuf[nbytes] = '\0'; af_close (versionFile); if (expandFlag) atExpandAttrs (aso, contentsBuf, nbytes, stdout, 0, AT_EXPAND_FILE); else fwrite(contentsBuf, sizeof (char), nbytes, stdout); fflush (stdout); free (contentsBuf); } /*========================= * retrv *=========================*/ EXPORT void retrieveAFile (path, aso) char *path; Af_key *aso; { char *busyLocation, destName[PATH_MAX], tmpName[PATH_MAX], *contentsBuf; char *reserveDate, *attrPtr; unsigned int permit = 0; int nbytes, i; FILE *newFile, *versionFile, *tmpFile; Af_key busyAso, lastAso; Af_attrs asoAttrBuf; Af_user *locker; struct stat iBuf; struct utimbuf oldDate; busyLocation = destPath ? destPath : (path[0] ? path : "."); if (destPath || path[0]) sprintf (destName, "%s/%s", busyLocation, af_retattr (aso, AF_ATTUNIXNAME)); else strcpy (destName, af_retattr (aso, AF_ATTUNIXNAME)); af_allattrs (aso, &asoAttrBuf); if (!lockFlag) { /* This creates a plain UNIX file from the specified ASO * The created copy is - in general - an object without * history. If, however, the copy happens to go into the * history-directory (the one containing the archive) it will * 'automatically' be considered the busy-version. * If - in this case - a copy replaces a formerly locked busy-version, * the lock will be released. */ if ((newFile = fopen (destName, "r")) == NULL) { /* take this as test for presence */ if (access (busyLocation, W_OK) == 0) { /* may we create ? */ permit |= DOIT; /* No scruples if no busyvers current */ } else { sprintf (stMessage, "write permission for directory %s denied.", busyLocation); stLog (stMessage, ST_LOG_ERROR); permit |= DENIED; } } else { /* file exists */ /* check if it is already restored */ if (!copyFlag && (fstat (fileno(newFile), &iBuf) != -1)) { if ((iBuf.st_size == af_retnumattr (aso, AF_ATTSIZE)) && (iBuf.st_mtime == af_rettimeattr (aso, AF_ATTMTIME)) && (iBuf.st_mode == (af_retnumattr (aso, AF_ATTMODE) & ~0222))) { if (stQuietFlag) permit |= UNCHANGED; else if (forceFlag) /* do nothing */; else { sprintf (stMessage, "%s and %s are identical, retrieve anyway ?", af_retattr (aso, AF_ATTBOUND), destName); if (stAskConfirm (stMessage, "no")) permit |= UNCHANGED; } } } fclose (newFile); if (permit & UNCHANGED) { sprintf (stMessage, "%s not retrieved", af_retattr (aso, AF_ATTBOUND)); stLog (stMessage, ST_LOG_MSGERR); return; } if (access (destName, W_OK) < 0) { if (access (busyLocation, W_OK) == 0) { if (stQuietFlag) permit |= forceFlag ? (RECREATE | DOIT) : DENIED; else if (forceFlag) permit |= RECREATE | DOIT; else { sprintf (stMessage, "%s write-protected, re-create it ?", destName); if (stAskConfirm (stMessage, "no")) permit |= DENIED; else permit |= (RECREATE | DOIT); } } else { sprintf (stMessage, "no write permission for %s", destName); stLog (stMessage, ST_LOG_ERROR); permit |= DENIED; } } else { /* write access on destfile */ if (strcmp (busyLocation, ".")) { if (stQuietFlag) permit |= forceFlag ? DOIT : 0; else if (forceFlag) permit |= DOIT; else { sprintf (stMessage, "%s exists and is writable. Overwrite it ?", destName); if (!stAskConfirm (stMessage, "no")) permit |= DOIT; } } else { /* current dir! - test for lock */ /* this test looks only for a lock in the last generation. Locks on other generations will not be recognized. However, this is not serious as these will go into the else part where "exists and is writable..." is asked. */ if (af_getkey (path, asoAttrBuf.af_name, asoAttrBuf.af_type, AF_LASTVERS, AF_LASTVERS, &lastAso) == -1) { /* No version -- this is impossible here */ sprintf (stMessage, "%s", af_errmsg (af_retattr (aso, AF_ATTUNIXNAME))); stLog (stMessage, ST_LOG_ERROR); stAbortThis (TRUE); } else { if (atUserUid (af_retuserattr (&lastAso, AF_ATTLOCKER)) == geteuid ()) { if (stQuietFlag) permit |= forceFlag ? DOIT : 0; if (forceFlag) permit |= DOIT; else { sprintf (stMessage, "Give up lock on %s and overwrite it ?", destName); if (!stAskConfirm (stMessage, "no")) { permit |= DOIT; atUnlock (&lastAso); } else { permit |= DENIED; } } } else { if (stQuietFlag) permit |= forceFlag ? DOIT : 0; else if (forceFlag) permit |= DOIT; else { sprintf (stMessage, "%s exists and is writable. Overwrite it ?", destName); if (!stAskConfirm (stMessage, "no")) permit |= DOIT; } } af_dropkey (&lastAso); } } } } if (permit & DOIT) { if ((versionFile = af_open (aso, "r")) == NULL) { stLog (af_errmsg ("af_open"), ST_LOG_ERROR); stAbortThis (TRUE); } strcpy (tmpName, stTmpFile (busyLocation)); if ((tmpFile = fopen (tmpName, "w")) == NULL) { sprintf (stMessage, "cannot create temporary file %s for writing.", tmpName); stLog (stMessage, ST_LOG_ERROR); stAbortThis (TRUE); } if (path[0]) sprintf (stMessage, "%s/%s -> %s", path, af_retattr (aso, AF_ATTBOUND), destName); else sprintf (stMessage, "%s -> %s", af_retattr (aso, AF_ATTBOUND), destName); stLog (stMessage, ST_LOG_MSGERR); if ((contentsBuf = malloc ((unsigned) asoAttrBuf.af_size+1)) == NULL) { stLog ("Out of memory", ST_LOG_ERROR); stAbortThis(TRUE); } nbytes = fread (contentsBuf, sizeof (char), asoAttrBuf.af_size, versionFile); contentsBuf[nbytes] = '\0'; af_close (versionFile); if (expandFlag) atExpandAttrs (aso, contentsBuf, nbytes, tmpFile, 0, AT_EXPAND_FILE); else fwrite(contentsBuf, sizeof (char), nbytes, tmpFile); free (contentsBuf); fclose (tmpFile); oldDate.actime = asoAttrBuf.af_atime; oldDate.modtime = asoAttrBuf.af_mtime; utime (tmpName, &oldDate); unlink (destName); if (link (tmpName, destName) < 0) { sprintf (stMessage, "cannot link %s to %s.", tmpName, destName); stLog (stMessage, ST_LOG_ERROR); stAbortThis (TRUE); } chmod (destName, asoAttrBuf.af_mode & ~0222); stUnRegisterFile (tmpName); unlink (tmpName); } else { sprintf (stMessage, "%s not retrieved", af_retattr (aso, AF_ATTBOUND)); stLog (stMessage, ST_LOG_MSGERR); stThisTransaction.tr_rc += 1; } return; } /* else lockFlag is set */ /* * Before a version is retrieved, set-busy, and locked, the * following preconditions must be fulfilled: * - the retrieve must go to the directory containing the * archive directory. -> current directory * - the retrieved version must not be locked by anybody but * the calling user. * - the current directory must grant write access to the * calling user. * - if some busy-version would be overwritten by the retrieve, * the user is asked if she wants that */ /* * The following checks are based on the permission information * stored in the archive files. It is unclear how * to properly handle vanilla filesystem related inquiries. */ if (af_getkey (path, asoAttrBuf.af_name, asoAttrBuf.af_type, fixFlag ? asoAttrBuf.af_gen : AF_LASTVERS, AF_LASTVERS, &lastAso) == -1) { sprintf (stMessage, "%s", af_errmsg (af_retattr (aso, AF_ATTBOUND))); stLog (stMessage, ST_LOG_ERROR); stAbortThis (TRUE); } /* there is a version */ if ((atUserUid (locker = af_retuserattr (&lastAso, AF_ATTLOCKER)) == geteuid ()) || !atUserValid (locker)) { if (access (destName, W_OK) == 0) { if (stQuietFlag) permit |= forceFlag ? DOIT : DENIED; else if (forceFlag) permit |= DOIT; else { sprintf (stMessage, "Writable %s exists, overwrite it ?", destName); permit |= (stAskConfirm (stMessage, "no")) ? DENIED : DOIT; } } else if (access (busyLocation, W_OK) == 0) { if (access (destName, F_OK) == 0) { if (stQuietFlag) permit |= forceFlag ? DOIT : DENIED; else if (forceFlag) permit |= DOIT; else { sprintf (stMessage, "Write access on %s denied. Overwrite it anyway ?", destName); permit |= (stAskConfirm (stMessage, "no")) ? DENIED : DOIT; } } else permit |= DOIT; } else { /* no write access on current dir */ sprintf (stMessage, "Can't create in %s", busyLocation); stLog (stMessage, ST_LOG_ERROR); stAbortThis (TRUE); } if (!atUserValid (locker)) { if (!af_lock (&lastAso, af_afuser (geteuid()))) { sprintf (stMessage, "%s", af_errmsg (af_retattr (aso, AF_ATTBOUND))); stLog (stMessage, ST_LOG_ERROR); stAbortThis (TRUE); } newLock = &lastAso; } if (af_commit () < 0) { stLog ("Cannot commit lock!", ST_LOG_ERROR); } af_transaction (); } else { /* busy version locked by someone else */ permit |= DENIED; sprintf (stMessage, "%s already locked by %s.", destName, atUserName (locker)); stLog (stMessage, ST_LOG_MSGERR); sprintf (stMessage, "%s not restored", af_retattr (aso, AF_ATTBOUND)); stLog (stMessage, ST_LOG_MSGERR); stAbortThis (FALSE); } /* now all the checks are done. set retrieved version busy and * create it in busyLocation. */ if ((permit & DOIT) && (!(permit & DENIED))) { /* * Try to get a description of intended changes. */ if (intent || !(stQuietFlag || forceFlag) || stdinFlag) { atSetComment (&lastAso, AT_COMMENT_INTENT, intent, AT_REUSE | AT_CONFIRM | (stdinFlag ? AT_FROMSTDIN : 0)); } /* * Create the file, containing the retrieved version. * "busyAso" is set up to be the AtFS reference to the file. */ /* setbusy sets just the attributes. data must be moved manually */ if ((versionFile = af_open (aso, "r")) == NULL) { stLog (af_errmsg ("af_open"), ST_LOG_ERROR); stAbortThis (TRUE); } strcpy (tmpName, stTmpFile (busyLocation)); if ((tmpFile = fopen (tmpName, "w")) == NULL) { sprintf (stMessage, "cannot create temporary file %s for writing.", tmpName); stLog (stMessage, ST_LOG_ERROR); stAbortThis (TRUE); } if (path[0]) sprintf (stMessage, "%s/%s -> %s", path, af_retattr (aso, AF_ATTBOUND), destName); else sprintf (stMessage, "%s -> %s", af_retattr (aso, AF_ATTBOUND), destName); stLog (stMessage, ST_LOG_MSGERR); if ((contentsBuf = malloc ((unsigned) asoAttrBuf.af_size+1)) == NULL) { stLog ("Out of memory", ST_LOG_ERROR); stAbortThis(TRUE); } nbytes = fread (contentsBuf, sizeof (char), asoAttrBuf.af_size, versionFile); contentsBuf[nbytes] = '\0'; af_close (versionFile); if (fwrite(contentsBuf, sizeof (char), nbytes, tmpFile) != nbytes) { stLog ("couldn't write busy file.", ST_LOG_ERROR); stAbortThis (TRUE); } free (contentsBuf); fclose (tmpFile); oldDate.actime = asoAttrBuf.af_atime; oldDate.modtime = asoAttrBuf.af_mtime; utime (tmpName, &oldDate); unlink (destName); if (link (tmpName, destName) < 0) { sprintf (stMessage, "cannot link %s to %s.", tmpName, destName); stLog (stMessage, ST_LOG_ERROR); stAbortThis (TRUE); } chmod (destName, asoAttrBuf.af_mode); stThisTransaction.tr_done = TRUE; stUnRegisterFile (tmpName); unlink (tmpName); if (af_getkey (path, asoAttrBuf.af_name, asoAttrBuf.af_type, AF_BUSYVERS, AF_BUSYVERS, &busyAso) == -1) { stLog (af_errmsg ("af_getkey"), ST_LOG_ERROR); stAbortThis (TRUE); } /* * "busyAso" points to the key of a newly created file, which * has been retrieved from the version archive in case no * file was present. */ /* * Register the busyversion appropriately: set busy if * needed, attach (most of) the user-defined attributes * of the original version, attach intent-description. */ if (!fixFlag) { Af_key previous_busy; if (af_setbusy (&busyAso, aso, &previous_busy) == -1) { stLog (af_errmsg ("af_getkey"), ST_LOG_ERROR); stAbortThis (TRUE); } af_dropkey (&previous_busy); } i = 0; while ((attrPtr = asoAttrBuf.af_udattrs[i++])) { if (af_setattr (&busyAso, AF_REPLACE, attrPtr) == -1) af_setattr (&busyAso, AF_ADD, attrPtr); } af_setattr (&busyAso, AF_REMOVE, AT_ATTALIAS); if ((reserveDate = malloc ((unsigned) (strlen ("rtime") + 32)))) { sprintf (reserveDate, "%s=%s", "rtime", af_retattr (&busyAso, AF_ATTCTIME)); if ((af_setattr (&busyAso, AF_REPLACE, reserveDate) == -1) && (af_setattr (&busyAso, AF_ADD, reserveDate) == -1)) { sprintf (stMessage, "Can't set reservation date for %s.", af_retattr (aso, AF_ATTUNIXNAME)); stLog (stMessage, ST_LOG_WARNING); } free (reserveDate); } else { sprintf (stMessage, "Can't set reservation date for %s (no memory).", af_retattr (aso, AF_ATTUNIXNAME)); stLog (stMessage, ST_LOG_WARNING); } af_dropkey (&busyAso); } else { /* denied or not doit */ sprintf (stMessage, "%s not restored", stThisTransaction.tr_fname); stLog (stMessage, ST_LOG_MSGERR); stThisTransaction.tr_rc += 1; } af_dropkey (&lastAso); af_freeattrbuf (&asoAttrBuf); } shapetools-1.4pl6.orig/src/vc/retrv/retrversion.c100444 2013 145 1407 5517473770 20250 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ char *retrversion () { static char release[] = "retrv-4.5 (Tue Aug 23 17:58:41 1994 by andy@cs.tu-berlin.de)"; return release; } shapetools-1.4pl6.orig/src/vc/retrv/Shapefile100444 2013 145 6456 5414052472 17342 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for retrv # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[6.0] Tue Jun 29 16:45:49 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) $(CC) -c $(CFLAGS) $(VERSIONFILE) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean memdebug: CFLAGS=-g -O LDFLAGS=-g #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/vc/retrv/Makefile100444 2013 145 22462 5426222136 17171 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for retrv # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[6.0] Fri Jul 30 17:47:08 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/vc/retrv # A short name for this node system NODENAME = retrv # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = $(BASE) INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. TARGET = retrv # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = retrversion.c # source VERSIONOBJECT = retrversion.o # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = vcat # The regular source and header files. SOURCES = retrv.c doretrv.c HEADERS = # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = retrv.1 vcat.1 MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. OBJECTS = retrv.o doretrv.o $(VERSIONOBJECT) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = $(LOCALLIBPATH)/libAtFStk.a $(LOCALLIBPATH)/libsttk.a $(LOCALLIBPATH)/libAtFS.a LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(TARGET) $(TARGET): $(LOCALLIBS) $(OBJECTS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET) to $$i; \ ln $(TARGET) $$i; \ done installtargets: $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$(TARGET): $(TARGET) @-echo "installing $(TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET); \ fi; \ cp $(TARGET) $(INSTALLBINPATH)/$(TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$$i; \ done installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/vc/retrv/Dependencies100444 2013 145 627 5336502373 20005 0ustar dokoswtdoretrv.o: $(BASE)/include/afsys.h doretrv.o: $(BASE)/include/atfs.h doretrv.o: $(BASE)/include/atfstk.h doretrv.o: $(BASE)/include/config.h doretrv.o: $(BASE)/include/sttk.h doretrv.o: doretrv.c retrv.o: $(BASE)/include/afsys.h retrv.o: $(BASE)/include/atfs.h retrv.o: $(BASE)/include/atfstk.h retrv.o: $(BASE)/include/config.h retrv.o: $(BASE)/include/sttk.h retrv.o: retrv.c retrversion.o: retrversion.c shapetools-1.4pl6.orig/src/vc/save/ 40755 2013 145 0 5626416313 15210 5ustar dokoswtshapetools-1.4pl6.orig/src/vc/save/save.c100444 2013 145 24645 5617457351 16447 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools Version Control System * * save.c - main program for "save" command * * Authors: Axel.Mahler@cs.tu-berlin.de * Andreas.Lampen@cs.tu-berlin.de * * $Header: save.c[8.1] Thu Aug 4 16:17:10 1994 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "atfstk.h" #include "sttk.h" #define SAVE_ATTRFILE "SVATTRS" void saveAFile(); /*==================== * global variables *====================*/ /* -?, -help */ EXPORT char *aliasName = NULL; /* -a, -alias */ EXPORT int deltaFlag = AF_STORE_DELTA; /* -delta, -nodelta */ EXPORT int forceFlag = FALSE; /* -f, -force*/ EXPORT int fixType = 0; /* -fix */ EXPORT char *fixString = NULL; EXPORT int fixGen = AF_NOVNUM; EXPORT int fixRev = AF_NOVNUM; EXPORT time_t fixDate = 0; EXPORT int newGenFlag = FALSE; /* -g, -newgen */ EXPORT int ignBusyFlag = FALSE; /* -ignore_busy_version */ EXPORT int keepLockFlag = FALSE; /* -l, -lock */ EXPORT char *historyLog = NULL; /* -m, -logmsg */ EXPORT int vnumGen = AF_NOVNUM; /* -n, -setvnum */ EXPORT int vnumRev = AF_NOVNUM; /* -q, -quiet */ EXPORT char *attrFile = NULL; /* -setattrs */ EXPORT int stdinFlag = FALSE; /* -stdin */ LOCAL int nameCount; /*======================== * command line parsing *========================*/ LOCAL int handleBinding (option, arg) char *option, *arg; { int bindType, bindGen, bindRev; char *bindString; time_t bindDate; void saveAFile (); if (!arg || !(*arg)) { sprintf (stMessage, "No binding specified -- '-%s' ignored.\n", option); stLog (stMessage, ST_LOG_MSGERR); return (1); } switch (option[0]) { case 'f': /* fix */ fixType = atScanBinding (arg, &fixString, &fixGen, &fixRev, &fixDate); if (fixType == AT_BIND_DEFAULT) { sprintf (stMessage, "invalid binding -- '-%s' ignored.\n", option); stLog (stMessage, ST_LOG_MSGERR); return (1); } /* assume generation number, when fixString contains only digits */ if (fixType == AT_BIND_ALIAS) { int i=0, isGen = TRUE; while (fixString[i]) if (!isdigit(fixString[i++])) isGen = FALSE; if (isGen) { fixGen = atoi (fixString); fixType = AT_BIND_VNUM; fixString = NULL; } } break; case 'a': /* alias */ aliasOpt: bindType = atScanBinding (arg, &aliasName, &bindGen, &bindRev, &bindDate); if (bindType != AT_BIND_ALIAS) { sprintf (stMessage, "invalid alias name -- '-%s' ignored.\n", option); stLog (stMessage, ST_LOG_MSGERR); return (1); } break; case 'n': /* number */ numberOpt: bindType = atScanBinding (arg, &bindString, &vnumGen, &vnumRev, &bindDate); if (bindType != AT_BIND_VNUM) { sprintf (stMessage, "invalid version number -- '-%s' ignored.\n", option); stLog (stMessage, ST_LOG_MSGERR); return (1); } break; case 's': /* alias or number */ if (option[3] == 'a') goto aliasOpt; else goto numberOpt; } return (0); } LOCAL int handleDelta (option, arg) char *option, *arg; { switch (option[0]) { case 'n': /* nodelta */ deltaFlag = AF_STORE_COMPLETE; break; case 'd': /* delta */ deltaFlag = AF_STORE_DELTA; break; } return (0); } LOCAL int handleLog (option, arg) char *option, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No log message specified -- '-%s' ignored.\n", option); stLog (stMessage, ST_LOG_MSGERR); return (1); } historyLog = arg; return (0); } LOCAL int handleAttrFile (option, arg) char *option, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No attributes file specified -- '-%s' ignored.\n", option); stLog (stMessage, ST_LOG_MSGERR); return (1); } attrFile = arg; return (0); } LOCAL int printVersion () { char *saveversion(); sprintf (stMessage, "This is %s version %s", stProgramName, saveversion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, "using AtFStk version %s", atVersion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " AtFS version %s", af_version()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " and Sttk version %s.", stVersion()); stLog (stMessage, ST_LOG_MSG); stExit (0); return (0); } static int usage(); static StOptDesc optDesc[] = { { "?", PCALL, usage, NULL, NULL }, { "a", PARG, handleBinding, NULL, NULL }, { "alias", PARG, handleBinding, NULL, NULL }, { "delta", PCALL, handleDelta, NULL, NULL }, { "f", PSWITCH|PSET, NULL, &forceFlag, NULL }, { "force", PSWITCH|PSET, NULL, &forceFlag, NULL }, { "fix", PARG, handleBinding, NULL, NULL }, { "g", PSWITCH|PSET, NULL, &newGenFlag, NULL }, { "help", PCALL, usage, NULL, NULL }, { "ignore_busy_version", PSWITCH|PSET, NULL, &ignBusyFlag, NULL }, { "l", PSWITCH|PSET, NULL, &keepLockFlag, NULL }, { "lock", PSWITCH|PSET, NULL, &keepLockFlag, NULL }, { "logmsg", PARG, handleLog, NULL, NULL }, { "m", PARG, handleLog, NULL, NULL }, { "n", PARG, handleBinding, NULL, NULL }, { "newgen", PSWITCH|PSET, NULL, &newGenFlag, NULL }, { "nodelta", PCALL, handleDelta, NULL, NULL }, { "q", PSWITCH|PSET, NULL, &stQuietFlag, NULL }, { "quiet", PSWITCH|PSET, NULL, &stQuietFlag, NULL }, { "setattrs", PARG, handleAttrFile, NULL, NULL }, { "setvnum", PARG, handleBinding, NULL, NULL }, { "stdin", PSWITCH|PSET, NULL, &stdinFlag, NULL }, { "version", PSWITCH, printVersion, NULL, NULL }, { NULL, 0, NULL, NULL, NULL }, }; LOCAL int usage() { stLog ("Usage:", ST_LOG_MSGERR); stShortUsage (stProgramName, optDesc, "names..."); atBindUsage (""); stExit (1); return (1); } /*===================== * signal handlers *=====================*/ LOCAL Sigret_t interrupt_action () /* is executed by appropriate signal handler */ { disableSig (SIGINT); stRmRegisteredFiles (); if ((nameCount - stThisTransaction.tr_seqno) > 1) { sprintf (stMessage, "\ncompletely stop saving (%d files unsaved) ?", nameCount - stThisTransaction.tr_seqno); if (stAskConfirm (stMessage, "no")) { if (stThisTransaction.tr_done) { sprintf (stMessage, "\ntoo late, %s already saved", stThisTransaction.tr_fname); stLog (stMessage, ST_LOG_MSG); enableSig(); return; /* continue where we've been interrupted */ } sprintf (stMessage, "%s not saved", stThisTransaction.tr_fname); stLog (stMessage, ST_LOG_MSG); enableSig(); stCatchSigs (); /* mostly to deal with %^%$#$ Sys V signal-handling */ af_cleanup (); longjmp (stThisTransaction.tr_env, 1); } else { sprintf (stMessage, "%s not saved", stThisTransaction.tr_fname); stLog (stMessage, ST_LOG_MSG); stExit (1); } } else { sprintf (stMessage, "\n%s %ssaved", stThisTransaction.tr_fname, stThisTransaction.tr_done ? "already " : "not "); stLog (stMessage, ST_LOG_MSG); stExit (1); } } /*==================== * main program *====================*/ EXPORT int main (argc, argv) int argc; char **argv; { int tmpArgc, newArgc, i, j, k, retCode=0; char *cp, **tmpArgv, **newArgv, path[PATH_MAX], *bindPtr; Af_key curKey; Af_set *setPtr; stProgramName = (cp = strrchr (argv[0], '/')) ? ++cp : argv[0]; if (argc < 2) { usage (); stExit (1); } if (isupper (stProgramName[0])) newGenFlag = TRUE; if (atBindOptions (argc, argv, &tmpArgc, &tmpArgv)) stExit (1); if (stParseArgs (tmpArgc, tmpArgv, &newArgc, &newArgv, optDesc)) stExit (1); if (newArgc == 1) { stLog ("No name(s) given.", ST_LOG_MSGERR); stExit (1); } if (ignBusyFlag && !newGenFlag) { stLog ("Option \"-ignore_busy_version\" makes no sense here. Ignored.", ST_LOG_MSGERR); } if (fixType && newGenFlag) { stLog ("Incompatible options: '-fix' and '-newgen'.", ST_LOG_MSGERR); stExit (1); } stInterruptAction = interrupt_action; stCatchSigs (); if (!attrFile) attrFile = getenv (SAVE_ATTRFILE); nameCount = newArgc-1; k=0; stThisTransaction.tr_rc = 0; for (i = 1; i < newArgc; i++) { /* interpret version binding in brackets as version number or alias to be set */ if ((bindPtr = strchr (newArgv[i], '['))) { int bindType, gen, rev; char *alias; time_t dummy; bindType = atScanBinding (bindPtr, &alias, &gen, &rev, &dummy); if (bindType == AT_BIND_VNUM) { vnumGen = gen; vnumRev = rev; } else if (bindType == AT_BIND_ALIAS) { aliasName = alias; } else { sprintf (stMessage, "invalid version number or alias -- '-%s' ignored.\n", bindPtr); stLog (stMessage, ST_LOG_MSGERR); } *bindPtr = '\0'; } if ((setPtr = atBindSet (newArgv[i], NULL, ignBusyFlag ? AT_BIND_LASTSAVED : AT_BIND_LAST)) == NULL) { stLog (atBindErrorMsg, ST_LOG_ERROR); stExit (2); } if (af_nrofkeys (setPtr) == 0) { sprintf (stMessage, "%s: nothing found -- skipped.", newArgv[i]); stLog (stMessage, ST_LOG_MSGERR); retCode++; continue; } strcpy (path, af_afpath (newArgv[i])); for (j = 0; j < af_nrofkeys (setPtr); j++) { af_setgkey (setPtr, j, &curKey); if (!setjmp (stThisTransaction.tr_env)) { stThisTransaction.tr_seqno = k++; strcpy (stThisTransaction.tr_fname, af_retattr (&curKey, AF_ATTUNIXNAME)); stThisTransaction.tr_done = FALSE; af_transaction (); saveAFile (path, &curKey); af_dropkey (&curKey); if (af_commit () < 0) { sprintf (stMessage, "Cannot save changes for %s%s%s -- %s.", path, path[0] ? "/" : "", af_retattr (&curKey, AF_ATTUNIXNAME), af_errmsg ("af_commit")); stLog (stMessage, ST_LOG_ERROR); retCode++; } } else { /* stThisTransaction was aborted */ retCode += stThisTransaction.tr_rc; af_abort (); } } } if (nameCount > 1) stLog ("done.", ST_LOG_MSG); return (retCode); } shapetools-1.4pl6.orig/src/vc/save/dosave.c100444 2013 145 51533 5621414110 16743 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools Version Control System * * dosave.c - functions for "save" command * * Authors: Axel.Mahler@cs.tu-berlin.de * Andreas.Lampen@cs.tu-berlin.de * * $Header: dosave.c[8.3] Mon Aug 8 13:35:52 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "atfstk.h" #include "sttk.h" /*==================== * global variables *====================*/ extern int af_errno; extern char *aliasName; extern char *attrFile; extern int deltaFlag; extern int forceFlag; extern int fixType; extern char *fixString; extern int fixGen; extern int fixRev; extern time_t fixDate; extern int newGenFlag; extern int keepLockFlag; extern char *historyLog; extern int vnumGen; extern int vnumRev; extern int stdinFlag; /*==================== * local routines *====================*/ #define fail(x) ((x) == -1) #define checkAtFSerr(obj) \ if (af_errno != AF_ENOREV) { \ stLog (af_errmsg (obj), ST_LOG_ERROR); \ stAbortThis (TRUE); \ } LOCAL int changed (new, old, realtruth) Af_key *new, *old; int *realtruth; { /* * Return true if new and old are actually different OR deposit is * forced OR if user says 'yes' when asked whether an unchanged version * shall be saved anyway. * As AtFS is still in the tests, this is programmed very defensively. */ FILE *newf, *oldf; size_t newSize = af_retnumattr (new, AF_ATTSIZE); size_t oldSize = af_retnumattr (old, AF_ATTSIZE); char *news, *olds; *realtruth = TRUE; /* initially assume that something has act. changed */ if (af_rettimeattr (new, AF_ATTMTIME) == af_rettimeattr (old, AF_ATTMTIME)) { *realtruth = FALSE; if (forceFlag) { return TRUE; } if (stQuietFlag) { return FALSE; } if (isatty (fileno (stdin)) && isatty (fileno (stdout))) { sprintf (stMessage, "There are no changes with respect to the previously saved version.\nSave anyway ?"); return (!stAskConfirm (stMessage, "no")); } } if (newSize != oldSize) { return (TRUE); } else { /* lets have a closer look at 'em */ if ((news = malloc ((unsigned)newSize)) == NULL) { sprintf (stMessage, "Can't malloc %lu bytes.", newSize); stLog (stMessage, ST_LOG_MSG); stAbortThis (TRUE); } if ((olds = malloc ((unsigned)oldSize)) == NULL) { sprintf (stMessage, "Can't malloc %lu bytes.", oldSize); stLog (stMessage, ST_LOG_MSG); free (news); stAbortThis (TRUE); } if ((newf = af_open (new, "r")) == NULL) { stLog (af_errmsg ("busy-version"), ST_LOG_ERROR); free (news); free (olds); stAbortThis(TRUE); } if ((oldf = af_open (old, "r")) == NULL) { stLog (af_errmsg ("lastsaved-version"), ST_LOG_ERROR); free (news); free (olds); af_close (newf); stAbortThis(TRUE); } *news = *olds = '\0'; if (fread (news, sizeof (char), (size_t)newSize, newf) != newSize) { stLog ("Couldn't read busy version.", ST_LOG_MSG); free (news); free (olds); af_close (newf); af_close (oldf); stAbortThis (TRUE); } if (fread (olds, sizeof (char), (size_t)oldSize, oldf) != oldSize) { stLog ("Couldn't read lastsaved version.", ST_LOG_MSG); free (news); free (olds); af_close (newf); af_close (oldf); stAbortThis (TRUE); } af_close (newf); af_close (oldf); if (memcmp (olds, news, (int)newSize)) { free (news); free (olds); return TRUE; } else { /* Hmmm, looks like nothing has changed ... */ free (news); free (olds); *realtruth = FALSE; /* return value may be a lie */ if (forceFlag) { return TRUE; } if (stQuietFlag) { return FALSE; } if (isatty (fileno (stdin)) && isatty (fileno (stdout))) { sprintf (stMessage, "There are no changes with respect to the previously saved version.\nSave anyway ?"); return (!stAskConfirm (stMessage, "no")); } else return FALSE; } } } LOCAL char *getText (msgText) char *msgText; { static char *txt = AT_EMPTYLOG; FILE *txtFile; struct stat statbuf; static int firsttime = TRUE; if (firsttime) { firsttime = FALSE; if (!msgText || !*msgText) { stLog ("empty descriptive text", ST_LOG_WARNING); return txt; } if (*msgText == '@') { /* filename */ if ((txtFile = fopen (&msgText[1], "r")) == NULL) { sprintf (stMessage, "cannot open '%s' -- empty descriptive text.", &msgText[1]); stLog (stMessage, ST_LOG_WARNING); return txt; } if (fstat (fileno(txtFile), &statbuf) == -1) { sprintf (stMessage, "cannot stat '%s' -- empty descriptive text.", &msgText[1]); stLog (stMessage, ST_LOG_WARNING); return txt; } if ((txt = malloc ((unsigned)(statbuf.st_size+1))) == NULL) { stLog ("not enough memory for descriptive text.", ST_LOG_WARNING); return txt; } memset (txt, 0, (int) statbuf.st_size+1); fread (txt, sizeof (char), (size_t)statbuf.st_size, txtFile); fclose (txtFile); } else { /* plain message text */ txt = msgText; } } return txt; } #define NOSHELL 127 LOCAL char *getnote (prompt, changeflg, force, xintent) char *prompt, *xintent; int changeflg, force; { char *tmpname = NULL, *edname, cmd[ST_MSGLEN], *intent; static char *notetxt, *rawnotetxt; FILE *tmpfil; struct stat statbuf; static int firsttime = TRUE; int istty; istty = isatty(fileno(stdin)); if (xintent) { intent = (char *)malloc (strlen (xintent) +1); if (!intent) return (AT_EMPTYLOG); strcpy (intent, xintent); } else intent = ""; if (stdinFlag) { char *edbuf; if (intent && istty && !stQuietFlag) { printf("%s\n", intent); } if (firsttime || (istty && !stQuietFlag && !stAskConfirm ("Use previous log message ?", "yes"))) { rawnotetxt = stGetFromStdin ('.'); rawnotetxt = rawnotetxt ? rawnotetxt : ""; if ((notetxt = malloc (strlen (rawnotetxt))) != (char *)NULL) strcpy (notetxt, rawnotetxt); else notetxt = rawnotetxt; /* not nice but safe */ firsttime = FALSE; } if ((edbuf = (char *)malloc (strlen (intent) + strlen (rawnotetxt) +1)) != (char *)NULL) { *edbuf = '\0'; strcat (edbuf, intent); strcat (edbuf, rawnotetxt); notetxt = realloc (notetxt, strlen (edbuf)); strcpy (notetxt, edbuf); free (edbuf); } return notetxt; } if (stQuietFlag || (!istty)) { if (intent) goto retintent; else return AT_EMPTYLOG; } if ((!force) && (!firsttime) && notetxt) { if (stAskConfirm ("Use previous log message ?", "yes")) { return notetxt; } else { free (notetxt); } } firsttime = FALSE; if (changeflg) { if (!stAskConfirm (prompt, "yes")) if (intent) goto retintent; else return (AT_EMPTYLOG); } else { if (stAskConfirm ("The new version is unmodified. Comment it anyway ?", "no")) if (intent) goto retintent; else return (AT_EMPTYLOG); } tmpname = stTmpFile (NULL); stRegisterFile (tmpname); if (intent) { FILE *tfd; tfd = fopen (tmpname, "w"); if (fwrite (intent, sizeof (char), strlen (intent), tfd) != strlen (intent)) { stLog ("write failure on tmp-file", ST_LOG_ERROR); } fclose (tfd); } edname = getenv ("EDITOR"); if (!edname) edname = "vi"; sprintf (cmd, "%s %s", edname, tmpname); sprintf (stMessage, "starting up %s ...", edname); stLog (stMessage, ST_LOG_MSG); if (system (cmd) == NOSHELL) { stLog ("couldn't execute shell", ST_LOG_ERROR); stUnRegisterFile (tmpname); } else { if ((tmpfil = fopen (tmpname, "r")) == NULL) { stLog ("empty logentry", ST_LOG_WARNING); stUnRegisterFile (tmpname); return AT_EMPTYLOG; } else { unlink (tmpname); stUnRegisterFile (tmpname); if (fstat (fileno(tmpfil), &statbuf) == -1) { sprintf (stMessage, "couldn't stat tmp file '%s'.", tmpname); stLog (stMessage, ST_LOG_WARNING); return AT_EMPTYLOG; } else { notetxt = malloc ((unsigned)(statbuf.st_size+1)); if (!notetxt) { stLog ("not enough memory for note text.", ST_LOG_WARNING); return AT_EMPTYLOG; } memset (notetxt, 0, (int) statbuf.st_size+1); fread (notetxt, sizeof (char), (size_t)statbuf.st_size, tmpfil); fclose (tmpfil); stUnRegisterFile (tmpname); return notetxt; } } } stLog ("Couldn't start editor. Please check EDITOR environment variable.", ST_LOG_WARNING); stUnRegisterFile (tmpname); return AT_EMPTYLOG; /* maybe we should try to read from stdin */ retintent: if ((notetxt = malloc ((unsigned)(strlen (intent) + 1))) == (char *) NULL){ stUnRegisterFile (tmpname); stLog ("not enough memory for note text.", ST_LOG_WARNING); return AT_EMPTYLOG; } strcpy (notetxt, intent); stUnRegisterFile (tmpname); return notetxt; } LOCAL void salvage (text) char *text; { static int serial = 0; FILE *fil; char fnam[ST_MSGLEN]; sprintf (fnam, "%s%d-%d", stProgramName, getpid(), serial++); if (text) { if ((fil = fopen (fnam, "w")) != NULL) { if (fwrite (text, sizeof (char), strlen (text), fil) != strlen (text)) stLog ("write failure on salvage file -- sorry!", ST_LOG_ERROR); else { sprintf (stMessage, "A temporary copy of your log can be found in %s.", fnam); stLog (stMessage, ST_LOG_MSG); } } fclose (fil); } } LOCAL int i_locked_gen (key, verbose) Af_key *key; int verbose; { Af_user *locker; uid_t myuid; myuid = (uid_t)geteuid(); if (!atUserValid (locker = af_testlock(key))) { if (verbose) { sprintf (stMessage, "You must lock %s before saving.", af_retattr (key, AF_ATTBOUND)); stLog (stMessage, ST_LOG_ERROR); } return FALSE; } else { /* there was some lock set */ if (atUserUid (locker) != myuid) { if (verbose) { sprintf (stMessage, "%s already locked by %s.", af_retattr (key, AF_ATTBOUND), atUserName (locker)); stLog (stMessage, ST_LOG_ERROR); } return FALSE; } return TRUE; } } /*===================== * exported routines *=====================*/ EXPORT void saveAFile (spath, busyAso) char *spath; Af_key *busyAso; { /* * Save working file with the given name. Check for changes before saving. * Unless stQuietFlag is set, the user will be prompted for a note * describing the changes to be saved. * On the locking strategy: * An author can save a busy version, only if he holds a lock (update * privilege) for the document history. When an archive is newly * created from a (busy) file, such a lock is assumed to be set. * Upon save operations - which are conceptually local to a user context - * the lock is released. * Locks on certain documents can be obtained through means of 'reserve' * which is a User <--> Project transaction. Locally created documents * are placed under project discipline (or configuration control) the * first time they are submitted -- even if they have not been reserved * yet. Locks have token-character, i.e. they may be passed around, but * never ever be duplicated. */ /* * NOTE: use of variant attribute in af_getkey is not yet functional. * The parameter, however, is necessary to occupy the slot. * Implementation of variant selection may make it necessary * to add another parameter to this procedure. */ char *curName, afname[NAME_MAX], aftype[NAME_MAX], *note = NULL; int changedFlag = TRUE, busystate, have_lock = FALSE, fix_generation; int aliasInUse = FALSE; Af_key lastsave, skey, *newkey, *tmpkey; curName = stThisTransaction.tr_fname; strcpy (afname, af_afname (curName)); strcpy (aftype, af_aftype (curName)); /* give a little feedback ... */ if (spath[0]) { sprintf (stMessage, "[%s]%s:", spath, curName); } else { sprintf (stMessage, "%s:", curName); } stLog (stMessage, ST_LOG_MSG); switch (fixType) { case AT_BIND_DATE: fixString = asctime (localtime (&fixDate)); case AT_BIND_ALIAS: if ((tmpkey = atBindVersion (curName, fixString))) { fix_generation = af_retnumattr (tmpkey, AF_ATTGEN); af_dropkey (tmpkey); } else { sprintf (stMessage, "symbolic name %s not known for %s.", fixString, curName); stLog (stMessage, ST_LOG_ERROR); stAbortThis (FALSE); } break; case AT_BIND_VNUM: if (fixGen == AF_NOVNUM) { sprintf (stMessage, "invalid version number given with '-fix' option"); stLog (stMessage, ST_LOG_ERROR); stAbortThis (FALSE); } else { fix_generation = fixGen; } } if (aliasName) { if ((tmpkey = atBindVersion (curName, aliasName))) { sprintf (stMessage, "symbolic name %s already in use by %s[%s] -- ignored.", aliasName, curName, af_retattr (tmpkey, AF_ATTVERSION)); af_dropkey (tmpkey); stLog (stMessage, ST_LOG_WARNING); aliasInUse = TRUE; } } busystate = af_retnumattr (busyAso, AF_ATTSTATE); if (fail(af_getkey (spath, afname, aftype, fixType ? fix_generation : AF_LASTVERS, AF_LASTVERS, &lastsave))) { if (fixType) { stLog ("No place to insert a version!", ST_LOG_ERROR); stAbortThis (FALSE); } checkAtFSerr(curName) stLog ("creating archive", ST_LOG_MSG); af_commit (); if (fail(af_saverev (busyAso, &skey, AF_LASTVERS, deltaFlag))) { stLog (af_errmsg (curName), ST_LOG_ERROR); stAbortThis(TRUE); } af_transaction (); newkey = &skey; stThisTransaction.tr_done = TRUE; if (historyLog) { note = getText (historyLog); } else { note = getnote ("How about describing the purpose of this document ?", changedFlag, TRUE, (char *)NULL); } } /* This was handling of newly created archive */ else { if ((busystate == AF_BUSY) && (changed (busyAso, &lastsave, &changedFlag)) && (have_lock = i_locked_gen (&lastsave, TRUE))) { Af_key previous_busy; if (fixType) { if (af_setbusy (busyAso, &lastsave, &previous_busy) < 0) { sprintf (stMessage, "Can't set predecessor for fixed version of %s.", curName); stLog (stMessage, ST_LOG_WARNING); stLog (af_errmsg (curName), ST_LOG_ERROR); } } if (historyLog) { note = getText (historyLog); } else { char *intent = (char *)0; if (!keepLockFlag) intent = af_retattr (&lastsave, AT_ATTINTENT); note = getnote ("Do you want to comment your modifications ?", changedFlag, FALSE, intent); if (intent) free (intent); } af_commit (); if (fail(af_saverev (busyAso, &skey, fixType ? fix_generation : AF_LASTVERS, deltaFlag))) { stLog (af_errmsg (curName), ST_LOG_ERROR); af_dropkey (&lastsave); salvage (note); stAbortThis (TRUE); } af_transaction (); if (fixType) { Af_key junk; if (af_setbusy (busyAso, &previous_busy, &junk) < 0) { sprintf (stMessage, "WARNING: Can't reset original busy version link for %s.", curName); stLog (stMessage, ST_LOG_ERROR); stLog (af_errmsg (curName), ST_LOG_ERROR); } } newkey = &skey; af_setattr (newkey, AF_REMOVE, AT_ATTINTENT); /* if lock is kept, move intent to new "last saved" */ if (keepLockFlag) { char *tmpAttr, *intent = NULL; if ((intent = af_retattr (&lastsave, AT_ATTINTENT))) { if ((tmpAttr = malloc (strlen(intent)+strlen(AT_ATTINTENT)+2)) == NULL) { stLog ("not enough memory.", ST_LOG_ERROR); stAbortThis (TRUE); } strcpy (tmpAttr, AT_ATTINTENT); strcat (tmpAttr, "="); strcat (tmpAttr, intent); af_setattr (newkey, AF_ADD, tmpAttr); free (intent); } } af_setattr (&lastsave, AF_REMOVE, AT_ATTINTENT); atUnlock (&lastsave); af_lock (newkey, af_afuser (geteuid())); stThisTransaction.tr_done = TRUE; } else { /* version is unchanged or not locked */ sprintf (stMessage, "%s not saved. %s ", curName, curName); stLog (stMessage, ST_LOG_MSG | ST_LOG_NONL); (void) strcpy (stMessage, "left unchanged."); if (changedFlag) { stLog (stMessage, ST_LOG_MSG); af_dropkey (&lastsave); stAbortThis (FALSE); } if ((!keepLockFlag && atUserValid (af_testlock(&lastsave))) || !i_locked_gen (&lastsave, FALSE)) { if (busystate == AF_BUSY) { Af_user *locker; /* busy version shall be removed. check if it is locked */ if (atUserValid (locker = af_testlock (busyAso))) { if (atUserUid (locker) != geteuid ()) { /* locked by somebody else */ if (!stQuietFlag) { sprintf (stMessage, "No permission to delete %s (locked by %s).", curName, atUserName (locker)); stLog (stMessage, ST_LOG_ERROR); } } } else { /* the version is not locked. We must lock it to delete it. */ if (af_lock (busyAso, af_afuser (geteuid ())) == NULL) { if (!stQuietFlag) { sprintf (stMessage, "Cannot lock %s for deletion -- not deleted.", curName); stLog (stMessage, ST_LOG_ERROR); } } } af_commit (); if (fail(af_rm (busyAso))) { if (!stQuietFlag) { (void) strcpy (stMessage, "-- cannot remove."); stLog (af_errmsg (stMessage), ST_LOG_ERROR); } strcpy (stMessage, "not removed."); } else { atUnlock (&lastsave); strcpy (stMessage, "removed."); } af_transaction (); } } stLog (stMessage, ST_LOG_MSG); af_dropkey (&lastsave); stAbortThis(FALSE); } } /* If we get here, something has been saved -- set note */ if (fail(af_snote (newkey, note))) { stLog (af_errmsg (curName), ST_LOG_ERROR); salvage (note); } if ((aliasName != NULL) && !aliasInUse) atSetVersAlias (newkey, aliasName); if (newGenFlag) { if (busystate != AF_BUSY) { Af_key ngkey; af_commit (); if (fail (af_newgen (newkey, &ngkey))) { stLog (af_errmsg (curName), ST_LOG_ERROR); af_dropkey (newkey); stAbortThis (TRUE); } af_transaction (); af_setattr (&ngkey, AF_REMOVE, AT_ATTALIAS); atUnlock (newkey); af_dropkey (newkey); newkey = &ngkey; } else { vnumGen = af_retnumattr (&lastsave, AF_ATTGEN) + 1; vnumRev = 0; } } if (vnumGen != AF_NOVNUM && vnumRev != AF_NOVNUM) { af_lock (newkey, af_afuser(geteuid())); if (af_svnum (newkey, vnumGen, vnumRev) < 0) { sprintf (stMessage, "can't set version number %d.%d for %s", vnumGen, vnumRev, curName); stLog (af_errmsg (stMessage), ST_LOG_ERROR); } } sprintf (stMessage, "%s saved%s.", af_retattr (newkey, AF_ATTBOUND), changedFlag ? "" : " (no changes)"); stLog (stMessage, ST_LOG_MSG); /* scan attribute file and set attributes */ if (attrFile && *attrFile) { if (atSetAttrFile (newkey, attrFile) == FALSE) stLog (atErrMsg, ST_LOG_MSGERR); } /* Take care of old locks and new locks (in case they'll be kept */ atUnlock (&lastsave); /* remove previous lock */ if (!keepLockFlag) { atUnlock (newkey); if (busystate == AF_BUSY) { Af_user *locker; /* busy version shall be removed. check if it is locked */ if (atUserValid (locker = af_testlock (busyAso))) { if (atUserUid (locker) != geteuid ()) { /* locked by somebody else */ if (!stQuietFlag) { sprintf (stMessage, "No permission to delete %s (locked by %s).", curName, atUserName (locker)); stLog (stMessage, ST_LOG_ERROR); } } } else { /* the version is not locked. We must lock it to delete it. */ if (af_lock (busyAso, af_afuser (geteuid ())) == NULL) { if (!stQuietFlag) { sprintf (stMessage, "Cannot lock %s for deletion -- not deleted.", curName); stLog (stMessage, ST_LOG_ERROR); } } } af_commit (); if (fail(af_rm (busyAso))) { if (!stQuietFlag) { sprintf (stMessage, "cannot remove %s", curName); stLog (af_errmsg (stMessage), ST_LOG_ERROR); } } else { sprintf (stMessage, "%s removed.", curName); stLog (stMessage, ST_LOG_MSG); } af_transaction (); } } else { /* KEEPLOCK */ /* if we keep the generation lock, the most recently * saved revision within the locked generation must be * version-locked. */ uid_t myuid = (uid_t)geteuid (); if (atUserUid (af_lock (newkey, af_afuser(myuid))) != myuid) { if (fixType) sprintf (stMessage, "Cannot lock generation %d of %s.", fix_generation, curName); else sprintf (stMessage, "Cannot lock %s-history.", curName); stLog (af_errmsg (stMessage), ST_LOG_ERROR); } } af_dropkey (newkey); af_dropkey (&lastsave); } shapetools-1.4pl6.orig/src/vc/save/saveversion.c100444 2013 145 1406 5621414243 20007 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ char *saveversion () { static char release[] = "save-4.7 (Tue Aug 23 17:58:59 1994 by andy@cs.tu-berlin.de)"; return release; } shapetools-1.4pl6.orig/src/vc/save/Shapefile100444 2013 145 6410 5414050202 17111 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for save # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[8.0] Tue Jun 29 16:27:33 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) $(CC) -c $(CFLAGS) $(VERSIONFILE) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/vc/save/Makefile100444 2013 145 23231 5426221640 16757 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for save # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[8.0] Fri Jul 30 17:28:25 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/vc/save # A short name for this node system NODENAME = save # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = $(BASE) INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. TARGET = save # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = saveversion.c # source VERSIONOBJECT = saveversion.o # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = Save # The regular source and header files. SOURCES = save.c dosave.c HEADERS = # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = save.1 MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. OBJECTS = save.o dosave.o $(VERSIONOBJECT) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = $(LOCALLIBPATH)/libAtFStk.a $(LOCALLIBPATH)/libsttk.a $(LOCALLIBPATH)/libAtFS.a LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(TARGET) $(TARGET): $(LOCALLIBS) $(OBJECTS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET) to $$i; \ ln $(TARGET) $$i; \ done installtargets: $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$(TARGET): $(TARGET) @-echo "installing $(TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET); \ fi; \ cp $(TARGET) $(INSTALLBINPATH)/$(TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$$i; \ done installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done installincludes: $(IFHEADERS) @-_includes="$(IFHEADERS)"; \ for i in $$_includes; \ do \ echo "installing $$i in $(INSTALLINCPATH)"; \ if [ -f $(INSTALLINCPATH)/$$i ] && \ [ ! -w $(INSTALLINCPATH)/$$i ]; \ then \ chmod u+w $(INSTALLINCPATH)/$$i; \ fi; \ cp $$i $(INSTALLINCPATH)/$$i; \ chmod $(INSTALLINCMODE) $(INSTALLINCPATH)/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/vc/save/Dependencies100444 2013 145 611 5333714236 17572 0ustar dokoswtdosave.o: $(BASE)/include/afsys.h dosave.o: $(BASE)/include/atfs.h dosave.o: $(BASE)/include/atfstk.h dosave.o: $(BASE)/include/config.h dosave.o: $(BASE)/include/sttk.h dosave.o: dosave.c save.o: $(BASE)/include/afsys.h save.o: $(BASE)/include/atfs.h save.o: $(BASE)/include/atfstk.h save.o: $(BASE)/include/config.h save.o: $(BASE)/include/sttk.h save.o: save.c saveversion.o: saveversion.c shapetools-1.4pl6.orig/src/vc/scripts/ 40755 2013 145 0 5626416336 15746 5ustar dokoswtshapetools-1.4pl6.orig/src/vc/scripts/vdiff.sh100555 2013 145 12102 5414052241 17474 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: vdiff.sh[4.0] Tue Jun 29 16:41:57 1993 andy@cs.tu-berlin.de frozen $ perror () { echo 1>&2 $* } match () { echo $1 | egrep "$2" > /dev/null } cleanup () { rm -f $rmlist } trapexit () { cleanup exit $estat } afterburner=false vcatopts=-q makepatch=false base=`pwd`/ estat=0 argc=$# trap trapexit 1 2 3 15 if [ $argc -lt 1 ] then perror usage: vdiff [ options ] [ -base '' ] file1 [ file2 ] exit 1 fi while [ $argc -gt 0 ] do i=$1 shift argc=`expr $argc - 1` case $i in -trace) set -x;; -ttrace) set -v set -x;; -base) if [ $afterburner = true ] then if [ $argc -gt 0 ] then base=$1/ shift argc=`expr $argc - 1` else perror usage: vdiff -base requires an argument. exit 1 fi fi;; -c) afterburner=true options="$options $i";; -cset) vcatopts="$vcatopts -xpoff";; -P) makepatch=true;; -version) echo This is 'vdiff-4.0 (Tue Aug 23 17:59:17 1994 by andy@cs.tu-berlin.de).' exit 0;; -*) options="$options $i";; *) if [ -z "$fn1" ] then fn1=$i fn1t=/tmp/`basename $fn1` elif [ -z "$fn2" ] then fn2=$i fn2t=/tmp/`basename $fn2` else perror usage: vdiff [ options ] [ -base '' ] file1 [ file2 ] exit 1 fi;; esac done # $__xpoff$ if [ -z "$fn2" ] then # only one filename argument if match $fn1 '..*\[.*\]' then # first and only filename object in bound version notation mt1=`vl -format '$__mtime$' $fn1 2> /dev/null` fn2=`echo $fn1 | sed -e 's/\[.*\]//'` mt2=`vl -format '$__mtime$' $fn2\[busy\] 2> /dev/null` if [ "$mt1" = "$mt2" ] then exit 0; fi vcat $vcatopts $fn1 > $fn1t if [ $? -gt 0 ] then perror ${fn1}: No such file or version. rm -f $fn1t cleanup exit 1 fi rmlist="$rmlist $fn1t" if [ "$afterburner" = true ] then diff $options $fn1t $fn2 | \ sed -e "s,^\([-*]\{3\} \)/tmp/\([^[]*\)\(.*\),\1$base\2 \3," | grep . [ $? -gt 0 ] estat=$? else diff $options $fn1t $fn2 estat=$? fi else # only filename of busy version given fn2=`vl -lastsaved $fn1` estat=$? mt1=`vl -format '$__mtime' $fn1\[busy\] 2> /dev/null` estat=`expr $estat \| $?` mt2=`vl -format '$__mtime' $fn2 2> /dev/null` estat=`expr $estat \| $?` if [ "$mt1" = "$mt2" ] then exit 0; fi if [ "$estat" -gt 0 ] then perror ${fn1}: No such file or version. estat=1 cleanup exit $estat else fn2t=/tmp/`basename $fn2` fi vcat $vcatopts $fn2 > $fn2t 2> /dev/null if [ $? -gt 0 ] then perror ${fn2}: No such file or version. rm -f $fn2t cleanup exit $estat fi rmlist="$rmlist $fn2t" if [ "$afterburner" = true ] then diff $options $fn2t $fn1 | \ sed -e "s,^\([-*]\{3\} \)/tmp/\([^[]*\)\(.*\),\1$base\2 \3," | grep . [ $? -gt 0 ] estat=`expr $estat \| $?` else diff $options $fn2t $fn1 estat=`expr $estat \| $?` fi fi else # two filename-objects specified if match $fn1 '..*\[.*\]' then # first fn-object in bound version notation mt1=`vl -format '$__mtime$' $fn1 2> /dev/null` rmlist="$rmlist $fn1t" vcat $vcatopts $fn1 > $fn1t 2> /dev/null if [ $? -gt 0 ] then perror ${fn1}: No such file or version. if [ "$makepatch" != true ] then rm -f $fn1t cleanup exit 1 fi fi fn1=$fn1t else mt1=`vl -format '$__mtime$' $fn1\[busy\] 2> /dev/null` fi if match $fn2 '..*\[.*\]' then # second fn-object in bound version notation mt2=`vl -format '$__mtime$' $fn2 2> /dev/null` rmlist="$rmlist $fn2t" vcat $vcatopts $fn2 > $fn2t 2> /dev/null if [ $? -gt 0 ] then perror ${fn2}: No such file or version. if [ "$makepatch" != true ] then rm -f $fn2t cleanup exit 1 fi fi fn2=$fn2t else mt2=`vl -format '$__mtime' $fn2\[busy\] 2> /dev/null` fi if [ "$mt1" = "$mt2" ] then estat=0 else if [ "$afterburner" = true ] then diff $options $fn1 $fn2 | \ sed -e "s,^\([-*]\{3\} \)/tmp/\([^[]*\)\(.*\),\1$base\2 \3," | grep . [ $? -gt 0 ] estat=`expr $estat \| $?` else diff $options $fn1 $fn2 estat=`expr $estat \| $?` fi fi fi rm -f $rmlist exit $estat shapetools-1.4pl6.orig/src/vc/scripts/cphist.sh100555 2013 145 622 5506324001 17632 0ustar dokoswt#$__copyright$ # # Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) # # $Header: cphist.sh[3.1] Wed Jan 26 16:25:55 1994 andy@cs.tu-berlin.de frozen $ # # copy a history to another directory myself=`basename $0` if [ $# != 2 ] ; then echo Usage: $myself history-name destination-dir 1>&2 exit 1 fi tar cf - ./AtFS/Data/"$1" ./AtFS/Attr/"$1" | (cd "$2"; tar xof -; atfsrepair -q "$1") shapetools-1.4pl6.orig/src/vc/scripts/rmhist.sh100444 2013 145 3445 5521524705 17703 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Author Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # # $Header: rmhist.sh[3.2] Wed Jan 26 18:35:43 1994 andy@cs.tu-berlin.de frozen $ # # remove a history myself=`basename $0` usage () { echo "usage: $myself [-f] [-h] [-q] [-v] names" } trapexit () { exit 1 } perror () { echo 1>&2 $* } trap trapexit 1 2 3 15 argc=$# force=false quiet=false while [ $argc -gt 0 ] do i=$1 shift argc=`expr $argc - 1` case $i in -f) force=true quiet=true ;; -h) usage exit 0;; -v) echo This is '$myself-3.2 (Tue Aug 23 17:59:18 1994 by andy@cs.tu-berlin.de).' exit 0;; -q) quiet=true ;; -*) perror invalid option $i usage exit 1;; *) # ToDo: check if name contanins path if [ $quiet = false ] then echo -n "Really remove history $i ? [y] > " read input if [ "$input" = "no" -o "$input" = "n" ] then echo "history $i not removed" exit 1 fi fi if [ $force = true ] then rm -f AtFS/Data/$i AtFS/Attr/$i $i 2> /dev/null else rm AtFS/Data/$i AtFS/Attr/$i $i 2> /dev/null fi esac done exit 0 shapetools-1.4pl6.orig/src/vc/scripts/vp.sh100555 2013 145 2433 5414052206 17012 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) # # $Header: vp.sh[3.0] Tue Jun 29 16:42:03 1993 andy@cs.tu-berlin.de frozen $ pager=${PAGER-more} options= while : ; do case $1 in -*) options="$options $1" # only options without argument supported shift ;; *) break ;; esac done if [ $# -lt 1 ] ; then echo Usage: `basename $0` '[vcat-options]' version ... exit 1 fi trap 'rm -f $tmpnames ; exit' 0 1 2 3 15 count=0 tmpnames= for i in "$@" ; do count=`expr $count + 1` tmpnm=/tmp/`basename $i`.$$$count tmpnames="$tmpnames $tmpnm" vcat $options $i > $tmpnm done $pager $tmpnames shapetools-1.4pl6.orig/src/vc/scripts/Release100444 2013 145 102 5521525006 17302 0ustar dokoswtvc_scripts-2.5 (Tue Aug 23 17:59:20 1994 by andy@cs.tu-berlin.de) shapetools-1.4pl6.orig/src/vc/scripts/Shapefile100444 2013 145 6270 5414051766 17666 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for vdiff # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[3.0] Tue Jun 29 16:42:08 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug_static # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds default: all $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/vc/scripts/Makefile100444 2013 145 25255 5426222103 17513 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for vdiff and other vc scripts # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[3.0] Fri Jul 30 17:45:34 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/vc/scripts # A short name for this node system NODENAME = vc_scripts # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = $(BASE) INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. VDIFF_TARGET = vdiff CPHIST_TARGET = cphist RMHIST_TARGET = rmhist VP_TARGET = vp # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = Release # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # The regular source and header files. VDIFF_SOURCE = vdiff.sh CPHIST_SOURCE = cphist.sh RMHIST_SOURCE = rmhist.sh VP_SOURCE = vp.sh SOURCES = $(VDIFF_SOURCE) $(CPHIST_SOURCE) $(RMHIST_SOURCE) $(VP_SOURCE) HEADERS = MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = vdiff.1 MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(VDIFF_TARGET) $(CPHIST_TARGET) $(RMHIST_TARGET) $(VP_TARGET) $(VDIFF_TARGET): $(VDIFF_SOURCE) @rm -f $(VDIFF_TARGET); \ if [ $(HOSTSYSTEM) = s_ultrix ] ; then \ echo '#!/bin/sh5' > $(VDIFF_TARGET) ; \ else \ echo '#!/bin/sh' > $(VDIFF_TARGET) ; \ fi cat $(VDIFF_SOURCE) >> $(VDIFF_TARGET) @chmod +x $(VDIFF_TARGET) $(CPHIST_TARGET): $(CPHIST_SOURCE) @rm -f $(CPHIST_TARGET); \ if [ $(HOSTSYSTEM) = s_ultrix ] ; then \ echo '#!/bin/sh5' > $(CPHIST_TARGET) ; \ else \ echo '#!/bin/sh' > $(CPHIST_TARGET) ; \ fi cat $(CPHIST_SOURCE) >> $(CPHIST_TARGET) @chmod +x $(CPHIST_TARGET) $(RMHIST_TARGET): $(RMHIST_SOURCE) @rm -f $(RMHIST_TARGET); \ if [ $(HOSTSYSTEM) = s_ultrix ] ; then \ echo '#!/bin/sh5' > $(RMHIST_TARGET) ; \ else \ echo '#!/bin/sh' > $(RMHIST_TARGET) ; \ fi cat $(RMHIST_SOURCE) >> $(RMHIST_TARGET) @chmod +x $(RMHIST_TARGET) $(VP_TARGET): $(VP_SOURCE) @rm -f $(VP_TARGET); \ if [ $(HOSTSYSTEM) = s_ultrix ] ; then \ echo '#!/bin/sh5' > $(VP_TARGET) ; \ else \ echo '#!/bin/sh' > $(VP_TARGET) ; \ fi cat $(VP_SOURCE) >> $(VP_TARGET) @chmod +x $(VP_TARGET) installtargets: $(INSTALLBINPATH)/$(VDIFF_TARGET) \ $(INSTALLBINPATH)/$(CPHIST_TARGET) \ $(INSTALLBINPATH)/$(RMHIST_TARGET) \ $(INSTALLBINPATH)/$(VP_TARGET) $(INSTALLBINPATH)/$(VDIFF_TARGET): $(VDIFF_TARGET) @-echo "installing $(VDIFF_TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(VDIFF_TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(VDIFF_TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(VDIFF_TARGET); \ fi; \ cp $(VDIFF_TARGET) $(INSTALLBINPATH)/$(VDIFF_TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(VDIFF_TARGET) $(INSTALLBINPATH)/$(CPHIST_TARGET): $(CPHIST_TARGET) @-echo "installing $(CPHIST_TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(CPHIST_TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(CPHIST_TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(CPHIST_TARGET); \ fi; \ cp $(CPHIST_TARGET) $(INSTALLBINPATH)/$(CPHIST_TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(CPHIST_TARGET) $(INSTALLBINPATH)/$(RMHIST_TARGET): $(RMHIST_TARGET) @-echo "installing $(RMHIST_TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(RMHIST_TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(RMHIST_TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(RMHIST_TARGET); \ fi; \ cp $(RMHIST_TARGET) $(INSTALLBINPATH)/$(RMHIST_TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(RMHIST_TARGET) $(INSTALLBINPATH)/$(VP_TARGET): $(VP_TARGET) @-echo "installing $(VP_TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(VP_TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(VP_TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(VP_TARGET); \ fi; \ cp $(VP_TARGET) $(INSTALLBINPATH)/$(VP_TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(VP_TARGET) installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(VDIFF_TARGET) $(CPHIST_TARGET) $(RMHIST_TARGET) $(VP_TARGET) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/vc/scripts/Dependencies100444 2013 145 22 5414051756 20300 0ustar dokoswt# no dependencies shapetools-1.4pl6.orig/src/vc/vadm/ 40755 2013 145 0 5626416366 15211 5ustar dokoswtshapetools-1.4pl6.orig/src/vc/vadm/vadm.c100444 2013 145 52664 5420251723 16416 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools Version Control System * * vadm.c - main program for "vadm" command * * by Axel.Mahler@cs.tu-berlin.de and Andreas.Lampen@cs.tu-berlin.de * * $Header: vadm.c[10.0] Mon Jul 12 14:17:39 1993 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "sttk.h" #include "atfstk.h" #include "vadm.h" #define MAX_ACTIONS 16 #define MAX_ALIASES 4 static int usage(); /*====================== * Globals *======================*/ LOCAL Af_user newAuthor = {"","",""}, newOwner = {"","",""}; LOCAL mode_t newMode = 0; LOCAL char *newCommentLeader = NULL, *commentType = NULL; EXPORT int lockType = -1, lockGen = 0, lockRev; EXPORT char *lockString; EXPORT time_t lockDate; LOCAL Af_set *lockArgSetPtr = NULL; LOCAL char *newAlias[MAX_ALIASES] = {"","","",""}; LOCAL char *delAlias[MAX_ALIASES] = {"","","",""}; LOCAL int newAliasCount = 0, delAliasCount = 0; LOCAL char *newAttrs[MAX_ACTIONS] = {"","","","","","","","","","","","","","","","",}; LOCAL int newAttrCount = 0; LOCAL char *delAttrs[MAX_ACTIONS] = {"","","","","","","","","","","","","","","",""}; LOCAL int delAttrCount = 0; LOCAL int cacheFlag = FALSE; EXPORT int forceFlag = FALSE; EXPORT int nomailFlag = FALSE; EXPORT int stdinFlag = FALSE; /*===================== * Action List *=====================*/ LOCAL int actionList[MAX_ACTIONS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; LOCAL int actionCount = 0; LOCAL int addToActionList (action, code) char *action; int code; { if (actionCount == MAX_ACTIONS) { sprintf (stMessage, "Too many actions (maximum number is %d) -- '%s' ignored.", MAX_ACTIONS, action); stLog (stMessage, ST_LOG_WARNING); return (0); } actionList[actionCount++] = code; return (0); } LOCAL int actionsPlausible () { if (actionCount == 0) { stLog ("Action(s) missing.", ST_LOG_MSGERR); usage (); /* exit */ } if (cacheFlag) { int i=0; while (i < actionCount) { switch (actionList[i++]) { case VADM_SBMT: case VADM_PUBL: case VADM_ACCS: case VADM_FRZE: case VADM_PROMOTE: case VADM_UNPROMOTE: stLog ("Cannot change status of cached objects.", ST_LOG_ERROR); return (FALSE); case VADM_NEWGEN: stLog ("Cannot open new generation for cached objects.", ST_LOG_ERROR); return (FALSE); case VADM_LOCK: case VADM_UNLOCK: stLog ("Cannot lock/unlock cached objects.", ST_LOG_ERROR); return (FALSE); case VADM_SET: stLog ("Cannot attach comment to cached objects.", ST_LOG_ERROR); return (FALSE); case VADM_CHOWN: case VADM_CHAUT: stLog ("Cannot change owner or author of cached objects.", ST_LOG_ERROR); return (FALSE); } } } return (TRUE); } /*======================== * Option handlers *========================*/ LOCAL int handleAlias (action, arg) char *action, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No alias name specified -- '%s' ignored.\n", action); stLog (stMessage, ST_LOG_WARNING); return (0); } if (action[0] == 'u') { /* unalias */ if (delAliasCount == MAX_ALIASES) { sprintf (stMessage, "Too many aliases (maximum number is %d) -- '%s %s' ignored.", MAX_ALIASES, action, arg); stLog (stMessage, ST_LOG_WARNING); return (0); } delAlias[delAliasCount++] = arg; return (addToActionList (action, VADM_UNALIAS)); } else { if (newAliasCount == MAX_ALIASES) { sprintf (stMessage, "Too many aliases (maximum number is %d) -- '%s %s' ignored.", MAX_ALIASES, action, arg); stLog (stMessage, ST_LOG_WARNING); return (0); } newAlias[newAliasCount++] = arg; return (addToActionList (action, VADM_ALIAS)); } } LOCAL int handleAttr (action, arg) char *action, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No attribute specified -- '%s' ignored.\n", action); stLog (stMessage, ST_LOG_WARNING); return (0); } newAttrs[newAttrCount++] = arg; return (addToActionList (action, VADM_ATTR)); } LOCAL int handleChaut (action, arg) char *action, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No new author specified -- '%s' ignored.\n", action); stLog (stMessage, ST_LOG_WARNING); return (0); } if (atUserValid (&newAuthor)) { sprintf (stMessage, "New author already set to '%s' -- additional '%s' ignored.", atUserName (&newAuthor), action); stLog (stMessage, ST_LOG_WARNING); return (0); } atScanUser (arg, &newAuthor); if (!atUserValid (&newAuthor)) { sprintf (stMessage, "%s is not a valid user on this machine -- '%s' ignored.", arg, action); stLog (stMessage, ST_LOG_WARNING); return (0); } return (addToActionList (action, VADM_CHAUT)); } LOCAL int handleChmod (action, arg) char *action, *arg; { mode_t mode = 0; char ciph, err = 0, *cp = arg; if (strlen (arg) > 4) err++; else while ((ciph = *cp++)) { ciph -= '0'; if ((ciph > 7) || (ciph < 0)) err++; else { mode <<= 3; mode += ciph; } } if (err) { sprintf (stMessage, "invalid mode '%s' -- '%s' ignored.", arg, action); stLog (stMessage, ST_LOG_WARNING); return (0); } newMode = mode; return (addToActionList (action, VADM_CHMOD)); } LOCAL int handleChown (action, arg) char *action, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No new owner specified -- '%s' ignored.\n", action); stLog (stMessage, ST_LOG_WARNING); return (0); } if (atUserValid (&newOwner)) { sprintf (stMessage, "New owner already set to '%s' -- additional '%s' ignored.", atUserName (&newOwner), action); stLog (stMessage, ST_LOG_WARNING); return (0); } atScanUser (arg, &newOwner); if (!atUserValid (&newOwner)) { sprintf (stMessage, "%s is not a valid user on this machine -- '%s' ignored.", arg, action); stLog (stMessage, ST_LOG_WARNING); return (0); } return (addToActionList (action, VADM_CHOWN)); } LOCAL int handleDelete (action, arg) char *action, *arg; { return (addToActionList (action, VADM_DELETE)); } LOCAL int handleDelAttr (action, arg) char *action, *arg; { char *attrNamePtr; if (!arg || !(*arg)) { sprintf (stMessage, "No attribute name specified -- '%s' ignored.\n", action); stLog (stMessage, ST_LOG_WARNING); return (0); } attrNamePtr = atAttrName (arg); if ((delAttrs[delAttrCount] = malloc (strlen (attrNamePtr)+1)) == NULL) { stLog ("Not enough memory", ST_LOG_ERROR); return (1); } strcpy (delAttrs[delAttrCount++], attrNamePtr); return (addToActionList (action, VADM_DELATTR)); } LOCAL int handleLock (action, arg) char *action, *arg; { if (lockType != -1) { sprintf (stMessage, "Cannot handle multiple lock/unlock actions -- '%s' ignored.", action); stLog (stMessage, ST_LOG_WARNING); return (0); } lockType = AT_BIND_DEFAULT; if (arg && *arg) { /* check if argument may be a filename -- if so, ignore it */ if ((lockArgSetPtr = atBindSet (arg, NULL, atBindModeOption ? atBindModeOption : AT_BIND_LAST)) && (af_nrofkeys (lockArgSetPtr) > 0)) { lockString = arg; /* special case: save -lock argument for use in main loop */ } else { lockArgSetPtr = NULL; lockType = atScanBinding (arg, &lockString, &lockGen, &lockRev, &lockDate); /* assume generation number, when lockString contains only digits */ if (lockType == AT_BIND_ALIAS) { if (!strcmp (lockString, "last")) { lockGen = AF_LASTVERS; lockType = AT_BIND_VNUM; lockString = NULL; } else { int i=0, isGen = TRUE; while (lockString[i]) if (!isdigit(lockString[i++])) isGen = FALSE; if (isGen) { lockGen = atoi (lockString); lockType = AT_BIND_VNUM; lockString = NULL; } } } } } if (action[0] == 'l') return (addToActionList (action, VADM_LOCK)); else return (addToActionList (action, VADM_UNLOCK)); } LOCAL int handleNewgen (action, arg) char *action, *arg; { int i=0; while (i < actionCount) { if (actionList[i++] == VADM_NEWGEN) { sprintf (stMessage, "You already requested the new generation -- '%s' ignored.", action); stLog (stMessage, ST_LOG_WARNING); return (0); } } return (addToActionList (action, VADM_NEWGEN)); } LOCAL int handlePromote (action, arg) char *action, *arg; { int i=0; while (i < actionCount) { if (actionList[i++] == VADM_UNPROMOTE) { sprintf (stMessage, "You already requested the unpromote action -- '%s' ignored.", action); stLog (stMessage, ST_LOG_WARNING); return (0); } } return (addToActionList (action, VADM_PROMOTE)); } LOCAL int handleSet (action, arg) char *action, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "'%s' what ? No comment type specified -- '%s' ignored.\n", action, action); stLog (stMessage, ST_LOG_WARNING); return (0); } if (commentType) { sprintf (stMessage, "Comment type already set to %s -- additional '%s' ignored.", commentType, action); stLog (stMessage, ST_LOG_WARNING); return (0); } commentType = arg; return (addToActionList (action, VADM_SET)); } LOCAL int handleSetc (action, arg) char *action, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No comment leader specified -- '%s' ignored.\n", action); stLog (stMessage, ST_LOG_WARNING); return (0); } if (newCommentLeader) { sprintf (stMessage, "Comment leader already set to '%s' -- additional '%s' ignored.", newCommentLeader, action); stLog (stMessage, ST_LOG_WARNING); return (0); } if (strlen (arg) > (AT_CLEADMAXLEN-(strlen(AT_ATTCLEAD)+2))) { sprintf (stMessage, "Specified comment leader is too long -- '%s' ignored.", action); stLog (stMessage, ST_LOG_WARNING); return (0); } newCommentLeader = arg; return (addToActionList (action, VADM_SETCLEAD)); } LOCAL int handleUnpromote (action, arg) char *action, *arg; { int i=0; while (i < actionCount) { if (actionList[i++] == VADM_PROMOTE) { sprintf (stMessage, "You already requested the promote action -- '%s' ignored.", action); stLog (stMessage, ST_LOG_WARNING); return (0); } } return (addToActionList (action, VADM_UNPROMOTE)); } /*====================== * Option Vector *======================*/ LOCAL int printVersion () { char *vadmversion(); sprintf (stMessage, "This is %s", vadmversion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " using %s,", atVersion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " %s,", af_version()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " and %s.", stVersion()); stLog (stMessage, ST_LOG_MSG); stExit (0); return (0); } LOCAL StOptDesc optDesc[] = { { "?", PCALL, usage, NULL, NULL }, { "alias", PCALL|PARG, handleAlias, NULL, NULL }, { "attr", PCALL|PARG, handleAttr, NULL, NULL }, { "cache", PSWITCH|PSET, NULL, &cacheFlag, NULL }, { "chaut", PCALL|PARG, handleChaut, NULL, NULL }, { "chmod", PCALL|PARG, handleChmod, NULL, NULL }, { "chown", PCALL|PARG, handleChown, NULL, NULL }, { "d", PCALL, handleDelete, NULL, NULL }, { "delattr", PCALL|PARG, handleDelAttr, NULL, NULL }, { "delete", PCALL, handleDelete, NULL, NULL }, { "f", PSWITCH|PSET, NULL, &forceFlag, NULL }, { "force", PSWITCH|PSET, NULL, &forceFlag, NULL }, { "help", PCALL, usage, NULL, NULL }, { "l", PCALL|POARG, handleLock, NULL, NULL }, { "lock", PCALL|POARG, handleLock, NULL, NULL }, { "nomail", PSWITCH|PSET, NULL, &nomailFlag, NULL }, { "newgen", PCALL, handleNewgen, NULL, NULL }, { "promote", PCALL, handlePromote, NULL, NULL }, { "q", PSWITCH|PSET, NULL, &stQuietFlag, NULL }, { "quiet", PSWITCH|PSET, NULL, &stQuietFlag, NULL }, { "set", PCALL|PARG, handleSet, NULL, NULL }, { "setc", PCALL|PARG, handleSetc, NULL, NULL }, { "stdin", PSWITCH|PSET, NULL, &stdinFlag, NULL }, { "symbolic", PCALL|PARG|PHIDDEN, handleAlias,NULL, NULL }, { "unalias", PCALL|PARG, handleAlias, NULL, NULL }, { "unlock", PCALL|POARG, handleLock, NULL, NULL }, { "unpromote",PCALL, handleUnpromote,NULL, NULL }, { "version", PCALL, printVersion, NULL, NULL }, { NULL, 0, NULL, NULL, NULL } }; LOCAL int usage() { stLog ("Usage:", ST_LOG_MSGERR); stShortUsage (stProgramName, optDesc, "names..."); atBindUsage (""); stExit (1); return (1); } /*=================== * perform actions *===================*/ LOCAL int doAction (path, aso) char *path; Af_key *aso; { int i=0, retCode = 0; int curNewAlias = 0, curDelAlias = 0, curNewAttr = 0, curDelAttr = 0; char asoName[PATH_MAX], commentSymAttr[AT_CLEADMAXLEN]; /* build name for output */ if (path && *path) { strcpy (asoName, path); strcat (asoName, "/"); } else asoName[0] = '\0'; if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) strcat (asoName, af_retattr (aso, AF_ATTUNIXNAME)); else strcat (asoName, af_retattr (aso, AF_ATTBOUND)); while (i < actionCount) { switch (actionList[i]) { case VADM_SBMT: retCode += doStatus (asoName, aso, AF_PROPOSED); break; case VADM_PUBL: retCode += doStatus (asoName, aso, AF_PUBLISHED); break; case VADM_ACCS: retCode += doStatus (asoName, aso, AF_ACCESSED); break; case VADM_FRZE: retCode += doStatus (asoName, aso, AF_FROZEN); break; case VADM_DELETE: retCode += doDelete (asoName, aso); break; case VADM_LOCK: retCode += doLock (path, asoName, aso, VADM_LOCK); break; case VADM_UNLOCK: retCode += doLock (path, asoName, aso, VADM_UNLOCK); break; case VADM_NEWGEN: { Af_key newKey; af_commit (); if (af_newgen (aso, &newKey) == -1) { sprintf (stMessage, "Cannot open new generation for %s -- %s.", asoName, af_errmsg ("af_newgen")); stLog (stMessage, ST_LOG_ERROR); retCode++; } af_setattr (&newKey, AF_REMOVE, AT_ATTALIAS); af_setattr (&newKey, AF_REMOVE, AT_ATTINTENT); af_transaction (); break; } case VADM_PROMOTE: retCode += doStatus (asoName, aso, VADM_STATUS_PROMOTE); break; case VADM_UNPROMOTE: retCode += doStatus (asoName, aso, VADM_STATUS_UNPROMOTE); break; case VADM_SET: retCode += doComment (path, asoName, aso, commentType); break; case VADM_SETCLEAD: sprintf (commentSymAttr, "%s=%s", AT_ATTCLEAD, newCommentLeader); if (!atSetAttr (aso, commentSymAttr, AF_REPLACE)) { sprintf (stMessage, "Cannot set comment leader attribute '%s' for %s -- %s.", commentSymAttr, asoName, atErrMsg); stLog (stMessage, ST_LOG_ERROR); retCode++; } break; case VADM_ATTR: /* check if attrs shall be read from file */ if (newAttrs[curNewAttr][0] == '@') { if (!atSetAttrFile (aso, &(newAttrs[curNewAttr][1]))) { sprintf (stMessage, "Cannot set attribute file '%s' for %s -- %s.", newAttrs[curNewAttr], asoName, atErrMsg); stLog (stMessage, ST_LOG_ERROR); retCode++; } } else if (strchr (newAttrs[curNewAttr], AF_UDANAMDEL) == NULL) { /* if just an attribute name is given */ stLog (atRetAttr (aso, newAttrs[curNewAttr]), ST_LOG_MSG); } else if (!atSetAttr (aso, newAttrs[curNewAttr], AF_REPLACE)) { sprintf (stMessage, "Attribute change '%s' for %s failed -- %s.", newAttrs[curNewAttr], asoName, atErrMsg); stLog (stMessage, ST_LOG_ERROR); retCode++; } curNewAttr++; break; case VADM_DELATTR: if (!atSetAttr (aso, delAttrs[curDelAttr], AF_REMOVE)) { sprintf (stMessage, "Cannot delete attribute '%s' from %s -- %s.", delAttrs[curDelAttr], asoName, atErrMsg); stLog (stMessage, ST_LOG_ERROR); retCode++; } curDelAttr++; break; case VADM_ALIAS: if (!atSetVersAlias (aso, newAlias[curNewAlias])) { sprintf (stMessage, "Cannot set version alias '%s' for %s -- %s.", newAlias[curNewAlias], asoName, atErrMsg); stLog (stMessage, ST_LOG_ERROR); retCode++; } curNewAlias++; break; case VADM_UNALIAS: if (!atDelVersAlias (aso, delAlias[curDelAlias])) { sprintf (stMessage, "Cannot delete version alias '%s' for %s -- %s.", delAlias[curDelAlias], asoName, atErrMsg); stLog (stMessage, ST_LOG_ERROR); retCode++; } curDelAlias++; break; case VADM_CHMOD: if (af_chmod (aso, newMode) < 0) { sprintf (stMessage, "Cannot change mode of %s -- %s.", asoName, af_errmsg ("af_chmod")); stLog (stMessage, ST_LOG_ERROR); retCode++; break; } break; case VADM_CHOWN: if (af_chowner (aso, &newOwner) < 0) { stLog ("Sorry, the 'change owner' action is not available on your system.", ST_LOG_ERROR); retCode++; break; } break; case VADM_CHAUT: if (af_chauthor (aso, &newAuthor) < 0) { sprintf (stMessage, "Cannot change author of %s -- %s.", asoName, af_errmsg ("af_chmod")); stLog (stMessage, ST_LOG_ERROR); retCode++; break; } break; } i++; } return (retCode); } /*====================== * main and friends *======================*/ LOCAL Sigret_t interrupt_action () /* is executed by appropriate signal handler */ { af_abort (); stExit (1); } EXPORT int main (argc, argv) int argc; char **argv; { int tmpArgc, newArgc, i, j, k, nameCount, retCode=0; char *cp, **tmpArgv, **newArgv, path[PATH_MAX]; Af_key curKey; Af_set *setPtr; stProgramName = (cp = strrchr (argv[0], '/')) ? ++cp : argv[0]; stInterruptAction = interrupt_action; stCatchSigs(); if (atBindOptions (argc, argv, &tmpArgc, &tmpArgv)) stExit (1); if (stParseArgs (tmpArgc, tmpArgv, &newArgc, &newArgv, optDesc)) stExit (1); if (strcmp (stProgramName, "vadm")) { if (actionCount) { sprintf (stMessage, "You may not specify any action parameter with '%s'.", stProgramName); stLog (stMessage, ST_LOG_WARNING); stLog ("\t\tAll action parameters ignored.", ST_LOG_ERROR); actionList[0] = 0; actionCount = 0; } if (!(strcmp (stProgramName, "vrm"))) addToActionList ("delete", VADM_DELETE); else if (!(strcmp (stProgramName, "vattr"))) { /* fetch off attribute from command line */ newAttrs[0] = newArgv[1]; newAttrCount = 1; for (i=2; i<=newArgc; i++) newArgv[i-1] = newArgv[i]; if (newArgc >= 2) newArgc--; addToActionList ("attr", VADM_ATTR); } else if (!(strcmp (stProgramName, "sbmt"))) addToActionList ("submit", VADM_SBMT); else if (!(strcmp (stProgramName, "publ"))) addToActionList ("publish", VADM_PUBL); else if (!(strcmp (stProgramName, "accs"))) addToActionList ("access", VADM_ACCS); else if (!(strcmp (stProgramName, "frze"))) addToActionList ("freeze", VADM_FRZE); } if (!actionsPlausible ()) { stExit (1); } if (((nameCount = newArgc-1) == 0) && !lockArgSetPtr) { stLog ("Filename(s) missing.", ST_LOG_MSGERR); stExit (1); } k=0; stThisTransaction.tr_rc = 0; for (i = 0; i < newArgc; i++) { /* Normally, this loop should start with i=1 (first argument). * The first loop body execution (i==0) handles just the case that * "lockArgSetPtr" points to an ASO set. This happens, when the * evaluation of the argument of the -lock option resulted in a * hit set rather than a generation binding. "vadm" then assumes * "-lock" to be meant without argument, but stParseArgs did not * recognize this. * Example: "vadm -lock version.c" */ if ((i == 0) && !lockArgSetPtr) continue; if (lockArgSetPtr) { setPtr = lockArgSetPtr; lockArgSetPtr = NULL; strcpy (path, af_afpath (lockString)); lockString = NULL; } else { /* do version binding */ if (cacheFlag) setPtr = atBindCache (newArgv[i], NULL); else setPtr = atBindSet (newArgv[i], NULL, atBindModeOption ? atBindModeOption :AT_BIND_LAST); if (setPtr == NULL) { stLog (atBindErrorMsg, ST_LOG_ERROR); stExit (1); } if (af_nrofkeys (setPtr) == 0) { sprintf (stMessage, "%s: nothing found -- skipped.", newArgv[i]); stLog (stMessage, ST_LOG_MSGERR); retCode++; continue; } strcpy (path, af_afpath (newArgv[i])); } for (j = 0; j < af_nrofkeys (setPtr); j++) { af_setgkey (setPtr, j, &curKey); if (!setjmp (stThisTransaction.tr_env)) { stThisTransaction.tr_seqno = k++; strcpy (stThisTransaction.tr_fname, af_retattr (&curKey, AF_ATTBOUND)); stThisTransaction.tr_done = FALSE; af_transaction (); retCode += doAction (path, &curKey); if (af_commit () < 0) { sprintf (stMessage, "Cannot save changes for %s%s%s -- %s.", path, path[0] ? "/" : "", af_retattr (&curKey, AF_ATTUNIXNAME), af_errmsg ("af_commit")); stLog (stMessage, ST_LOG_ERROR); retCode++; } } else { /* stThisTransaction was aborted */ retCode += stThisTransaction.tr_rc; af_abort (); } } } if (nameCount > 1) stLog ("done.", ST_LOG_MSG); return (retCode); } shapetools-1.4pl6.orig/src/vc/vadm/dovadm.c100444 2013 145 35565 5617465304 16754 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools Version Control System * * dovadm.c - several routines for "vadm" command * * by Andreas.Lampen@cs.tu-berlin.de * * $Header: dovadm.c[7.1] Thu Aug 4 16:18:16 1994 andy@cs.tu-berlin.de frozen $ */ #include "atfs.h" #include "sttk.h" #include "atfstk.h" #include "vadm.h" extern int forceFlag; extern int nomailFlag; extern int stdinFlag; extern int lockType, lockGen, lockRev; extern char *lockString; extern time_t lockDate; /*======================= * doDelete *=======================*/ EXPORT int doDelete (asoName, aso) char *asoName; Af_key *aso; { Af_user *locker; int asoStatus = af_retnumattr (aso, AF_ATTSTATE); if (VATTR(aso).af_state != AF_DERIVED) { if (asoStatus > AF_SAVED) { sprintf (stMessage, "Cannot delete %s -- version status must be 'saved'.", asoName); stLog (stMessage, ST_LOG_ERROR); return (1); } if (atUserValid (locker = af_testlock (aso))) { if (atUserUid (locker) != geteuid ()) { /* locked by somebody else */ sprintf (stMessage, "No permission to delete %s (locked by %s).", asoName, atUserName (locker)); stLog (stMessage, ST_LOG_ERROR); return (1); } } else { /* the version is not locked. We must lock it to delete it. */ if (af_lock (aso, af_afuser (geteuid ())) == NULL) { sprintf (stMessage, "Cannot lock %s for deletion -- not deleted.", asoName); stLog (stMessage, ST_LOG_ERROR); return (1); } } } if (!forceFlag && !stQuietFlag) { sprintf (stMessage, "Delete %s ?", asoName); if (!stAskConfirm (stMessage, "yes")) { sprintf (stMessage, "%s not deleted.", asoName); stLog (stMessage, ST_LOG_MSG); return (0); } } if (af_rm (aso) < 0) { sprintf (stMessage, "Cannot delete %s -- %s.", asoName, af_errmsg ("af_rm")); stLog (stMessage, ST_LOG_ERROR); return (1); } sprintf (stMessage, "%s deleted.", asoName); stLog (stMessage, ST_LOG_MSG); return (0); } /*======================= * doLock *=======================*/ static Af_key lastLockAso = {NULL, 0}; EXPORT int doLock (path, asoName, aso, mode) char *path; char *asoName; Af_key *aso; int mode; { char busyName[PATH_MAX], lockName[PATH_MAX], hostname[HOST_MAX+1]; char *opName; Af_key lockAso, *tmpKey; Af_user *locker, *caller = af_afuser (geteuid()); struct stat ibuf; FILE *pip; /* get proper version to be locked */ switch (lockType) { case AT_BIND_DATE: lockString = asctime (localtime (&lockDate)); /* no break -- continue with next case */ case AT_BIND_ALIAS: if ((tmpKey = atBindVersion (asoName, lockString))) { lockGen = af_retnumattr (tmpKey, AF_ATTGEN); af_dropkey (tmpKey); } else { sprintf (stMessage, "Symbolic name %s not known for %s -- skipped.", lockString, asoName); stLog (stMessage, ST_LOG_ERROR); return (1); } break; case AT_BIND_VNUM: /* do nothing */ break; case AT_BIND_DEFAULT: if ((lockGen = af_retnumattr (aso, AF_ATTGEN)) == AF_BUSYVERS) lockGen = AF_LASTVERS; break; } strcpy (busyName, af_retattr (aso, AF_ATTUNIXNAME)); if (af_getkey (path, af_afname (busyName), af_aftype (busyName), lockGen, AF_LASTVERS, &lockAso) < 0) { if (mode == VADM_UNLOCK) opName = "unlock"; else opName = "lock"; if (lockGen == AF_LASTVERS) sprintf (stMessage, "%s not %sed -- no versions found.", asoName, opName); else sprintf (stMessage, "Cannot %s %s -- generation %d does not exist.", opName, asoName, lockGen); stLog (stMessage, ST_LOG_ERROR); return (1); } /* sort out multiple versions from the same history/generation */ if ((lastLockAso.af_ldes == lockAso.af_ldes) && (lastLockAso.af_lpos == lockAso.af_lpos)) return (0); af_dropkey (&lastLockAso); lastLockAso = lockAso; /* build lockName for output */ if (path && *path) { strcpy (lockName, path); strcat (lockName, "/"); strcat (lockName, af_retattr (&lockAso, AF_ATTBOUND)); } else strcpy (lockName, af_retattr (&lockAso, AF_ATTBOUND)); /* if not locked */ if (!atUserValid (locker = af_testlock(&lockAso))) { if (mode == VADM_UNLOCK) { sprintf (stMessage, "%s was already unlocked.", lockName); stLog (stMessage, ST_LOG_MSG); return (0); } if (!stQuietFlag) atSetComment (&lockAso, AT_COMMENT_INTENT, NULL, AT_REUSE | AT_CONFIRM | (stdinFlag ? AT_FROMSTDIN : 0)); if (stat (busyName, &ibuf) == 0) { stLog ("WARNING!", ST_LOG_MSG); stLog ("*** Locking of read-only copies is not recommended.", ST_LOG_MSG); stLog ("*** You may eclipse modifications made by other users.", ST_LOG_MSG); stLog ("*** Attribute references in the source text may also be lost.", ST_LOG_MSG); stLog ("*** The recommended procedure is to use \"retrv -lock ", ST_LOG_MSG | ST_LOG_NONL); stLog (busyName, ST_LOG_MSG | ST_LOG_NONL); stLog ("\".", ST_LOG_MSG); if (!forceFlag && stAskConfirm ("Continue locking ?", "no")) { return (0); } } if (!(af_lock (&lockAso, caller))) { sprintf (stMessage, "Cannot lock %s -- %s.", asoName, af_errmsg ("af_lock")); stLog (stMessage, ST_LOG_ERROR); return (1); } if (stat (busyName, &ibuf) == 0) { chmod (busyName, (int)(ibuf.st_mode | 0200)); /* * Attach attributes of lockAso to soon-to-be busy version */ if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) { Af_attrs attrbuf; char *reserveDate, *attrPtr; register int j; if (af_allattrs (&lockAso, &attrbuf) < 0) { af_perror ("af_allattrs"); return (1); } j = 0; while ((attrPtr = attrbuf.af_udattrs[j++])) { if (af_setattr (aso, AF_REPLACE, attrPtr) == -1) af_setattr (aso, AF_ADD, attrPtr); } af_freeattrbuf (&attrbuf); af_setattr (aso, AF_REMOVE, AT_ATTALIAS); af_setattr (aso, AF_REMOVE, AT_ATTINTENT); if ((reserveDate = malloc ((unsigned) (strlen ("rtime") + 32)))) { sprintf (reserveDate, "%s=%s", "rtime", af_retattr (aso, AF_ATTCTIME)); if ((af_setattr (aso, AF_REPLACE, reserveDate) == -1) && (af_setattr (aso, AF_ADD, reserveDate) == -1)) { sprintf (stMessage, "Can't set reservation date for %s.", busyName); stLog (stMessage, ST_LOG_WARNING); } free (reserveDate); } else { sprintf (stMessage, "Can't set reservation date for %s (no memory).", busyName); stLog (stMessage, ST_LOG_WARNING); } } } sprintf (stMessage, "%s locked.", lockName); stLog (stMessage, ST_LOG_MSG); return (0); } /* else there is a locker and it's me */ if (atUserUid (locker) == geteuid()) { if (mode == VADM_UNLOCK) { /* clear write bits */ if (stat (busyName, &ibuf) == 0) { chmod (busyName, (int)(ibuf.st_mode & ~0222)); } af_unlock (&lockAso); sprintf (stMessage, "%s unlocked.", lockName); stLog (stMessage, ST_LOG_MSG); return (0); } /* else VADM_LOCK */ sprintf (stMessage, "%s was already locked by us.", lockName); stLog (stMessage, ST_LOG_MSG); return (0); } /* else it is locked by someone else */ if (mode == VADM_LOCK) { sprintf (stMessage, "%s is already locked by %s.", lockName, atUserName (locker)); stLog (stMessage, ST_LOG_MSG); return (1); } if (atUserUid (af_retuserattr (aso, AF_ATTOWNER)) == geteuid()) { /* we've got the power ... */ sprintf (stMessage, "%s currently locked by %s. Break the lock ?", lockName, atUserName (locker)); if (stAskConfirm (stMessage, "yes")) { if (af_unlock (&lockAso) == NULL) { stLog (af_errmsg ("af_unlock"), ST_LOG_ERROR); return (1); } if (!nomailFlag) { sprintf (stMessage, "/bin/mail %s", atUserName(locker)); if ((pip = popen (stMessage, "w")) == NULL) { stLog ("Couldn't notify lockholder...", ST_LOG_WARNING); } else { gethostname (hostname, HOST_MAX); fprintf (pip, "Subject: Your lock on %s was broken by %s\n", af_retattr (&lockAso, AF_ATTBOUNDPATH), atUserName (caller)); fprintf (pip, "This message was issued automatically by "); fprintf (pip, "the ShapeTools version control system.\n"); fprintf (pip, "Your lock on %s was broken by %s.\n", af_retattr (&lockAso, AF_ATTBOUNDPATH), atUserName (caller)); pclose (pip); } } sprintf (stMessage, "%s unlocked.", lockName); stLog (stMessage, ST_LOG_MSG); return (0); } else { /* we don't wanna break the lock */ sprintf (stMessage, "%s remains locked by %s.", lockName, atUserName (locker)); stLog (stMessage, ST_LOG_MSG); return (0); } } else { /* we cannot unlock the required version */ sprintf (stMessage, "%s is locked by %s.", lockName, atUserName (locker)); stLog (stMessage, ST_LOG_MSGERR); return (1); } } /*======================= * doStatus *=======================*/ EXPORT int doStatus (asoName, aso, status) char *asoName; Af_key *aso; int status; { int oldStatus = af_retnumattr (aso, AF_ATTSTATE), newStatus; Af_user *locker; char *actionName; if (oldStatus == AF_BUSY) { sprintf (stMessage, "Cannot change status of %s -- is a busy version.", asoName); stLog (stMessage, ST_LOG_ERROR); return (1); } if ((atUserUid (locker = af_retuserattr (aso, AF_ATTLOCKER)) != geteuid ()) && atUserValid (locker)) { sprintf (stMessage, "Cannot change status of %s -- locked by %s.", asoName, atUserName (locker)); stLog (stMessage, ST_LOG_ERROR); return (1); } if (status == VADM_STATUS_PROMOTE) { if (oldStatus == AF_FROZEN) { sprintf (stMessage, "Status of %s is 'frozen' -- cannot promote.", asoName); stLog (stMessage, ST_LOG_ERROR); return (1); } newStatus = oldStatus+1; actionName = "promoted"; } else if (status == VADM_STATUS_UNPROMOTE) { if (oldStatus == AF_SAVED) { sprintf (stMessage, "Status of %s is 'saved' -- cannot unpromote.", asoName); stLog (stMessage, ST_LOG_ERROR); return (1); } newStatus = oldStatus-1; actionName = "unpromoted"; } else { if ((status - oldStatus) < 0) { sprintf (stMessage, "Status of %s already '%s' (better than desired status) -- not changed.", asoName, atWriteStatus (aso, TRUE)); stLog (stMessage, ST_LOG_MSGERR); return (1); } newStatus = status; actionName = "set"; } /* lock aso if this is not yet done */ if (!atUserValid (locker)) { if (af_lock (aso, af_afuser (geteuid())) == NULL) { sprintf (stMessage, "Cannot change status of %s -- cannot lock.", asoName); stLog (stMessage, ST_LOG_ERROR); return (1); } } if (af_sstate (aso, newStatus) < 0) { stLog (af_errmsg ("af_sstate"), ST_LOG_ERROR); return 1; } /* unlock ASO again if the lock was set only for the status change */ if (!atUserValid (locker)) af_unlock (aso); sprintf (stMessage, "Status of %s %s to '%s'.", asoName, actionName, atWriteStatus (aso, TRUE)); stLog (stMessage, ST_LOG_MSG); return (0); } /*======================= * doComment *=======================*/ EXPORT int doComment (path, asoName, aso, commentType) char *path; char *asoName; Af_key *aso; char *commentType; { Af_key tmpAso; Af_user *locker; char outName[PATH_MAX], busyName[PATH_MAX]; strcpy (busyName, af_retattr (aso, AF_ATTUNIXNAME)); /************ description **************/ if (!strncmp (commentType, "description", strlen (commentType))) { /* description must be set to first version of all */ if (af_getkey (path, af_afname (busyName), af_aftype (busyName), AF_FIRSTVERS, AF_FIRSTVERS, &tmpAso) < 0) { sprintf (stMessage, "Cannot find first version of %s -- skipped.", asoName); stLog (stMessage, ST_LOG_ERROR); return (1); } /* build name for output */ if (path && *path) { strcpy (outName, path); strcat (outName, "/"); strcat (outName, af_retattr (&tmpAso, AF_ATTBOUND)); } else strcpy (outName, af_retattr (&tmpAso, AF_ATTBOUND)); if (!atSetComment (&tmpAso, AT_COMMENT_DESCR, NULL, AT_REUSE | (stdinFlag ? AT_FROMSTDIN : 0))) { sprintf (stMessage, "Cannot set description for %s -- %s.", outName, atErrMsg); stLog (stMessage, ST_LOG_ERROR); af_dropkey (&tmpAso); return (1); } af_dropkey (&tmpAso); } /************ intent **************/ else if (!strncmp (commentType, "intent", strlen (commentType))) { /* intent is set to last version of generation */ if (af_getkey (path, af_afname (busyName), af_aftype (busyName), af_retnumattr (aso, AF_ATTGEN), AF_LASTVERS, &tmpAso) < 0) { sprintf (stMessage, "Cannot find most recent version of %s -- skipped.", asoName); stLog (stMessage, ST_LOG_ERROR); return (1); } /* build name for output */ if (path && *path) { strcpy (outName, path); strcat (outName, "/"); strcat (outName, af_retattr (&tmpAso, AF_ATTBOUND)); } else strcpy (outName, af_retattr (&tmpAso, AF_ATTBOUND)); if (atUserValid (locker = af_testlock(&tmpAso))) { if (atUserUid (locker) == geteuid ()) { if (!atSetComment (&tmpAso, AT_COMMENT_INTENT, NULL, AT_REUSE | (stdinFlag ? AT_FROMSTDIN : 0))) { sprintf (stMessage, "Cannot set intent for %s -- %s.", outName, atErrMsg); stLog (stMessage, ST_LOG_ERROR); af_dropkey (&tmpAso); return (1); } } else { sprintf (stMessage, "Cannot set intent on %s -- locked by %s.", outName, atUserName (locker)); stLog (stMessage, ST_LOG_ERROR); af_dropkey (&tmpAso); return (1); } } else { sprintf (stMessage, "You must have a lock on %s to set change intention.", outName); stLog (stMessage, ST_LOG_MSGERR); af_dropkey (&tmpAso); return (1); } af_dropkey (&tmpAso); } /************ note **************/ else if (!strncmp (commentType, "note", strlen (commentType))) { if (!atSetComment (aso, AT_COMMENT_LOG, NULL, AT_REUSE | (stdinFlag ? AT_FROMSTDIN : 0))) { sprintf (stMessage, "Cannot set note for %s -- %s.", asoName, atErrMsg); stLog (stMessage, ST_LOG_ERROR); return (1); } } /************ default **************/ else { sprintf (stMessage, "usage: %s -set {note|description|intent} ...", stProgramName); stLog (stMessage, ST_LOG_MSGERR); return (1); } return (0); } shapetools-1.4pl6.orig/src/vc/vadm/vadm.h100444 2013 145 3460 5417305730 16375 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * by Axel.Mahler@cs.tu-berlin.de * * $Header: vadm.h[10.0] Fri Jul 9 18:58:01 1993 andy@cs.tu-berlin.de frozen $ */ /*====================== * Constants *======================*/ /* action codes */ #define VADM_SBMT 01 #define VADM_PUBL 02 #define VADM_ACCS 03 #define VADM_FRZE 04 #define VADM_DELETE 11 #define VADM_LOCK 12 #define VADM_UNLOCK 13 #define VADM_PROMOTE 14 #define VADM_UNPROMOTE 15 #define VADM_NEWGEN 16 #define VADM_ATTR 21 #define VADM_DELATTR 22 #define VADM_ALIAS 23 #define VADM_UNALIAS 24 #define VADM_CHMOD 25 #define VADM_CHOWN 26 #define VADM_CHAUT 27 #define VADM_SET 28 #define VADM_SETCLEAD 29 /* state transitions */ #define VADM_STATUS_PROMOTE -10 #define VADM_STATUS_UNPROMOTE -11 /*===================================== * Functions Prototypes *=====================================*/ #ifdef __STDC__ #define A(alist) alist #else #define A(alist) () #endif /*** dovadm.c ***/ int doDelete A((char *asoName, Af_key *aso)); int doLock A((char *path, char *asoName, Af_key *aso, int mode)); int doStatus A((char *asoName, Af_key *aso, int status)); int doComment A((char *path, char *asoName, Af_key *aso, char *commentType)); shapetools-1.4pl6.orig/src/vc/vadm/vadmversion.c100444 2013 145 205 5620174274 17753 0ustar dokoswtchar *vadmversion () { static char release[] = "vadm-4.10 (Tue Aug 23 17:59:44 1994 by andy@cs.tu-berlin.de)"; return release; } shapetools-1.4pl6.orig/src/vc/vadm/Shapefile100444 2013 145 6411 5414052660 17115 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for vadm # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[10.0] Tue Jun 29 16:48:19 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) $(CC) -c $(CFLAGS) $(VERSIONFILE) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/vc/vadm/Makefile100444 2013 145 22657 5437120751 16766 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for vadm # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[10.0] Thu Aug 26 13:56:10 1993 axel@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/vc/vadm # A short name for this node system NODENAME = vadm # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = $(BASE) INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. TARGET = vadm # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = vadmversion.c # source VERSIONOBJECT = vadmversion.o # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = sbmt publ accs frze vrm vattr # The regular source and header files. SOURCES = vadm.c dovadm.c HEADERS = vadm.h # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = vadm.1 sbmt.1 publ.1 accs.1 frze.1 vrm.1 vattr.1 MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. OBJECTS = vadm.o dovadm.o $(VERSIONOBJECT) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = ATFSTKLIB = $(LOCALLIBPATH)/libAtFStk.a STTKLIB = $(LOCALLIBPATH)/libsttk.a ATFSLIB = $(LOCALLIBPATH)/libAtFS.a LOCALLIBS = $(ATFSTKLIB) $(STTKLIB) $(ATFSLIB) LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(TARGET) $(TARGET): $(LOCALLIBS) $(OBJECTS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET) to $$i; \ ln $(TARGET) $$i; \ done installtargets: $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$(TARGET): $(TARGET) @-echo "installing $(TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET); \ fi; \ cp $(TARGET) $(INSTALLBINPATH)/$(TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$$i; \ done installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/vc/vadm/Dependencies100444 2013 145 655 5365307345 17577 0ustar dokoswtdovadm.o: ./vadm.h dovadm.o: $(BASE)/include/afsys.h dovadm.o: $(BASE)/include/atfs.h dovadm.o: $(BASE)/include/atfstk.h dovadm.o: $(BASE)/include/config.h dovadm.o: $(BASE)/include/sttk.h dovadm.o: dovadm.c vadm.o: ./vadm.h vadm.o: $(BASE)/include/afsys.h vadm.o: $(BASE)/include/atfs.h vadm.o: $(BASE)/include/atfstk.h vadm.o: $(BASE)/include/config.h vadm.o: $(BASE)/include/sttk.h vadm.o: vadm.c vadmversion.o: vadmversion.c shapetools-1.4pl6.orig/src/vc/vfind/ 40755 2013 145 0 5626416411 15357 5ustar dokoswtshapetools-1.4pl6.orig/src/vc/vfind/vfind.c100444 2013 145 61506 5504346245 16756 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools Version Control System * * vfind.c - main program for "vfind" command * * Author: Andreas.Lampen@cs.tu-berlin.de * previous versions by Uli.Pralle@cs.tu-berlin.de * Credits for Steve Emmerson (steve@unidata.ucar.edu) who provided * the primary ``SinceName''. [15/Aug/90] uli@coma * * $Header: vfind.c[5.1] Fri Dec 17 18:44:18 1993 andy@cs.tu-berlin.de frozen $ */ #include #include "atfs.h" #include "atfstk.h" #include "sttk.h" #define BLKSIZE 512 /* used in size */ #define VF_FIRST 0 /* used in position */ #define VF_LAST 1 /* dito. */ #define MAXDIRS 100 /* # of directories per nesting depth */ typedef struct expr *Expr; struct expr { int (*eval)(); /* evaluator */ Expr left; /* left op */ Expr right; /* right op */ }; static int nac; /* ac after option parsing */ static char **nav; /* av after option parsing */ static char startDir[PATH_MAX]; /* dir at beginning of process */ static time_t now; /* time in secs */ static int idx; /* used as array index */ static dev_t thisDevice; /* device # of starting point */ static char dirPrefix[PATH_MAX];/* current path name prefix */ static struct expr *exprList; /* expression list */ static int trueHits; /* # of expression yielding true */ static int maxDepth = 0; /* max traverse depth if -cut given */ static int attrFlag = FALSE; static int cacheFlag = FALSE; static int cutFlag = FALSE; static int forceFlag = FALSE; static int hitsFlag = FALSE; static int pruneFlag = FALSE; static int stateFlag = FALSE; static int userFlag = FALSE; static int xFlag = FALSE; /* Options */ LOCAL int handleCut (arg, opt) char *arg, *opt; { cutFlag++; if ((*opt) && !(maxDepth = atoi(opt)) && (*opt != '0')) { fprintf(stderr, "%s: -cut: integer expected\n", stProgramName); return 1; } return 0; } LOCAL int printVersion () { char *vfversion(); sprintf (stMessage, "This is %s", vfversion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " using %s,", atVersion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " %s,", af_version()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " and %s.", stVersion()); stLog (stMessage, ST_LOG_MSG); stExit (0); return (0); } static int usage(); static StOptDesc optDesc[] = { { "?", PCALL, usage, NULL, NULL }, { "cache", PSWITCH|PSET, NULL, &cacheFlag, NULL }, { "cut", POARG|PCALL, handleCut, NULL, NULL }, { "help", PCALL, usage, NULL, NULL }, { "force", PSWITCH|PSET, NULL, &forceFlag, NULL }, { "hits", PSWITCH|PSET, NULL, &hitsFlag, NULL }, { "version", PCALL, printVersion, NULL, NULL }, { "xdev", PSWITCH|PSET, NULL, &xFlag, NULL }, { NULL, 0, NULL, NULL, NULL }, }; static char helpmsg[] = "path-list expression\n\ \tprimary expressions are: atime, ctime, mtime, stime, ltime, exec,\n\ \texit, vl, name, perm, print, prune, symbolic, state, type, last, first,\n\ \tuda, user, locked, locker, eq, lt, le, gt, ge, newer, SinceName, size."; LOCAL int usage() { stLog ("Usage:", ST_LOG_MSGERR); stShortUsage (stProgramName, optDesc, helpmsg); stExit (2); return (2); } /*================= * primaries *=================*/ LOCAL int vfNoop () { /* for performance tests only */ return 1; } LOCAL int vfPrint (aso, exp) Af_key *aso; Expr exp; { fprintf (stdout, "%s%s\n", dirPrefix, af_retattr (aso, AF_ATTBOUND)); return 1; } LOCAL int vfPrune () { pruneFlag++; return 0; } LOCAL int vfTerminate (aso, exp) Af_key *aso; Expr exp; { stExit ((int) exp->left); return 0; } LOCAL int vfName (aso, exp) Af_key *aso; Expr exp; { char *cp; if ((cp = re_comp(stConvertPattern((char *) exp->left)))) { fprintf(stderr, "%s: %s\n", stProgramName, cp); stExit (1); } return re_exec (af_retattr (aso, AF_ATTUNIXNAME)); } LOCAL int vfState (aso, exp) Af_key *aso; Expr exp; { return af_retnumattr (aso, AF_ATTSTATE) == (int) exp->left; } LOCAL int uda (aso, exp) Af_key *aso; Expr exp; { return atMatchAttr (aso, (char *) exp->left); } LOCAL int symname (aso, exp) Af_key *aso; Expr exp; { char symnameuda[AT_MAXALIASLEN+AF_UDANAMLEN+2]; sprintf(symnameuda, "%s=%s", AT_ATTALIAS, (char *) exp->left); return atMatchAttr (aso, symnameuda); } LOCAL time_t gettime (val) char *val; { Af_attrs attrs; Af_set set; char thisvers[PATH_MAX + NAME_MAX + TYPE_MAX + 1]; char *cp1, *cp2; int hits; time_t retVal; af_initattrs(&attrs); af_initset(&set); attrs.af_gen = AF_BUSYVERS; attrs.af_rev = AF_BUSYVERS; strcpy (thisvers, val); if ((cp1 = strrchr(thisvers, '[')) && (cp2 = strrchr(thisvers,']')) && (cp1 < cp2) && (*(cp2+1) == '\0')) { if ((cp2 = strchr(cp1, '.')) && cp2 > cp1) { *cp1 = '\0'; cp1++; *cp2 = '\0'; cp2++; attrs.af_gen = atoi(cp1); attrs.af_rev = atoi(cp2); } } strcpy (attrs.af_syspath, af_afpath(thisvers)); strcpy (attrs.af_name, af_afname(thisvers)); strcpy (attrs.af_type, af_aftype(thisvers)); if (af_find(&attrs, &set) <= 0) { fprintf (stderr, "%s: cannot access < %s >\n", stProgramName, val); stExit (1); } hits = af_nrofkeys (&set); if (hits > 1) { fprintf(stderr, "%s: ambigious < %s >\n", stProgramName, val); stExit (1); } af_allattrs(&(set.af_klist[hits-1]), &attrs); if (af_retnumattr (&(set.af_klist[hits-1]), AF_ATTSTATE) == AF_BUSY) retVal = af_rettimeattr (&(set.af_klist[hits-1]), AF_ATTMTIME); else retVal = af_rettimeattr (&(set.af_klist[hits-1]), AF_ATTSTIME); af_dropset (&set); return (retVal); } LOCAL int vfNewer (aso, exp) Af_key *aso; Expr exp; { if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) return (af_rettimeattr (aso, AF_ATTMTIME) > (time_t) exp->left); else return (af_rettimeattr (aso, AF_ATTSTIME) > (time_t) exp->left); } LOCAL int SinceName (aso, exp) Af_key *aso; Expr exp; { int status = 0; /* return status = no match */ Af_set set; Af_attrs sattrs; char symnameuda[AT_MAXALIASLEN+AF_UDANAMLEN+2]; af_initattrs (&sattrs); strcpy (sattrs.af_host, af_retattr (aso, AF_ATTHOST)); strcpy (sattrs.af_syspath, af_retattr (aso, AF_ATTSPATH)); strcpy (sattrs.af_name, af_retattr (aso, AF_ATTNAME)); strcpy (sattrs.af_type, af_retattr (aso, AF_ATTTYPE)); sprintf (symnameuda, "%s=%s", AT_ATTALIAS, (char *) exp->left); sattrs.af_udattrs[0] = symnameuda; sattrs.af_udattrs[1] = 0; af_initset(&set); if (af_find(&sattrs, &set) == -1) { sprintf(stMessage, "%s: af_find()", stProgramName); af_perror(stMessage); } else { int hits = af_nrofkeys(&set); if ((hits = af_nrofkeys(&set)) > 1) { fprintf(stderr, "%s: ambigious < %s[%s] >\n", stProgramName, af_retattr (aso, AF_ATTUNIXNAME), (char*)exp->left); } else if (hits == 1) { if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) status = af_rettimeattr (&(set.af_klist[0]), AF_ATTSTIME) < af_rettimeattr (aso, AF_ATTMTIME); else status = af_rettimeattr (&(set.af_klist[0]), AF_ATTSTIME) < af_rettimeattr (aso, AF_ATTSTIME); } } af_dropset(&set); return status; } LOCAL int vfPosition (aso, exp) Af_key *aso; Expr exp; { Af_set tset; Af_attrs tattrs; Af_key tkey; int hits, i; af_initattrs (&tattrs); strcpy (tattrs.af_host, af_retattr (aso, AF_ATTHOST)); strcpy (tattrs.af_syspath, af_retattr (aso, AF_ATTSPATH)); strcpy (tattrs.af_name, af_retattr (aso, AF_ATTNAME)); strcpy (tattrs.af_type, af_retattr (aso, AF_ATTTYPE)); if (stateFlag) tattrs.af_state = af_retnumattr (aso, AF_ATTSTATE); if (userFlag) { Af_user *asoOwner = af_retuserattr (aso, AF_ATTOWNER); strcpy (tattrs.af_owner.af_username, asoOwner->af_username); strcpy (tattrs.af_owner.af_userdomain, asoOwner->af_userdomain); } if (attrFlag) { Af_attrs attrs; af_allattrs (aso, &attrs); for (i = 0; i < AF_MAXUDAS; i++) tattrs.af_udattrs[i] = attrs.af_udattrs[i]; af_freeattrbuf (&attrs); } if (af_find(&tattrs, &tset) == -1) { sprintf(stMessage, "%s: af_find()", stProgramName); af_perror(stMessage); return 0; } if ((hits = af_nrofkeys(&tset)) > 1) { af_sortset(&tset, AF_ATTBOUND); if (((int) exp->left) == VF_FIRST) af_setgkey(&tset, 0, &tkey); else af_setgkey(&tset, hits - 1, &tkey); hits = ((af_retnumattr (&tkey, AF_ATTGEN) == af_retnumattr (aso, AF_ATTGEN)) && (af_retnumattr (&tkey, AF_ATTREV) == af_retnumattr (aso, AF_ATTREV))) ? 1 : 0; af_dropkey (&tkey); } af_dropset (&tset); return hits; } LOCAL int vfSize (aso, exp) Af_key *aso; Expr exp; { int s; s = af_retnumattr (aso, AF_ATTSIZE) / BLKSIZE; if (af_retnumattr (aso, AF_ATTSIZE) % BLKSIZE) s++; return (s == (int) exp->left); } LOCAL int vfPerm (aso, exp) Af_key *aso; Expr exp; { return (af_retnumattr (aso, AF_ATTMODE) & (int) exp->right & 07777) == (int) exp->left; } LOCAL int vfUser (aso, exp) Af_key *aso; Expr exp; { Af_user cmpUser, *asoUser; atScanUser ((char *)exp->left, &cmpUser); asoUser = af_retuserattr (aso, AF_ATTOWNER); return (!strcmp (cmpUser.af_username, asoUser->af_username) && !strcmp (cmpUser.af_userdomain, asoUser->af_userdomain)); } LOCAL int locked (aso, exp) Af_key *aso; Expr exp; { return (atUserValid (af_testlock(aso))); } LOCAL int locker (aso, exp) Af_key *aso; Expr exp; { Af_user cmpUser, *asoUser; atScanUser ((char *)exp->left, &cmpUser); asoUser = af_retuserattr (aso, AF_ATTLOCKER); return (!strcmp (cmpUser.af_username, asoUser->af_username) && !strcmp (cmpUser.af_userdomain, asoUser->af_userdomain)); } LOCAL int vfType (aso, exp) Af_key *aso; Expr exp; { switch ((int) exp->left) { case 1: if (S_ISBLK(af_retnumattr (aso, AF_ATTMODE))) return (TRUE); break; case 2: if (S_ISCHR(af_retnumattr (aso, AF_ATTMODE))) return (TRUE); break; case 3: if (S_ISDIR(af_retnumattr (aso, AF_ATTMODE))) return (TRUE); break; case 4: if (S_ISREG(af_retnumattr (aso, AF_ATTMODE))) return (TRUE); break; #ifdef S_ISLNK case 5: if (S_ISLNK(af_retnumattr (aso, AF_ATTMODE))) return (TRUE); break; #endif #ifdef S_ISSOCK case 6: if (S_ISSOCK(af_retnumattr (aso, AF_ATTMODE))) return (TRUE); break; #endif } return (FALSE); } LOCAL int vl (aso, exp) Af_key *aso; Expr exp; { fprintf(stdout, "%s %s %s %8d %s %s%s\n", atWriteMode (aso), atWriteStatus (aso, FALSE), atUserName (af_retuserattr (aso, AF_ATTOWNER)), af_retnumattr (aso, AF_ATTSIZE), (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) ? atWriteDate (aso, AF_ATTMTIME) : atWriteDate (aso, AF_ATTSTIME), dirPrefix, af_retattr (aso, AF_ATTBOUND)); return 1; } LOCAL int eq (aso, exp) Af_key *aso; Expr exp; { return (af_retnumattr (aso, AF_ATTGEN) == (int) exp->left) && (af_retnumattr (aso, AF_ATTREV) == (int) exp->right); } LOCAL int lt (aso, exp) Af_key *aso; Expr exp; { return (af_retnumattr (aso, AF_ATTGEN) < (int) exp->left || (af_retnumattr (aso, AF_ATTGEN) == (int) exp->left && af_retnumattr (aso, AF_ATTREV) < (int) exp->right)); } LOCAL int le (aso, exp) Af_key *aso; Expr exp; { return lt (aso, exp) || eq (aso, exp); } LOCAL int gt (aso, exp) Af_key *aso; Expr exp; { return (af_retnumattr (aso, AF_ATTGEN) > (int) exp->left || (af_retnumattr (aso, AF_ATTGEN) == (int) exp->left && af_retnumattr (aso, AF_ATTREV) > (int) exp->right)); } LOCAL int ge (aso, exp) Af_key *aso; Expr exp; { return gt (aso, exp) || eq (aso, exp); } #define SECSPERDAY 86400L LOCAL int comptime(secs, days, sign) time_t secs; int days; char sign; { int d; d = (int) ((now - secs) / SECSPERDAY); switch (sign) { case '+': return (d>days); case '-': return (d < (days * -1)); default: return (d==days); } } LOCAL int vfMtime (aso, exp) Af_key *aso; Expr exp; { return comptime (af_rettimeattr (aso, AF_ATTMTIME), (time_t) exp->left, *(char*)(exp->right)); } LOCAL int vfAtime (aso, exp) Af_key *aso; Expr exp; { return comptime (af_rettimeattr (aso, AF_ATTATIME), (time_t) exp->left, *(char*)(exp->right)); } LOCAL int vfCtime (aso, exp) Af_key *aso; Expr exp; { return comptime (af_rettimeattr (aso, AF_ATTCTIME), (time_t) exp->left, *(char*)(exp->right)); } LOCAL int vfStime (aso, exp) Af_key *aso; Expr exp; { return comptime (af_rettimeattr (aso, AF_ATTSTIME), (time_t) exp->left, *(char*)(exp->right)); } LOCAL int vfLtime (aso, exp) Af_key *aso; Expr exp; { return comptime (af_rettimeattr (aso, AF_ATTLTIME), (time_t) exp->left, *(char*)(exp->right)); } LOCAL int execute (aso, exp) Af_key *aso; Expr exp; { char *pav[128], *arg, pathName[PATH_MAX]; int i, j; Wait_t retcode; pid_t pid, wpid; strcpy (pathName, dirPrefix); if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) strcat (pathName, af_retattr (aso, AF_ATTUNIXNAME)); else strcat (pathName, af_retattr (aso, AF_ATTBOUND)); i = (int) exp->left; for (j = 0; strcmp((arg = nav[i++]), ";"); j++) if (!strcmp(arg, "{}")) pav[j] = pathName; else pav[j] = arg; pav[j] = (char *) NULL; if (j == 0) return 1; fflush(stdout); switch (pid = fork()) { case -1: sprintf (stMessage, "%s: fork failed\n", stProgramName); perror (stMessage); stExit (1); break; case 0: chdir(startDir); execvp(pav[0], pav); perror("vfind: exec failed"); kill (getpid(), SIGHUP); _exit(127); break; default: while ((wpid = wait(&retcode)) != -1 && wpid != pid); if (WEXITSTATUS (retcode)) { fprintf(stderr, "%s: execution terminated\n", stProgramName); stExit (1); } return (!WEXITSTATUS (retcode)); break; } /*NOTREACHED*/ return 0; } LOCAL int not (aso, exp) Af_key *aso; Expr exp; { return ! ((*exp->left->eval) (aso, exp->left)); } LOCAL int and (aso, exp) Af_key *aso; Expr exp; { return ((*exp->left->eval) (aso, exp->left) && (*exp->right->eval) (aso, exp->right)) ? 1 : 0; } LOCAL int or (aso, exp) Af_key *aso; Expr exp; { return ((*exp->left->eval) (aso, exp->left) || (*exp->right->eval) (aso, exp->right)) ? 1 : 0; } /* constructors */ LOCAL Expr build(func, l, r) int (*func)(); Expr l, r; { Expr this; if ((this = (Expr) malloc((unsigned) sizeof (struct expr))) == (Expr) NULL) { fprintf(stderr, "%s: out of memory.\n", stProgramName); stExit (1); } this->eval = func; this->left = l; this->right = r; return this; } LOCAL void skip() { if (nav[idx]) idx++; else { fprintf(stderr, "%s: parsing error\n", stProgramName); stExit (1); } } LOCAL Expr primary () { char *prim, *val, *cp; char c; int i = 0; int mode = 0; int mask = 0; val = cp = (char *) NULL; if (!(prim = nav[idx])) { fprintf(stderr, "%s: parsing error\n", stProgramName); stExit (1); } if (*prim != '-') { fprintf(stderr, "%s: %s is not a primary\n", stProgramName, prim); stExit (1); } prim++; if (!strcmp(prim, "noop")) return build(vfNoop, (Expr) NULL, (Expr) NULL); if (!strcmp(prim, "print")) return build(vfPrint, (Expr) NULL, (Expr) NULL); if (!strcmp(prim, "prune")) return build(vfPrune, (Expr) NULL, (Expr) NULL); if (!strcmp(prim, "ls") || !strcmp(prim, "vl")) return build(vl, (Expr) NULL, (Expr) NULL); if (!strcmp(prim, "locked")) return build(locked, (Expr) NULL, (Expr) NULL); if(!strcmp(prim, "last")) return build(vfPosition, (Expr) VF_LAST, (Expr) NULL); if(!strcmp(prim, "first")) return build(vfPosition, (Expr) VF_FIRST, (Expr) NULL); skip(); if (!(val = nav[idx])) { fprintf(stderr, "%s: parsing error\n", stProgramName); stExit (1); } if (!strcmp(prim, "name")) return build(vfName, (Expr) val, (Expr) NULL); if (!strcmp(prim, "type")) { c = *val; i = 0; if (c=='b') i = 1; else if (c=='c') i = 2; else if (c=='d') i = 3; else if (c=='f') i = 4; #ifdef S_ISLNK else if (c=='l') i = 5; #endif #ifdef S_ISSOCK else if (c=='s') i = 6; #endif return build(vfType, (Expr) i, (Expr) NULL); } if (!strcmp(prim, "perm")) { while((c = *val++)) if (c=='-') mask++; else { c -= '0'; mode <<= 3; mode += c; } return build(vfPerm, (Expr) mode, (Expr) (mask ? mode : 07777)); } if (!strcmp(prim, "atime")) return build(vfAtime, (Expr) atoi(val), (Expr) val); if (!strcmp(prim, "ctime")) return build(vfCtime, (Expr) atoi(val), (Expr) val); if (!strcmp(prim, "mtime")) return build(vfMtime, (Expr) atoi(val), (Expr) val); if (!strcmp(prim, "stime")) return build(vfStime, (Expr) atoi(val), (Expr) val); if (!strcmp(prim, "ltime")) return build(vfLtime, (Expr) atoi(val), (Expr) val); if (!strcmp(prim, "user")) { userFlag++; return build(vfUser, (Expr) val, (Expr) val); } if (!strcmp(prim, "exit")) return build(vfTerminate, (Expr) atoi(val), (Expr) NULL); if (!strcmp(prim, "eq")) { if ((cp = strrchr(val, '.'))) *cp++ = '\0'; return build(eq, (Expr) atoi(val), (Expr) atoi(cp)); } if (!strcmp(prim, "le")) { if ((cp = strrchr(val, '.'))) *cp++ = '\0'; return build(le, (Expr) atoi(val), (Expr) atoi(cp)); } if (!strcmp(prim, "lt")) { if ((cp = strrchr(val, '.'))) *cp++ = '\0'; return build(lt, (Expr) atoi(val), (Expr) atoi(cp)); } if (!strcmp(prim, "ge")) { if ((cp = strrchr(val, '.'))) *cp++ = '\0'; return build(ge, (Expr) atoi(val), (Expr) atoi(cp)); } if (!strcmp(prim, "gt")) { if ((cp = strrchr(val, '.'))) *cp++ = '\0'; return build(gt, (Expr) atoi(val), (Expr) atoi(cp)); } if (!strcmp(prim, "locker")) { if ((cp = strrchr(val, '@'))) *cp++ = '\0'; return build(locker, (Expr) val, (Expr) cp); } if (!strcmp(prim, "exec") || !strcmp(prim, "ok")) { i = idx; while(nav[++idx] && strcmp(nav[idx], ";")); return build(execute, (Expr) i, (Expr) prim); } if (!strcmp(prim, "state")) { stateFlag++; return build(vfState, (Expr) atScanStatus (val), (Expr) NULL); } if (!strcmp(prim, "uda")) { attrFlag++; return build(uda, (Expr) val, (Expr) NULL); } if (!strcmp(prim, "symbolic")) { attrFlag++; return build(symname, (Expr) val, (Expr) NULL); } if (!strcmp(prim, "newer")) return build(vfNewer, (Expr) gettime(val), (Expr) NULL); if (!strcmp(prim, "SinceName")) { return build(SinceName, (Expr) val, (Expr) NULL); } if (!strcmp(prim, "size")) return build(vfSize, (Expr) atoi(val), (Expr) NULL); fprintf(stderr,"%s: unknown primary `%s'.\n", stProgramName, prim); stExit (1); /*NOTREACHED*/ return 0; } LOCAL Expr alternation(); LOCAL Expr grouping () { Expr expr; if (!strcmp(nav[idx], "(")){ skip(); expr = alternation(); if (nav[idx] && !strcmp(nav[idx], ")")) { skip(); return expr; } fprintf(stderr, "%s: missing closing ')'.\n", stProgramName); stExit (1); } else { expr = primary(); skip(); /* primary() does not skip the */ /* processed token, so we do it here. */ return expr; } /*NOTREACHED*/ return 0; } LOCAL Expr negation() { if (nav[idx] && !strcmp(nav[idx], "!")) { skip(); return build(not, grouping(), (Expr) NULL); } else return grouping(); } LOCAL Expr concatenation() { Expr left; char *this; left = negation (); this = nav[idx]; if (this && (!strcmp(this, "-a") || !strcmp(this, "!") || !strcmp(this, "(") || (*this == '-' && strcmp(this, "-o")))){ if (!strcmp(this, "-a")) skip(); return build(and, left, concatenation()); } else return left; } LOCAL Expr alternation() { Expr left; left = concatenation(); if (nav[idx] && !strcmp(nav[idx], "-o")) { skip(); return build(or, left, concatenation()); } else return left; } LOCAL Expr expression() { return alternation(); } LOCAL void traverse (name) char *name; { Af_set set, cacheSet; Af_key key; Af_attrs attrs; struct stat buf, abuf; int hits, i, ndir; char *prefix, thisaso[PATH_MAX+1]; Af_key *dirs[MAXDIRS]; static int ncalls = 0; if (af_access(af_afpath(name), af_afname(name), af_aftype(name), AF_CLASS_SOURCE) == -1) { af_perror (name); return; } if (stat(name, &buf) == -1) memset((char *) &buf, 0, sizeof (buf)); prefix = dirPrefix + strlen (dirPrefix); ndir = 0; af_initset (&set); af_initattrs (&attrs); if (S_ISDIR (buf.st_mode)) { strcpy(attrs.af_syspath, name); i = strlen (name) - 1; if (name[i] == '/' && i > 0) name[i] = '\0'; sprintf (prefix, "%s/", name); } else { strcpy (attrs.af_name, af_afpath(name)); strcpy (attrs.af_name, af_afname(name)); strcpy (attrs.af_type, af_aftype(name)); } /* check only busy versions if AtFS is not a directory */ if (!forceFlag) { sprintf (thisaso, "%s/%s", S_ISDIR (buf.st_mode) ? name : af_afpath(name), AF_SUBDIR); if ((stat (thisaso, &abuf) != -1) && (!S_ISDIR (abuf.st_mode))) attrs.af_state = AF_BUSY; } if (af_find(&attrs, &set) == -1) { sprintf(stMessage, "%s: af_find(%s)", stProgramName, name); af_perror(stMessage); return; } if (cacheFlag) { af_initset(&cacheSet); if (af_cachefind(&attrs, &cacheSet) == -1) { sprintf(stMessage, "%s: cachefind(%s)", stProgramName, name); af_perror(stMessage); af_dropset(&set); return; } af_union (&set, &cacheSet, &set, TRUE); af_dropset(&cacheSet); } hits = af_nrofkeys(&set); af_sortset (&set, AF_ATTBOUND); for (i = 0; i < hits; i++) { if (af_setgkey (&set, i, &key) == -1) { sprintf(stMessage, "%s: af_setgkey()", stProgramName); af_perror(stMessage); continue; } if (S_ISDIR (af_retnumattr (&key, AF_ATTMODE))) { if (ndir == MAXDIRS) { fprintf(stderr, "%s: too many directories.\n", stProgramName); af_dropkey (&key); stExit (1); } dirs[ndir] = (Af_key *) malloc((unsigned) sizeof(Af_key)); if (dirs[ndir] == (Af_key *) NULL) { fprintf(stderr, "%s: out of memory\n", stProgramName); af_dropkey (&key); stExit (1); } memcpy ((char *) dirs[ndir++], (char *) &key, sizeof(Af_key)); af_dropkey (&key); continue; } if ((*exprList->eval)(&key, exprList)) trueHits++; af_dropkey (&key); } if ((!S_ISDIR (buf.st_mode)) || (xFlag && (buf.st_dev != thisDevice)) || (cutFlag && ncalls > maxDepth) || !strcmp(name, AF_SUBDIR)) { af_dropset (&set); return; } if (chdir(name) == -1) { af_dropset (&set); return; } sprintf(prefix, "%s/", name); for (i = 0; i < ndir; i++) { strcpy (thisaso, af_retattr (dirs[i], AF_ATTUNIXNAME)); if (!strcmp(thisaso, ".") || !strcmp(thisaso, "..") || !strcmp(thisaso, AF_SUBDIR)) continue; if ((*exprList->eval)(dirs[i], exprList)) trueHits++; free((char *) dirs[i]); if (pruneFlag) { pruneFlag = 0; continue; } ncalls++; traverse(thisaso); ncalls--; } af_dropset (&set); chdir(".."); *prefix = '\0'; return; } /*============== * main *==============*/ LOCAL Sigret_t interrupt_action () /* is executed by appropriate signal handler */ { stExit (1); } EXPORT int main (argc, argv) int argc; char *argv[]; { char *cp; int pathCount; stProgramName = (cp = strrchr (argv[0], '/')) ? ++cp : argv[0]; if (stParseArgs (argc, argv, &nac, &nav, optDesc)) stExit (2); getcwd (startDir, PATH_MAX); now = time ((time_t *)0); if (nac < 2) usage(); for (idx = 1; idx < nac; idx++) /* find path list */ if (*nav[idx] == '-' || *nav[idx] == '!' || *nav[idx] == '(') break; if (!(pathCount = idx)){ fprintf(stderr, "%s: no path list.\n", stProgramName); usage(); } if (idx == nac) { fprintf(stderr, "%s: no expression.\n", stProgramName); usage(); } if ((exprList = expression()) == (Expr) NULL) stExit (1); stInterruptAction = interrupt_action; stCatchSigs(); for (idx = 1 ; idx < pathCount; idx++) { /* for all directories */ chdir (startDir); /* back to normal */ cp = nav[idx]; if (xFlag) { struct stat buf; stat(cp, &buf); thisDevice = buf.st_dev; } *dirPrefix = '\0'; traverse (cp); } stExit (hitsFlag ? trueHits : 0); return 0; } shapetools-1.4pl6.orig/src/vc/vfind/vfversion.c100444 2013 145 1405 5504367775 17654 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ char *vfversion () { static char release[] = "vfind-3.3 (Tue Aug 23 18:00:04 1994 by andy@cs.tu-berlin.de)"; return release; } shapetools-1.4pl6.orig/src/vc/vfind/Shapefile100444 2013 145 6411 5414051016 17266 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for vfind # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[5.0] Tue Jun 29 16:31:51 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) $(CC) -c $(CFLAGS) $(VERSIONFILE) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/vc/vfind/Makefile100444 2013 145 22416 5426221745 17141 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for vfind # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[5.0] Fri Jul 30 17:42:25 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/vc/vfind # A short name for this node system NODENAME = vfind # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = $(BASE) INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. TARGET = vfind # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = vfversion.c # source VERSIONOBJECT = vfversion.o # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = # The regular source and header files. SOURCES = vfind.c HEADERS = # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = vfind.1 MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. OBJECTS = vfind.o $(VERSIONOBJECT) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = $(LOCALLIBPATH)/libAtFStk.a $(LOCALLIBPATH)/libsttk.a $(LOCALLIBPATH)/libAtFS.a LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(TARGET) $(TARGET): $(LOCALLIBS) $(OBJECTS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET) to $$i; \ ln $(TARGET) $$i; \ done installtargets: $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$(TARGET): $(TARGET) @-echo "installing $(TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET); \ fi; \ cp $(TARGET) $(INSTALLBINPATH)/$(TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$$i; \ done installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/vc/vfind/Dependencies100444 2013 145 317 5367227067 17755 0ustar dokoswtvfind.o: $(BASE)/include/afsys.h vfind.o: $(BASE)/include/atfs.h vfind.o: $(BASE)/include/atfstk.h vfind.o: $(BASE)/include/config.h vfind.o: $(BASE)/include/sttk.h vfind.o: vfind.c vfversion.o: vfversion.c shapetools-1.4pl6.orig/src/vc/vl/ 40755 2013 145 0 5626416435 14700 5ustar dokoswtshapetools-1.4pl6.orig/src/vc/vl/vl.c100444 2013 145 71426 5517471727 15616 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools Version Control System * * vl.c - main program for "vl" command * * Author: Andreas.Lampen@cs.tu-berlin.de * previous versions by Uli.Pralle@cs.tu-berlin.de * * $Header: vl.c[9.0] Thu Jan 20 13:10:24 1994 andy@cs.tu-berlin.de frozen $ */ extern int errno; #include "atfs.h" #include "atfstk.h" #include "sttk.h" void initDisplay (); char *asoName (), *histAddName (); void displayAsoAttrs (), displayAsoShort (), displayAsoLong (); void displayAsoFormat (), displayAsoAll (); void displayHistShort (), displayHistLong (), displayHistAll (); void displayHistFormat (), displayColumns (); /*==================== * global variables *====================*/ static int outputTty; /* true if output goes to a tty */ EXPORT char examineDir[PATH_MAX]; static int retCode = 0; /* -?,-help */ int singleColumnFlag = FALSE; /* -1 (ls) */ int allFlag = FALSE; /* -a (ls) */ int showAllFlag = FALSE; /* -all */ int showHiddenAttrsFlag = TRUE; /* (always true) */ char *requiredAttrs[AF_MAXUDAS];/* -attr */ LOCAL int requiredAttrCount = 0; int nearlyAllFlag = FALSE; /* -A (ls) */ int sortCtimeFlag = FALSE; /* -c (ls) */ int multiColumnFlag = FALSE; /* -C (ls) */ int cacheFlag = FALSE; /* -cache */ int directoryFlag = FALSE; /* -d (ls) */ int expandAttrFlag = FALSE; /* -expand | -xpon */ int fastFlag = FALSE; /* -fast */ char *formatString = NULL; /* -format */ int fileClassFlag = FALSE; /* -F (ls) */ int groupFlag = FALSE; /* -g (ls) */ int justHistoriesFlag = FALSE; /* -h */ int intentFlag = FALSE; /* -intent */ int longFlag = FALSE; /* -l (ls) */ int lockedFlag = FALSE; /* -locked */ /* -lll (== -l -locker -locked) */ int logFlag = FALSE; /* -log */ int followSymLinksFlag = FALSE; /* -L (ls) */ int lockerFlag = FALSE; /* -locker */ char *bindName = NULL; /* -n (for compatibility) */ /* expandAttrFlag */ /* -noexpand | -xpoff */ int ownerFlag = FALSE; /* -O */ int showAllAttrsFlag = FALSE; /* -p [all|] */ char *showAttrs[AF_MAXUDAS]; LOCAL int showAttrCount = 0; int replNonGraphicFlag = FALSE; /* -q (ls) (not implemented) */ /* stQuietFlag */ /* -Q */ int reverseOrderFlag = FALSE; /* -r (ls) */ int recursiveFlag = FALSE; /* -R (ls) */ int longStatusFlag = FALSE; /* -S */ int sortMtimeFlag = FALSE; /* -t (ls) */ int sortAtimeFlag = FALSE; /* -u (ls) */ int fullUser = FALSE; /* -U */ /* justHistoriesFlag */ /* -v */ /* -version */ /* -V (for compatibility) */ int sortLinesFlag = FALSE; /* -x (ls) */ int displayPath = FALSE; int vlogFlag = FALSE; /*======================== * command line parsing *========================*/ LOCAL int handleFormat (option, arg) char *option, *arg; { char *srcPtr, *formatPtr; if (!arg || !(*arg)) { stLog ("You must specify a format string.", ST_LOG_MSGERR); stExit (2); } if (formatString) { sprintf (stMessage, "You can specify only one format string -- add. '-%s' ignored.", option); stLog (stMessage, ST_LOG_MSGERR); return (0); } if ((formatString = malloc ((unsigned) (strlen (arg) + 2))) == NULL) { stLog ("Not enough memory.", ST_LOG_ERROR); stExit (2); } /* handle special characters */ srcPtr = arg; formatPtr = formatString; while (*srcPtr) { if (*srcPtr != '\\') { *formatPtr++ = *srcPtr++; continue; } if (!*++srcPtr) continue; switch (*srcPtr) { case 'n': *formatPtr++ = '\n'; break; case 't': *formatPtr++ = '\t'; break; case '\\': *formatPtr++ = '\\'; break; } srcPtr++; } *formatPtr = '\0'; return (0); } LOCAL int handleAttr (option, arg) char *option, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No attribute specified -- '-%s' ignored.", option); stLog (stMessage, ST_LOG_MSGERR); return (0); } if (requiredAttrCount == AF_MAXUDAS) { sprintf (stMessage, "Too many attributes specified -- additional '-%s' ignored.", option); stLog (stMessage, ST_LOG_MSGERR); return (0); } requiredAttrs[requiredAttrCount++] = arg; requiredAttrs[requiredAttrCount] = NULL; return (0); } LOCAL int handleBindName (option, arg) char *option, *arg; { if (!arg || !(*arg)) { sprintf (stMessage, "No bind name specified -- '-%s' ignored.", option); stLog (stMessage, ST_LOG_MSGERR); return (0); } if (bindName) { sprintf (stMessage, "Too many bind names (-n,-V,-bind) specified -- '-%s' ignored.", option); stLog (stMessage, ST_LOG_MSGERR); return (0); } bindName = arg; return (0); } LOCAL int handleLll () { longFlag = TRUE; lockedFlag = TRUE; lockerFlag = TRUE; return (0); } LOCAL int handleShowAttr (option, arg) char *option, *arg; { if (!arg || !(*arg)) { showAllAttrsFlag = TRUE; return (0); } if (!strcmp (arg, "all")) { showAllAttrsFlag = TRUE; return (0); } if (!strcmp (arg, AT_ATTLOG)) { logFlag = TRUE; return (0); } if (showAttrCount == AF_MAXUDAS) { sprintf (stMessage, "Too many attribute names specified -- additional '-%s' ignored.", option); stLog (stMessage, ST_LOG_MSGERR); return (0); } showAttrs[showAttrCount++] = arg; showAttrs[showAttrCount] = NULL; return (0); } LOCAL int printVersion () { char *vlversion(); sprintf (stMessage, "This is %s", vlversion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " using %s,", atVersion()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " %s,", af_version()); stLog (stMessage, ST_LOG_MSG); sprintf (stMessage, " and %s.", stVersion()); stLog (stMessage, ST_LOG_MSG); stExit (0); return (0); } static int usage(); static StOptDesc optDesc[] = { { "?", PCALL, usage, NULL, NULL }, { "1", PSWITCH|PSET, NULL, &singleColumnFlag, NULL }, { "a", PSWITCH|PSET, NULL, &allFlag, NULL }, { "all", PSWITCH|PSET, NULL, &showAllFlag, NULL }, { "attr", PARG|PCALL, handleAttr, NULL, NULL }, { "A", PSWITCH|PSET, NULL, &nearlyAllFlag, NULL }, { "c", PSWITCH|PSET, NULL, &sortCtimeFlag, NULL }, { "C", PSWITCH|PSET, NULL, &multiColumnFlag, NULL }, { "cache", PSWITCH|PSET, NULL, &cacheFlag, NULL }, { "d", PSWITCH|PSET, NULL, &directoryFlag, NULL }, { "expand", PSWITCH|PSET, NULL, &expandAttrFlag, NULL }, { "fast", PSWITCH|PSET, NULL, &fastFlag, NULL }, { "xpon", PSWITCH|PSET, NULL, &expandAttrFlag, NULL }, { "format", PARG|PCALL, handleFormat, NULL, NULL }, { "F", PSWITCH|PSET, NULL, &fileClassFlag, NULL }, { "g", PSWITCH|PSET, NULL, &groupFlag, NULL }, { "h", PSWITCH|PSET, NULL, &justHistoriesFlag, NULL }, { "help", PCALL, usage, NULL, NULL }, { "intent", PSWITCH|PSET, NULL, &intentFlag, NULL }, { "l", PSWITCH|PSET, NULL, &longFlag, NULL }, { "lll", PCALL, handleLll, NULL, NULL }, { "locked", PSWITCH|PSET, NULL, &lockedFlag, NULL }, { "locker", PSWITCH|PSET, NULL, &lockerFlag, NULL }, { "log", PSWITCH|PSET, NULL, &logFlag, NULL }, { "L", PSWITCH|PSET, NULL, &followSymLinksFlag, NULL }, { "n", PARG|PCALL, handleBindName, NULL, NULL }, { "noexpand", PSWITCH|PCLEAR, NULL, &expandAttrFlag, NULL }, { "xpoff", PSWITCH|PCLEAR, NULL, &expandAttrFlag, NULL }, { "O", PSWITCH|PSET, NULL, &ownerFlag, NULL }, { "p", POARG|PCALL, handleShowAttr, NULL, NULL }, { "q", PSWITCH|PSET, NULL, &replNonGraphicFlag, NULL }, { "Q", PSWITCH|PSET, NULL, &stQuietFlag, NULL }, { "r", PSWITCH|PSET, NULL, &reverseOrderFlag, NULL }, { "R", PSWITCH|PSET, NULL, &recursiveFlag, NULL }, { "S", PSWITCH|PSET, NULL, &longStatusFlag, NULL }, { "t", PSWITCH|PSET, NULL, &sortMtimeFlag, NULL }, { "u", PSWITCH|PSET, NULL, &sortAtimeFlag, NULL }, { "U", PSWITCH|PSET, NULL, &fullUser, NULL }, { "v", PSWITCH|PCLEAR, NULL, &justHistoriesFlag, NULL }, { "version", PCALL, printVersion, NULL, NULL }, { "V", PARG|PCALL, handleBindName, NULL, NULL }, { "x", PSWITCH|PSET, NULL, &sortLinesFlag, NULL }, { NULL, 0, NULL, NULL, NULL }, }; LOCAL int usage() { stLog ("Usage:", ST_LOG_MSGERR); stShortUsage (stProgramName, optDesc, "names..."); atBindUsage (""); stExit (2); return (2); } /*============================== * histories (local routines) *==============================*/ LOCAL int histNameComp (name1, name2) char **name1, **name2; { if (!*name1 && !*name2) return (0); else if (!*name1) return (1); else if (!*name2) return (-1); return (strcmp (*name1, *name2)); } LOCAL int histCtimeComp (name1, name2) char **name1, **name2; { /* ToDo: histCtimeComp */ return (0); } LOCAL int histMtimeComp (name1, name2) char **name1, **name2; { /* ToDo: histMtimeComp */ return (0); } LOCAL int histAtimeComp (name1, name2) char **name1, **name2; { /* ToDo: histAtimeComp */ return (0); } /*============================== * sort and print histories *==============================*/ LOCAL void printHistories (histList, path) char **histList; char *path; { int histCount=0, subtractCount=0, nameIdx=0, maxNameLen=0; int len, pathLen=0, i; char **nameList, *nameExt; if (path && *path) pathLen = strlen (path) +1; /* additional byte for the '/' */ while (histList[histCount]) histCount++; /*---------- narrow list-----------------*/ for (i=0; i maxNameLen) maxNameLen = len; } if (histCount) displayColumns (nameList, histCount, maxNameLen); } else { i=0; while (histList[i]) { if (formatString) displayHistFormat (histList[i], formatString); else if (showAllFlag) displayHistAll (histList[i]); else if (longFlag) displayHistLong (histList[i], path); else displayHistShort (histList[i], path); i++; } } } /*====================== * collect histories *======================*/ LOCAL char **collectHistories (path, name) char *path, *name; { char **sourceList = NULL, **cacheList = NULL; if (!cacheFlag) if ((sourceList = af_histories (path, name)) == NULL) return (NULL); if (cacheFlag || allFlag || nearlyAllFlag) if ((cacheList = af_cachenames (path, name)) == NULL) return (NULL); if (sourceList && cacheList) { /* check cacheList for names that are not known in sourceList */ int sourceCount = 0, cacheCount = 0, newCount, i, j; while (sourceList[sourceCount]) sourceCount++; while (cacheList[cacheCount]) cacheCount++; if ((sourceList = (char **)realloc (sourceList, (unsigned) ((sourceCount+cacheCount)*sizeof (char *)))) == NULL) { stLog ("Not enough memory.", ST_LOG_ERROR); stExit (2); } newCount = sourceCount; for (i=0; i examineDir) { *pathAddPtr = '/'; strcpy (pathAddPtr+1, histList[i]); } else strcpy (pathAddPtr, histList[i]); if ((stat (examineDir, &iBuf) != ERROR) && S_ISDIR(iBuf.st_mode)) { if ((traverseList = collectHistories (examineDir, "^.*$")) == NULL) { sprintf (stMessage, "\n%s -- unreadable.", examineDir); stLog (stMessage, ST_LOG_MSGERR); retCode = 1; } else { fputc ('\n', stdout); fputs (examineDir, stdout); fputs (":\n", stdout); printHistories (traverseList, NULL); free (traverseList); traverseList = af_histories (examineDir, "^.*$"); historyTraverse (traverseList); free (traverseList); } } *pathAddPtr = '\0'; i++; } } /*====================== * histories *======================*/ LOCAL void histories (newArgc, newArgv) int newArgc; char **newArgv; { int i, prevWasDir=FALSE; char **histList, path[PATH_MAX], *name; struct stat iBuf; /* no names given on the command line */ if (newArgc == 1) { if ((histList = collectHistories (NULL, "^.*$")) == NULL) { stLog (af_errmsg (""), ST_LOG_ERROR); stExit (2); } strcpy (examineDir, ""); printHistories (histList, NULL); free (histList); if (recursiveFlag) { histList = af_histories (NULL, "^.*$"); historyTraverse (histList); free (histList); } return; } /* explicit names on the command line */ for (i = 1; i < newArgc; i++) { /* cut trailing slash if present */ if (newArgv[i][strlen(newArgv[i])-1] == '/') { newArgv[i][strlen(newArgv[i])-1] = '\0'; followSymLinksFlag = TRUE; } /* list directory contents when directory name is given an no -d */ if (!directoryFlag && (stat (newArgv[i], &iBuf) != ERROR) && S_ISDIR(iBuf.st_mode)) { if ((histList = collectHistories (newArgv[i], "^.*$")) == NULL) { sprintf (stMessage, "%s -- unreadable.", newArgv[i]); stLog (stMessage, ST_LOG_MSGERR); retCode = 1; continue; } /* if there are more than two args, print directory name */ if (newArgc > 2) { if (i>1) fputc ('\n', stdout); fputs (newArgv[i], stdout); fputs (":\n", stdout); } strcpy (examineDir, newArgv[i]); printHistories (histList, NULL); prevWasDir = TRUE; } else { strcpy (path, af_afpath (newArgv[i])); if (*path) { char *type = af_aftype (newArgv[i]); name = af_afname (newArgv[i]); if (*type) { strcat (name, "."); strcat (name, type); } } else name = newArgv[i]; if ((histList = collectHistories (path, stConvertPattern(name))) == NULL) { stLog (af_errmsg (""), ST_LOG_ERROR); stExit (2); } if (histList[0]) { /* ToDo: collect lists for columnized output */ strcpy (examineDir, path); if (prevWasDir) fputc ('\n', stdout); printHistories (histList, path); prevWasDir = FALSE; } else { /* list is empty */ sprintf (stMessage, "%s -- not found.", newArgv[i]); stLog (stMessage, ST_LOG_MSGERR); retCode = 1; } } free (histList); if (recursiveFlag) { histList = af_histories (newArgv[i], "^.*$"); historyTraverse (histList); free (histList); } } } /*=========================== * sort and print versions *===========================*/ LOCAL int needReverseCorrection = TRUE; LOCAL void printVersions (asoSet, path) Af_set *asoSet; char *path; { char **nameList, *name; int asoCount, nameIdx = 0, maxNameLen = 0, len, i, j, cleanOut, pathLen=0; Af_key tmpKey; if (path && *path) pathLen = strlen (path) +1; /* additional byte for the '/' */ /*---------- narrow set-----------------*/ asoCount = af_nrofkeys (asoSet); for (i=asoCount-1; i >= 0; i--) { af_setgkey (asoSet, i, &tmpKey); /* check if aso has required attributes */ j = 0; cleanOut = FALSE; while (requiredAttrs[j]) { if (!atMatchAttr (&tmpKey, requiredAttrs[j])) { cleanOut = TRUE; break; } j++; } if (cleanOut) { af_dropkey (&tmpKey); af_setposrmkey (asoSet, i); continue; } name = af_retattr (&tmpKey, AF_ATTNAME); if (!allFlag && name[0] == '.') { if ((nearlyAllFlag) && strcmp (name, ".") && strcmp (name, "..")) continue; af_dropkey (&tmpKey); af_setposrmkey (asoSet, i); continue; } if (!allFlag && !strcmp (name, AF_SUBDIR)) { af_dropkey (&tmpKey); af_setposrmkey (asoSet, i); continue; } af_dropkey (&tmpKey); } /* for */ /*-------------- sort -------------------*/ if (sortCtimeFlag) { af_sortset (asoSet, AF_ATTCTIME); if (needReverseCorrection) { if (reverseOrderFlag) reverseOrderFlag = FALSE; else reverseOrderFlag = TRUE; needReverseCorrection = FALSE; } } else if (sortMtimeFlag) { af_sortset (asoSet, AF_ATTMTIME); if (needReverseCorrection) { if (reverseOrderFlag) reverseOrderFlag = FALSE; else reverseOrderFlag = TRUE; needReverseCorrection = FALSE; } } else if (sortAtimeFlag) { af_sortset (asoSet, AF_ATTATIME); if (needReverseCorrection) { if (reverseOrderFlag) reverseOrderFlag = FALSE; else reverseOrderFlag = TRUE; needReverseCorrection = FALSE; } } else af_sortset (asoSet, AF_ATTBOUND); if ((asoCount = af_nrofkeys (asoSet)) == 0) { retCode = 1; return; } if (reverseOrderFlag) { /* reverse Set */ int lo = 0, hi = asoCount-1; Af_key tmp; while (lo < hi) { tmp = asoSet->af_klist[hi]; asoSet->af_klist[hi--] = asoSet->af_klist[lo]; asoSet->af_klist[lo++] = tmp; } } /*-------------- display -------------------*/ if (stQuietFlag) return; /* display columns */ if ((!formatString && !showAllFlag && !showAllAttrsFlag && !showAttrs[0] && !logFlag && !intentFlag && !longFlag && !singleColumnFlag) && (outputTty || multiColumnFlag)) { if (allFlag) { /* ToDo: fake "." and ".." */; } if ((nameList = (char **)malloc (sizeof(char*) * (asoCount+1))) == NULL) { stLog ("Not enough memory.", ST_LOG_ERROR); stExit (2); } for (i=0; i < asoCount; i++) { af_setgkey (asoSet, i, &tmpKey); name = asoName (&tmpKey); af_dropkey (&tmpKey); len = strlen (name) + pathLen; if ((nameList[nameIdx] = malloc ((unsigned) len+1)) == NULL) { stLog ("Not enough memory.", ST_LOG_ERROR); stExit (2); } if (path && *path) { strcpy (nameList[nameIdx], path); strcat (nameList[nameIdx], "/"); strcat (nameList[nameIdx], name); } else strcpy (nameList[nameIdx], name); nameIdx++; if (len > maxNameLen) maxNameLen = len; } if (asoCount) displayColumns (nameList, asoCount, maxNameLen); } else { if (allFlag) { /* ToDo: fake "." and ".." */; } for (i=0; i < asoCount; i++) { af_setgkey (asoSet, i, &tmpKey); if (formatString) displayAsoFormat (&tmpKey, formatString); else if (showAllFlag) displayAsoAll (&tmpKey); else if (longFlag) displayAsoLong (&tmpKey, path); else displayAsoShort (&tmpKey, path); af_dropkey (&tmpKey); } } } /*====================== * collect versions *======================*/ LOCAL Af_set *collectVersions (name) char *name; { Af_set *sourceSet = NULL, *cacheSet = NULL, emptySet; static Af_set resultSet; af_initset (&emptySet); if (!cacheFlag) if ((sourceSet = atBindSet (name, NULL, 0)) == NULL) return (NULL); if (cacheFlag || allFlag || nearlyAllFlag) if ((cacheSet = atBindCache (name, NULL)) == NULL) return (NULL); /* fourth parameter "FALSE" means, that no checking for duplicated elements in the result set is performed */ af_union (sourceSet ? sourceSet : &emptySet, cacheSet ? cacheSet : &emptySet, &resultSet, FALSE); if (sourceSet) af_dropset (sourceSet); if (cacheSet) af_dropset (cacheSet); return (&resultSet); } /*====================== * versionTraverse *======================*/ LOCAL void versionTraverse (asoSet) Af_set *asoSet; { Af_key tmpKey; Af_set *bindSet, *tmpSet, traverseSet; char *pathAddPtr, *asoName, pathPattern[PATH_MAX]; int i; for (i=0; i < af_nrofkeys (asoSet); i++) { af_setgkey (asoSet, i, &tmpKey); /* skip ".", "..", and "AtFS" */ asoName = af_retattr (&tmpKey, AF_ATTUNIXNAME); if (!strcmp (asoName, ".") || !strcmp (asoName, "..") || !strcmp (asoName, AF_SUBDIR)) { af_dropkey (&tmpKey); continue; } /* ToDo: follow symbolic links */ if (S_ISDIR(af_retnumattr (&tmpKey, AF_ATTMODE))) { pathAddPtr = &examineDir[strlen(examineDir)]; if (pathAddPtr > examineDir) { *pathAddPtr = '/'; strcpy (pathAddPtr+1, asoName); } else strcpy (pathAddPtr, asoName); strcpy (pathPattern, examineDir); strcat (pathPattern, "/*"); if ((bindSet = collectVersions (pathPattern)) == NULL) { sprintf (stMessage, "\n%s -- unreadable.", examineDir); stLog (stMessage, ST_LOG_MSGERR); retCode = 1; } else { fputc ('\n', stdout); fputs (examineDir, stdout); fputs (":\n", stdout); printVersions (bindSet, NULL); af_dropset (bindSet); tmpSet = atBindSet (pathPattern, "[]", AT_BIND_LAST); af_copyset (tmpSet, &traverseSet); af_dropset (tmpSet); versionTraverse (&traverseSet); af_dropset (&traverseSet); } *pathAddPtr = '\0'; } af_dropkey (&tmpKey); } } /*====================== * versions *======================*/ LOCAL void versions (newArgc, newArgv) int newArgc; char **newArgv; { int i, prevWasDir=FALSE; Af_set *bindSet, *tmpSet, traverseSet; struct stat iBuf; /* if there are no name arguments on the command line */ if (newArgc == 1) { if ((bindSet = collectVersions ("*")) == NULL) { stLog (atBindErrorMsg, ST_LOG_ERROR); stExit (2); } strcpy (examineDir, ""); printVersions (bindSet, NULL); af_dropset (bindSet); if (recursiveFlag) { tmpSet = atBindSet ("*", "[]", AT_BIND_LAST); af_copyset (tmpSet, &traverseSet); af_dropset (tmpSet); versionTraverse (&traverseSet); af_dropset (&traverseSet); } return; } /* explicit names on the command line */ for (i = 1; i < newArgc; i++) { /* cut trailing slash if present */ if (newArgv[i][strlen(newArgv[i])-1] == '/') { newArgv[i][strlen(newArgv[i])-1] = '\0'; followSymLinksFlag = TRUE; } /* list directory contents when directory name is given an no -d */ if (!directoryFlag && (stat (newArgv[i], &iBuf) != ERROR) && S_ISDIR(iBuf.st_mode)) { char realName[PATH_MAX]; strcpy (realName, newArgv[i]); strcat (realName, "/*"); if ((bindSet = collectVersions (realName)) == NULL) { sprintf (stMessage, "%s -- unreadable.", newArgv[i]); stLog (stMessage, ST_LOG_MSGERR); retCode = 1; continue; } /* if there are more than two args, print directory name */ if (newArgc > 2) { if (i>1) fputc ('\n', stdout); fputs (newArgv[i], stdout); fputs (":\n", stdout); } strcpy (examineDir, newArgv[i]); printVersions (bindSet, NULL); prevWasDir = TRUE; } else { if ((bindSet = collectVersions (newArgv[i])) == NULL) { retCode = 1; stLog (atBindErrorMsg, ST_LOG_ERROR); continue; } if (af_nrofkeys (bindSet)) { /* ToDo: collect sets for columnized output */ strcpy (examineDir, af_afpath (newArgv[i])); if (prevWasDir) fputc ('\n', stdout); printVersions (bindSet, examineDir); prevWasDir = FALSE; } else { /* set is empty */ sprintf (stMessage, "%s -- not found.", newArgv[i]); stLog (stMessage, ST_LOG_MSGERR); retCode = 1; } } af_dropset (bindSet); if (recursiveFlag) { char pathPattern[PATH_MAX]; strcpy (pathPattern, newArgv[i]); strcat (pathPattern, "/*"); tmpSet = atBindSet (pathPattern, "[]", AT_BIND_LAST); af_copyset (tmpSet, &traverseSet); af_dropset (tmpSet); versionTraverse (&traverseSet); af_dropset (&traverseSet); } } } /*============== * main *==============*/ LOCAL Sigret_t interrupt_action () /* is executed by appropriate signal handler */ { stExit (1); } int main (argc, argv) int argc; char *argv[]; { int tmpArgc, newArgc; char *cp, **tmpArgv, **newArgv; stProgramName = (cp = strrchr (argv[0], '/')) ? ++cp : argv[0]; if (geteuid() == 0) allFlag = TRUE; if (atBindOptions (argc, argv, &tmpArgc, &tmpArgv)) stExit (2); if (stParseArgs (tmpArgc, tmpArgv, &newArgc, &newArgv, optDesc)) stExit (2); /* map vl -n option to bind -bind option */ if (bindName) { char *auxArgv[4]; int auxArgc = 3; auxArgv[0] = stProgramName; auxArgv[1] = "-bind"; auxArgv[2] = bindName; auxArgv[3] = NULL; atBindOptions (auxArgc, auxArgv, &tmpArgc, &tmpArgv); } if (!(outputTty = isatty (fileno (stdout)))) { replNonGraphicFlag = TRUE; fileClassFlag = FALSE; } if (!strcmp (stProgramName, "vlog")) { vlogFlag = TRUE; if (!intentFlag && !logFlag) intentFlag = logFlag = TRUE; atBindModeOption = AT_BIND_LASTSAVED; } if (intentFlag) { showHiddenAttrsFlag = TRUE; showAttrs[showAttrCount++] = AT_ATTINTENT; showAttrs[showAttrCount] = NULL; /* requiredAttrs[requiredAttrCount++] = AT_ATTINTENT; requiredAttrs[requiredAttrCount] = NULL; */ } if (logFlag) { showHiddenAttrsFlag = TRUE; /* requiredAttrs[requiredAttrCount++] = AT_ATTLOG; requiredAttrs[requiredAttrCount] = NULL; */ } if (lockedFlag) { requiredAttrs[requiredAttrCount++] = AF_ATTLOCKER; requiredAttrs[requiredAttrCount] = NULL; } if (showAllFlag) { showHiddenAttrsFlag = TRUE; showAllAttrsFlag = TRUE; } af_noReadLock = TRUE; if (fastFlag) { af_suppressUdas = TRUE; } else { /* check if reading udas can be suppressed */ int bindOptionRequiringUdas = TRUE; /* if there is no bind argument except "-last" or "-laststaved" */ if (argc == tmpArgc) bindOptionRequiringUdas = FALSE; else if ((argc == tmpArgc+1) && ((atBindModeOption == AT_BIND_LAST) || (atBindModeOption == AT_BIND_LASTSAVED))) bindOptionRequiringUdas = FALSE; if ((newArgc == 1) /* no filename arguments */ && !bindOptionRequiringUdas && !showAllFlag && (requiredAttrCount == 0) && !formatString && !intentFlag && !lockedFlag && !lockerFlag && !logFlag && !bindName && !showAllAttrsFlag && (showAttrCount == 0) && !vlogFlag) af_suppressUdas = TRUE; } stInterruptAction = interrupt_action; stCatchSigs (); signal (SIGPIPE, interrupt_action); initDisplay (); if (justHistoriesFlag) histories (newArgc, newArgv); else versions (newArgc, newArgv); return (retCode); } shapetools-1.4pl6.orig/src/vc/vl/display.c100444 2013 145 46524 5521226302 16621 0ustar dokoswt/* Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. */ /* * ShapeTools Version Control System * * display.c - output procedures for "vl" command * * Author: Andreas Lampen, TU-Berlin (Andreas.Lampen@cs.tu-berlin.de) * * $Header: display.c[9.0] Tue Jan 25 17:43:02 1994 andy@cs.tu-berlin.de frozen $ */ #include #include #include "atfs.h" #include "atfstk.h" #include "sttk.h" extern int expandAttrFlag; extern int fastFlag; extern int fileClassFlag; extern int fullUser; extern int groupFlag; extern int lockerFlag; extern int logFlag; extern int longStatusFlag; extern int ownerFlag; extern int showAllAttrsFlag; extern char *showAttrs[]; extern int showHiddenAttrsFlag; extern int sortLinesFlag; extern char examineDir[]; static int lineLen, userLen, longStatus = FALSE; EXPORT void initDisplay () { int maxUserLen; lineLen = stGetTermWidth (1); if (fullUser) maxUserLen = 24; else if (groupFlag) maxUserLen = 18; else maxUserLen = 10; userLen = lineLen - 59; if (userLen > maxUserLen) userLen = maxUserLen; else if (userLen < 8) userLen = 8; if (lineLen > 100) longStatus = TRUE; } /*================================== * local general output routines *==================================*/ LOCAL void addGroup (userStr, gid) char *userStr; int gid; { struct passwd *pwent; struct group *group = NULL; char *atPtr = NULL, *grPtr; if (gid >= 0) group = getgrgid (gid); else { if (fullUser) { if ((atPtr = strchr (userStr, '@'))) *atPtr = '\0'; } else { if ((atPtr = strchr (userStr, ' '))) *atPtr = '\0'; } if ((pwent = getpwnam (userStr)) != NULL) group = getgrgid (pwent->pw_gid); } if (group) { int groupNameLen = strlen (group->gr_name), maxLen; if (userLen >= 20) maxLen = 8; else if (userLen <= 12) maxLen = 4; else maxLen = 6; grPtr = &userStr[userLen-(maxLen+1)]; *grPtr++ = ' '; strncpy (grPtr, " ", maxLen); strncpy (grPtr, group->gr_name, (groupNameLen > maxLen) ? maxLen : groupNameLen); if (atPtr && (atPtr < grPtr-1)) { if (fullUser) *atPtr = '@'; else *atPtr = ' '; } } } /*===================== * ASO output routines *=====================*/ EXPORT char *asoName (aso) Af_key *aso; { static char name[NAME_MAX+1]; if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) strcpy (name, af_retattr (aso, AF_ATTUNIXNAME)); else if (af_retnumattr (aso, AF_ATTSTATE) == AF_DERIVED) { strcpy (name, af_retattr (aso, AF_ATTBOUND)); strcpy (&name[strlen(name)-1], "-drvd]"); } else strcpy (name, af_retattr (aso, AF_ATTBOUND)); if (fileClassFlag) strcat (name, atFileClassExt (aso)); return (name); } EXPORT void displayAsoAttrs (aso, attrBuf, indent) Af_key *aso; Af_attrs *attrBuf; char *indent; { int i=0, j, found; char *attrName, *attrValue; Af_attrs myAttrBuf; if (!attrBuf) { af_allattrs (aso, &myAttrBuf); attrBuf = &myAttrBuf; } while (attrBuf->af_udattrs[i]) { if ((attrName = atAttrName (attrBuf->af_udattrs[i])) == NULL) attrName = "__xXxXxX__"; if (!showAllAttrsFlag) { /* check if attribute is in list of attributes to be shown */ j = 0; found = FALSE; while (showAttrs[j]) { if (!strcmp (attrName, showAttrs[j])) { found = TRUE; break; } j++; } if (!found) { i++; continue; } } /* skip hidden attribute unless showHiddenAttrsFlag is set */ if ((attrName[0] == '_') && (attrName[1] == '_') && !showHiddenAttrsFlag) { i++; continue; } /* ToDo: implement proper attribute output format */ /* expand attribute if necessary */ if (expandAttrFlag) { attrValue = atRetAttr (aso, attrName); printf ("%s%s=%s\n", indent, attrName, attrValue ? attrValue : ""); } else printf ("%s%s\n", indent, attrBuf->af_udattrs[i]); i++; } if (logFlag || showAllAttrsFlag) { if (expandAttrFlag) attrValue = atRetAttr (aso, "note"); else attrValue = af_rnote (aso); printf ("%s%s=%s\n", indent, AT_ATTLOG, attrValue ? attrValue : ""); } } EXPORT void displayAsoShort (aso, path) Af_key *aso; char *path; { if (path && *path) { fputs (path, stdout); fputc ('/', stdout); } fputs (asoName (aso), stdout); fputc ('\n', stdout); if (showAllAttrsFlag || showAttrs[0] || logFlag) displayAsoAttrs (aso, NULL, " "); } EXPORT void displayAsoLong (aso, path) Af_key *aso; char *path; { Af_user *userPtr; char userStr[USER_MAX+1]; int i; /* write mode -- 10 chars plus 1 char space */ fputs (atWriteMode (aso), stdout); fputc (' ', stdout); /* write status -- 1(short) or 6(long) chars plus 1 char space */ if (longStatusFlag) longStatus = TRUE; fputs (atWriteStatus (aso, longStatus), stdout); fputc (' ', stdout); /* write user -- default 20 chars plus 1 char space */ if (lockerFlag) userPtr = af_retuserattr (aso, AF_ATTLOCKER); else if (ownerFlag) userPtr = af_retuserattr (aso, AF_ATTOWNER); else userPtr = af_retuserattr (aso, AF_ATTAUTHOR); if (userPtr) { strncpy (userStr, userPtr->af_username, userLen); if (fullUser) { int len = strlen (userStr); if (len < userLen) { strcat (userStr, "@"); strncat (userStr, userPtr->af_userdomain, userLen-(len+1)); } } i = strlen (userStr); } else i = 0; /* fill up with blanks */ for (; iaf_ldes->af_owngid); else { struct stat iBuf; if ((af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) && (stat (af_retattr (aso, AF_ATTUNIXPATH), &iBuf) != ERROR)) addGroup (userStr, iBuf.st_gid); else addGroup (userStr, -1); } } fputs (userStr, stdout); fputc (' ', stdout); /* write size (right adjusted) -- max 8 digits */ fprintf (stdout, "%8d ", af_retnumattr (aso, AF_ATTSIZE)); /* write date -- narrowed to 12 chars */ if (lockerFlag) fputs (atWriteDate (aso, AF_ATTLTIME), stdout); else { if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) fputs (atWriteDate (aso, AF_ATTMTIME), stdout); else fputs (atWriteDate (aso, AF_ATTSTIME), stdout); } fputc (' ', stdout); /* write name */ if (path && *path) { fputs (path, stdout); fputc ('/', stdout); } fputs (asoName (aso), stdout); fputc ('\n', stdout); if (showAllAttrsFlag || showAttrs[0] || logFlag) displayAsoAttrs (aso, NULL, " "); } EXPORT void displayAsoFormat (aso, formatString) Af_key *aso; char *formatString; { /* ToDo: handle expandAttrFlag * Difficult, because it should do expansion exactly once. * This needs AtFStk suppport ! * When atExpand is just set FALSE, the unmodified format string * is written to the output. */ atExpandAttrs (aso, formatString, strlen (formatString), stdout, 0, AT_EXPAND_FILE); } EXPORT void displayAsoAll (aso) Af_key *aso; { int i, nameLen; char *titleName; Af_attrs attrBuf; af_allattrs (aso, &attrBuf); titleName = asoName (aso); nameLen = strlen (titleName); printf ("********%s", titleName); for (i = nameLen+4; i<=40; i++) fputc ('*', stdout); fputc ('\n', stdout); if (af_retnumattr (aso, AF_ATTSTATE) == AF_BUSY) printf (" Name: %s:%s\n", attrBuf.af_host, af_retattr (aso, AF_ATTUNIXPATH)); else printf (" Name: %s:%s\n", attrBuf.af_host, af_retattr (aso, AF_ATTBOUNDPATH)); printf (" Status: %s\n", atWriteStatus (aso, TRUE)); printf (" Owner: %-24.24s", af_retattr (aso, AF_ATTOWNER)); printf (" Last accessed: %s\n", af_retattr (aso, AF_ATTATIME)); printf (" Author: %-24.24s", af_retattr (aso, AF_ATTAUTHOR)); printf (" Last changed: %s\n", af_retattr (aso, AF_ATTCTIME)); if (attrBuf.af_locker.af_username[0]) printf (" Locker: %-24.24s", af_retattr (aso, AF_ATTLOCKER)); else printf (" Locker: %-24.24s", ""); if (attrBuf.af_ltime != AF_NOTIME) printf (" (Un)Locked at: %s\n", af_retattr (aso, AF_ATTLTIME)); else printf ("\n"); printf (" Size: %-24d", af_retnumattr (aso, AF_ATTSIZE)); printf (" Last modified: %s\n", af_retattr (aso, AF_ATTMTIME)); printf (" Mode: %-24.24s", atWriteMode (aso)); if (attrBuf.af_stime != AF_NOTIME) printf (" Saved at: %s\n", af_retattr (aso, AF_ATTSTIME)); else printf ("\n"); printf (" User defined attributes:\n"); displayAsoAttrs (aso, &attrBuf, " "); af_freeattrbuf (&attrBuf); printf ("\n"); } /*========================== * History output routines *==========================*/ int internalCall = FALSE; /* this flag tells histAddName, if global variables are already initialized */ Af_key firstAso, lastAso, busyAso; int firstExists = FALSE, lastExists = FALSE, busyExists = FALSE, cachedExist = FALSE; LOCAL void fillGlobals (hist) char *hist; { char name[NAME_MAX+1], type[TYPE_MAX]; strcpy (name, af_afname (hist)); strcpy (type, af_aftype (hist)); if (af_getkey (examineDir, name, type, AF_FIRSTVERS, AF_FIRSTVERS, &firstAso) != -1) firstExists = TRUE; if (af_getkey (examineDir, name, type, AF_LASTVERS, AF_LASTVERS, &lastAso) != -1) lastExists = TRUE; if (af_getkey (examineDir, name, type, AF_BUSYVERS, AF_BUSYVERS, &busyAso) != -1) busyExists = TRUE; if (af_access (examineDir, name, type, AF_CLASS_DERIVED) != -1) cachedExist = TRUE; } LOCAL void destroyGlobals () { af_dropkey (&firstAso); af_dropkey (&lastAso); af_dropkey (&busyAso); firstExists = lastExists = busyExists = cachedExist = FALSE; } EXPORT char *histAddName (hist, longName) char *hist; int longName; /* 1 - inclusive "busy" and "cached", 0 - exclusive */ { static char histVinfo[64]; if (fastFlag) { histVinfo[0] = '\0'; return (histVinfo); } if (!internalCall) fillGlobals (hist); histVinfo[0] = '['; histVinfo[1] = '\0'; if (firstExists) { strcat (histVinfo, af_retattr (&firstAso, AF_ATTVERSION)); if ((lastExists) && (lastAso.af_lpos != firstAso.af_lpos)) { strcat (histVinfo, "-"); strcat (histVinfo, af_retattr (&lastAso, AF_ATTVERSION)); } if (cachedExist & longName) strcat (histVinfo, ",cached"); if (busyExists & longName) strcat (histVinfo, ",busy"); strcat (histVinfo, "]"); } else if (cachedExist) { histVinfo[0] = '\0'; if (busyExists & longName) strcpy (histVinfo, "[cached,busy]"); else strcpy (histVinfo, "[]"); } else if (busyExists) { histVinfo[0] = '\0'; } else { char *namePtr = strrchr (hist, '/'); if (!namePtr) namePtr = hist; if (strcmp (namePtr, ".") && strcmp (namePtr, "..")) strcpy (histVinfo, "[]"); else histVinfo[0] = '\0'; } if (fileClassFlag) { if (busyExists) { strcat (histVinfo, atFileClassExt (&busyAso)); } else if (lastExists) { strcat (histVinfo, atFileClassExt (&lastAso)); } else if (cachedExist) { strcat (histVinfo, "$"); } } if (!internalCall) destroyGlobals (); return (histVinfo); } EXPORT void displayHistShort (hist, path) char *hist, *path; { if (!fastFlag) fillGlobals (hist); if (path && *path) { fputs (path, stdout); fputc ('/', stdout); } fputs (hist, stdout); internalCall = TRUE; fputs (histAddName (hist, 1), stdout); internalCall = FALSE; fputc ('\n', stdout); if (!fastFlag) destroyGlobals (); } EXPORT void displayHistLong (hist, path) char *hist, *path; { Af_user *userPtr; char userStr[USER_MAX+1], lockerStr[USER_MAX+1]; int i, cached=0, saved=0, isHist = FALSE; uid_t ownGid = -1; fillGlobals (hist); /* determine number of saved and cached versions */ if (lastExists) { afAccessAso (&lastAso, AF_ATTRS); saved = lastAso.af_ldes->af_nrevs; } else if (busyExists) { saved = 1; } if (cachedExist) { Af_attrs attrBuf; Af_set resultSet; af_initattrs (&attrBuf); strcpy (attrBuf.af_name, af_afname(hist)); strcpy (attrBuf.af_type, af_aftype(hist)); cached = af_cachefind (&attrBuf, &resultSet); af_dropset (&resultSet); if (cached <= 0) { /* huh ?, something went wrong */ cached = 0; } } /* write type */ if (busyExists) { mode_t busyMode = af_retnumattr (&busyAso, AF_ATTMODE); if (S_ISDIR(busyMode)) fputc ('d', stdout); else if (S_ISCHR(busyMode)) fputc ('c', stdout); else if (S_ISBLK(busyMode)) fputc ('b', stdout); else if (S_ISREG(busyMode)) { if (cachedExist && (saved == 1)) fputc ('o', stdout); else if (cachedExist && (saved > 1)) fputc ('x', stdout); else { fputc ('h', stdout); isHist = TRUE; } } #ifdef S_ISLNK else if (S_ISLNK(busyMode)) fputc ('l', stdout); #endif #ifdef S_ISSOCK else if (S_ISSOCK(busyMode)) fputc ('s', stdout); #endif } else { if (cachedExist && (saved == 0)) fputc ('o', stdout); else if (cachedExist && (saved > 0)) fputc ('x', stdout); else { fputc ('h', stdout); isHist = TRUE; } } lockerStr[0] = '\0'; /* write locked generations */ if (isHist && lastExists) { int gen=0, gen1=0, gen2=0; Af_key tmpAso; Af_user *tmpUser; char genStr[16]; for (i=af_retnumattr (&lastAso, AF_ATTGEN); i>=1; i--) { if (af_getkey (NULL, af_afname(hist), af_aftype(hist), i, AF_LASTVERS, &tmpAso) != -1) { tmpUser = af_testlock (&tmpAso); if (atUserValid (tmpUser)) { if (gen == 0) gen = i; else if (gen1 == 0) gen1 = i; else if (gen2 == 0) gen2 = i; else { af_dropkey (&tmpAso); break; } if (!lockerStr[0]) { strncpy (lockerStr, tmpUser->af_username, userLen); if (fullUser) { int len = strlen (lockerStr); if (len < userLen) { strcat (lockerStr, "@"); strncat (lockerStr, tmpUser->af_userdomain, userLen -(len+1)); } } } } af_dropkey (&tmpAso); } } if (gen) { if (gen <= 9) { if (gen2) sprintf (genStr, "^%d..", gen); else if (gen1 > 9) sprintf (genStr, "^%d..", gen); else if (gen1) sprintf (genStr, "^%d,%d", gen, gen1); else sprintf (genStr, "^%d ", gen); } else { if (gen1 || gen2) sprintf (genStr, "^%d.", gen); else sprintf (genStr, "^%d ", gen); } fputs (genStr, stdout); } else fputs (" ", stdout); } else fputs (" ", stdout); /* indicate busy version */ if (busyExists) fputs (" b ", stdout); else fputs (" ", stdout); /* write owner or locker -- default 20 chars plus 1 char space */ userPtr = NULL; if (firstExists) { userPtr = af_retuserattr (&firstAso, AF_ATTOWNER); ownGid = firstAso.af_ldes->af_owngid; } else if (lastExists) { userPtr = af_retuserattr (&lastAso, AF_ATTOWNER); ownGid = lastAso.af_ldes->af_owngid; } else if (busyExists) { userPtr = af_retuserattr (&busyAso, AF_ATTOWNER); ownGid = busyAso.af_ldes->af_owngid; } if (lockerFlag && lockerStr[0]) { strncpy (userStr, lockerStr, userLen); i = strlen (userStr); } else if (!lockerFlag && userPtr) { strncpy (userStr, userPtr->af_username, userLen); if (fullUser) { int len = strlen (userStr); if (len < userLen) { strcat (userStr, "@"); strncat (userStr, userPtr->af_userdomain, userLen-(len+1)); } } i = strlen (userStr); } else i = 0; /* fill up with blanks */ for (; i 9) { if (saved) fprintf (stdout, "%2d+%2dc ", saved, cached); else fprintf (stdout, "%5dc ", cached); } else if (cached) fprintf (stdout, "%3d+%dc ", saved, cached); else fprintf (stdout, "%6d ", saved); /* write date -- narrowed to 12 chars */ if (busyExists) fputs (atWriteDate (&busyAso, AF_ATTMTIME), stdout); else if (lastExists) fputs (atWriteDate (&lastAso, AF_ATTSTIME), stdout); else fputs (" ", stdout); fputc (' ', stdout); /* write name */ if (path && *path) { fputs (path, stdout); fputc ('/', stdout); } fputs (hist, stdout); internalCall = TRUE; fputs (histAddName (hist, 0), stdout); internalCall = FALSE; fputc ('\n', stdout); destroyGlobals (); } EXPORT void displayHistAll (hist) char *hist; { static int done = FALSE; if (!done) { stLog ("Sorry, '-all' Option for histories (-h) not implemented.", ST_LOG_MSGERR); done = TRUE; } /* ToDo: displayHistAll */ } EXPORT void displayHistFormat (hist, formatString) char *hist; char *formatString; { static int done = FALSE; if (!done) { stLog ("Sorry, '-format' Option for histories (-h) not implemented.", ST_LOG_MSGERR); done = TRUE; } /* ToDo: displayHistFormat */ } /*----------------------------------------------- * columns *-----------------------------------------------*/ EXPORT void displayColumns (nameList, nameCount, maxLen) char **nameList; int nameCount; /* number of entries in name list */ int maxLen; /* length of longest string in nameList */ { int colWidth = maxLen + 2, columns, nameLen, spaces, newLine, i, j; /* calculate number of columns to be displayed */ if (!(columns = lineLen / colWidth)) columns++; if (columns > nameCount) columns = nameCount; newLine = FALSE; if (sortLinesFlag) { for (i=0; i&2 exit 1 fi objs=-subs # may contain -comp or -subs if [ $1 = -comp ] ; then objs=-comp shift elif [ $1 = -subs ] ; then shift fi rootdir=$1 ; shift curdir=`pwd` cd $rootdir subsystems=`shape -echo SUBSYSTEMS` cd $curdir for path in $subsystems ; do $0 $objs $rootdir/$path $* done if [ "$objs" = -subs ] ; then # operate on subsystems # we must do awful things to make sure sed doesn't get confused subspattern=`echo $rootdir | sed 's|/|\\\\/|g'` cmdline=`echo "$@" | sed 's/{}/'$subspattern'/g'` if [ "$cmdline" ] ; then cd $rootdir eval "$cmdline" cd $curdir else echo $rootdir fi else # operate on components cd $rootdir components=`shape -echo COMPONENTS` cd $curdir for comp in $components ; do subspattern=`echo $rootdir/$comp | sed 's|/|\\\\/|g'` cmdline=`echo "$@" | sed 's/{}/'$subspattern'/g'` if [ "$cmdline" ] ; then cd $rootdir eval "$cmdline" cd $curdir else echo $rootdir/$comp fi done fi exit 0 shapetools-1.4pl6.orig/src/rms/lastrelease.sh100555 2013 145 2607 5412611327 17401 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) # # Little utility to print essential information about last # release of a (Sub-)System managed with shapeTools RMS. # # $Header: lastrelease.sh[6.0] Fri Jun 25 17:01:22 1993 andy@cs.tu-berlin.de frozen $ # # $__xpoff$ # argc=$# short=nope while [ $argc -gt 0 ] do i=$1 shift argc=`expr $argc - 1` case $i in -s) short=yes;; esac done if [ "$short" = "yes" ] then vl -format '$__lastrelease$' -lastsaved `shape -echo VERSIONFILE` exit 0 fi node=`shape -echo NODENAME` echo -n Last release of $node vl -format ': $__lastrelease$\nMade on $__ctime$ by $__author$.\n' \ -lastsaved `shape -echo VERSIONFILE` shapetools-1.4pl6.orig/src/rms/Makefile.tmpl100444 2013 145 25735 5441636752 17213 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # shape_CM Environment -- Makefile.template # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile.tmpl[6.0] Fri Sep 3 14:52:00 1993 andy@cs.tu-berlin.de frozen $ # # This is a template for Makefiles in the shape_CM environment. # Generate your Makefile by copying this template, deleting the two # lines beginning with $__xpoff$ and $__xpon$ (this disables/enables # attribute citation.), and setting the macros to an appropriate value. # #---- cut here ---- cut here ---- cut here ---- cut here ---- # # Makefile for ... # # $__xpoff$ <- Delete this when you have inserted Makefile.tmpl. # $__Header$ # $__xpon$ <- Delete this, too. # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = # A short name for this node system NODENAME = # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = /usr/local INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. TARGET = # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = # source VERSIONOBJECT = # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = # The regular source and header files. SOURCES = HEADERS = # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. OBJECTS = $(VERSIONOBJECT) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = $(LOCALLIBPATH)/xxx.a LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(TARGET) $(TARGET): $(LOCALLIBS) $(OBJECTS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET) to $$i; \ ln $(TARGET) $$i; \ done # Construction of a library would look like: #$(LIBTARGET): $(OBJECTS) # @ar ruv $(LIBTARGET) $(OBJECTS); \ # ($(RANLIB) $(LIBTARGET)) 2> /dev/null #local installation of a project wide library #localinstalltargets: $(INSTALLLIBPATH)/$(LIBTARGET) \ # $(INSTALLINCPATH)/lib-header.h installtargets: $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$(TARGET): $(TARGET) @-echo "installing $(TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET); \ fi; \ cp $(TARGET) $(INSTALLBINPATH)/$(TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$$i; \ done # Installing a library #installtargets: $(INSTALLLIBPATH)/$(TARGET) installincludes # #$(INSTALLLIBPATH)/$(TARGET): $(TARGET) # @-echo "installing $(TARGET) in $(INSTALLLIBPATH)"; \ # if [ -f $(INSTALLLIBPATH)/$(TARGET) ] ;\ # then \ # mv -f $(INSTALLLIBPATH)/$(TARGET) \ # $(INSTALLLIBPATH)/$(TARGET).old;\ # fi; \ # cp $(TARGET) $(INSTALLLIBPATH)/$(TARGET); \ # chmod $(INSTALLLIBMODE) $(INSTALLLIBPATH)/$(TARGET); \ # ($(RANLIB) $(INSTALLLIBPATH)/$(TARGET)) 2> /dev/null # installing a header file belonging to the library above # $(INSTALLINCPATH)/lib-header.h: lib-header.h # @-echo "Installing lib-header.h in $(INSTALLINCPATH)"; \ # if [ -f $(INSTALLINCPATH)/lib-header.h ] && \ # [ ! -w $(INSTALLINCPATH)/lib-header.h ]; \ # then \ # chmod u+w $(INSTALLINCPATH)/lib-header.h; \ # fi; \ # cp lib-header.h $(INSTALLINCPATH)/lib-header.h; \ # chmod $(INSTALLINCMODE) $(INSTALLINCPATH)/lib-header.h installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "installing $$i in $(INSTALLMANPATH)/man1"; \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) \ ALLTARGETS= \ MAINTARGET= \ $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" clean; \ fi shapetools-1.4pl6.orig/src/rms/Shapefile.tmpl100444 2013 145 7411 5412611222 17324 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # shape_CM Environment -- Shapefile.template # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile.tmpl[6.0] Fri Jun 25 17:01:25 1993 andy@cs.tu-berlin.de frozen $ # # This is a template for Shapefiles in the shape_CM environment. # Generate your Shapefile by copying this template, deleting the two # lines beginning with $__xpoff$ and $__xpon$ (this disables/enables # attribute citation.), and setting the macros to an appropriate value. # #---- cut here ---- cut here ---- cut here ---- cut here ---- # # Shapefile for ... # # $__xpoff$ <- Delete this when you have inserted Shapefile.tmpl. # $__Header$ # $__xpon$ <- Delete this, too. # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds _all: all $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) $(CC) -c $(CFLAGS) $(VERSIONFILE) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile CFLAGS += $(VARCFLAGS) LDFLAGS += $(VARLDFLAGS) SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=shape #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/rms/Release.tmpl100444 2013 145 267 5144546175 17006 0ustar dokoswt/* $__xpoff$ -- Delete this line when you have copied Release.tmpl */ $__lastrelease$ ($__ctime$ by $__author$) /* $__xpon$ -- Delete this line when you have copied Release.tmpl */ shapetools-1.4pl6.orig/src/rms/release.c.tmpl100444 2013 145 401 5144546132 17246 0ustar dokoswt/* $__xpoff$ -- Delete this line after you have copied release.c.tmpl */ char *release () { static char release[] = "$__lastrelease$ ($__ctime$ by $__author$)"; return release; } /* $__xpon$ -- Delete this line after you have copied release.c.tmpl */ shapetools-1.4pl6.orig/src/rms/stdconf100444 2013 145 42557 5443632353 16157 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # shape_CM environment -- standard configuration targets # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: stdconf[6.0] Thu Sep 9 15:53:17 1993 andy@cs.tu-berlin.de frozen $ # # $__xpoff$ check_releasable:- *, attrnot (state, busy), attrmax (version), attr (locker, $(USERATDOMAIN)), msg ($_af_unixname$ locked by us); *, attrnot (state, busy), attrmax (version), attrnot (locker, ), msg ($_af_unixname$ locked by somebody else -- STOP), -; *, attrnot (state, busy), attrmax(version), msg ($_af_unixname$ is available); *, attr (state, busy), msg ($_af_unixname$ is a new busy version -- lock assumed). most_recently_released:- *, attr (__SymbolicName__, $(LASTNODEPRERELEASE)), confirm ($_af_unixname$: $(LASTNODEPRERELEASE) more recent than $(LASTNODERELEASE)! Ignore ?, no), -; *, attr (__SymbolicName__, $(LASTNODERELEASE)). most_recently_prereleased:- *, attr (__SymbolicName__, $(LASTNODEPRERELEASE)); *, attr (__SymbolicName__, $(LASTNODERELEASE)). prerelease:+ RELEASENAME=`$(SHAPELIBPATH)/gen_rel_id $(PATCH) prerelease \ $(NODENAME) $(VERSIONFILE) $(PRERELSEQ) $(PATCHLEVEL)` NODERELEASERULE=check_releasable SUBNODERELEASERULE=most_recently_prereleased NODERELEASE=_elementary_prerelease SUBNODERELEASE=_include_prerelease SETSTATE=_set_accessed UNLOCKEDCHANGES=_check_unlocked_changes fullrelease:+ RELEASENAME=`$(SHAPELIBPATH)/gen_rel_id $(PATCH) release \ $(NODENAME) $(VERSIONFILE) $(PRERELSEQ) $(PATCHLEVEL)` NODERELEASERULE=most_recently_prereleased SUBNODERELEASERULE=most_recently_released NODERELEASE=_elementary_release SUBNODERELEASE=_include_release SETSTATE=_set_frozen_or_published UNLOCKEDCHANGES= USERATDOMAIN:=`$(SHAPELIBPATH)/user_at` NOTOPRELEASE=$(NODEPATH) LASTNODERELEASE:=`$(SHAPELIBPATH)/gen_rel_id $(PATCH) release $(NODENAME) \ $(BASE)/$(NODEPATH)/$(VERSIONFILE) $(BASE)/$(NODEPATH)/$(PRERELSEQ) \ $(BASE)/$(NODEPATH)/$(PATCHLEVEL)` LASTNODEPRERELEASE:=`$(SHAPELIBPATH)/gen_rel_id $(PATCH) prerelease $(NODENAME) \ $(BASE)/$(NODEPATH)/$(VERSIONFILE) $(BASE)/$(NODEPATH)/$(PRERELSEQ) \ $(BASE)/$(NODEPATH)/$(PATCHLEVEL)` LASTRELEASE:=`vl -format '$$__lastrelease$$' -lastsaved $(BASE)/$(NODEPATH)/$(VERSIONFILE)` PRERELSEQ=AtFS/.prerelseq PLPRERELSEQ=AtFS/.plprerelseq PATCHLEVEL=AtFS/.patchlevel RETRVOPTS= #"vetags extension" TAGS=TAGS TAGS= INDENT= INDENTINCR=" " # # This file defines the targets ``release'' and ``prerelease'' to # generate a new release of an AtFS application. # Target ``save'' is useful to make an intermediate save of all components. # # You should not use targets beginning with an underscore (`_'). release: +fullrelease _start_release _checkrelease _newrel _xrelease \ _resetseq _resetpl _end_release _patchlevel: +fullrelease _start_release _checkrelease _newpl _xrelease \ _resetseq _end_release prerelease: +prerelease _start_prerelease _checkseq _checkrelease \ _newprel _xrelease _end_prerelease plrelease: @shape _patchlevel PRERELSEQ=$(PLPRERELSEQ) PATCH=-p plprerelease: @shape prerelease PRERELSEQ=$(PLPRERELSEQ) PATCH=-p extractrelease: _extract_subreleases partial_extractrelease \ partial_extractrelman _start_release: @echo; echo Starting release process for $(NODENAME); echo; @echo Checking for release preconditions...; echo; _end_release: @echo Construction of release $(RELEASENAME) finished \!; echo _start_prerelease: @echo; echo Starting pre-release process for $(NODENAME); echo @echo Checking for pre-release preconditions...; echo; _end_prerelease: @echo Construction of pre-release $(RELEASENAME) finished \!; echo _end_prerelease: _extract_subreleases: @-_subsystems="$(SUBSYSTEMS)"; \ if [ -n "$(RELEASENAME)" ]; \ then \ symname=$(RELEASENAME); \ else \ symname=$(LASTNODERELEASE); \ fi; \ for i in $$_subsystems; \ do \ (cd $$i; $(MAKE) RELEASENAME=$$symname \ NOTOPRELEASE=$(NOTOPRELEASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ RETRVOPTS="$(RETRVOPTS)" \ extractrelease); \ done partial_extractrelease: @-if [ -n "$(RELEASENAME)" ]; \ then \ symname=$(RELEASENAME); \ else \ symname=$(LASTNODERELEASE); \ fi; \ if [ -n "$(NOTOPRELEASE)" ]; \ then \ relarea=$(PARTIALRELEASEBASE); \ else \ relarea=$(TOTALRELEASEBASE); \ fi; \ if [ -n "$$relarea" ]; \ then \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASESRCPATH); \ echo $(INDENT)Copying release $$symname of $(SOURCES) $(HEADERS) \ Shapefile Makefile and Dependencies in $$relarea/$(RELEASESRCPATH); \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASESRCPATH) -bind $$symname \ $(SOURCES) $(HEADERS) $(VERSIONFILE) Shapefile Makefile \ Dependencies; \ if [ -n "$(SUBSOURCES)$(SUBHEADERS)" ]; then \ echo $(INDENT)Copying release $$symname of $(SUBSOURCES) \ $(SUBHEADERS) in $$relarea/$(RELEASESRCPATH); \ _subsources="$(SUBSOURCES) $(SUBHEADERS)"; \ for i in $$_subsources; \ do \ subsrcpath=`echo $$i | sed 's,[^/]*$$,,' | sed 's,/$$,,'`; \ if [ -n "$$subsrcpath" ]; \ then \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASESRCPATH)/$$subsrcpath; \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASESRCPATH)/$$subsrcpath \ -bind $$symname $$i; \ else \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASESRCPATH) \ -bind $$symname $$i; \ fi; \ done; \ fi; \ else \ if [ -n "$(NOTOPRELEASE)" ]; \ then \ echo $(INDENT)"Copying to partial-release area skipped ! (no path specified)"; \ else \ echo $(INDENT)"Copying to release area skipped ! (no path specified)"; \ fi; \ fi partial_extractrelman: @-if [ -n "$(RELEASENAME)" ]; \ then \ symname=$(RELEASENAME); \ else \ symname=$(LASTNODERELEASE); \ fi; \ if [ -n "$(NOTOPRELEASE)" ]; \ then \ relarea=$(PARTIALRELEASEBASE); \ else \ relarea=$(TOTALRELEASEBASE); \ fi; \ if [ -n "$$relarea" ]; \ then \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASEMANPATH); \ if [ -n "$(MAN1)" ]; then \ echo $(INDENT)"Copying manual page(s) $(MAN1)"; \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASEMANPATH)/man1; \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASEMANPATH)/man1 -bind $$symname $(MAN1); \ fi; if [ -n "$(MAN3)" ]; then \ echo $(INDENT)"Copying manual page(s) $(MAN3)"; \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASEMANPATH)/man3; \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASEMANPATH)/man3 -bind $$symname $(MAN3); \ fi; if [ -n "$(MAN4)" ]; then \ echo $(INDENT)"Copying manual page(s) $(MAN4)"; \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASEMANPATH)/man4; \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASEMANPATH)/man4 -bind $$symname $(MAN4); \ fi; if [ -n "$(MAN5)" ]; then \ echo $(INDENT)"Copying manual page(s) $(MAN5)"; \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASEMANPATH)/man5; \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASEMANPATH)/man5 -bind $$symname $(MAN5); \ fi; if [ -n "$(MAN6)" ]; then \ echo $(INDENT)"Copying manual page(s) $(MAN6)"; \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASEMANPATH)/man6; \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASEMANPATH)/man6 -bind $$symname $(MAN6); \ fi; if [ -n "$(MAN7)" ]; then \ echo $(INDENT)"Copying manual page(s) $(MAN7)"; \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASEMANPATH)/man7; \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASEMANPATH)/man7 -bind $$symname $(MAN7); \ fi; if [ -n "$(MAN8)" ]; then \ echo $(INDENT)"Copying manual page(s) $(MAN8)"; \ $(SHAPELIBPATH)/mkpdir -m 775 $$relarea/$(RELEASEMANPATH)/man8; \ retrv -fq $(RETRVOPTS) -dest $$relarea/$(RELEASEMANPATH)/man8 -bind $$symname $(MAN8); \ fi; echo; \ else \ echo; \ fi _checkrelease: _checksub _checkmain # # This predicate checks whether all necessary preconditions for a # release of all subsystems are met, i.e. the subrelease must be # identifyable. # _checksub: @echo $(INDENT)$(NODENAME)...; \ if [ -n "$(SUBSYSTEMS)" ] ; \ then \ if [ -n "$(NODEPATH)" ] ; \ then \ echo $(INDENT)"Checking subsystem(s) $(NODEPATH)/{$(SUBSYSTEMS)} for releasability"; \ else \ echo $(INDENT)"Checking subsystem(s) {$(SUBSYSTEMS)} for releasability"; \ fi; \ fi; \ _subsystems="$(SUBSYSTEMS)"; \ exitcode=0; \ for i in $$_subsystems; \ do \ (cd $$i; $(SHAPE) NODERELEASERULE=$(SUBNODERELEASERULE) \ SUBNODERELEASERULE=$(SUBNODERELEASERULE) \ INDENT='$(INDENT)$(INDENTINCR)' _checksub _checkmain); \ if [ $$? -ne 0 ]; then exitcode=1; fi; \ done; \ if [ -n "$(SUBSYSTEMS)" ] ; \ then \ echo $(INDENT)$(NODENAME)...; \ fi; \ exit $$exitcode # # This predicate checks whether all preconditions for a local # release (i.e. of TARGET, COMPONENTS etc.) are met. In particular # we must be able to lock all components, before we check them # in. This is intended to prevent interference with programmers # who might have locked particular COMPONENTS. In the case of a global # release it is checked whether there are at all subreleases in all # of the subsystems. # # For prereleases, this predicate checks, whether there is a current # regular release that shall be included into the pre-release. # _checkmain: _check_foreign_locks $(UNLOCKEDCHANGES) @echo $(INDENT)" ...is releasable" _check_foreign_locks: $(NODERELEASERULE) $(COMPONENTS) $(VERSIONFILE) _check_unlocked_changes: @echo -n $(INDENT)Checking for unsaved changes without lock...; \ nll=`vfind $(COMPONENTS) -last \! -locked -print | \ egrep '.*\[.*\..*\]' | sed -e 's/\[.*\]//'`; \ for i in $$nll; \ do \ if [ ! -f $$i ] || vdiff $$i > /dev/null ; \ then : ; \ else \ ulcl="$$ulcl $$i"; \ fi; \ done; \ if [ -n "$$ulcl" ] ; \ then \ echo; \ echo $(INDENT)The following files have been changed but are not locked: ; \ echo $(INDENT)" $$ulcl"; \ echo $(INDENT)...$(NODENAME) is currently not releasable.; \ exit 1; \ fi; \ echo OK!; \ exit 0; # # This action creates a new versionid for our local release which # is also used to construct a symbolic name for it. # _newrel: @-if [ ! -f $(VERSIONFILE) ] ; \ then \ retrv -lock -q $(VERSIONFILE); \ else \ vadm -fq -lock $(VERSIONFILE); \ fi; \ vadm -q -attr nodename=$(NODENAME) $(VERSIONFILE); \ if vl -attr norelease -lastsaved $(VERSIONFILE) > /dev/null 2>&1; \ then \ vadm -q -lastsaved -delattr norelease $(VERSIONFILE); \ else \ save -fq -lock $(VERSIONFILE); \ fi; \ vadm -q -lastsaved -attr lastrelease=$(RELEASENAME) \ -alias $(RELEASENAME) -unlock $(VERSIONFILE); \ echo; echo New release name is $(RELEASENAME); echo _newprel: _incseq @-if vl -lastsaved $(VERSIONFILE) > /dev/null 2>&1; \ then :; \ else \ save -fq -lock $(VERSIONFILE); \ vadm -q -lastsaved -attr norelease=true -unlock $(VERSIONFILE); \ fi; \ vadm -q -lastsaved -attr nodename=$(NODENAME) \ -attr lastrelease=$(RELEASENAME) \ -alias $(RELEASENAME) $(VERSIONFILE); \ echo; echo New pre-release name is $(RELEASENAME); echo _newpl: _incpl @-if vl -lastsaved $(VERSIONFILE) > /dev/null 2>&1; \ then :; \ else \ echo *** Error ***; \ echo --- You need to release $(NODENAME) before creating \ patchlevels ---; \ exit 1; \ fi; \ vadm -q -lastsaved -attr nodename=$(NODENAME) \ -attr lastrelease=$(RELEASENAME) \ -alias $(RELEASENAME) $(VERSIONFILE); \ echo; echo New patchlevel-release name is $(RELEASENAME); echo _xrelease: _subreleases $(NODERELEASE) $(SETSTATE) _newline \ partial_extractrelease partial_extractrelman _newline: @echo # # This action visits all subsystems and triggers global releases for # them. Subsystems of subsystems are globally released recursively. # The maintarget is globally released after the subsystems. # _subreleases: @-_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ (symName=$(RELEASENAME); cd $$i; \ $(SHAPE) _xrelease \ INDENT='$(INDENT)$(INDENTINCR)' \ NODERELEASE=$(SUBNODERELEASE) \ SUBNODERELEASE=$(SUBNODERELEASE) \ UNLOCKEDCHANGES= \ NODERELEASERULE=$(SUBNODERELEASERULE) \ SUBNODERELEASERULE=$(SUBNODERELEASERULE) \ RELEASENAME=$$symName \ NOTOPRELEASE=$(NOTOPRELEASE) \ SETSTATE=$(SETSTATE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE)); \ done # # This action takes care that all yet unsubmitted work results are # deposited in the version object base and assigned the status "proposed". # The new, locally generated releasename is attached to all COMPONENTS. # _elementary_prerelease: @-symName=$(RELEASENAME); \ echo Pre-releasing $$symName...; \ save -q $(COMPONENTS); \ vadm -q -lastsaved -alias $$symName -attr lastrelease=$$symName $(COMPONENTS); \ retrv -xpoff -fq $(VERSIONFILE); \ touch -c -f $(VERSIONFILE); \ sbmt -q -bind $$symName $(COMPONENTS) $(VERSIONFILE) $(TAGS) # vetags extension #_elementary_prerelease: # @-symName=$(RELEASENAME); \ # echo Pre-releasing $$symName...; \ # save -q $(COMPONENTS); \ # vadm -q -lastrelease -alias $$symName -attr lastrelease=$$symName $(COMPONENTS); \ # rm -f $(TAGS) 2>&1 > /dev/null; \ # vadm -q -lock $(TAGS); \ # vetags -bind $$symName $(SOURCES); \ # save -alias $$symName -q $(TAGS); \ # retrv -xpoff -fq $(VERSIONFILE); \ # touch -c -f $(VERSIONFILE); \ # sbmt -q -bind $$symName $(COMPONENTS) $(VERSIONFILE) $(TAGS) _elementary_release: @-last_elementary_prerelease=`$(SHAPELIBPATH)/gen_rel_id $(PATCH) lastprerelease \ $(NODENAME) $(VERSIONFILE) $(PRERELSEQ) $(PATCHLEVEL)`; \ if vl -bind $$last_elementary_prerelease $(VERSIONFILE) > /dev/null 2>&1; \ then \ echo Releasing $(RELEASENAME) \(consists of $$last_elementary_prerelease\); \ vadm -q -bind $$last_elementary_prerelease -alias $(RELEASENAME) \ -attr lastrelease=$(RELEASENAME) $(COMPONENTS) $(TAGS); \ else \ last_elementary_release=`$(SHAPELIBPATH)/gen_rel_id $(PATCH) lastrelease \ $(NODENAME) $(VERSIONFILE) $(PRERELSEQ) $(PATCHLEVEL)`; \ echo Releasing $(RELEASENAME) \(consists of $$last_elementary_release \); \ vadm -q -bind $$last_elementary_release -alias $(RELEASENAME) \ -attr lastrelease=$(RELEASENAME) $(COMPONENTS) $(TAGS); \ fi; \ vadm -fq -bind $(RELEASENAME) -lock $(COMPONENTS) $(TAGS); \ vadm -q -bind $(RELEASENAME) -newgen -unlock $(COMPONENTS) $(TAGS) # # This action is triggered by an incoming global release process, i.e. # when we are in the role of a subtarget. It retrieves the most recent # local release of TARGET (see selection rule) and marks its COMPONENTS # with the global releasename which is passed down to us in the macro # RELEASENAME. If this is an intermediate global release, i.e. the release # was initiated by a non-toplevel subsystem of the overall system, no # status-change of the involved COMPONENTS takes place. If this is a "real" # TOPLEVEL release of the entire system, all COMPONENTS are set to status # "frozen". # _include_release: @-last_elementary_release=$(LASTNODERELEASE); \ echo $(INDENT)Including $$last_elementary_release into $(RELEASENAME); \ vadm -q -bind $$last_elementary_release -alias $(RELEASENAME) \ $(COMPONENTS) $(VERSIONFILE) _include_prerelease: @-last_elementary_prerelease=$(LASTNODEPRERELEASE); \ if vl -bind $$last_elementary_prerelease $(VERSIONFILE) > /dev/null 2>&1; \ then \ echo $(INDENT)Including $$last_elementary_prerelease into $(RELEASENAME); \ vadm -q -bind $$last_elementary_prerelease -alias $(RELEASENAME) $(COMPONENTS) $(VERSIONFILE); \ else \ last_elementary_release=$(LASTNODERELEASE); \ echo $(INDENT)Including $$last_elementary_release into $(RELEASENAME); \ vadm -q -bind $$last_elementary_release -alias $(RELEASENAME) $(COMPONENTS) $(VERSIONFILE); \ fi _set_accessed: @-last_elementary_release=$(RELEASENAME); \ if [ -n "$(NOTOPRELEASE)" ] ; \ then :; \ else \ echo $(INDENT)Accessing $(NODENAME) components; \ accs -q -bind $$last_elementary_release $(COMPONENTS) \ $(VERSIONFILE); \ fi _set_frozen_or_published: @-last_elementary_release=$(RELEASENAME); \ if [ -n "$(NOTOPRELEASE)" ] ; \ then \ echo $(INDENT)Publishing $(NODENAME) components; \ publ -q -bind $$last_elementary_release $(COMPONENTS) $(VERSIONFILE); \ else \ echo $(INDENT)Freezing $(NODENAME) components; \ frze -q -bind $$last_elementary_release $(COMPONENTS) \ $(VERSIONFILE); \ fi # # make sure that prerelase sequence number is present and initialized # _checkseq: $(PRERELSEQ) _resetseq: $(PRERELSEQ) @rm -f $(PRERELSEQ) 2> /dev/null; \ echo 0 > $(PRERELSEQ); \ chmod 664 $(PRERELSEQ) _incseq: $(PRERELSEQ) @awk < $(PRERELSEQ) '{ print $$1+1; }' > AtFS/.prereltmp; \ mv AtFS/.prereltmp $(PRERELSEQ);\ chmod 664 $(PRERELSEQ) _resetpl: @rm -f $(PATCHLEVEL) 2> /dev/null; \ echo 0 > $(PATCHLEVEL); \ chmod 664 $(PATCHLEVEL) _incpl: @awk < $(PATCHLEVEL) '{ print $$1+1; }' > AtFS/.patchtmp; \ mv AtFS/.patchtmp $(PATCHLEVEL);\ chmod 664 $(PATCHLEVEL) $(PRERELSEQ): @-if [ ! -f $(PRERELSEQ) ]; \ then \ echo 0 > $(PRERELSEQ); \ chmod 664 $(PRERELSEQ); \ fi shapetools-1.4pl6.orig/src/rms/stdrules100444 2013 145 6500 5412611115 16315 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # shape_CM environment -- stdrules # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: stdrules[6.0] Fri Jun 25 17:01:30 1993 andy@cs.tu-berlin.de frozen $ # # Standard version selection rules to be activated by setting the # "VERSIONS" macro in the Shapefile. # most_recent:- *.c, attr(state,busy), msg(Using busy version of $_af_unixname$.); *.c, attrmax(version), msg(Using $_af_bound$.); *, attr(state,busy); *, attrmax(version). last_proposed:- *.c, attr(state,proposed), attrmax(version), msg(Using last proposed version of $_af_unixname$.); *, attr(state,proposed), attrmax(version); $(LOCALINCLUDEPATH)/*.h, attr(state, busy); $(LOCALLIBPATH)/*.a, attr(state, busy). last_released:- *, attr(__SymbolicName__, $(LASTNODERELEASE)), msg(Using $_af_unixname$ from release $(LASTNODERELEASE)); $(LOCALINCLUDEPATH)/*.h, attr(state, busy), msg(Using Unix include file $_af_unixname$); $(LOCALLIBPATH)/*.a, attr(state, busy), msg(Using Unix archive file $_af_unixname$). last_prereleased:- *, attr(__SymbolicName__, $(LASTNODEPRERELEASE)), msg(Using $_af_unixname$ from release $(LASTNODEPRERELEASE)); $(LOCALINCLUDEPATH)/*.h, attr(state, busy), msg(Using Unix include file $_af_unixname$); $(LOCALLIBPATH)/*.a, attr(state, busy), msg(Using Unix archive file $_af_unixname$). recent_release:- *.c, attr(__SymbolicName__, $(LASTRELEASE)), msg(Using $_af_unixname$ from release $(LASTRELEASE)); *, attr(__SymbolicName__, $(LASTRELEASE)); $(LOCALINCLUDEPATH)/*.h, attr(state, busy); $(LOCALLIBPATH)/*.a, attr(state, busy). from_release:- *.c, attr(__SymbolicName__, $(RELEASENAME)), msg(Using $_af_unixname$ from release $(RELEASENAME)); *, attr(__SymbolicName__, $(RELEASENAME)); $(LOCALINCLUDEPATH)/*.h, attr(state, busy); $(LOCALLIBPATH)/*.a*, attr(state, busy); /home/stone/shape/lib/*.a*, attr(state, busy). extern:- *, attr(state, busy), msg(Using regular file for $_af_unixname$). unit_test:- *, attr (state, busy), msg(Using busy version for $_af_unixname$); *, attrge (state, published), attrmax (version), msg(Using published version of $_af_unixname$); *, attrmax (version), msg(Using most recently saved version of $_af_unixname$). integration_test:- *, attrgt (state, saved), attrmax (version), attr (state, published), msg(Using approved version of $_af_unixname$); *, attr (state, proposed), attr (test_switch, on), msg(Using test candidate version of $_af_unixname$); *, attrge (state, published), attrmax (version), msg(Using baseline version of $_af_unixname$); *, msg (Cannot bind $_af_unixname$ -- something's wrong here!), -. shapetools-1.4pl6.orig/src/rms/stdtargets100444 2013 145 15327 5412611104 16661 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # shape_CM environment -- stdtargets # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: stdtargets[6.0] Fri Jun 25 17:01:31 1993 andy@cs.tu-berlin.de frozen $ # rms: help info: help help: @echo shapeTools Release Managemet System; \ echo Usage: ; \ echo " shape [all] [VERSIONS=] [variants] [macro settings]"; \ echo " make [all] []"; \ echo " shape clean"; \ echo " make clean"; \ echo " shape cleancache"; \ echo " shape depend [VERSIONS=] [variants]"; \ echo " shape extractrelease [RELEASENAME=] [(PARTIAL)RELEASEBASE=]"; \ echo " shape install [VERSIONS=] [INSTALLBASE=] [variants] [macros]"; \ echo " make install [INSTALLBASE=] []"; \ echo " shape patch OLDRELEASE= NEWRELEASE= [PATCHFILE=]"; \ echo " shape plprerelease"; \ echo " shape plrelease"; \ echo " shape prerelease"; \ echo " shape release"; \ echo " shape shar [VERSIONS=] [ARCHIVE=]"; \ echo " shape tar [VERSIONS=] [ARCHIVE=]"; \ cleancache: cclean cclean: @echo "Cleaning derived object cache"; \ atfsrepair -C -q lint: $(VERSIONS) +$(HOSTSYSTEM) $(SOURCES) $(HEADERS) $(VERSIONFILE) @echo "Linting..."; \ lint $(CFLAGS) $(SOURCES) $(VERSIONFILE) $(LINTLIBS) lintlibrary: $(VERSIONS) +$(HOSTSYSTEM) $(SOURCES) $(HEADERS) $(VERSIONFILE) @echo "Making lint library."; \ lint -C$(NODENAME) $(CFLAGS) $(SOURCES) $(VERSIONFILE) depend: $(VERSIONS) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY)\ $(SOURCES) $(VERSIONFILE) $(AUXSOURCES) $(HEADERS) $(AUXHEADERS) @-echo "Generating Dependencies file."; \ if [ "$(HOSTSYSTEM)" ]; \ then \ _hostsystem=$(HOSTSYSTEM); \ else \ _hostsystem=_xXxXxX_; \ fi; \ if [ "$(BASE)" ]; \ then \ _basepath=$(BASE); \ else \ _basepath=_xXxXxX_; \ fi; \ cc $(CFLAGS) -M $(SOURCES) $(VERSIONFILE) $(AUXSOURCES) \ | grep -v "/usr/include" \ | sort | uniq | \ sed -e "s:$$_basepath:$$(BASE):" -e "s:$$_hostsystem:$$(HOSTSYSTEM):" \ > Dependencies ARCHIVE=$(NODENAME) tar: $(VERSIONS) $(COMPONENTS) $(VERSIONFILE) @-if [ -z "$(ARCHIVE)" ]; \ then \ echo "Empty output filename."; exit 1; \ fi; \ if [ "$(ARCHIVE)" = "-" ]; \ then \ tar cf - $(COMPONENTS) $(VERSIONFILE); \ else \ echo "Making tar archive $(ARCHIVE).tar." ; \ tar cf $(ARCHIVE).tar $(COMPONENTS) $(VERSIONFILE); \ fi shar: $(VERSIONS) $(COMPONENTS) $(VERSIONFILE) @-if [ -z "$(ARCHIVE)" ]; \ then \ echo "Empty output filename."; exit 1; \ fi; \ if [ "$(ARCHIVE)" = "-" ]; \ then \ shar $(COMPONENTS) $(VERSIONFILE); \ else \ echo "Making shell archive $(ARCHIVE).shar."; \ shar $(COMPONENTS) $(VERSIONFILE) > $(ARCHIVE).shar; \ fi VDIFF=vdiff DEFAULT_PFILE=$(OLDRELEASE)+2+$(NEWRELEASE) patch: _start_patch _patchsub _patchere _done_patch _start_patch: @_subsystems="$(SUBSYSTEMS)"; \ if [ -z "$(OLDRELEASE)" -o -z "$(NEWRELEASE)" ]; \ then \ echo Usage: shape patch OLDRELEASE='' NEWRELEASE='' '[PATCHFILE=]'; \ exit 1; \ fi; \ echo Generating patch to update $(OLDRELEASE) to $(NEWRELEASE).; \ if [ -z "$(PATCHFILE)" ]; \ then \ pfname=`pwd`/$(DEFAULT_PFILE).pat; \ else \ pfname=$(PATCHFILE); \ fi; \ echo The patchfile will be $$pfname .; \ rm -f $$pfname; \ exit 0 _done_patch: @echo Patchgeneration done.; echo _patchsub: @_subsystems="$(SUBSYSTEMS)"; \ if [ -n "$(SUBSYSTEMS)" ]; \ then \ echo ...visiting subsystems: $(SUBSYSTEMS); \ else \ exit 0; \ fi; \ exitcode=0; \ if [ -z "$(PATCHFILE)" ]; \ then \ pfname=`pwd`/$(DEFAULT_PFILE).pat; \ else \ pfname=$(PATCHFILE); \ fi; \ for i in $$_subsystems; \ do \ (cd $$i; $(MAKE) OLDRELEASE=$(OLDRELEASE) NEWRELEASE=$(NEWRELEASE) \ PATCHFILE=$$pfname CH_FILES=$$ch_files _patchsub _patchere); \ if [ $$? -ne 0 ]; then exitcode=1; fi; \ done; \ exit $$exitcode _patchere: @_components="$(COMPONENTS)"; \ if [ -n "$(COMPONENTS)" ]; \ then \ echo ...comparing $(NODEPATH) components.; \ else \ exit 0; \ fi; \ if [ -z "$(PATCHFILE)" ]; \ then \ pfname=`pwd`/$(DEFAULT_PFILE).pat; \ else \ pfname=$(PATCHFILE); \ fi; \ if [ -n "$(NODEPATH)" ]; \ then \ path_prefix=$(NODEPATH)/; \ else \ path_prefix=; \ fi; \ for i in $$_components; \ do \ $(VDIFF) -P -c -base $(NODEPATH) $$i[$(OLDRELEASE)] \ $$i[$(NEWRELEASE)] >> $$pfname; \ done unit_test: unit_test +test $(TARGET) $(TESTFILES) $(TESTDRIVER) @-if ./$(TESTDRIVER); \ then \ echo `date`: $(TARGET) passed the regression test suite; \ else \ echo `date`: $(TARGET) failed the testsuite.; \ fi integration_test: @-testmods=`vl -last -attr af_state=proposed $(SOURCES)`; \ rm -f protocol 2>&1 > /dev/null; \ echo PROTOCOL for integration test of $(TARGET). > protocol; \ echo `date` >> protocol; \ (echo; echo) >> protocol; \ if [ -n "$${testmods}" ]; \ then \ echo Modules proposed for approval: $$testmods >> protocol; \ else \ echo `date`: No modules proposed for testing >> protocol; \ exit 0; \ fi; \ for i in $$testmods; \ do \ vadm -setuda test_switch=on $$i 2>&1 > /dev/null; \ echo `date`: beginning test of $$i. >> protocol; \ echo `date`: beginning test of $$i.; \ shape -V test i_test TESTMOD=$$i TPROT=protocol; \ echo >> protocol; \ done; \ echo `date`: Integration test for $(TARGET) completed. >> protocol i_test: _run_i_test @echo `date`: $(TESTMOD) passed the integration test suite >> $(TPROT); @publ $(TESTMOD) 2>&1 > /dev/null; @echo `date`: $(TESTMOD) was approved for publication. >> $(TPROT) _build_i_test: integration_test $(TARGET) @vadm -unsetuda test_switch $(TESTMOD) 2>&1 > /dev/null _run_i_test: _build_i_test $(TESTFILES) $(TESTDRIVER) if ./$(TESTDRIVER); \ then : ; \ else \ echo `date`: $(TESTMOD) failed the integration test. >> $(TPROT); \ vadm -setuda test_status=fail $(TESTMOD) 2>&1 > /dev/null; \ vadm -unpromte $(TESTMOD) 2>&1 > /dev/null; \ echo `date`: $(TESTMOD) not approved for publication. >> $(TPROT); \ fi shapetools-1.4pl6.orig/src/rms/stdvar100444 2013 145 6146 5426223605 15771 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # shape_CM environment -- standard variants # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: stdvar[6.0] Fri Jul 30 16:39:56 1993 andy@cs.tu-berlin.de frozen $ # # # vclass system # vclass system ::= (s_aix, s_hpux, s_irix, s_mach, s_sunos_4, s_svr_4, s_ultrix) s_aix:+ VARCFLAGS = -Ds_aix SYSLIBS = -lPW HOSTSYSTEM = s_aix s_hpux:+ VARCFLAGS = -Ds_hpux SYSLIBS = -lPW HOSTSYSTEM = s_hpux s_irix:+ VARCFLAGS = -Ds_irix SYSLIBS = -lsun HOSTSYSTEM = s_irix s_mach:+ VARCFLAGS = -Ds_mach HOSTSYSTEM = s_mach s_sunos_4:+ VARCFLAGS = -Ds_sunos_4 HOSTSYSTEM = s_sunos_4 s_svr_4:+ VARCFLAGS = -Ds_svr_4 SYSLIBS = -lnsl -lgen HOSTSYSTEM = s_svr_4 s_ultrix:+ VARCFLAGS = -Ds_ultrix HOSTSYSTEM = s_ultrix # # vclass compiler # vclass compiler ::= (pcc, gnu, gnu_ansi) pcc:+ CC=cc COMPILER=pcc gnu:+ CC=gcc -W COMPILER=gnu gnu_ansi:+ CC=gcc -ansi -Wall COMPILER=gnu_ansi gnu_posix:+ CC=gcc -ansi -Wall -D_POSIX_SOURCE COMPILER=gnu_posix # # vclass quality # vclass quality ::= (debug, debug_static, profiling, \ profiling_static, optimize, maxoptimize) debug:+ VARCFLAGS=-g VARLDFLAGS=-g MAKECFLAGS= MAKELDFLAGS= QUALITY=debug debug_static:+ VARCFLAGS=-g -Bstatic VARLDFLAGS=-g -Bstatic MAKECFLAGS= MAKELDFLAGS= QUALITY=debug_static profiling:+ VARCFLAGS=-pg -g VARLDFLAGS=-pg -g MAKECFLAGS= MAKELDFLAGS= QUALITY=profiling profiling_static:+ VARCFLAGS=-pg -g -Bstatic VARLDFLAGS=-pg -g -Bstatic MAKECFLAGS= MAKELDFLAGS= QUALITY=profiling_static optimize:+ VARCFLAGS=-O VARLDFLAGS=-s MAKECFLAGS= MAKELDFLAGS= QUALITY=optimize maxoptimize:+ VARCFLAGS=-O -fcombine-regs -fstrength-reduce VARLDFLAGS=-s MAKECFLAGS= MAKELDFLAGS= QUALITY=maxoptimize # # memory checks # vclass memory_checks ::= (electric_fence, malloc_debug) electric_fence:+ SYSLIBS = /usr/local/lib/electric_fence.o malloc_debug:+ INCLUDES = -I$(LOCALINCLUDEPATH) -I/usr/local/debug_include VARCFLAGS = -DDEBUG_MALLOC LOCALLIBS = $(LOCALLIBPATH)/libAtFStk_malloc_debug.a $(LOCALLIBPATH)/libAtFS_malloc_debug.a $(LOCALLIBPATH)/libsttk_malloc_debug.a SYSLIBS = /usr/local/lib/libdbmalloc.a # # local variants # andy_localtest:+ LOCALBASE = /home/stone/andy INCLUDES = -I$(LOCALBASE)/atfstk -I$(LOCALBASE)/atfs1/src -I$(LOCALBASE)/shape/sttk -I$(BASE)/include LOCALLIBS = $(LOCALBASE)/atfstk/libAtFStk.a $(LOCALBASE)/shape/sttk/libsttk.a $(LOCALBASE)/atfs1/src/libAtFS.a VARCFLAGS= -D$(HOSTSYSTEM) shapetools-1.4pl6.orig/src/rms/user_at100555 2013 145 1662 5412611034 16121 0ustar dokoswt#!/bin/sh # ## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # # $Header: user_at[6.0] Fri Jun 25 17:01:34 1993 andy@cs.tu-berlin.de frozen $ # if [ -f /bin/domainname ]; then domain=`/bin/domainname | sed -e 's/^\.//' | sed -e 's/^+//'` else domain=`hostname` fi echo $USER@$domain shapetools-1.4pl6.orig/src/rms/cptree100555 2013 145 2510 5412611003 15726 0ustar dokoswt#!/bin/sh # ## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # # $Header: cptree[6.0] Fri Jun 25 17:01:35 1993 andy@cs.tu-berlin.de frozen $ # if [ $# -ne 2 ]; then echo Usage: $0 '' ''; exit 1; fi; srcdir=$1; targetdir=$2; if [ ! -d $srcdir ] || [ ! -r $srcdir ] || [ ! -x $srcdir ]; then echo Can\'t access $srcdir; exit 1; fi; if [ ! -d $targetdir ] && [ ! -f $targetdir ]; then echo creating directory $targetdir; mkdir $targetdir; fi; dirs=`find $srcdir -type d -print | sed -e "s/$srcdir/$targetdir/" | \ tr '\012' ' '`; for i in $dirs; do if [ ! -d $i ] && [ ! -f $i ]; then echo creating directory $i; mkdir $i; fi; done; exit 0; shapetools-1.4pl6.orig/src/rms/gen_rel_id100555 2013 145 4245 5516563273 16566 0ustar dokoswt#!/bin/sh # ## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: gen_rel_id[6.2] Thu Jan 20 12:41:16 1994 andy@cs.tu-berlin.de frozen $ # # $__xpoff$ # if [ "$1" = "-p" ] then patch=1 shift fi ty=$1 sn=$2 vf=$3 pf=$4 pl=$5 pls="pl" if [ $# -ne 5 ]; then echo usage: gen_rel_id [-p] type systemname versionfile prerelfile patchlevelfile 1>&2; exit 1; fi if [ $patch ] then if [ ! -r $pl ] then # echo "Warning: can't read $pl. Assuming patchlevel 0." 1>&2 plev=0 else plev=`cat $pl 2> /dev/null` fi fi pseq=`cat $pf 2> /dev/null` if [ -n "$pseq" ] then : else pseq=0 fi vnum=`vl -format '$__version$' -lastsaved $vf 2> /dev/null` if [ -n "$vnum" ] then : else vnum="1.-1" fi case $ty in release) if [ $patch ] then rid=$sn-${vnum}${pls}$plev else rid=$sn-$vnum fi;; prerelease) if vl -attr norelease -lastsaved $vf > /dev/null 2>&1 then nvnum=1.0; else nvnum=`echo $vnum | awk -F. '{ print $1 "." $2+1; }'` fi if [ $patch ] then nplnum=`expr $plev + 1` rid=$sn-${vnum}${pls}${nplnum}pre$pseq else rid=$sn-${nvnum}pre$pseq fi;; lastrelease) ovnum=`echo $vnum | awk -F. '{ print $1 "." $2-1; }'` rid=$sn-$ovnum ;; lastprerelease) if [ $patch ] then rid=$sn-${vnum}${pls}${plev}pre$pseq else rid=$sn-${vnum}pre$pseq fi ;; *) echo invalid release type \"$ty\" >&2 exit 1 ;; esac echo $rid exit 0 shapetools-1.4pl6.orig/src/rms/mkpdir100555 2013 145 2726 5416020733 15753 0ustar dokoswt#!/bin/sh # ## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) # # $Header: mkpdir[6.0] Fri Jul 9 19:53:21 1993 andy@cs.tu-berlin.de frozen $ notdir='File exists' progname=`basename $0` if [ $# -lt 1 ] then echo usage: $progname [-m mode] directory 1>&2 exit 2 fi argc=$# while [ $argc -gt 0 ] do argstr=$1 shift argc=`expr $argc - 1` case $argstr in -m) if [ $argc -gt 0 ] then mode=$1 shift argc=`expr $argc - 1` else echo usage: $progname -m requires a mode argument. 1>&2 exit 1 fi;; *) for i in `echo $argstr | sed 's|\(.\)/|\1 |g'` do if [ -f $i ] then echo $progname: $notdir 1>&2 exit 1 elif [ ! -d $i ] then mkdir $i || exit 3 fi if [ "$mode" ] then chmod $mode $i 2> /dev/null fi cd $i done esac done shapetools-1.4pl6.orig/src/rms/Release100444 2013 145 112 5522264104 16005 0ustar dokoswt$__subsystemname$-1.15 (Mon Jan 31 15:45:23 1994 by andy@cs.tu-berlin.de) shapetools-1.4pl6.orig/src/rms/Shapefile100444 2013 145 6245 5412610444 16362 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for shape_RMS (release management system) # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[6.0] Fri Jun 25 17:01:55 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug_static # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds _all: all $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. # .BPOOL: $(OBJECTS) .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/rms/Makefile100444 2013 145 30140 5522262763 16217 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for shape_RMS (release management system) # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[6.1] Fri Jan 28 20:31:43 1994 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's development area. BASE = /home/stone/shape/development # Path of a subsystem relative to the root of the system hierarchy # (e.g. vc/save) NODEPATH = src/rms # A short name for the (sub)system (used for building the release ID) NODENAME = shape_RMS # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DSTATISTICS) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = /home/stone/shape INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib INSTALLSHAPELIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 444 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like TARGET1 TARGET2 or any better names). In this case you # have to adjust the system building actions accordingly. TARGET1 = sfind TARGET2 = lastrelease # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = Release # source VERSIONOBJECT = # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = # The regular source and header files. SOURCE1 = sfind.sh SOURCE2 = lastrelease.sh SOURCES = $(SOURCE1) $(SOURCE2) HEADERS = Makefile.tmpl Shapefile.tmpl Release.tmpl release.c.tmpl \ stdconf stdrules stdtargets stdvar \ user_at cptree gen_rel_id mkpdir # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Interface header files. These are the header files to be installed # together with eg. a library. $(IFHEADERS) usually is a subset of # $(HEADERS). IFHEADERS = $(HEADERS) # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = shape_RMS.1 shape_build.1 shape_depend.1 shape_patch.1 \ shape_releas.1 shape_tar.1 sfind.1 MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = shape_stdrul.7 shape_stdvar.7 shape_tmpl.7 MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are autamatically produced during # a build process should be listed here. OBJECTS = $(VERSIONOBJECT) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(TARGET1) $(TARGET2) $(TARGET1): $(SOURCE1) @rm -f $(TARGET1); \ if [ $(HOSTSYSTEM) = s_ultrix ]; \ then \ echo '#!/bin/sh5' > $(TARGET1); \ else \ echo '#!/bin/sh' > $(TARGET1); \ fi cat $(SOURCE1) >> $(TARGET1); @chmod +x $(TARGET1) $(TARGET2): $(SOURCE2) @rm -f $(TARGET2); \ if [ $(HOSTSYSTEM) = s_ultrix ]; \ then \ echo '#!/bin/sh5' > $(TARGET2); \ else \ echo '#!/bin/sh' > $(TARGET2); \ fi cat $(SOURCE2) >> $(TARGET2); @chmod +x $(TARGET2) installtargets: installincludes $(INSTALLBINPATH)/$(TARGET1) $(INSTALLBINPATH)/$(TARGET2) $(INSTALLBINPATH)/$(TARGET1): $(TARGET1) @echo "Installing $(TARGET1) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET1) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET1) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET1); \ fi; \ cp $(TARGET1) $(INSTALLBINPATH)/$(TARGET1); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET1); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET1) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET1) $(INSTALLBINPATH)/$$i; \ done $(INSTALLBINPATH)/$(TARGET2): $(TARGET2) @echo "Installing $(TARGET2) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET2) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET2) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET2); \ fi; \ cp $(TARGET2) $(INSTALLBINPATH)/$(TARGET2); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET2); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET2) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET2) $(INSTALLBINPATH)/$$i; \ done installmanuals: $(MANUALS) @-_manuals="$(MAN1)"; \ for i in $$_manuals; \ do \ echo "Installing $$i in $(INSTALLMANPATH)/man1"; \ if [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done; \ _manuals="$(MAN7)"; \ for i in $$_manuals; \ do \ echo "Installing $$i in $(INSTALLMANPATH)/man7"; \ if [ ! -w $(INSTALLMANPATH)/man7/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man7/$$i; \ fi; \ cp $$i $(INSTALLMANPATH)/man7/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man7/$$i; \ done installincludes: $(IFHEADERS) @-_components="$(IFHEADERS)"; \ for i in $$_components; \ do \ echo "Installing $$i in $(INSTALLSHAPELIBPATH)"; \ if [ -f $(INSTALLSHAPELIBPATH)/$$i ] && \ [ ! -w $(INSTALLSHAPELIBPATH)/$$i ]; \ then \ chmod u+w $(INSTALLSHAPELIBPATH)/$$i 2> /dev/null; \ fi; \ if [ -f $(INSTALLSHAPELIBPATH)/$$i ] && \ [ ! -w $(INSTALLSHAPELIBPATH)/$$i ]; \ then \ rm -f $(INSTALLSHAPELIBPATH)/$$i; \ fi; \ cp $$i $(INSTALLSHAPELIBPATH)/$$i; \ if [ $$i = "user_at" ] || [ $$i = "cptree" ] || \ [ $$i = "gen_rel_id" ] || [ $$i = "mkpdir" ]; \ then \ chmod $(INSTALLBINMODE) $(INSTALLSHAPELIBPATH)/$$i; \ else \ chmod $(INSTALLLIBMODE) $(INSTALLSHAPELIBPATH)/$$i; \ fi; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET1) $(TARGET2) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ VERSIONBINDING=$(VERSIONBINDING) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ ALLTARGETS= \ MAINTARGET= \ SHAPELIBPATH=$(SHAPELIBPATH) $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) localinstall: +localinstall $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ VERSIONBINDING=$(VERSIONBINDING) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ VERSIONBINDING=$(VERSIONBINDING) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ SHELL="$(SHELL)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ VERSIONBINDING=$(VERSIONBINDING) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) clean; \ fi shapetools-1.4pl6.orig/src/rms/Dependencies100444 2013 145 22 5412610400 16763 0ustar dokoswt# no dependencies shapetools-1.4pl6.orig/src/interface/ 40755 2013 145 0 5626416545 15611 5ustar dokoswtshapetools-1.4pl6.orig/src/interface/callp-err.el100444 2013 145 6104 5412607262 20077 0ustar dokoswt;;; Name: callp-err.el ;;; Author: Juergen Nickelsen ;;; Version: 3.0 ;;; State: frozen ;;; Last modification: Fri Jun 25 16:41:54 1993 by andy@cs.tu-berlin.de (defvar callp-err-copyright " Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. " "Copyright notice for this file.") (provide 'callp-err) (defun call-process-with-error (command buffer &optional noerror) "Call the shell-command in COMMAND in a separate process. Insert output in BUFFER before point; t means current buffer; nil for BUFFER means discard it. BUFFER may be a buffer name. Optional third arg NOERROR non-nil means don't raise an error but silently return nil. This function waits for COMMAND to terminate; if you quit, the process is killed. On succesful termination of COMMAND t is returned. If the command returns a non-zero exit status and NOERROR is not given or nil, the command output is displayed in a separate window and an error is raised. The implementation is a weird hack since the exit status of the inferior process is tested by a shell, which inserts a message into a buffer. Commands containing an exit statement for the shell are not properly handled. Based on code from levin@eos.ncsu.edu (Dr. Hal Levin)." (let* ((old-buffer (current-buffer)) (process-error-string "\nProcess terminated with error") (bourne-shell "/bin/sh") (process-ok-string "OK") (bufname "*Process Error*") (error-buffer (get-buffer-create bufname))) (set-buffer error-buffer) (erase-buffer) (call-process bourne-shell nil error-buffer nil "-c" (concat command ";if test $? != 0\nthen\necho '" process-error-string "'\nelse\necho " process-ok-string "\nfi")) (if (string-match (concat process-error-string "\n$") (buffer-string)) (if noerror nil (progn (goto-char (point-max)) (pop-to-buffer error-buffer) (other-window 1) (error (substitute-command-keys "Type \\[delete-other-windows] to remove error window")))) (if buffer (progn (delete-region (1+ (string-match (concat process-ok-string "\n$") (buffer-string))) (point-max)) (let ((contents (buffer-string)) (target-buffer (cond ((eq buffer t) old-buffer) ((stringp buffer) (generate-new-buffer buffer)) (t buffer)))) (set-buffer target-buffer) (insert contents)))) (set-buffer old-buffer) (kill-buffer error-buffer) t))) shapetools-1.4pl6.orig/src/interface/find-atfs.el100444 2013 145 101754 5521251703 20134 0ustar dokoswt;;; find-atfs.el -- find-file interface to AtFS ;;; Author: Juergen Nickelsen ;;; $Header: find-atfs.el[3.2] Tue Jan 25 18:30:34 1994 andy@cs.tu-berlin.de frozen $ ;;; ;;; See the variable atfs-copyright for a copyright notice below. ;;; ;;; Provides: ;;; - AtFS versions can be read directly into an Emacs buffer by ;;; invoking find-file with the version ID (with version number ;;; or symbolic name). ;;; - Filename completion is done on version IDs as well. ;;; - If find-file tries to read a non-existent file, and an AtFS ;;; history of that file exists, the default version of this history ;;; will be read instead. ;;; - minor mode atfs-mode (without any features yet, but its name ;;; appears in the mode line) ;;; - toggle-read-only on a version checks a version out and a busy ;;; file in with asking for change intent resp. log message. ;;; - toggle-read-only on a file asks if the file shall be checked ;;; in as AtFS version. ;;; - If Emacs is running as TkEmacs, appropriate notifications ;;; are sent to the Message Broadcast Server on checkin/checkout. ;;; (Not yet functional) ;;; To install it: ;;; Put the file find-atfs.el into a directory of your Emacs ;;; load-path. ;;; Put the following line in your ~/.emacs file or in Emacs' ;;; systemwide default.el: ;;; (load "find-atfs") ;;; Requirements: ;;; - Emacs 18.58, a later Emacs 18 version, or Lucid Emacs 19 ;;; for the new call-process function, which returns ;;; a meaningful value ;;; - the shapeTools programs (vl, vcat) in $PATH, or appropriate ;;; settings of the user-customizable variables (see below) ;;; BUGS: ;;; - due to a bug in vbind(1) it is not possible to read AtFS versions ;;; where the filename (sans version) contains a pair of matching ;;; brackets with at least one character between them. ;;; - depends strongly on some internals of find-file-noselect, which ;;; may change in future Emacs versions ;;; - completion on version IDs is slow ;;; - environment variables in filenames are not expanded ;;; - some still unknown ;;; Redefined functions: ;;; - file-writable-p ;;; - file-exists-p ;;; - toggle-read-only ;;; - find-file (require 'callp-err) (provide 'find-atfs) (defconst atfs-copyright " Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. ") (defconst atfs-AtFS-version "$Header: find-atfs.el[3.2] Tue Jan 25 18:30:34 1994 andy@cs.tu-berlin.de frozen $") ;;; user options (defvar atfs-kill-version-buffer-on-checkout t "*If non-nil, kill the buffer of a version when it is checked out. Otherwise put it at the end of the buffer list.") (defvar atfs-find-file-always-complete nil "*If non-nil, always do completion on version IDs in find-file. Otherwise completion is done only with prefix argument.") (defvar atfs-completion-show-versions nil "*If non-nil, all versions are shown when doing completion.") (defvar atfs-keep-position-on-checkout t "*If non-nil, try to keep point at the same position on check in/out. This will not always succeed.") (defvar atfs-offer-symname-completions nil "*If non-nil, offer completion of symbolic names of versions as well. Not yet implemented.") (defvar atfs-offer-selrule-completions nil "*If non-nil, offer completion of version selection rules as well. Not yet implemented.") (defvar atfs-default-vbind-rules "" "*String containing default version binding rules. These rules are considered by atfs-readin-version which is called by find-file. Not yet implemented, implicit default rule is most_recent.") ;;; key bindings (defvar atfs-install-key-bindings t "If non-nil, key bindings are installed when loading find-atfs. If this is set to nil before loading find-atfs, key bindings are not installed. It is set to nil after installing the key bindings. To re-install the key bindings, set it to t and re-load find-atfs. Note: There are no special key bindings of find-atfs yet.") (if atfs-install-key-bindings (progn ;; no special key bindings yet (setq atfs-install-key-bindings nil))) ;;; user-customizable variables (defvar atfs-vcat-command "vcat" "Name (possibly pathname) with which vcat(1) can be invoked.") (defvar atfs-vcat-options '("-q") "Options to give to vcat for reading the contents of a version.") (defvar atfs-vl-command "vl" "Name (possibly pathname) with which vl(1) can be invoked.") (defvar atfs-vl-completion-options '("-A" "-fast") "List of options given to vl when doing completions.") (defvar atfs-vlog-command "vlog" "Name (possibly pathname) with which vlog(1) can be invoked.") (defvar atfs-intent-format "vl -lastsaved -format '$____Intent__$\\n' %s > %s" "Format string for the command to retrieve the change intent.") (defvar atfs-retrv-command "retrv" "Name (possibly pathname) with which retrv(1) can be invoked.") (defvar atfs-retrv-format "%s -f -lock -intent @%s %s" "Format string for retrv(1) command. Arguments: atfs-retrv-command, file with change intent, version id.") (defvar atfs-save-command "save" "Name (possibly pathname) with which save(1) can be invoked.") (defvar atfs-save-format "%s -f -logmsg @%s %s %s" "Format string for save(1) command. Arguments: atfs-save-command, file with log message, atfs-save-setvnum-option with argument (if setvnum desired), filename.") (defvar atfs-save-setvnum-option "-setvnum %s" "Option format for save with setting of version number.") (defvar atfs-vbind-command "vbind" "Name (possibly pathname) with which vbind(1) can be invoked.") (defvar atfs-bourne-shell-command "/bin/sh" "Name (possibly pathname) with which sh(1) can be invoked.") ;;; variables (defvar atfs-restore-position-fallback 200 "Number of characters to go backward or forward if context can't be found.") (defvar atfs-save-position-context 200 "Number of characters to store as context when saving a position.") (defvar atfs-buffer-version-id nil "If non-nil, file in this buffer is an AtFS version with this version ID.") (make-variable-buffer-local 'atfs-buffer-version-id) (defvar atfs-temp-buffer " *atfs-temp*" "Name of temporary buffer for command output.") (defconst atfs-version-match-re "^\\([^[]+\\)\\(\\[[^]]+\\]\\)$" "Regexp matching an AtFS version ID. First group matches the filename part, second group the version part. We assume that \"[\" and \"]\" do not appear in the filename part.") (defconst atfs-canonical-version-match-re "^\\([^[]+\\)\\(\\[[0-9]+\\.[0-9]+\\]\\)$" "Regexp matching the canonical form of an AtFS version ID. First group matches the filename part, second group the version part.") (defconst atfs-function-prefix "atfs-" "Prefix for functions used for redefining Emacs functions.") (defconst atfs-original-function-prefix "atfs-original-" "Prefix for the name of redefined functions. The redefined functions are reachable under the original name prefixed with this string.") (defconst atfs-mbs-notification-alist '((create . "objectCreate") (delete . "objectDelete"))) (defvar atfs-mode-buffers-alist nil "Alist of buffers with AtFS versions. The car of each pair is the buffer, the cdr the name of the version in this buffer.") (defvar atfs-user-home-directory (regexp-quote (getenv "HOME")) "Home-directory of the user.") (defvar atfs-completion-cache-list nil "List of cached completions for atfs-find-file. Consists of lists: First element is the (expanded) name of the directory. Second is the list of completions. third to sixth are mtime of the directory and mtime of the AtFS directory, if it exists. Used by atfs-get-completion-alist.") (defconst atfs-data-directory "AtFS/Data" "Name of the subdirectory wgere AtFS stores its versions.") (defvar atfs-be-version-aware nil "If non-nil, several functions redefined by find-atfs look for AtFS versions. Otherwise Emacs' normal functions are invoked. Functions like atfs-find-file-not-found-hook etc. set this to t temporarily.") ;;; macro atfs-save-match-data ;; The following shamelessly stolen from ange-ftp -- I guess ;; I couldn't do it any better. The setting of case-fold-search isn't ;; needed here, so I took that out. Thanks to Andy Norman. (defmacro atfs-save-match-data (&rest body) "Execute the BODY forms, restoring the global value of the match data." (let ((original (make-symbol "match-data"))) (list 'let (list (list original '(match-data))) (list 'unwind-protect (cons 'progn body) (list 'store-match-data original))))) ;; should be indented like save-excursion etc. (put 'atfs-save-match-data 'lisp-indent-hook 0) ;;; redefine functions: ;;; - file-writable-p ;;; - file-exists-p ;;; - toggle-read-only ;;; - find-file ;;; set hooks: find-file-hooks, find-file-not-found-hooks (defun atfs-function-redefine (function-symbol) "Redefine the function of FUNCTION-SYMBOL for use with find-atfs. The original function is bound to a symbol whose name is FUNCTION-SYMBOL prefixed with atfs-original-function-prefix. The function which is bound to FUNCTION-SYMBOL afterwards has the name of this symbol prefixed with atfs-function-prefix." (let ((atfs-symbol (intern (concat atfs-function-prefix (symbol-name function-symbol)))) (atfs-original-symbol (intern (concat atfs-original-function-prefix (symbol-name function-symbol))))) (if (not (fboundp atfs-original-symbol)) (progn (fset atfs-original-symbol (symbol-function function-symbol)) (fset function-symbol atfs-symbol))))) (atfs-function-redefine 'file-writable-p) (atfs-function-redefine 'file-exists-p) (atfs-function-redefine 'toggle-read-only) (atfs-function-redefine 'find-file) (if (not (memq 'atfs-find-file-hook find-file-hooks)) (setq find-file-hooks (cons 'atfs-find-file-hook find-file-hooks))) (if (not (memq 'atfs-find-file-not-found-hook find-file-not-found-hooks)) (setq find-file-not-found-hooks (cons 'atfs-find-file-not-found-hook find-file-not-found-hooks))) ;;; the hook functions: ;;; - atfs-find-file-not-found-hook ;;; - atfs-find-file-hook (defun atfs-find-file-not-found-hook () "Try to read an AtFS version of a file which has not been found. To be placed into find-file-not-found-hooks." ;; Requested file does not exist. Perhaps we have an AtFS version. (let ((atfs-be-version-aware t) (version-id (atfs-get-version-id buffer-file-name))) (if version-id ;; Ok, we have. Perhaps it is already in a buffer other than ;; this? (let ((buffer (get-file-buffer version-id))) (if (and buffer (not (eq buffer (current-buffer)))) ;; We already have a buffer with this version, so let's ;; use that one. (progn ;; This is awful cheating! ;; It depends very much on the internals ;; of find-file-noselect. ;; Don't try this at home, kids! (setq filename version-id) (setq buf buffer) (kill-buffer (current-buffer)) (set-buffer buffer) (setq error nil) t) ;; we must read the version from the archive (if (not (equal buffer-file-name version-id)) (message (if (atfs-version-p buffer-file-name) "Using version %s" "Using last saved version %s") (file-name-nondirectory version-id))) (if (atfs-readin-version version-id) (progn ;success (setq error nil) t)))) ;; No version exists. But if the name looks like an AtFS ;; version, complain. (if (atfs-version-p buffer-file-name) (progn (kill-buffer (current-buffer)) (error "No appropriate AtFS version found")))))) (defun atfs-find-file-hook () "Hook to be executed after find-file. If the file in the current buffer is an AtFS version, invoke atfs-mode and make sure the buffer-name is something useful." (let ((id (atfs-get-buffer-version-id (current-buffer)))) (if id (atfs-save-match-data (setq atfs-buffer-version-id id) (atfs-mode 1) (let ((newname (file-name-nondirectory atfs-buffer-version-id))) (if (not (string-match (concat "^" (regexp-quote newname)) (buffer-name))) (if (not (get-buffer newname)) (rename-buffer newname) (let* ((count 2)) (while (get-buffer (format "%s<%d>" newname count)) (setq count (1+ count))) (rename-buffer (format "%s<%d>" newname count)))))))))) ;;; AtFS support functions: ;;; - atfs-get-version-id ;;; - atfs-readin-version ;;; - atfs-get-version-list ;;; - atfs-get-symnames (yet to come) ;;; - atfs-get-rulenames (yet to come) (defun atfs-get-version-list (directory &optional options pattern) "Return list of versions in DIRECTORY. Optional second argument OPTIONS is a list containing vl-options. If optional third argument PATHNAME is non-nil, full pathnames are returned. Optional fourth argument PATTERN is a pattern for the version name. If the child process terminates with a non-zero status, return nil." (let* ((optstring "") command) (while options (setq optstring (concat optstring (car options) " ")) (setq options (cdr options))) (setq command (format "cd %s ; %s %s %s" directory atfs-vl-command optstring (regexp-quote (or pattern "*")))) (atfs-command-to-list command))) (defun old-atfs-get-version-list (directory &optional options pathname pattern) "Return list of versions in DIRECTORY. Optional second argument OPTIONS is a list containing vl-options. If optional third argument PATHNAME is non-nil, full pathnames are returned. Optional fourth argument PATTERN is a pattern for the version name. If the child process terminates with a non-zero status, return nil." (let ((tmp-buffer (get-buffer-create atfs-temp-buffer)) result) (save-excursion (set-buffer tmp-buffer) (erase-buffer) (setq result (apply 'call-process atfs-vl-command nil t nil (append options (list directory)))) (if (stringp result) ;; child process has been killed by a signal (error "Signal %s killed vl %s, " result filename)) (if (zerop result) (let ((vlist (atfs-buffer-to-list))) (if pathname vlist (mapcar 'file-name-nondirectory vlist))))))) (defun atfs-get-version-id (filename &optional all-versions) "If an AtFS version of FILENAME exists, return the id of the default version as a string or just the filename, if there is only a busy version. If optional second argument ALL-VERSIONS is non-nil, a list of all matching version IDs is returned (e.g. for completion). Returns nil if no appropriate version is found. I try to compensate for a bug in vl(1) by not allowing \"[...]\" in a file or version name *before* the and, i.e. atfs-get-version-id returns nil for a name like \"foo.c[2.5].Z\"." (atfs-save-match-data (if (string-match "^.+\\[[^]]+\\].+$" filename) nil ; fake, see above (let ((tmp-buffer (get-buffer-create atfs-temp-buffer)) (path (file-name-directory filename)) result version-list) (save-excursion (set-buffer tmp-buffer) (erase-buffer) (setq result (if all-versions (call-process atfs-vbind-command nil t nil "-set" filename) (call-process atfs-vbind-command nil t nil filename))) (if (stringp result) ;; vbind has been killed by a signal (error "Signal %s killed vbind %s, " result filename)) (if (zerop result) (progn ; success (setq version-list (atfs-buffer-to-list 'reverse)) (if all-versions (mapcar (function (lambda (name) (concat path name))) version-list) (concat path (car version-list)))))))))) (defun atfs-readin-version (version-id &optional signal) "Reads VERSION from the AtFS archive into the current buffer at point. If optional argument SIGNAL is non-nil, signal a file-error if the version could not be retrieved. Point is at point-min afterwards. Sets buffer-modified-p, buffer-read-only, normal-mode, and buffer-file-name. Include buffer in atfs-mode-buffers-alist." (let ((result (apply 'call-process atfs-vcat-command nil t nil (append atfs-vcat-options (list version-id))))) (if (or (stringp result) (not (zerop result))) (if signal (signal 'file-error (list atfs-vcat-command "error: " result version-id))) (goto-char (point-min)) (set-buffer-modified-p nil) (setq buffer-read-only t) (buffer-disable-undo (current-buffer)) ;; normal-mode needs buffer-file-name without version number (setq buffer-file-name (atfs-file-name-sans-version version-id)) (normal-mode) (atfs-include-in-buffers-alist (current-buffer) version-id) (setq buffer-file-name version-id) t))) ; success ;;; minor mode atfs-mode ;;; No features yet, but its name appears in the mode line. (defvar atfs-mode nil "Pseudo minor mode for visiting AtFS files. No special features yet, just shows its name in the mode line.") (make-variable-buffer-local 'atfs-mode) (setq-default atfs-mode nil) (if (not (assq 'atfs-mode minor-mode-alist)) (setq minor-mode-alist (cons '(atfs-mode " AtFS") minor-mode-alist))) (defun atfs-mode (&optional arg) "Minor mode for visiting AtFS versions. Toggle atfs-mode, or turn it on iff optional ARG is positive. No features yet." (setq atfs-mode (if (null arg) (not atfs-mode) (> (prefix-numeric-value arg) 0)))) ;;; minor utility functions (defun atfs-command-to-list (command &optional raise-error) "Execute COMMAND and return the output as a list of strings. If COMMAND returns a non-zero exit status, return nil. If optional second argument RAISE-ERROR is non-nil, an error is raised if COMMAND returns a non-zero exit status." (let ((tmp-buffer (get-buffer-create atfs-temp-buffer)) result) (save-excursion (set-buffer tmp-buffer) (erase-buffer) (if (call-process-with-error command t (not raise-error)) (atfs-buffer-to-list))))) (defun atfs-include-in-buffers-alist (buffer version-id) "Make sure BUFFER containing VERSION-ID appears in atfs-mode-buffers-alist." (let ((pair (assq buffer atfs-mode-buffers-alist))) (if (not pair) (setq atfs-mode-buffers-alist (cons (cons buffer version-id) atfs-mode-buffers-alist))))) (defun atfs-delete-from-buffers-alist (buffer) "Delete BUFFER from atfs-mode-buffers-alist." (let ((pair (assq buffer atfs-mode-buffers-alist))) (if pair (setq atfs-mode-buffers-alist (delq pair atfs-mode-buffers-alist))))) (defun atfs-get-buffer-version-id (buffer) "Look up BUFFER's version name in atfs-mode-buffers-alist. If buffer does not contain a version, return nil." (let ((pair (assq buffer atfs-mode-buffers-alist))) (if pair (cdr pair)))) (defun atfs-buffer-to-list (&optional reverse buffer) "Return a list of all lines in the current buffer. If optional argument REVERSE is non-nil, return the reverse list. Optional second argument BUFFER means scan this buffer." (let ((llist nil) opoint) (if buffer (set-buffer buffer)) (goto-char (point-max)) (while (not (bobp)) (setq opoint (1- (point))) (forward-line -1) (setq llist (cons (buffer-substring (point) opoint) llist))) (if reverse (nreverse llist) llist))) (defun atfs-file-name-sans-version (version-id) "Return the filename part of VERSION-ID." (atfs-save-match-data (if (string-match atfs-version-match-re version-id) (substring version-id 0 (match-end 1)) version-id))) (defun atfs-version-p (filename &optional canonical) "Return non-nil if FILENAME is the name of an AtFS version. If optional second argument CANONICAL is non-nil, return non-nil only if the name is a canonical version ID." (atfs-save-match-data (string-match (if canonical atfs-canonical-version-match-re atfs-version-match-re) filename))) (defun atfs-file-writable-p (filename) ; replacement for file-writable-p "Return t if file FILENAME can be written or created by you. Note: This function has been modified to work with find-atfs-version." (if (atfs-version-p filename 'canonical) ;; this is a fake, but keeps after-find-file ;; from complaining too much. nil (atfs-original-file-writable-p filename))) (defun atfs-file-exists-p (filename) ; replacement for file-exists-p "Return t if FILENAME or AtFS version of it exists. (This does not mean you can read it.) See also file-readable-p and file-attributes." (if atfs-be-version-aware (or (atfs-original-file-exists-p filename) (file-directory-p filename) (atfs-get-version-id filename)) (atfs-original-file-exists-p filename))) (defun atfs-edit-description-file (descfile &optional message initial-contents noerase) "Edit a description file, e.g. for a \"save\" or \"retrv\" command. DESCFILE is the Name of the file. Optional second arg MESSAGE is prepended to the \"Type C-c C-c to continue\" message in the echo area. Optional third arg INITIAL-CONTENTS is a string inserted into the buffer. If optional fourth arg NOERASE is non-nil, the contents of DESCFILE is not erased before editing. The buffer visiting DESCFILE is shown in a separate window. The window configuration is restored afterwards." (save-window-excursion (let ((buffer (find-file-noselect descfile)) (intro (concat (if message (concat message " and type ") "Type ") "\\[exit-recursive-edit] to continue"))) (condition-case error-condition (progn (pop-to-buffer buffer) (if (not noerase) (erase-buffer)) ; just in case (if initial-contents (insert initial-contents)) (local-set-key "\C-c\C-c" 'exit-recursive-edit) (message (substitute-command-keys intro)) (recursive-edit) (write-file buffer-file-name) ; force writing of file (kill-buffer buffer)) (error (set-buffer-modified-p nil) (condition-case dummy (delete-file descfile) (error)) (kill-buffer buffer) (signal (car error-condition) (cdr error-condition))))))) (defun atfs-execute-save (file log-file &optional vnum) "Save FILE as AtFS version. Take the log message from LOG-FILE. Return the version-id of the save version as a string. Optional third arg VNUM is the version number to use as a string." (let ((tmp-buffer (generate-new-buffer " *atfs-save*"))) (unwind-protect (save-excursion (atfs-save-match-data (set-buffer tmp-buffer) (call-process-with-error (format atfs-save-format atfs-save-command (expand-file-name log-file) (if vnum (format atfs-save-setvnum-option vnum) "") file) t) (goto-char (point-min)) (if (re-search-forward (format "^\\(%s\\[[0-9]+\\.[0-9]+\\]\\) %s.$" (regexp-quote file) "saved") (point-max) t) (buffer-substring (match-beginning 1) (match-end 1))))) (kill-buffer tmp-buffer)))) ;;; Check in/out (defun atfs-toggle-read-only () ; replacement for toggle-read-only "Change whether this buffer is visiting its file read-only. Note: This function has been modified to work with AtFS. If the buffer contains an AtFS version, a checkout is offered. If it contains a writable file, a checkin is offered." (interactive) (if atfs-buffer-version-id (progn (if (yes-or-no-p "Check this version out with lock? ") (atfs-do-checkout atfs-buffer-version-id t t nil atfs-keep-position-on-checkout) (message "Buffer still read-only."))) (if (and (not buffer-read-only) (yes-or-no-p "Check this file in as AtFS version? ")) (atfs-do-checkin buffer-file-name t t nil atfs-keep-position-on-checkout) (atfs-original-toggle-read-only)))) (defun atfs-do-checkin (file &optional find-file save log-message keep-position) "Check FILE in as AtFS version. If optional second argument FIND-FILE is non-nil, read the default version of the file into a buffer. If optional third argument SAVE is non-nil, silently save the buffer of FILE if it is modified. Optional fourth argument LOG-MESSAGE is used as a log-message for the resulting version. If optional fifth argument KEEP-POSITION is non-nil, try to keep point at the same position (only with FIND-FILE)." (interactive (list (expand-file-name (read-file-name "Check in file: " default-directory buffer-file-name nil)) t t)) (let* ((tmp-file (concat default-directory (make-temp-name "atfs-"))) (old-buffer (get-file-buffer file)) version position) (if keep-position (setq position (atfs-save-position nil))) (if (and save old-buffer) (save-excursion (set-buffer old-buffer) (save-buffer))) (if log-message (save-excursion (let ((buffer (find-file-noselect tmp-file))) (set-buffer buffer) (erase-buffer) (insert log-message) (save-buffer 0))) ; don't make a backup (call-process-with-error (format atfs-intent-format file (expand-file-name tmp-file)) nil 'noerror) (atfs-edit-description-file tmp-file "Edit log message" nil t)) (message "Saving %s..." file) (setq version (atfs-execute-save file tmp-file)) ;; (atfs-mbs-notify version 'create) ;; (atfs-mbs-notify file 'delete) (delete-file tmp-file) (kill-buffer old-buffer) (message "Saving %s...done" file) (if find-file (progn (find-file file) (if keep-position (atfs-restore-position position nil)))))) (defun atfs-do-checkout (version &optional lock find-file intent keep-position) "Check VERSION out from the AtFS archive. If optional second argument LOCK is non-nil, ask for a change intent and check out with lock. If optional third argument FIND-FILE is non-nil, read the busy file into an Emacs buffer and switch to that buffer. Optional fourth argument INTENT is used as a change intent if the version is to be checked out with lock. If optional fifth argument KEEP-POSITION is non-nil, try to keep point at the same position (only with FIND-FILE)." (interactive (list (expand-file-name (read-file-name "Check out version: " default-directory atfs-buffer-version-id nil)) (yes-or-no-p "Check out with lock? ") t)) (let* ((tmp-file (concat default-directory (make-temp-name "atfs-"))) (filename (atfs-file-name-sans-version version)) position pos-string) (if keep-position (setq position (atfs-save-position t))) (atfs-edit-description-file tmp-file "Edit change intent" intent) (message "Retrieving %s..." version) (call-process-with-error (format atfs-retrv-format atfs-retrv-command (expand-file-name tmp-file) version) nil) ;; (atfs-mbs-notify filename 'create) (if lock (delete-file tmp-file)) (let ((vbuf (get-file-buffer version))) (if atfs-kill-version-buffer-on-checkout (kill-buffer vbuf) (bury-buffer vbuf))) (message "Retrieving %s...done" version) (if find-file (progn (find-file filename) (if keep-position (atfs-restore-position position t)))))) ;; save and restore context position (defun atfs-save-position (backwards) "Return the current position in the selected window as a list. First element is the value of point. Second element is the substring following (if BACKWARDS is non-nil) or preceding (if BACKWARDS is nil) point (number of characters is atfs-save-position-context). Third element is the difference between point and the first character in the window. This position is used to return to the same position in a file after checking in or out a version." (let* ((pos (point)) (pos-string (if backwards (buffer-substring (max (point-min) (- pos atfs-save-position-context)) pos) (buffer-substring pos (min (point-max) (+ pos atfs-save-position-context))))) (window-pos (- pos (window-start)))) (list pos pos-string window-pos))) (defun atfs-restore-position (position backwards) "Restore the saved POSITION in the selected window. If BACKWARDS is non-nil, the context is searched for backwards. For a description of POSITION, see the documentation of atfs-save-position." (goto-char (car position)) (atfs-save-match-data (if backwards (if (search-backward (car (cdr position)) nil t) (goto-char (match-end 0)) (goto-char (min (+ (point) atfs-restore-position-fallback) (point-max))) (if (search-backward (car (cdr position)) nil t) (goto-char (match-end 0)))) (if (search-forward (car (cdr position)) nil t) (goto-char (match-beginning 0)) (goto-char (max (- (point) atfs-restore-position-fallback) (point-max))) (if (search-forward (car (cdr position)) nil t) (goto-char (match-beginning 0)))))) (set-window-start (selected-window) (- (point) (car (cdr (cdr position)))))) ;;; completion on version names (defun atfs-clear-completion-cache () "Clear completion cache. For testing purposes only." (interactive) (setq atfs-completion-cache-list nil)) (defun atfs-find-file (filename) "Edit file FILENAME. Switch to a buffer visiting file FILENAME, creating one if none already exists. This function has been modified to work with atfs-mode. If atfs-find-file-always-complete is non-nil or prefix arg is given, completion is done on versions as well." (interactive (let ((atfs-be-version-aware)) (list (if (or current-prefix-arg atfs-find-file-always-complete) (atfs-read-version-id "Find Version: " default-directory) (read-file-name "Find file: " default-directory))))) (let ((atfs-be-version-aware)) (switch-to-buffer (find-file-noselect filename)))) (defun atfs-read-version-id (prompt dir) "Read version id prompting with PROMPT and completing in directory DIR." (let ((directory (atfs-massage-file-name dir))) (completing-read prompt 'atfs-read-version-id-internal nil nil directory))) (defun atfs-massage-file-name (filename) "Construct a canonical representation of FILENAME." (atfs-save-match-data (let* ((old-name (concat default-directory filename)) new-name) (catch 'ready (while t (setq new-name (cond ((string-match (concat "^" atfs-user-home-directory "/") old-name) (concat "~/"(substring old-name (match-end 0)))) ((string-match "^.*/~" old-name) (concat "~" (substring old-name (match-end 0)))) ((string-match "^.*//" old-name) (concat "/" (substring old-name (match-end 0)))) ((equal old-name "~") "~/") (t old-name))) (if (equal new-name old-name) (throw 'ready new-name) (setq old-name new-name))))))) (defun atfs-read-version-id-internal (file-name pred flag) "Internal to be called by completing-read. Do not call this." (setq file-name (atfs-massage-file-name file-name)) (let* ((dir (file-name-directory file-name)) (nondir (file-name-nondirectory file-name)) vlist) (if dir (progn (setq vlist (atfs-get-completion-alist (expand-file-name dir))) (cond ((null flag) (let ((completion (try-completion nondir vlist))) (if (stringp completion) (concat dir completion) completion))) ((eq 'lambda flag) (assoc nondir vlist)) ((eq 't flag) (all-completions nondir vlist))))))) (defun atfs-get-completion-alist (directory) "Return list of possible completions in DIRECTORY. Completions are cached in atfs-completion-cache-list. A cache entry is only valid if the mtimes of the directory and the associated AtFS data directory have not changed in between." (let* ((clist (assoc directory atfs-completion-cache-list)) (dirattrs (file-attributes directory)) (atfsattrs (file-attributes (concat directory atfs-data-directory))) (mtimes (append (elt dirattrs 6) (elt atfsattrs 6)))) (if (and clist (equal mtimes (cdr (cdr clist)))) (car (cdr clist)) (atfs-new-completion-alist directory nil mtimes)))) (defun atfs-new-completion-alist (directory cache-entry mtimes) "Return a new list of possible completions in DIRECTORY. DIRECTORY has to be expanded. If CACHE-ENTRY is non-nil, update this entry with the completions and MTIMES. Otherwise create a new entry in atfs-completion-cache-list." (message "Making completion list...") (let* ((vl-options (if atfs-completion-show-versions (atfs-vl-completion-options) (cons "-h" atfs-vl-completion-options))) (completions (if (file-directory-p (concat directory atfs-data-directory)) (mapcar (function (lambda (filename) (list (if (file-directory-p (concat directory filename)) (concat filename "/") filename)))) (atfs-get-version-list directory vl-options)) (mapcar 'list (file-name-all-completions "" directory)))) (entry (or cache-entry (progn (setq atfs-completion-cache-list (cons (cons directory nil) atfs-completion-cache-list)) (car atfs-completion-cache-list))))) (rplacd entry (cons completions mtimes)) completions)) ;;; Local Variables: ;;; eval: (put 'atfs-save-match-data 'lisp-indent-hook 0) ;;; End: ;; End of file shapetools-1.4pl6.orig/src/interface/README100444 2013 145 13744 5521253426 16604 0ustar dokoswt-*- text -*- find-atfs is a package for GNU Emacs to provide access to AtFS versions via the "find-file" function (the function usually invoked with "C-x C-f"). For a terse introduction look at the beginning of the source file find-atfs.el. The dired-like interface "shapeTools mode" included in shapeTools 1.3 is not supported in this release. Requirements find-atfs.el works with GNU Emacs version 19.22 or a later version of Emacs 19. find-atfs.el needs callp-err.el to work. The shapeTools version control commands retrv, save, vbind, vcat, vl, and vlog must be available in your command search path $PATH. Otherwise you have to change the variables atfs-*-command in find-atfs.el (near the beginning of the file). Install To use find-atfs, load the file find-atfs.el (or find-atfs.elc, if you have byte-compiled it). If you want to load find-atfs on Emacs startup, copy find-atfs.el or find-atfs.elc and callp-err.el or callp-err.elc into a directory in your Emacs load path and put the following line into your Emacs startup file $HOME/.emacs: (load "callp-err") (load "find-atfs") Visiting versions When find-atfs.el is loaded, AtFS versions can be visited in an Emacs buffer like Unix files by giving the version ID as argument to find-file. E.g. to visit version 2.6 of mumble.c in an Emacs buffer, type C-x C-f mumble.c[2.6] RET Instead of the version number 2.6 you can also use a symbolic name or a version selection rule (see vbind(1)) to select the desired version. If no busy version of mumble.c exists, you can type C-x C-f mumble.c RET and find-file will read the most recent version of mumble.c into a buffer. This buffer is write-protected and you will see the minor mode "AtFS" in the mode line. Checking out an AtFS version If you want to edit a version in an Emacs buffer, use the command toggle-read-only (C-x C-q). If you answer with "yes" to the question "Check this version out with lock?", Emacs will ask you for a change intent in a separate buffer. After typing the change intent, continue with C-c C-c. The version is then checked out with lock. The busy version is read into a buffer which you can edit as usual. If the version is already locked by someone else, you will get an appropriate error message. The buffer containing the AtFS version is killed when you check the version out as a file. If you want to keep the buffer, set the option atfs-kill-version-buffer-on-checkout to nil. (See below for setting of options.) The buffer of a version is then put to the end of the buffer list on checkout. Find-atfs tries to keep the point at the appropriate location of the file on checkout and on checkin i.e. at the same context. (This may not always succeed.) If you don't like that, set the option atfs-keep-position-on-checkout to nil. Checking in a file as AtFS version To check a busy file in as AtFS version, type C-x C-q in the file buffer. If you answer the question "Check this file in as AtFS version?" with yes, Emacs will ask you for a log message. After typing the log message, continue with C-c C-c. The file is then checked in as AtFS version. If no AtFS archive exists, save(1) will create it. File name completion To make Emacs do file name completion on version names, type C-u before invoking find-file. Be aware that file name completion on versions is slow. If you want to enable file name completion on version names permanently, set the option atfs-find-file-always-complete to t in your emacs startup file by (setq atfs-find-file-always-complete t) File name completion on histories By default, atfs file name completion shows all known names in a directory without any version specifications. Behind the name you may type the desired version number or alias name in square brackets or omit the version specification to visit the most recent version. If you want all versions to be listed in your *completion* buffer, set the option atfs-completion-show-versions to t. histories are shown in the *completion* buffer. You then have to type the desired version number yourself or omit the version number if you want to visit the most recent version. Setting options To enable an option, set its value to t. You can do that interactively by typing M-x set-variable RET RET t RET or by putting a setq statement into your $HOME/.emacs file like this: (setq t) (In either case, replace by the literal name of the option.) To disable an option, set its value to nil. Option summary atfs-kill-version-buffer-on-checkout Default value: t If non-nil, kill the buffer of a version when it is checked out. Otherwise put it at the end of the buffer list. atfs-find-file-always-complete Default value: nil If non-nil, always do completion on version IDs in find-file. Otherwise completion is done only with prefix argument. atfs-completion-show-versions Default value: nil If non-nil, all versions are shown when doing completion. atfs-keep-position-on-checkout Default value: t If non-nil, try to keep point at the same position on check in/out. This will not always succeed. There are some other option variables mentioned in find-atfs.el, but these are non-operational yet. Problems - find-atfs depends strongly on some internals of Emacs, so this version may not work with future versions of Emacs - completion on full version IDs is quite slow - environment variables in pathnames are not expanded during file name completions Redefined functions find-atfs redefines some Emacs functions to make Emacs aware of AtFS versions. These are: - file-writable-p - file-exists-p - toggle-read-only - find-file ;;; EOF shapetools-1.4pl6.orig/src/interface/Release100444 2013 145 100 5521253561 17145 0ustar dokoswtshape_IF-1.7 (Tue Aug 23 18:01:33 1994 by andy@cs.tu-berlin.de) shapetools-1.4pl6.orig/src/interface/Shapefile100444 2013 145 6206 5412607127 17522 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for interface # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[3.0] Fri Jun 25 16:42:29 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug_static # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds _all: all $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/src/interface/Makefile100444 2013 145 23602 5425776275 17375 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for interface # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[3.0] Thu Jul 29 18:37:20 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the # repository area defined above (e.g. src/vc/save). NODEPATH = src/interface # A short name for this node system NODENAME = shape_IF # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = /home/stone/shape INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib INSTALLEMACSLISPPATH = $(INSTALLBASE)/lib/emacs/lisp INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like PROGTARGET LIBTARGET or any better names). In this case you # have to adjust the system building actions accordingly. TARGET = # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = Release # source VERSIONOBJECT = # derived (if source contains program code) # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = # Aliases for (filesystem links to) $(TARGET). ALIASES = # The regular source and header files. SOURCES = callp-err.el find-atfs.el README HEADERS = # Auxiliary source and header files that are not genuine part of the # system (eg. a test environment). These will also be processed on # system building, but will *not* be included in releases. AUXSOURCES = AUXHEADERS = # Sources of variant source components stored under equal names in # different locations. During system builds, only one of each (equally # named) group is chosen. Source distributions need all of them. VARIANTSOURCES = VARIANTHEADERS = # The manuals MANUALS = $(MAN1) $(MAN3) $(MAN4) $(MAN5) $(MAN6) $(MAN7) $(MAN8) MAN1 = MAN3 = MAN4 = MAN5 = MAN6 = MAN7 = MAN8 = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # The derived files. All files, that are automatically produced during # a build process should be listed here. OBJECTS = callp-err.elc find-atfs.elc $(VERSIONOBJECT) # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = $(LOCALLIBPATH)/libafstk.a $(LOCALLIBPATH)/libafs.a LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) # The final system building action. targets: $(OBJECTS) callp-err.elc : callp-err.el PWD=`pwd` emacs -batch -f batch-byte-compile callp-err.el find-atfs.elc : find-atfs.el callp-err.elc PWD=`pwd` emacs -batch -l ./callp-err.elc -f batch-byte-compile find-atfs.el installtargets: find-atfs.el callp-err.el $(OBJECTS) @-_components="find-atfs.el callp-err.el $(OBJECTS)"; \ for i in $$_components; \ do \ echo "Installing $$i in $(INSTALLEMACSLISPPATH)"; \ if [ -f $(INSTALLEMACSLISPPATH)/$$i ] && \ [ ! -w $(INSTALLEMACSLISPPATH)/$$i ]; \ then \ chmod u+w $(INSTALLEMACSLISPPATH)/$$i 2> /dev/null; \ fi; \ if [ -f $(INSTALLEMACSLISPPATH)/$$i ] && \ [ ! -w $(INSTALLEMACSLISPPATH)/$$i ]; \ then \ rm -f $(INSTALLEMACSLISPPATH)/$$i; \ fi; \ cp $$i $(INSTALLEMACSLISPPATH)/$$i; \ chmod $(INSTALLLIBMODE) $(INSTALLEMACSLISPPATH)/$$i; \ done # Build a TAGS file from all sources tags: TAGS TAGS: $(SOURCES) etags $(SOURCES) # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) # Recursive builds. Performed *before* building $(TARGET) subsystems: @_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ VERSIONBINDING=$(VERSIONBINDING) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ ALLTARGETS= \ MAINTARGET= \ SHAPELIBPATH=$(SHAPELIBPATH) $(MAINTARGET) ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLEMACSLISPPATH=$(INSTALLEMACSLISPPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ VERSIONBINDING=$(VERSIONBINDING) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) all; \ fi +install: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLEMACSLISPPATH=$(INSTALLEMACSLISPPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ VERSIONBINDING=$(VERSIONBINDING) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLEMACSLISPPATH=$(INSTALLEMACSLISPPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ VERSIONBINDING=$(VERSIONBINDING) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) clean; \ fi shapetools-1.4pl6.orig/src/interface/Dependencies100444 2013 145 22 5040353713 20132 0ustar dokoswt# No dependencies shapetools-1.4pl6.orig/src/patches/ 40755 2013 145 0 5626416566 15303 5ustar dokoswtshapetools-1.4pl6.orig/src/patches/vgdb-patch100444 2013 145 13633 5575341643 17362 0ustar dokoswtThis is a patch for GNU gdb 4.12. Apply this patch with "patch -p0 < vgdb-patch " in the root directory of the gdb 4.12 distribution *after* you have configured the distribution. *** Makefile.orig Wed Jun 8 13:58:44 1994 --- Makefile Wed Jun 8 14:28:30 1994 *************** *** 31,36 **** --- 31,38 ---- # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ # + LDFLAGS = -L$$SHAPETOOLS/lib + srcdir = . prefix = /usr/local *** gdb/Makefile.orig Wed Jun 8 13:59:47 1994 --- gdb/Makefile Wed Jun 8 14:25:44 1994 *************** *** 101,107 **** # This is essentially the header file directory for the library # routines in libiberty. INCLUDE_DIR = $(srcdir)/../include ! INCLUDE_CFLAGS = -I$(INCLUDE_DIR) # Where is the "-liberty" library, containing getopt and obstack? LIBIBERTY = ../libiberty/libiberty.a --- 101,107 ---- # This is essentially the header file directory for the library # routines in libiberty. INCLUDE_DIR = $(srcdir)/../include ! INCLUDE_CFLAGS = -I$(INCLUDE_DIR) -I$$SHAPETOOLS/include # Where is the "-liberty" library, containing getopt and obstack? LIBIBERTY = ../libiberty/libiberty.a *************** *** 570,576 **** gdb: $(OBS) $(TSOBS) $(ADD_DEPS) $(CDEPS) init.o rm -f gdb $(CC-LD) $(INTERNAL_LDFLAGS) -o gdb \ ! init.o $(OBS) $(TSOBS) $(ADD_FILES) $(CLIBS) $(LOADLIBES) saber_gdb: $(SFILES) $(DEPFILES) copying.c version.c #setopt load_flags $(CFLAGS) $(BFD_CFLAGS) -DHOST_SYS=SUN4_SYS --- 570,577 ---- gdb: $(OBS) $(TSOBS) $(ADD_DEPS) $(CDEPS) init.o rm -f gdb $(CC-LD) $(INTERNAL_LDFLAGS) -o gdb \ ! init.o $(OBS) $(TSOBS) $(ADD_FILES) $(CLIBS) $(LOADLIBES) \ ! -lAtFStk -lAtFS -lsttk saber_gdb: $(SFILES) $(DEPFILES) copying.c version.c #setopt load_flags $(CFLAGS) $(BFD_CFLAGS) -DHOST_SYS=SUN4_SYS *** source.c.orig Thu Feb 3 17:42:16 1994 --- source.c Wed Jun 8 14:53:43 1994 *************** *** 17,22 **** --- 17,26 ---- along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include + #include + #define _memory_h + #include "defs.h" #include "symtab.h" #include "expression.h" *************** *** 38,43 **** --- 42,48 ---- #include "symfile.h" #include "objfiles.h" + /* Prototypes for local functions. */ static int *************** *** 488,495 **** if (try_cwd_first || string[0] == '/') { filename = string; ! fd = open (filename, mode, prot); if (fd >= 0 || string[0] == '/' || strchr (string, '/')) goto done; } --- 493,507 ---- if (try_cwd_first || string[0] == '/') { + Af_key *src_key; filename = string; ! src_key = atBindVersion (string, NULL); ! if (src_key && (mode == O_RDONLY)) { ! fd = fileno (af_open (src_key, "r")); ! af_dropkey (src_key); ! } ! else ! fd = open (filename, mode, prot); if (fd >= 0 || string[0] == '/' || strchr (string, '/')) goto done; } *************** *** 535,541 **** strcat (filename+len, "/"); strcat (filename, string); ! fd = open (filename, mode, prot); if (fd >= 0) break; } --- 547,561 ---- strcat (filename+len, "/"); strcat (filename, string); ! { ! Af_key *src_key = atBindVersion (filename, NULL); ! if (src_key && (mode == O_RDONLY)) { ! fd = fileno (af_open (src_key, "r")); ! af_dropkey (src_key); ! } ! else ! fd = open (filename, mode, prot); ! } if (fd >= 0) break; } *************** *** 572,578 **** /* Quick way out if we already know its full name */ if (s->fullname) { ! result = open (s->fullname, O_RDONLY); if (result >= 0) return result; /* Didn't work -- free old one, try again. */ --- 592,605 ---- /* Quick way out if we already know its full name */ if (s->fullname) { ! Af_key *src_key = atBindVersion (s->fullname, NULL); ! ! if (src_key) { ! result = fileno (af_open (src_key, "r")); ! af_dropkey (src_key); ! } ! else ! result = open (s->fullname, O_RDONLY); if (result >= 0) return result; /* Didn't work -- free old one, try again. */ *** gdb/defs.h.orig Wed May 12 17:34:12 1993 --- gdb/defs.h Fri Jul 30 16:33:36 1993 *************** *** 620,627 **** extern NORETURN void /* Does not return to the caller. */ fatal (); ! extern NORETURN void /* Not specified as volatile in ... */ ! exit PARAMS ((int)); /* 4.10.4.3 */ extern NORETURN void /* Does not return to the caller. */ nomem PARAMS ((long)); --- 620,627 ---- extern NORETURN void /* Does not return to the caller. */ fatal (); ! /* extern NORETURN void /* Not specified as volatile in ... */ ! /* exit PARAMS ((int)); /* 4.10.4.3 */ extern NORETURN void /* Does not return to the caller. */ nomem PARAMS ((long)); *************** *** 717,727 **** #endif /* MALLOC_INCOMPATIBLE */ extern void qsort PARAMS ((void *base, size_t nmemb, /* 4.10.5.2 */ size_t size, int (*comp)(const void *, const void *))); ! #ifndef MEM_FNS_DECLARED /* Some non-ANSI use void *, not char *. */ extern PTR memcpy PARAMS ((void *, const void *, size_t)); /* 4.11.2.1 */ --- 717,728 ---- #endif /* MALLOC_INCOMPATIBLE */ + #if 0 extern void qsort PARAMS ((void *base, size_t nmemb, /* 4.10.5.2 */ size_t size, int (*comp)(const void *, const void *))); ! #endif #ifndef MEM_FNS_DECLARED /* Some non-ANSI use void *, not char *. */ extern PTR memcpy PARAMS ((void *, const void *, size_t)); /* 4.11.2.1 */ *************** *** 743,750 **** --- 744,753 ---- strtok PARAMS ((char *, const char *)); /* 4.11.5.8 */ #ifndef MEM_FNS_DECLARED /* Some non-ANSI use void *, not char *. */ + #if 0 extern PTR memset PARAMS ((void *, int, size_t)); /* 4.11.6.1 */ + #endif #endif extern char * shapetools-1.4pl6.orig/src/patches/README.vgdb100444 2013 145 4756 5575342134 17203 0ustar dokoswt-*-text-*- The file vgdb-patch contains a patch to GNU gdb 4.12 to enable working on AtFS versions. This patch works on SPARC machines running SunOS 4.1.2 and is not tested with other platforms yet. What it does: This patch turns GNU gdb into "Vgdb" -- a debugger that can work on AtFS versions of source files as well as on "normal" sources. Vgdb is capable to do source-level debugging on C programs compiled with shape directly from an archive. Provided the C files have been compiled with shape's default rule, gdb automagically identifies the versions the binary has been compiled from if it has been compiled from non-busy source files. Together with GNU Emacs and the find-atfs package for Emacs, you can use Emacs' gdb-mode with Vgdb such that Emacs displays the appropriate source version in the source window. Just set the Emacs variable gdb-command-name to the name of the Vgdb executable, e.g. with '(setq gdb-command-name "vgdb")' in your ~/.emacs file. Gdb's normal capabilities are not in any way affected by this patch -- you can use Vgdb exactly like you have used gdb before. How to apply the patch: Unpack the gdb 4.12 distribution. This should create a directory named gdb-4.12. Change to this directory and configure gdb for your machine by invoking "configure". Copy the file vgdb-patch into this directory and patch the source files with "patch -p0 < vgdb-patch". Please note that the "-p0" switch is important -- the patch will not succeed without it. Set the SHAPETOOLS environment variable to the base path where you installed the ShapeTools stuff (e.g. /usr/local). Now type "make". This should build an executable "gdb" in the gdb directory. You may want to rename the executable to "vgdb". If you want to apply the patch to a different version of GNU gdb, you may have to modify the sources by hand, we haven't tried it. Problems: Due to some irregularities in the declarations of external functions, the vgdb-patch currently works only with Sun's C compiler, not with gcc. If Vgdb is working on a version with attribute citations that expand to more than a single line, it will display the wrong source context when used stand-alone. (Vgdb does not expand attributes when it reads the source file.) To avoid this, use Vgdb with GNU Emacs' gdb-mode and the find-atfs package. (This is the morally superior way of debugging anyway.) shapetools-1.4pl6.orig/src/patches/vgrep-patch100444 2013 145 27644 5575317165 17574 0ustar dokoswt*** ../grep-2.0/Makefile.in Sun May 2 21:54:24 1993 --- Makefile.in Fri Apr 22 10:04:31 1994 *************** *** 1,4 **** ! # Makefile for GNU grep # Copyright (C) 1992 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify --- 1,4 ---- ! # Makefile for ve?grep, derived from GNU grep # Copyright (C) 1992 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify *************** *** 40,58 **** DEFS=-DGREP @DEFS@ # Extra libraries. ! LIBS=@LIBS@ ALLOCA=@ALLOCA@ ! CFLAGS=-O ! LDFLAGS=$(CFLAGS) prefix=/usr/local exec_prefix=$(prefix) # Prefix for installed program, normally empty or `g'. ! binprefix= # Prefix for installed man page, normally empty or `g'. ! manprefix= # Where to install executables. bindir=$(exec_prefix)/bin --- 40,63 ---- DEFS=-DGREP @DEFS@ # Extra libraries. ! SHAPELIBPATH = $$SHAPETOOLS/lib ! SHAPEINCPATH = $$SHAPETOOLS/include ! SHAPELIBS = -lAtFStk -lAtFS -lsttk ! ! LIBS=$(SHAPELIBS) @LIBS@ ALLOCA=@ALLOCA@ ! CDEBUG=-O -I$(SHAPEINCPATH) ! CFLAGS=$(CDEBUG) ! LDFLAGS=-O -L$(SHAPELIBPATH) prefix=/usr/local exec_prefix=$(prefix) # Prefix for installed program, normally empty or `g'. ! binprefix=v # Prefix for installed man page, normally empty or `g'. ! manprefix=v # Where to install executables. bindir=$(exec_prefix)/bin *************** *** 74,80 **** .c.o: $(CC) $(CFLAGS) $(DEFS) -I$(srcdir) -c $< ! all: grep check.done # For Saber C. grep.load: $(SRCS) --- 79,85 ---- .c.o: $(CC) $(CFLAGS) $(DEFS) -I$(srcdir) -c $< ! all: vgrep check.done # For Saber C. grep.load: $(SRCS) *************** *** 85,91 **** $(LINT) $(CFLAGS) $(DEFS) -I$(srcdir) $(SRCS) install: all ! $(INSTALL_PROGRAM) grep $(bindir)/$(binprefix)grep rm -f $(bindir)/$(binprefix)egrep $(LN) $(bindir)/$(binprefix)grep $(bindir)/$(binprefix)egrep rm -f $(bindir)/$(binprefix)fgrep --- 90,96 ---- $(LINT) $(CFLAGS) $(DEFS) -I$(srcdir) $(SRCS) install: all ! $(INSTALL_PROGRAM) vgrep $(bindir)/$(binprefix)grep rm -f $(bindir)/$(binprefix)egrep $(LN) $(bindir)/$(binprefix)grep $(bindir)/$(binprefix)egrep rm -f $(bindir)/$(binprefix)fgrep *************** *** 96,107 **** AWK=$(AWK) sh $(srcdir)/tests/check.sh $(srcdir)/tests touch check.done ! check.done: grep AWK=$(AWK) sh $(srcdir)/tests/check.sh $(srcdir)/tests touch check.done ! grep: $(OBJS) $(LIBOBJS) $(ALLOCA) ! $(CC) $(LDFLAGS) -o grep $(OBJS) $(LIBOBJS) $(LIBS) $(ALLOCA) clean: rm -f core grep *.o check.done tmp.script khadafy.out --- 101,112 ---- AWK=$(AWK) sh $(srcdir)/tests/check.sh $(srcdir)/tests touch check.done ! check.done: vgrep AWK=$(AWK) sh $(srcdir)/tests/check.sh $(srcdir)/tests touch check.done ! vgrep: $(OBJS) $(LIBOBJS) $(ALLOCA) ! $(CC) $(LDFLAGS) -o vgrep $(OBJS) $(LIBOBJS) $(LIBS) $(ALLOCA) clean: rm -f core grep *.o check.done tmp.script khadafy.out *** ../grep-2.0/grep.c Sun May 23 06:52:52 1993 --- grep.c Fri Apr 22 09:54:12 1994 *************** *** 309,318 **** bufmapped = 0; lseek(bufdesc, bufoffset, 0); } ! cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc); } #else ! cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc); #endif if (cc > 0) buflim = buffer + bufsalloc + cc; --- 309,318 ---- bufmapped = 0; lseek(bufdesc, bufoffset, 0); } ! cc = atReadExpand(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc); } #else ! cc = atReadExpand(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc); #endif if (cc > 0) buflim = buffer + bufsalloc + cc; *************** *** 563,572 **** return nlines; } ! static char version[] = "GNU grep version 2.0"; #define USAGE \ ! "usage: %s [-[[AB] ]] [-[CEFGVchilnqsvwx]] [-[ef]] []\n" static void usage() --- 563,572 ---- return nlines; } ! static char version[] = "ve?grep 1.0, derived from GNU grep version 2.0"; #define USAGE \ ! "usage: %s [vbind-options] [-[[AB] ]] [-[CEFGVchilnqsvwx]] [-[ef]] []\n" static void usage() *************** *** 606,611 **** --- 606,613 ---- extern char *optarg; extern int optind; + atBindSetArgv(&argc, &argv); + prog = argv[0]; if (prog && strrchr(prog, '/')) prog = strrchr(prog, '/') + 1; *************** *** 777,783 **** if (optind < argc) while (optind < argc) { ! desc = strcmp(argv[optind], "-") ? open(argv[optind], O_RDONLY) : 0; if (desc < 0) { if (!suppress_errors) --- 779,785 ---- if (optind < argc) while (optind < argc) { ! desc = strcmp(argv[optind], "-") ? atOpenExpand(argv[optind], 0) : 0; if (desc < 0) { if (!suppress_errors) *************** *** 803,809 **** printf("%s\n", filename); } if (desc != 0) ! close(desc); ++optind; } else --- 805,811 ---- printf("%s\n", filename); } if (desc != 0) ! atCloseExpand(desc); ++optind; } else *** ../grep-2.0/grep.man Sat Oct 17 03:08:16 1992 --- grep.man Fri Apr 22 10:40:51 1994 *************** *** 1,9 **** ! .TH GREP 1 "1992 September 10" "GNU Project" .SH NAME ! grep, egrep, fgrep \- print lines matching a pattern .SH SYNOPOSIS ! .B grep [ .BR \- [[ AB "] ]\c" .I "num" ] --- 1,11 ---- ! .TH VGREP 1 "1992 September 10" "GNU Project" .SH NAME ! vgrep, vegrep, vfgrep \- print lines matching a pattern .SH SYNOPOSIS ! .B vgrep [ + .I vbind-options + ] [ .BR \- [[ AB "] ]\c" .I "num" ] *************** *** 17,41 **** | .BI \-f file ] [ ! .I files... ] .SH DESCRIPTION .PP ! .B Grep ! searches the named input ! .I files ! (or standard input if no files are named, or ! the file name .B \- is given) for lines containing a match to the given .IR pattern . By default, ! .B grep prints the matching lines. .PP There are three major variants of ! .BR grep , controlled by the following options. .PD 0 .TP --- 19,45 ---- | .BI \-f file ] [ ! .I "names..." ] .SH DESCRIPTION .PP ! .B Vgrep ! is GNU ! .B grep ! with a patch to access AtFS version objects. ! .I Vgrep ! searches the files and AtFS version objects listed in the arguments ! (or standard input if no names are given, or the name .B \- is given) for lines containing a match to the given .IR pattern . By default, ! .B vgrep prints the matching lines. .PP There are three major variants of ! .BR vgrep , controlled by the following options. .PD 0 .TP *************** *** 56,77 **** any of which is to be matched. .LP In addition, two variant programs ! .B egrep and ! .B fgrep are available. ! .B Egrep is similiar (but not identical) to ! .BR "grep\ \-E" , and is compatible with the historical Unix .BR egrep . ! .B Fgrep is the same as ! .BR "grep\ \-F" . .PD .LP All variants of ! .B grep understand the following options: .PD 0 .TP --- 60,94 ---- any of which is to be matched. .LP In addition, two variant programs ! .B vegrep and ! .B vfgrep are available. ! .B Vegrep is similiar (but not identical) to ! .BR "vgrep\ \-E" , and is compatible with the historical Unix .BR egrep . ! .B Vfgrep is the same as ! .BR "vgrep\ \-F" . .PD .LP + .I Vgrep + understands the standard version binding options of the Shape toolkit. + The + .I names + on the command line are replaced by the appropriate version IDs of the + selected version object. + .LP + The + .I vbind-options + are shapeTools' standard options for version binding. + A description of these options can be found in the manual page of + .IR vbind (1). + .LP All variants of ! .B vgrep understand the following options: .PD 0 .TP *************** *** 79,85 **** Matches will be printed with .I num lines of leading and trailing context. However, ! .B grep will never print any given line more than once. .TP .BI \-A " num" --- 96,102 ---- Matches will be printed with .I num lines of leading and trailing context. However, ! .B vgrep will never print any given line more than once. .TP .BI \-A " num" *************** *** 98,104 **** .TP .B \-V Print the version number of ! .B grep to standard error. This version number should be included in all bug reports (see below). .TP --- 115,121 ---- .TP .B \-V Print the version number of ! .B vgrep to standard error. This version number should be included in all bug reports (see below). .TP *************** *** 172,178 **** Regular expressions are constructed analagously to arithmetic expressions, by using various operators to combine smaller expressions. .PP ! .B Grep understands two different versions of regular expression syntax: ``basic'' and ``extended.'' In .RB "GNU\ " grep , --- 189,195 ---- Regular expressions are constructed analagously to arithmetic expressions, by using various operators to combine smaller expressions. .PP ! .B Vgrep understands two different versions of regular expression syntax: ``basic'' and ``extended.'' In .RB "GNU\ " grep , *************** *** 343,349 **** .BR \e) . .PP In ! .B egrep the metacharacter .B { loses its special meaning; instead use --- 360,366 ---- .BR \e) . .PP In ! .B vegrep the metacharacter .B { loses its special meaning; instead use *************** *** 357,362 **** --- 374,401 ---- Exit status is 2 if there were syntax errors in the pattern, inaccessible input files, or other system errors. + .SH EXAMPLES + Grep for ``foo'' in version 1.43 of smile.c: + .IP + \fCvgrep foo smile.c[1.43]\fP + .LP + Grep for ``foo'' in the last version of smile.c (last saved version or + busy file, if available): + .IP + \fCvgrep -last foo smile.c\fP + .LP + Grep for ``foo'' in all versions of C files that have been created + since February 14 1993: + .IP + \fCvgrep -since 14.2.93 foo \e\(**.c\fP + .LP + Grep for ``foo'' in all versions carrying the symbolic name + ``Release-2.3'': + .IP + \fCvgrep foo \e\(**[Release-2.3]\fP + .SH "SEE ALSO" + emacs(1), ed(1), sh(1), vbind(1), atread(3), + .I "GNU Emacs Manual" .SH BUGS .PP Email bug reports to *************** *** 365,375 **** .PP Large repetition counts in the .BI { m , n } ! construct may cause grep to use lots of memory. In addition, certain other obscure regular expressions require exponential time and space, and may cause ! .B grep to run out of memory. .PP Backreferences are very slow, and may require exponential time. --- 404,414 ---- .PP Large repetition counts in the .BI { m , n } ! construct may cause vgrep to use lots of memory. In addition, certain other obscure regular expressions require exponential time and space, and may cause ! .B vgrep to run out of memory. .PP Backreferences are very slow, and may require exponential time. *** ../grep-2.0/tests/check.sh Sun May 2 20:13:22 1993 --- tests/check.sh Fri Apr 22 10:09:38 1994 *************** *** 7,13 **** failures=0 # The Khadafy test is brought to you by Scott Anderson . . . ! ./grep -E -f $testdir/khadafy.regexp $testdir/khadafy.lines > khadafy.out if cmp $testdir/khadafy.lines khadafy.out then : --- 7,13 ---- failures=0 # The Khadafy test is brought to you by Scott Anderson . . . ! ./vgrep -E -f $testdir/khadafy.regexp $testdir/khadafy.lines > khadafy.out if cmp $testdir/khadafy.lines khadafy.out then : *** ../grep-2.0/tests/scriptgen.awk Sun Apr 4 00:49:54 1993 --- tests/scriptgen.awk Wed Jun 8 11:29:29 1994 *************** *** 1,6 **** BEGIN { print "failures=0"; } $0 !~ /^#/ && NF == 3 { ! print "echo '" $3 "' | ./grep -E -e '" $2 "' > /dev/null 2>&1"; print "if [ $? != " $1 " ]" print "then" printf "\techo Spencer test \\#%d failed\n", ++n --- 1,6 ---- BEGIN { print "failures=0"; } $0 !~ /^#/ && NF == 3 { ! print "echo '" $3 "' | ./vgrep -E -e '" $2 "' > /dev/null 2>&1"; print "if [ $? != " $1 " ]" print "then" printf "\techo Spencer test \\#%d failed\n", ++n shapetools-1.4pl6.orig/src/patches/vgrep-Makefile-patch100444 2013 145 1230 5575315760 21245 0ustar dokoswt*** Makefile Wed Jun 8 11:18:58 1994 --- ../vgrep-2.0/Makefile Fri Apr 22 10:07:05 1994 *************** *** 75,81 **** #### End of system configuration section. #### SRCS=grep.c getopt.c regex.c dfa.c kwset.c obstack.c search.c ! OBJS=grep.o getopt.o regex.o dfa.o kwset.o obstack.o search.o .c.o: $(CC) $(CFLAGS) $(DEFS) -I$(srcdir) -c $< --- 75,82 ---- #### End of system configuration section. #### SRCS=grep.c getopt.c regex.c dfa.c kwset.c obstack.c search.c ! #OBJS=grep.o getopt.o regex.o dfa.o kwset.o obstack.o search.o ! OBJS=grep.o getopt.o dfa.o kwset.o obstack.o search.o .c.o: $(CC) $(CFLAGS) $(DEFS) -I$(srcdir) -c $< shapetools-1.4pl6.orig/src/patches/README.vgrep100444 2013 145 4454 5575327565 17412 0ustar dokoswt-*-text-*- The file vgrep-patch contains a patch to GNU grep 2.0 to enable working on AtFS versions. What is does: This patch turns GNU grep into Vgrep -- a grep program that is aware of AtFS version and selection rules. With Vgrep (and Vegrep) you can work on AtFS version as well as on normal Files. GNU grep's normal capabilities are not affected by the patch -- you can use Vgrep exactly like GNU grep. For further information refer to the manual pages of vgrep(1) (after applying the patch and installing vgrep) and vbind(1). How to apply the patch: Unpack the GNU grep 2.0 distribution. This should create a directory named grep-2.0. Copy the file vgrep-patch into this directory and change to this directory. Patch the source files with "patch -p0 < vgrep-patch". Now configure the package as described in the file INSTALL. Before you run "make", define an environment variable "SHAPETOOLS" that points to the place where ShapeTools are installed. This should be the directory that contains the "lib", and "include" subdirectories for shape. After that, you probably only need to type "configure ; make ; make install". This installs vgrep and vegrep in /usr/local/bin and the manual page vgrep.man as /usr/local/man/man1/vgrep.1. IMPORTANT NOTE: Some systems, such as Linux, provide functions for regular expression matching in their C-Libraries. In order to prevent multiple symbol definition errors when vgrep is loaded, you should apply the vgrep-Makefile-patch *after* you have configured the grep-2.0 distribution, *before* running "make". GNU grep comes with a test suite that is run automatically after (v)grep has been built. Some of these tests may fail (they failed when I ran them under Linux-1.0, and under SunOS 4.1.2). Nevertheless, vgrep works OK. The following tests are failing: Spencer test #67 failed Spencer test #68 failed Spencer test #82 failed Spencer test #117 failed If you want to apply the patch to a different version of GNU grep, you may have to apply the patches by hand, we haven't tried it. There exists an older version of the vgrep-patch that applies to GNU-grep 1.6. It is available on demand. We recommend upgrading to grep-2.0, however. shapetools-1.4pl6.orig/src/patches/vetags-patch100444 2013 145 6506 5517553432 17707 0ustar dokoswt*** /tmp_mnt/home/stone/axel/shape/vetags/etags.c [1.0] Thu Jan 20 20:10:15 1994 --- /tmp_mnt/home/stone/axel/shape/vetags/etags.c [1.1] Thu Jan 20 20:10:17 1994 *************** *** 22,27 **** --- 22,30 ---- #include #include + #include + #include + /* Define the symbol ETAGS to make the program "etags", which makes emacs-style tag tables by default. Define CTAGS to make the program "ctags" compatible with the usual one. *************** *** 36,41 **** --- 39,48 ---- #endif #endif + #ifndef ETAGS + #define ETAGS + #endif + /* Exit codes for success and failure. */ #ifdef VMS *************** *** 49,56 **** --- 56,67 ---- #define reg register #define logical char + #ifndef TRUE #define TRUE (1) + #endif + #ifndef FALSE #define FALSE (0) + #endif #define iswhite(arg) (_wht[arg]) /* T if char is white */ #define begtoken(arg) (_btk[arg]) /* T if char can start token */ *************** *** 188,193 **** --- 199,206 ---- eflag = 0; #endif + atBindSetArgv(&ac, &av) ; + while (ac > 1 && av[1][0] == '-') { for (i=1; av[1][i]; i++) *************** *** 257,262 **** --- 270,276 ---- ac--; av++; } + if (ac <= 1) { usage: *************** *** 263,269 **** #ifdef VMS fprintf (stderr, "Usage: %s [-aetwvx] [-f outfile] file ...\n", progname); #else ! fprintf (stderr, "Usage: %s [-BFaetuwvx] [-f outfile] file ...\n", progname); #endif exit(BAD); } --- 277,283 ---- #ifdef VMS fprintf (stderr, "Usage: %s [-aetwvx] [-f outfile] file ...\n", progname); #else ! fprintf (stderr, "Usage: %s [vbind-options] [-BFaetuwvx] [-f outfile] file ...\n", progname); #endif exit(BAD); } *************** *** 407,422 **** find_entries (file) char *file; { ! char *cp; ! if ((inf=fopen(file,"r")) == NULL) { fprintf (stderr, "%s: ", progname); ! perror(file); return; } ! curfile = savestr(file); ! cp = rindex(file, '.'); /* .tex, .aux or .bbl implies LaTeX source code */ if (cp && (!strcmp (cp + 1, "tex") || !strcmp (cp + 1, "aux") || !strcmp (cp + 1, "bbl"))) --- 421,443 ---- find_entries (file) char *file; { ! char *cp, *unixfile; ! Af_key *aso = atBindVersion (file, ""); ! if (!aso) { ! af_perror (file); ! return; ! } ! ! if ((inf=af_open(aso,"r")) == NULL) { fprintf (stderr, "%s: ", progname); ! af_perror(file); return; } ! curfile = atRetAttr (aso, AF_ATTBOUND); ! unixfile = atRetAttr (aso, AF_ATTUNIXNAME); ! cp = rindex(unixfile, '.'); /* .tex, .aux or .bbl implies LaTeX source code */ if (cp && (!strcmp (cp + 1, "tex") || !strcmp (cp + 1, "aux") || !strcmp (cp + 1, "bbl"))) *************** *** 461,473 **** { if (PF_funcs(inf) != 0) { ! fclose(inf); return; } rewind(inf); /* no fortran tags found, try C */ } C_entries(); ! fclose(inf); } /* Nonzero if string STR is composed of digits. */ --- 482,494 ---- { if (PF_funcs(inf) != 0) { ! af_close(inf); return; } rewind(inf); /* no fortran tags found, try C */ } C_entries(); ! af_close(inf); } /* Nonzero if string STR is composed of digits. */ shapetools-1.4pl6.orig/src/patches/README.vetags100444 2013 145 2206 5517562122 17533 0ustar dokoswt-*-text-*- The file vetags-patch contains a patch to etags.c (coming with the GNU emacs distribution) to extract tag-information from AtFS versions. What is does: This file turns etags into vetags, a version sensitive variant of emacs' tags program etags. Etags normally resides in /etc. Vetags behaves just as as etags, with the extension that taggification can be applied to versions of files (as opposed to just plain files) that are stored in the AtFS version object base. Which version of the source files are analyzed is determined by the ``vbind'' options that can be passed from the command line. For further information refer to the manual pages of etags(1) and vbind(1). How to apply the patch: Unpack the GNU Emacs distribution. This should create a directory named "etc". Copy the file etags.c from this directory into /src/patches, and change to this directory. Type "make vetags". Voila ! The patch is known to work with the version of etags.c that comes with emacs-18.59. No warranty for emacs-19.* versions of etags. shapetools-1.4pl6.orig/src/patches/Release100444 2013 145 102 5575344566 16655 0ustar dokoswtst_Patches-1.5 (Tue Aug 23 18:01:51 1994 by axel@cs.tu-berlin.de) shapetools-1.4pl6.orig/src/patches/Shapefile100444 2013 145 6306 5517555150 17216 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for st_Patches # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Shapefile[4.0] Thu Jan 20 20:24:55 1994 axel@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=gnu QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds _all: all $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) $(VERSIONOBJECT): $(VERSIONFILE) : +(LASTRELEASE) +(CC) +(CFLAGS) $(CC) -c $(CFLAGS) $(VERSIONFILE) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- SHAPELIBPATH = /home/stone/shape/lib/shape include Makefile include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # The system's include dependencies (C development specific). # This file is automatically generated by invocation of "shape depend". # !!! shape depend requires a C compiler supporting the -M option. include Dependencies # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=$(SHAPE) all:+ MAINTARGET=all ALLTARGETS=subsystems targets install:+ MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean:+ MAINTARGET=clean ALLTARGETS=subsystems doclean shapetools-1.4pl6.orig/src/patches/Makefile100444 2013 145 10241 5575344423 17047 0ustar dokoswt## Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for st_Patches # # Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) # Axel Mahler (Axel.Mahler@cs.tu-berlin.de) # # $Header: Makefile[4.2] Wed Jun 8 15:35:38 1994 axel@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # locations and general macros # -------------------------------------------------------------------- # The base directory of the project's source repository area. BASE = /home/stone/shape/development # Path to this node system relative to the root of the source # repository defined above (e.g. vc/save). NODEPATH = src/patches # A short name for this node system NODENAME = st_Patches # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = Release # source VERSIONOBJECT = # derived (if source contains program code) # The operating system, $(TARGET) shall be built for. HOSTSYSTEM = s_sunos_4 # The processor type. HOSTTYPE = sun4 # Preprocessor switches. (eg. -DDEBUG) SWITCHES = # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBASE = $(BASE) INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib/shape INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # The regular source files. SOURCES = vgdb-patch README.vgdb vgrep-patch vgrep-Makefile-patch \ README.vgrep vetags-patch README.vetags # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- MAKE = make SHELL = /bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -g MAKELDFLAGS = -g CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = /usr/bin/ranlib # System libraries, local libraries and lint libraries. SYSLIBS = LOCALLIBS = $(LOCALLIBPATH)/libAtFStk.a $(LOCALLIBPATH)/libsttk.a $(LOCALLIBPATH)/libAtFS.a LINTLIBS = # The following instructions are only used for vetags (see README's for # details) TARGET = vetags OBJECTS = vetags.o $(TARGET): $(LOCALLIBS) $(OBJECTS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LOCALLIBS) $(SYSLIBS) @_aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $$i; \ echo linking $(TARGET) to $$i; \ ln $(TARGET) $$i; \ done installtargets: $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$(TARGET): $(TARGET) @-echo "installing $(TARGET) in $(INSTALLBINPATH)"; \ if [ -f $(INSTALLBINPATH)/$(TARGET) ] && \ [ ! -w $(INSTALLBINPATH)/$(TARGET) ]; \ then \ chmod u+w $(INSTALLBINPATH)/$(TARGET); \ fi; \ cp $(TARGET) $(INSTALLBINPATH)/$(TARGET); \ chmod $(INSTALLBINMODE) $(INSTALLBINPATH)/$(TARGET); \ _aliases="$(ALIASES)"; \ for i in $$_aliases; \ do \ rm -f $(INSTALLBINPATH)/$$i; \ echo "linking $(INSTALLBINPATH)/$(TARGET) to $(INSTALLBINPATH)/$$i"; \ ln $(INSTALLBINPATH)/$(TARGET) $(INSTALLBINPATH)/$$i; \ done vetags.c: etags.c -if patch < vetags-patch; \ then \ mv etags.c vetags.c; \ mv etags.c.orig etags; \ else \ echo patching etags failed; \ exit 1; \ fi shapetools-1.4pl6.orig/src/patches/Dependencies100444 2013 145 22 5412610073 17617 0ustar dokoswt# no dependencies shapetools-1.4pl6.orig/man/ 40755 2013 145 0 5626416071 13627 5ustar dokoswtshapetools-1.4pl6.orig/man/man1/ 40755 2013 145 0 5626416521 14463 5ustar dokoswtshapetools-1.4pl6.orig/man/man1/atfsrepair.1100444 2013 145 6475 5516554257 17023 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atfsrepair.1[7.0] Thu Jan 20 12:06:00 1994 andy@cs.tu-berlin.de frozen $ .. .TH atfsrepair 1 "Thu Jan 20 12:06:00 1994" "AtFS-1.71" "ShapeTools" .SH NAME atfsrepair \- repair corrupted AtFS repository, or convert old repository to new format. .SH SYNOPSIS .B atfsrepair .RB [ \-Ceinqv ] file1 ... .SH DESCRIPTION \fIAtfsrepair\fR checks the AtFS repository for inconsistencies in the a given file history. If a corrupted archive file is found in the repository, atfsrepair tries to repair it by reconstructing missing parts and eliminating inconsistencies. Without a \fIfile\fP argument, atfsrepair handles the complete repository. Atfsrepair is interactive and (hopefully) self explanatory. .LP If you have permission problems, e.g. your AtFS repository grants group write permission but another user from your group can still not save data to the repository, atfsrepair is also the right thing to do. The programs straightens permission bits within the repository. .LP Atfsrepair automatically updates archive files, when the archive file format or the arrangement of archive files within the AtFS subdirectory was changed. Before taking any permanent action, atfsrepair asks the user for a confirmation. This behaviour can be switched off by either the -n or the -q option (see below). .LP Atfsrepair shall not be called concurrently with other applications on an AtFS repository. Make sure, that nobody else works on the repository to be repaired as atfsrepair may ignore existing archive locks and does not set own locks. .SH OPTIONS .TP \f(BI\-C\fR This option causes atfsrepair to try it's hand at a derived object cache. .TP \f(BI\-e\fR Edit Mode. Invoking atfsrepair with this option rather serves for manipulating archive files than for repairing them. It shall only be used by \fIvery experienced\fR users. For nearly every item in the archive file, \fIatfsrepair\fR asks the caller for confirmation or modification. Beware, this level of verbosity can be very annoying when the archive file is big. .TP \f(BI\-i\fR Interactive mode (default). .TP \f(BI\-n\fR Non-interactive mode. In this mode, atfsrepair tries to repair corrupted archive files without human assistance. It does not perform any user interaction and behaves as if the user would always choose the default decision in interactive mode. .TP \f(BI\-q\fR Quiet mode. Same as \fI-n\fP but also supresses all informative messages. Only error messages will be displayed. .TP \f(BI\-v\fR Print current version number. No file processing is done. .SH SEE ALSO afarchive(5) .SH BUGS Dates appear in internal form (seconds since 1970) rather than in human readable form. .SH AUTHOR Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/cacheadm.1100444 2013 145 6132 5515253352 16365 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: cacheadm.1[3.0] Thu Jan 13 15:30:55 1994 andy@cs.tu-berlin.de frozen $ .. .TH cacheadm 1 "Thu Jan 13 15:30:55 1994" "AtFS-1.71" "ShapeTools" .SH NAME cacheadm \- administer and configure AtFS derived object cache .SH SYNOPSIS .B cacheadm .RB [ \-A \fImax_cached_per_cacheattr\fP ] .RB [ \-N \fImax_cached_per_name\fP ] .RB [ \-T \fImax_total_cached\fP ] .RB [ \-q ] .RB [ \-v ] .I directories .SH DESCRIPTION \fIcacheadm\fP provides control over the size of a derived object cache. You may set the maximum total number (T) of derived files to be stored, the maximum number of derived files per name (N) and the maximum number of derived files with the same name and the same caching attribute (A). Called without any options, \fIcacheadm\fP returns the actual sizes of the derived object caches in the named dirctories. An empty list of directories causes \fIcacheadm\fP to operate on the current directory. .LP The relationship of the three cache size values must always be T\ >=\ N\ >=\ A. The caching attribute mechanism is described on the af_cache(3) manual page. When calculating your caching sizes you should keep in mind that you may set the total size (\fIT\fP) to any value but your cache will never grow bigger than \fIN\|*\|number_of_names\fP. Number_of_names is the number of source object histories in your directories, where derived objects may be compiled from. If you set \fIT\fP to an astronomic value, the cache adapt it's size to the number of source histories automatically. .LP In the current implementation, the caching sizes can only be increased. Reduction of the maximum cache size is only possible when the cache is empty. Hence you have to clean your cache (atfsrepair\ -C\ (1)) first if you want to shrink its size. .SH OPTIONS .TP 2c \fB-A\fP \fImax_cached_per_cacheattr\fP Set the maximum number of derived files with the same name and the same caching attribute to be stored. Default is 1. .TP \fB-N\fP \fImax_cached_per_name\fP Set the maximum number of derived files with the same name to be stored. Default is 3. .TP \fB-T\fP \fImax_total_cached\fP Set the total maximum number of derived files to be stored in the derived object cache. Default is 64. \fB-q\fP Quiet operation. Suppresses any output to stdout. This option does not affect error messages (stderr). .TP \fB-v\fP Output version identification string. .SH SEE ALSO chgrp(1), chmod(1), atfsrepair(1), af_cache(3) .SH AUTHOR Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/mkatfs.1100444 2013 145 10000 5621413202 16120 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: mkatfs.1[7.2] Mon Aug 8 13:28:26 1994 andy@cs.tu-berlin.de frozen $ .. .TH mkatfs 1 "Mon Aug 8 13:28:26 1994" "AtFS-1.71" "ShapeTools" .SH NAME mkatfs \- create and configure AtFS object repository and derived object cache .SH SYNOPSIS .B mkatfs .RB [ \-cA \fImax_cached_per_cacheattr\fP ] .RB [ \-cN \fImax_cached_per_name\fP ] .RB [ \-cT \fImax_total_cached\fP ] .RB [ \-cQ ] .RB [ \-g \fIgroup\fP ] .RB [ \-h ] .RB [ \-l \fIpath\fP ] .RB [ \-m \fImode\fP ] .RB [ \-v ] .I pathnames .SH DESCRIPTION \fImkatfs\fP may be used to create an AtFS object repository, to link an existing repository, to configure a repository, or to set the size attributes of an derived object cache. It applies to all directories occurring in the \fIpathnames\fP list. If the list is empty, mkatfs performs its action in the current directory. .LP Creating an AtFS object repository makes a directory named \fIAtFS\fP with several files and subdirectories in it. .LP The \fI-l\fP option causes mkatfs to link an existing AtFS repository to the current directory (or the directories in the pathnames list). The -l option expects a pathname to a directory containing an AtFS repository or a link to an AtFS repository (links may be chained) as argument. When linking a repository, mkatfs either creates a symbolic link or, if symbolic links are not available on your system, a file containing the name of the target directory. The latter will be interpreted by AtFS like a symbolic link. .LP Configuring an AtFS repository means, that the group and the protection may be changed. These operations perform a chgrp(1) and a chmod(1) operation on the AtFS directory and all its subdirectories. .LP The \fI-cT\fP, \fI-cN\fP, and \fI-cA\fP options set the size of the derived object cache in the created AtFS object repository. You may set the maximum total number (cT) of derived files to be stored, the maximum number of derived files per name (cN) and the maximum number of derived files with the same name and the same caching attribute (cA). The relationship of the three values must always be cT\ >=\ cN\ >=\ cA. For more information on that topic check the cacheadm(1) manual page. The \fI-cQ\fP option queries the actual settings for the derived object cache size. .SH OPTIONS .TP 2c \fB-cA\fP \fImax_cached_per_cacheattr\fP Set the maximum number of derived files with the same name and the same caching attribute to be stored. Default is 1. .TP \fB-cN\fP \fImax_cached_per_name\fP Set the maximum number of derived files with the same name to be stored. Default is 3. .TP \fB-cT\fP \fImax_total_cached\fP Set the total maximum number of derived files to be stored in the derived object cache. Default is 64. \fB-g\fP \fIgroup\fP Set the group id of the generated directory to \fIgroup\fP (see chgrp(1)). \fB-h\fP Display help message. .TP \fB-l\fP \fIpath\fP Create an AtFS directory entry by setting a symbolic link to an existing AtFS object repository, rather than creating a new (empty) one. On System V machines, a file containing the target directory name will be generated. The AtFS functions will interpret this as surrogate for a symbolic link. .TP \fB-m\fP \fImode\fP Set the mode of all generated directories to \fImode\fP (see chmod(1)). .TP \fB-v\fP Output version identification string. .SH SEE ALSO chgrp(1), chmod(1), atfsrepair(1), af_cache(3) .SH AUTHOR Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/vbind.1100444 2013 145 27643 5537600243 15773 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: vbind.1[7.0] Thu Mar 10 12:15:43 1994 andy@cs.tu-berlin.de frozen $ .. .TH vbind 1 "Thu Mar 10 12:15:43 1994" "AtFStk-1.12" "ShapeTools" .SH NAME vbind \- bind name to version .SH SYNOPSIS \fBvbind\fP [ \fIoptions\fP ] filenames \.\|. .na .TP 1.2c \fIGeneral version binding options:\fP [\ \fB\-bind\fP\ \fIversion\ binding\fP\ ] [\ \fB\-before\fP\ \fIbaseline\fP\ ] [\ \fB\-since\fP\ \fIbaseline\fP\ ] [\ \fB\-last\fP\ ] [\ \fB\-lastsaved\fP\ ] [\ \fB\-uniq\fP\ ] [\ \fB\-nonuniq\fP\ ] [\ \fB\-rule\fP\ \fIrulebody\fP\ |\ \fIrulename\fP\ ] [\ \fB\-rulefile\fP\ \fIfilename\fP\ ] [\ \fB\-trace\fP\ ] .TP 1.2c \fIvbind command specific options:\fP [\ \fB\-?\fP\ (or\ \fB\-help\fP)\ ] [\ \fB\-alias\fP\ \fIversion\ alias\fP\ ] [\ \fB\-date\fP\ \fIdate\fP\ ] [\ \fB\-vnum\fP\ \fIversion\ number\fP\ ] [\ \fB\-nomsg\fP\ ] [\ \fB\-ruledump\fP\ ] [\ \fB\-ruleerr\fP\ ] [\ \fB\-rulelist\fP\ ] [\ \fB\-ruletest\fP\ ] [\ \fB\-version\fP\ ] .ad .SH OVERVIEW This manual page describes the \fIShapeTools Version Binding\fP mechanism, available in most commands of the toolkit. The general version binding options described on this page are available in many commands such like vl(1), vcat(1), vadm(1), save(1) and retrv(1) (just to name the most important ones). The vbind command specific options are private to the vbind command (see below). .LP Version binding is the process of selecting one or more versions from a filenames history in order to provides access to these version(s). This is conducted by version bind directives (or just \fIversion bindings\fP), which may be one of the following: .TP 3.5c version numbers "\fC1.2\fP" (version), "\fC1.\fP" (generation), "\fC.2\fP" (revision) .TP version alias names "\fCShapeTools-1.4\fP", or "\fCAtFS-2.0\fP" .br Version alias names are symbolic names tagged to single versions. They must be unique throughout a history. .TP date specifications "\fC10.2.93\fP" or "\fC4.3.\fP" (European), "\fCFeb 10, 1993\fP" or "\fCMar 4\fP{ (American) .br A date may additionally contain a time in the form \fIhh:mm\fP or \fIhh:mm:ss\fP. See sttime(3) for a complete list of recognized date formats. .TP bind rule names "\fCmost_recent:\fP" (plain), "\fCfrom_release(VC-4.0):\fP" (with argument) .br The colon is not part of the rule name. See the bindrules(7) manual page for a description on how to define version bind rules. .LP By default, version binding selects all versions fulfilling the given version bind requirements. The \fI-uniq\fP option changes this behavior and treats only unique identification as success. With this option given, version bind ignores all histories with more than one selected version. The \fI-last\fP and \fI-lastsaved\fP options unify a non unique selection by choosing the last version (modification/saving time) or the last saved version (saving time) from the bind hit set of each name. .LP The file \fI$SHAPETOOLS/lib/shape/BindRules\fP contains predefined rules for various cases. You may also define your own rule file and invoke this by either the \fI-rulefile\fP option or by extending the search space defined by the SHAPETOOLS environment variable. For information on how to write version bind rules, see the bindrules(7) manual page. .SH VERSION BINDING IN ACTION Version bind directives can be given either in brackets, directly following the name to be bound, or as option arguments. Options may be user to set version bindings to be applied to all name arguments (\fI-bind\fP and \fI-rule\fP options) or to define version ranges (\fI-since\fP and \fI-before\fP options). .LP \fIVersion identification by version number\fP or \fIversion alias\fP either results in a unique selection or fails, when no appropriate version was found. .TP 4c \fCfoo[1.2]\fP Identifies a specific version by it's version number. .TP \fCfoo[release-2]\fP Is interpreted as identification by version alias name. .LP \fIVersion identification by date\fP selects the versions from a history that have been the most recently saved versions at the given date. Identification by date may lead to multiple versions when development work in multiple generations happened simultaneously at the given date. Vbind understands various date formats such as in the list below. The sttime(3) manual page lists all recognized date formats. .TP \fCfoo[Jan 31, 1992]\fP .TP \fCfoo[92/01/31]\fP .TP \fCfoo[10.5.92 7:00:00]\fP .LP \fIVersion bind rules\fP describe general version binding policies. They are usually not dependent on particular file histories and may be applied to all histories. Version bind rules may have arguments enclosed in parentheses following the name. .TP 4c \fCfoo[bind_rule:]\fP .TP \fCfoo[bind_rule(arg1,arg2,...argN):]\fP .LP When the colon at the end of the rule name in brackets is omitted, vbind first interprets the given string as version alias. When no version with this alias name was found, vbind treats the string as rule name and gives it a second try. .LP \fIPlain filenames\fP are those not followed by any version bind directive in square brackets. Without a rule given with the -rule option on the command line, plain filenames are bound using the \fIdefault version bind rule\fP. It selects the busy version if there is one, or the most recent non busy version otherwise. .TP \fCeq (state, busy); max (version).\fP .LP The \fIdefault version binding\fP may also be indicated by an empty pair of brackets: \fCfoo[]\fP .LP .SH NAME PATTERNS The ShapeTools version binding mechanism performs filename substitution for given name patterns similar to sh(1). This is necessary, as shell filename substitution does not recognize the names of saved versions. Magic cookies are are: .IP \f(CB*\fP 2c matching any string, including the empty string, .IP \f(CB?\fP matching any single character, .IP \f(CB[c...]\fP matching any one of the characters enclosed in the square brackets, .IP \f(CB[l-r]\fP matching any character lexically between the left (\f(CBl\fP) and the right (\f(CBr\fP) character, inclusive, and .IP \f(CB[!c...]\fP .IP \f(CB[!l-r]\fP matching any character not recognized by their counterparts above. .LP As square brackets on the command line may either be part of a pattern (e.g. \fC*.[ch]\fP) or a version binding (e.g. \fC*[release-2]\fP), this may lead to some confusion. The leftmost pair of brackets is \fIalways\fP interpreted as version binding. Hence, in the first case, the string will be misinterpreted and you must add an explicit version binding to avoid this (e.g. \fC*.[ch][]\fP, default version binding added). .SH GENERAL VERSION BINDING OPTIONS .TP \fB\-before\fP\ \fIbaseline\fP Define the lower boundary of a time interval for selecting all versions evolved in this interval. \fIBaseline\fP can be any version bind directive uniquely selecting a version (e.g. version number, version alias, or date). The saving date of the baseline version is the interval start time. The boundary version (exactly matching the time given) is \fInot\fP included in the result set. .TP \fB\-bind\fP\ \fIversion binding\fP Use \fIversion binding\fP for binding each name on the command line, that has no explicit version binding in brackets. .TP \fB\-last\fP Select the last (modification/saving time) version of each nonunique selection. This causes the resulting version list to contain at most one version of each history. \fI-last\fP may be combined with other version bindings. .TP \fB\-lastsaved\fP Like \fI-last\fP, but busy versions are ignored. .TP \fB\-nonuniq\fP Force non-unique version identification. This option can be used to swich off the default behavior of some commands (e.g. vadm) that suggests unique version identification. .TP \fB\-rule\fP\ \fIrulename\fP\ |\ \fIrulebody\fP With a name argument, this option sets the named rule as default rule for binding all names on the command line. Alternatively, a rule body (a version selection rule without a name) may be given as argument, which will be evaluated for each name on the command line. This option disables any previous -bind or -rule definition. It does not affect names with a version binding in brackets. .TP \fB\-rulefile\fP\ \fIfilename\fP Read in the named rule file and add all contained rules to the list of known rules. A syntactical error, detected while parsing a rule causes the according rule to be skipped. Use vbind(1) with the \fI-ruleerr\fP option for inspecting bind rule files. Multiple rule files may be specified on the command line. .TP \fB\-since\fP\ \fIbaseline\fP Define the upper boundary of a time interval for selecting all versions evolved in this interval. \fIBaseline\fP can be any version bind directive uniquely selecting a version (e.g. version number, version alias, or date. The saving date of the baseline version is the interval end time. The boundary version (exactly matching the time given) is \fInot\fP included in the result set. .TP \fB\-trace\fP Trace the evaluation. Each evaluated predicate is reported to standard output. Additionally, the set of versions fulfilling the expressed (the \fIhits set\fP) is displayed after evaluation of each predicate. .TP \fB\-uniq\fP Require unique version identification. All history names on the command line, where multiple versions meet the version bind requirements are ignored. .SH THE VBIND COMMAND \fIVbind\fP performs a version binding and returns a \fIbound filename\fP for each selected version. A bound filename is a filename followed by a version number enclosed in brackets (e.g. foo[1.2]). .LP .TP 2c \fB\-?, \-help\fP Display a short usage description. .TP \fB\-alias\fP\ \fIversion alias\fP Use version alias for binding all names on the command line. This disables any previous -alias, -bind, -date, -rule or -vnum definition. It does not affect names in pseudo bound version notation. .TP \fB\-date\fP\ \fIdate\fP Use date for binding all names occurring on the command line. This disables any previous -alias, -bind, date, -rule or -vnum definition. It does not affect names in pseudo bound version notation. .TP \fB\-nomsg\fP\ Suppress output produced by version bind rules. .TP \fB\-ruledump\fP The -ruledump option causes all known version bind rules to be written to standard output. The generated output contains all rule definitions in regular format and may be used as input rulefile for subsequent calls of vbind. .TP \fB\-ruleerr\fP This option makes sense, when testing a new, hand written file containing bind rules. The -ruleerr option causes syntax errors detected in the rule file to be reported to standard error. Make sure, that this option occurs on the command line prior to the rulefile to be inspected. .TP \fB\-rulelist\fP Write a list of all known rule names to standard output. .TP \fB\-ruletest\fP Interpret all names on the command line as rule names and test the existence of equally named rules in the list of known rules. .TP \fB\-version\fP Print version identification of vbind command and used libraries. .TP \fB\-vnum\fP\ \fIversion number\fP Use version number for binding all names on the command line. This disables any previous -alias, -bind, -date, -rule or -vnum definition. It does not affect names in pseudo bound version notation. .SH ENVIRONMENT \fISHAPETOOLS\fP \- list of path names as search space for files containing version bind rules. The bind rule files must be named \fIBindRules\fP. Default path is \fI/usr/local/lib/shape\fP. .SH FILES $SHAPETOOLS/lib/shape/BindRules .SH SEE ALSO vl(1), sttime(3), bindrules(7) .SH AUTHOR Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/shape.1100444 2013 145 166453 5416655213 16017 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) $Header: shape.1[7.0] Thu Jul 8 01:21:54 1993 axel@cs.tu-berlin.de frozen $ .. .TH shape 1 "Thu Jul 8 01:21:47 1993" "shape_CM-4.9" "ShapeTools" .SH NAME \fRshape \- identify and build program configurations from versions of source objects .SH SYNOPSIS .IP \fBshape\fR 0.5i [\ \fB\-f \fI\fR\ ] .br [\ \fB\-R \fI\fR\ ] [\ \fB\-V\ \fI\fR\ ] .br [\ \fB\-echo\ \fI\fR\ ] [\ \fB\-force\ \fI\fR\ ] [\ \fB\-rebuild \fI\fR\ ] .br [\ \fB\- dDehiknprs\fR\ ] .br [\ \fB\-bct\fR\ ] [\ \fB\-help\fR\ ] [\ \fB\-nomsg\fR\ ] [\ \fB\-novclass\fR\ ] [\ \fB\-version\fR\ ] [\ \fB\-xpoff\fR\ ] [\ \fB\-xpon\fR\ ] .br [\ \fItarget1\ target2 ...\fR\ ] [\ \fImacro=value ...\fR\ ] [\ \fImacro+=value ...\fR\ ] .SH DESCRIPTION Shape allows to transparently compile source objects that are either regular files, or source object \fIversions\fP in the ShapeTools version object base. More generally, shape produces a set of \fIderived objects\fP (``targets'') from appropriately selected versions of corresponding source objects according to a description of the dependencies between the objects. Shape keeps track of the relevant parameters for compilations (source versions, compiler versions, compiler switches etc.) and thus provides a safe and efficient build machinery. .PP When shape compiles source objects, it stores the resulting derived objects together with the effective compile parameters in its \fIderived object cache\fP. Before the derivation process for a requested object is actually started, shape attempts to find an existing derived object that matches the requirements for the target, in the derived object cache. Caching and restoring of objects that are derived from immutable versions allows developers to profit from previous builds by other team members. Overall compile costs in projects are substantially reduced. .PP When serving a build request, shape considers a possibly large number of versions that are stored for an object. Which particular version is \fIbound\fP to an object's name in the description file, is determined by \fIversion selection rules\fP. .PP Shape can manage builds of different variants of a system in parallel. Shape uses the combined potential of dynamic version selection, dynamic macro redefinition, and derived object management to handle variant builds. As most \- if not all \- of the objects and parameters involved in a build are defined as \fImacros\fP, shape provides a great deal of flexibility by allowing to alter some or all of the macros dynamically, depending on which variant shall be built. The concept of \fIvariant definition\fP in shape's description file offers a clear focal point for all definitions that are relevant for a certain variant. .SH OPTIONS .IP "\fB\-f\ \fI\fR" \fIshape\fR uses the supplied argument as name of the description file to be used for the build. If no \fB\-f\fP option is specified, shape tries to find a description file under one of the names ``Shapefile'', ``shapefile'', ``Makefile'', and ``makefile'' (from left to right). If no regular file with one of these names can be found, but versions of respective files are available in the version object base, shape will use the most recent version. When more than one \fB\-f\fR \fI\fR argument pair appears, shape reads each description file in turn. If the name of the description file is specified as ``\-'', shape will read the system description from standard input. It is possible to specify the description file in bound version notation, e.g. \fIShapefile[2.8]\fP or \fIShapefile[Release4]\fP (see \fBvbind(1)\fP for details about bound version notation). .IP "\fB\-R\fI \fR" activates the specified selection rule as initial version binding for source objects. If the \fB\-R\fR option is present, and a selection rule is defined as the first dependency of the first target, shape will use the selection rule passed via the command line, and ignore the first (and only the first) selection rule activation within the description file. The option is useful to override initial default selection rules, specified within the description file, from the command line. .IP "\fB\-V\fI \fR" activates the variant specified by \fI\fP. Several variants can be activated simultaneously from the command line by specifying the \fB\-V\fP option multiple times. All variant specific definitions will be in effect as soon as shape reads the corresponding variant definition in the description file. .IP "\fB\-force \fI\fR" forces shape to build the specified target unconditionally, i.e. even if a suitable, previously build object exists. .IP "\fB\-echo \fI\fR" the value of the macro \fI\fR is written to standard output. This option is useful to extract information from the system description file (e.g. \fCshape \-echo SOURCES\fP, or \fCshape \-echo SUBSYSTEMS\fP), or to control the effect of variant activations. .IP "\fB\-rebuild \fI\fR" attempt a precise rebuild of \fItarget\fP according to a \fIbound configuration thread\fP, supplied in a file named \fI.\fCbct\fR (see description of \fB\-bct\fP switch). .IP \fB\-d\fR run shape in debug mode. Print out detailed information about object dependencies and attributes. .IP \fB\-D\fR print detailed information about the version binding process, and shape's reasoning regarding (re)builds of targets, or retrievals from the derived object cache. This switch is useful to find out about the exact reasons, why shape rederives a target (or not). .IP \fB\-e\fR macro definitions that are imported from the environment (see description of special macro \fIIMPORT\fP, below) override macro definitions in the description file (by default, macro definitions in the description file have precedence over imports from the environment). .IP \fB\-h\fP print usage information on standard output (this is an abbreviation for the \fB\-help\fP switch, see below). .IP \fB\-i\fR ignore error codes returned by commands. .IP \fB\-k\fR when a nonzero error status is returned by an invoked command, the work on the current target is abandoned but shape continues with other branches that do not depend on the failed target. .IP \fB\-n\fR no execution mode. Shape prints out commands, but does not execute them. Even command lines beginning with @ are printed. If a command contains the $(MAKE) macro reference, however, that line is always executed in order to allow tracing of recursive build processes. .IP \fB\-p\fR print out the complete set of macro definitions, target descriptions, and rule definitions, respectively. .IP \fB\-r\fR do not use shape's built-in implicit rules. Implicit rules defined in the description file remain in effect. .IP \fB\-s\fR run in silent mode. Shape does not print out the commands before executing them. .IP \fB\-bct\fP record the build in a \fIbound configuration thread\fP file. A shape configuration thread contains precise definitions of all source versions, their dependencies, the involved tools, and related options that were in effect for a build. The configuration thread for a produced toplevel target (the first target in the description file, or a target requested from the command line) is stored in a file named \fI.\fCbct\fR. Bound configuration threads can be used as input for rebuilds (see option \fB\-rebuild\fP, above). If the source version context of a bct-build is unsafe, shape will record that fact in the bct, and issue a warning message. .IP \fB\-help\fP print usage information on standard output. .IP \fB\-nomsg\fP turn off the trace facility \fImsg\fP in version selection rules. .IP \fB\-novclass\fP disable checking for incompatibility of activated variants. .IP \fB\-version\fP print the version identification of the shape program. .IP \fB\-xpoff\fP turn off attribute expansion in source versions retrieved from the object base. By default, attribute expansion is turned on for all source objects that are directly retrieved from the object base, and turned off for source objects that are regular files (see \fBretrv(1)\fP for details about attribute expansion). .IP \fB\-xpon\fP turn on attribute expansion for all source objects, even in regular files. By default, attribute expansion is turned off for source objects that are regular files, and turned on for all source objects that are directly retrieved from the object base. .IP \fItarget\ ...\fP A list of target names can be passed to shape via the command line. If no target is given on the command line, and the special target .DEFAULT is not defined within the description file, shape tries to produce the first target defined in the description file. .IP "\fI\fR" It is possible to define or modify macros in the description file from the command line. Macros that are defined this way take precedence over all other definitions. Command line macro definitions have either of two forms: .PP .ta 2.0c .nf \fINAME=VALUE\fP and \fINAME+=VALUE\fP .fi .PP with \fINAME\fP being a word and \fIVALUE\fP an arbitrary string. If \fIVALUE\fP contains white space, make sure to quote it. The first form of command line macro definitions sets \fINAME\fP to the substitution \fIVALUE\fP. If \fIVALUE\fP is empty, the macro is reset. The second form appends \fIVALUE\fP with a leading space character to the \fIcurrent substitution\fP of \fINAME\fP. The current substitution may be defined in the description file, or by a previous setting on the command line. For details about the semantics of macro definitions and substitutions, see the respective sections below. .SH "DESCRIPTION FILES" The operation of shape is controlled by a system description file (usually a \fIMakefile\fP) that provides structural information about the system to be managed. Other than \fBmake(1)\fP, shape works on top of \fIAtFS\fP (\fIAt\fPtributed \fPF\fPile \fPS\fPystem), a repository of versioned objects, rather than plain files. Thus, genuine shape description files (usually called \fIShapefile\fP) feature version selection rules, and variant definitions in addition to standard Makefile dependency rules. Shape's description file is an upward compatible extension of make(1)'s description file, the Makefile. A useful structuring convention for shape description files is to maintain a Makefile, and a Shapefile in parallel. Only genuine shape constructs (such as version selection rules, or variant definitions) are kept in \fIShapefile\fP, while the bulk of target rule- and macro definitions is kept in \fIMakefile\fP. The Makefile shall be \fIincluded\fP in \fIShapefile\fP (see description of \fIinclude\fP directive, below). This structuring convention has the advantage that programs that were developed with the support of the ShapeTools system can be shipped as source distribution to sites that don't use ShapeTools. .PP Although shape is largely downward compatible with the original make program, it should be noted that several popular extensions of the original make program, such as GNU Make or Sun Make, provide features \fInot\fP present in shape. See the section on known incompatibilities below. .PP The description file provides an ideal central information base for all sorts of product related definitions. Shape encourages the development of a set of (project\- or organization-specific) conventions for system description, and provides a simple way to extract this information for use by other tools (see \fB\-echo\fP option, above). The description file syntax not only serves to specify component dependencies that are relevant for build processes, but allows a general, hierarchical definition of product oriented tasks. The concept of recursive dependencies maps directly to a stepwise refinement of task definitions. Such tasks can be fully, partly, or not at all automated as appropriate. Thus, certain activities may be automated and standardized, while other activities are just informally described in order to document them or to reason about them (see \fBshape_rms(1)\fP for examples). .PP .SH "\fBSyntactical Structure\fP" The basic syntactical structure of shape's description file is made up of: .IP \fIComments\fP Comments begin with a ``\fC#\fP'' character and extend to the end of the line. In Shapefiles, the end of a line is defined as an unescaped newline (``\e\fI\fP''), or the end of the file. The comment character can't be escaped, but can be quoted in single\- or double quotes. Comment characters in command lines of target rules are ignored by shape. .IP \fIDirectives\fP Directives are special keywords, known to shape. Directives begin at column 0 of a line and extend to the line end. Currently, the only directive recognized by shape is .PP .nf \fCinclude\fI \fP .fi .IP "\fIMacro Definitions\fP" Macro definitions have the general form: .PP .nf \fINAME VALUE\fP .fi .PP \fINAME\fP must be a single word consisting of a sequence of name characters. Name characters are all printable characters except the following: .PP .ce \fC$ # : = ; \fI\fP \et \en\fR .PP The macro definition symbol is either of ``\fC=\fP'', ``\fC+=\fP'', or ``\fC:=\fP''. \fIVALUE\fP is an arbitrary string terminated by the end of the line, or a comment. Macro definitions usually begin in the first column of a line, but may be preceded by leading \fI\fP characters. Macro definitions must not contain leading \fI\fP characters (see section on \fIMacro Definitions\fP, below, for more details). .IP "\fIMacro References\fP" Macro references have one of the following forms: .PP .nf \fC$(\fI\fP) ${\fP\fP} $\fP\fR .fi .PP The macro substitution operator (``\fC$\fP'') can't be escaped, but can be represented by the substitution ``\fC$$\fP''. Macro substitution occurs anywhere in the description file, except in comments, macro names, left hand sides of version selection rule\- and variant definition headers (see next section), and variant class definitions (see section on \fIMacro Substitutions\fP, below, for more details). .IP \fIRules\fP Rules are made up from a \fIrule header\fP, and an optional \fIrule body\fP. The rule header consists of a \fIleft hand side\fP, a \fIrule definition symbol\fP, and an optional \fIright hand side\fP. The left hand side usually begins in column 0 of a line, and may be preceded by leading \fI\fP characters. Left hand sides of rule headers must not contain leading \fI\fP characters. The optional right hand side of a rule header extends to the end of the line, or the beginning of the rule body. A rule body consists of consecutive lines beginning with a \fI\fP character. The body of a rule is terminated by the next line not beginning with a \fI\fP character, or the end of the file. .RS .PP Shape recognizes three different kinds of rules, distinguished by their respective rule definition symbols: .IP \(bu 0.5c \fBtarget rules\fP. Target rules have a single colon character (``\fC:\fP'') as rule definition symbol. The left hand side of target rule headers is a space-separated list of names. The optional right hand side consists of a space-separated list of names, followed by an optional list of production ingredients (see section on \fITarget Rules\fP, below). .IP \(bu \fBversion selection rules\fP. Version selection rules have the rule definition symbol ``\fC:-\fP''. The rule header of version selection rules has a single word on its left hand side, and no right hand side (see section on \fIVersion Selection Rules\fP, below). .IP \(bu \fBvariant definitions\fP. Although variant definitions are \- as the name suggests \- \fIdefinitions\fP, not rules (from a semantical view point), their syntactical representation is that of a rule. Variant definitions have the rule definition symbol ``\fC:+\fP''. The rule header of a variant definition has a single word on its left hand side, and no right hand side (see section on \fIVariant Definitions\fP, below). .RE .IP "\fIVariant Class Definitions\fP" Variant class definitions have the form .PP .ce \fCvclass \fI\fP ::= (\fIvariant1, variant2, ...\fP)\fR .PP (see section on \fIVariants\fP, below). .IP "\fILine Continuations\fP If the end of an input line is escaped by a backslash (``\e'') the next line is considered as a continuation line. The backslash newline character sequence is replaced by a space. .SH \fBMacro Definitions\fP Macro definitions associate names with strings that will be substituted wherever the name of the macro is referenced (see next section). Macros are useful for writing maintainable, and somewhat generic description files. Even moderately large projects will find it extremely rewarding to define conventions for naming and usage of certain macros throughout the product description file. .PP There are three different kinds of macro definitions: .PP \fISimple Macro Definitions\fP .PP A simple macro definition looks like .PP .nf \fINAME \fC=\fP \fR .fi .PP The string that is associated with the macro name can contain macro references. If a macro is defined multiple times within a description file, the last definition will be effective. Macros defined on the command line take precedence over definitions of the same macro in the description file. .PP \fIAdditive Macro Definitions\fP .PP This type of macro definition looks like .PP .nf \fINAME \fC+=\fP \fR .fi .PP The string on the right hand side of the definition is appended to any existing value associated with \fINAME\fP, separated by a space character. Multiple additive macro definitions are concatenated in the order in which they appear in the description file. If an additive macro definition occurs on the command line, the last string value defined in the description file is prepended to the string value defined on the command line. Additive macro definitions in the description file are appended to string values defined on the command line. .PP \fIEvaluative Macro Definitions\fP .PP Evaluative macros are defined in the following way: .PP .nf \fINAME \fC:=\fP \fR .fi .PP First, the string value is associated to \fINAME\fP in the same way as for simple macro definitions. When \fINAME\fP is substituted for the first time, the right hand side of the definition is evaluated, and the result of this evaluation replaces the original string value associated with \fINAME\fP. Thus, evaluation of the right hand side occurs exactly once. This is particularly useful if the defining string is a command substitution (see next section). .SH \fBMacro Substitutions\fP Macro substitution is the process of substituting a \fImacro reference\fP by the string value associated with a macro name. References to undefined macros are substituted by an empty string. Macro references have either of the forms: .PP .nf \fC$(\fINAME\fP) ${\fINAME\fP} $\fI\fR .fi .PP The following are valid macro references: .PP .nf \fC$(CFLAGS) $7 ${SOURCE-FILES} $(X) $X\fR .fi .PP The last two references have identical substitutions. The macro reference .PP .nf \fC$$\fR .fi .PP will substitute a single dollar sign. .PP Before a macro reference is substituted, the associated string will be evaluated. Evaluation of a string value includes .IP \- 0.5c substitution of all macro references in the string value .IP \- command substitution. Any substring of the string value enclosed in backquotes (``\fC`\fP'') will be passed as command to the shell, and be replaced by the command's standard output. .IP \- string substitution. If a macro reference has the form .PP .nf \fC$(\fINAME\fP:\fP\fP=\fP\fP)\fR .fi .PP the reference will be substituted by the evaluated value of \fINAME\fP, with all occurrences of the string \fI\fP replaced by the string \fI\fP. This is particularly useful to maintain related lists, such as \fICSOURCES\fP and \fIOBJECTS\fP for example, automatically: .PP .nf \fCCSOURCES := `echo *.c` OBJECTS := $(CSOURCES:.c=.o) .fi .PP Shape substitutes macro references as late as possible. Macro references occurring in a macro definition are only substituted when the defined macro itself is substituted. Macro references on the dependencies side of target rules are substituted when the rule is evaluated. Macro references on the target side of target rules are substituted immediately after shape has read the description file, i.e. before any production is started. Macro references in include directives are substituted when the directive is executed while shape reads the description file. .SH \fBBuilt-in and Special Purpose Macros\fP In order to provide parametrization of shape's built-in implicit rules, a number of predefined macros is supplied by convention. These macros have meaningful initial values that can be altered by the user. There are also several macros that have special meaning for shape. .PP .nf .ta 3.0c 8.0c 12c \fBMacro Purpose Initial value Remark\fP .sp \fC@\fR full name of the current \fI\fP special target \fC?\fR list of target dependencies \fI\fP special \fC<\fR name of the first target \fI\fP special dependency \fC*\fR prefix shared by target \fI\fP special and the dependent filenames \fC#\fR bound version id of the current \fI\fP special dependency \fC$\fR the character ``\fC$\fP'' $ \fI\fP \fC+\fR name of object to be bound \fI\fP special to a version (selection rules only!) AS Program for doing assembly as conventional ASFLAGS Flags for the assembler \fI\fP conventional CC Program for compiling C cc conventional programs CFLAGS Flags for the C compiler \fI\fP conventional FC Program for compiling Fortran f77 conventional programs FFLAGS Flags for the Fortran compiler \fI\fP conventional HOSTTYPE Host architecture of the \fI\fP special computer that runs shape. The value of this macro is used by shape to construct the derivation key attribute for derived objects IMPORT List of environment variables \fI\fP special that shall be imported as macro definitions LD Program to link programs ld conventional LDFLAGS Flags for the linker \fI\fP conventional LEX Program to turn Lex grammars lex conventional into C or Ratfor programs LFLAGS Flags for the lexical analyzer \fI\fP conventional lex LOGNAME The name or network-id under \fI\fP special which the user who owns the shape process is logged on M2C Program for compiling Modula2 m2c conventional programs M2FLAGS Flags for the Modula2 compiler \fI\fP conventional MAKE The command line with which shape $(MAKEFLAGS) special shape has been invoked. This macro is used for recursive calls to shape MAKEFLAGS Command line flags relevant \fI\fP PC Program for compiling Pascal pc conventional programs PFLAGS Flags for the Pascal compiler \fI\fP conventional RFLAGS Flags for the Fortran compiler \fI\fP conventional for Ratfor programs SHAPEPID The process id of the \fI\fP special running shape program SHAPEVERSION The version id of the shape_CM-4.4 special shape program (or above) SHELL The command processor for /bin/sh special the target rule command lines. The referenced command processor must be able to take its commands from standard input (see section on \fICommand execution\fP, below) VPATH Search path extension for \fI\fP special localizing source components YACC Program to turn Yacc grammars yacc conventional into C programs YFLAGS Flags for yacc \fI\fP conventional vpath Dynamic search path extension \fI\fP special for variants of source components .fi .PP The function of the special purpose macros \fIHOSTTYPE\fP, \fIIMPORT\fP, \fPMAKE\fP, \fIVPATH\fP, and \fIvpath\fP are described in the sections on OPERATION, and Variants below. .SH \fBTarget Rules\fP A target rule defines how, and under what conditions a target is derived from a set of source objects and/or other targets. A target is a name that can refer to a file but need not to do so. Target rules have the following format: .ta 2.0c 4.0c .nf \fI... \fC:\fP [] [\fC+\fI...] [...] \e [\fC:\fI ...] [\fC;\fI ] \fC\et\fI[] ...\fR .fi .PP The header of a target rule (see \fISyntactical Structure\fP, above) consists of a list of \fBtargets\fP, terminated by a colon, followed by an optional list of \fBdependencies\fP, and an optional list of \fBproduction ingredients\fP, beginning after a second colon character. The rule header is terminated by a newline or a semicolon, and followed by the optional rule body. The rule body consists of \fBcommand lines\fP that are executed when a target needs to be rederived. The first command line may immediately follow the semicolon that terminates the rule header. Subsequent command lines must begin with a \fI\fP character. The target rule body is terminated by the first line that doesn't begin with a \fI\fP, or by the end of the file. .PP \fITargets\fP .PP When multiple targets appear on the left hand side of a rule header, and the derivation process needs to be started, shape will derive all of the targets in a single run. .PP \fIDependencies\fP .PP Shape checks a target's dependencies from left to right. The first dependency is examined whether it is the name of a version selection rule. If it is, shape sets the selection rule active (eclipsing all previous selection rule activations), and proceeds to the next dependency. Next, shape checks whether the dependency is a variant activation. If the dependency starts with a ``+'' character followed by the name of a variant, the variant is activated (see the section on \fIVariants\fP, below). Shape proceeds to check for variant activations until the first dependency that isn't a variant activation is found. Next, shape proceeds through the list of remaining dependencies, and \fIbinds\fP (or \fIderives\fP) each of them as necessary, performing a depth first traversal of the dependency graph (see the section on \fIOPERATION\fP, below). .PP \fIProduction Ingredients\fP .PP After all dependencies have been bound, shape constructs the \fIderivation key\fP for the target. The derivation key is an attribute that defines the complete set of parameters that determine whether a target needs to be rebuild. Besides all bound dependencies, the derivation key contains the \fIproduction ingredients\fP that were specified in the target rule header. Production ingredients are typically complete definitions of the macros that are referenced in the command lines of the rule's body. Thus, tool versions and switches affecting the operation of a tool can be made part of the derivation parameters of a target. In order to include macro definitions into the derivation key of a target, the special reference .PP .nf \fI+(NAME1) +(NAME2) ...\fP .fi .PP must occur in place of the production ingredients. .PP \fICommand Lines\fP .PP When shape concludes that a target needs to be (re-)derived, the commands in the target rule body are executed. The rule body consists of consecutive lines that are treated as separate commands. Each command line is evaluated as described in the section on \fIMacro Substitution\fP, above, and passed to the command interpreter defined by the macro \fISHELL\fP. Each command line is executed as a separate process. If complex commands are needed that don't fit on a single line, or if the overhead of repeated process invocations shall be avoided, a logical command line can be extended by escaping the newline with a backslash character (\e\fI\fP), and continuing it on the next physical line. .PP Command lines may be preceded by one or two special characters: .IP \fC\-\fP shape ignores any nonzero error code returned by a command line for which the first character is a minus sign. The minus sign is not passed to the shell. When a command returns a nonzero return status, shape usually considers the derivation process for the target as failure and terminates, unless the \fB\-i\fR or \fB\-k\fR switches, or the \fB.IGNORE\fR special target is in effect. .IP \fC@\fP If the first character of a command is a ``\fC@\fP'', shape does not print the command before executing it. The ``\fC@\fP'' is not passed to the shell. .IP \fC\@\-\fP If the first two non-\fI\fP characters are ``\fC@\-\fP'', shape ignores nonzero return codes, and suppresses the printing of the command line. .PP If shape is invoked in \fIno execution mode\fP (\fB\-n\fP), the evaluated command lines are printed on standard output, showing what shape \fIwould\fP do if invoked without \fB\-n\fP. Command lines that contain the macro reference \fI$(MAKE)\fP are always executed, even if \fB\-n\fP is set. This is done to allow simulation of recursive builds that may span over subdirectories. The reference \fI$(MAKE)\fP is substituted by a shape command invocation with all relevant command line switches set. .PP Within command lines of the rule body, some parts of the target rule header can be dynamically referenced. When a command line is evaluated, the following substitutions are possible .PP .ta 3.0c 4.0c .nf \fBReference Substitution\fR \fC$@\fR full name of the current target \fC$?\fR list of dependencies \fC$<\fR name of the first dependency \fC$*\fR prefix shared by current and the dependent filenames \fC$#\fR bound version id of the current dependency (implicit rules only) .fi .SH \fBImplicit Rules\fP Shape's target rules come in two different flavors: explicit, and implicit. Implicit rules can be seen as templates that define dependency patterns which apply to most targets of a given kind. For this reason, implicit rules are sometimes called \fIpattern rules\fP. Shape converts make's old-style implicit rules (e.g. \fC.c.o:\fP) to pattern rules while it reads the description file. A typical dependency pattern is, for example, the dependency of files containing linkable object code, e.g. \fImodule.o\fP to corresponding files containing source code, e.g. \fImodule.c\fP. The derivation process for most of these source/derived pairs is identical. Rather than writing separate rules for all source/derived dependencies of a system, it is possible to write a single, generic rule, called implicit rule. An implicit rule has the following format: .PP .ta 2.0c 3.0c 3.5c .nf \fC%\fI[\fC.\fI] \fC%\fI[\fC.\fI] ... \fC: %\fI[\fC.\fI] \fC%\fI[\fC.\fI]...\fC \e\fP [\fC:\fP ...] [\fC;\fI ] \fC\et\fP[] \fC\et\fP[] ...\fR .fi .PP While the structure of implicit rules is the same as described above, the names of targets and dependencies are replaced by target patterns, and dependency templates respectively. The percent character in a target pattern acts as wildcard that is matched against all of a target's name up to the optional trailing suffix. For shape, an object name \fIsuffix\fP is the sequence of characters enclosed by the last period character (``.'') within the name, and the \fI\fP character terminating the name. The following example illustrates shape's concept of suffixes: .PP .nf .ta 1.0c 4.0c \fBName Suffix\fC sample.cde cde sample.x.y.c c sample_c .sample.c c\fR .fi .PP The following is an example for an implicit rule that derives linkable object code from corresponding C source files: .ta 1.0c 2.0c 2.5c .PP .nf \fC%.o : %.c : +(CC) +(CFLAGS) \et@echo shape - executing: $(CC) -c $(CFLAGS) $#; \et@$(CC) $(CFLAGS) -E %.c | sed 's;^\e(# [0-9][0-9]* \e"\e)%.c\e(\e".*\e)$$;e\1$#\e2;' > %.i; \et@$(CC) -c $(CFLAGS) %.i; \et@rm %.i;\fR .fi .PP NOTE: This rule is shape's built-in implicit rule to compile C source files. The cryptic command sequence has the purpose to encode the complete file version id into the object code (e.g. \fCsample.c[3.4]\fP rather than \fCsample.c\fP). This is extremely useful in conjunction with with the \fB\-g\fP switch of most C compilers, and version sensitive debuggers, such as \fBvgdb\fP. .PP If a target is derived using implicit rules, the name of the target is matched against the target patterns of the implicit rules. If a rule matches, the matching portion of the target name (the \fIstem\fP, referred to by the ``\fC%\fP'') is consistently substituted for all other occurrences of the wildcard character throughout the rule. Once this is done, the implicit rule is treated like an explicit target rule. .SH \fBExplicit Rules\fP Explicit rules associate explicit target names with explicit dependencies. Explicit rules are most typically used to specify dependencies that cannot be covered by implicit rules, such as deriving an executable program by linking many object code modules. In many cases, explicit rules are used to specify only those target dependencies that are not implied by an implicit rule (such as include dependencies for object files), while the ``natural'' dependencies are assumed as being present. If a description file contains only this sort of explicit dependencies, the omitted implicit dependencies (and an applicable rule body) are automatically added by shape to the total list of target dependencies. .SH \fBBuilt-in Implicit Rules\fP Shape provides a number of predefined implicit target rules that cover many common source/target derivations. The following table lists target patterns, and dependency templates for shape's built-in implicit rules. .PP .nf .ta 3.0c 6.0c \fBTarget Dependency Derivation\fP \fC%.a %.c\fP Compile archive library from C source \fC%.c %.l\fP Generate C programs from Lex grammar \fC%.c %.y\fP Generate C programs from Yacc grammar \fC%.o %.l\fP Compile object code from Lex grammar \fC%.o %.y\fP Compile object code from Yacc grammar \fC%.o %.s\fP Translate assembler program to object code \fC%.o %.r\fP Compile Ratfor source \fC%.o %.F\fP Compile Fortran source \fC%.o %.f\fP Compile Fortran source \fC%.sym %.def\fP Compile Modula definition modules \fC%.o %.mod\fP Compile Modula implementation modules \fC%.o %.p\fP Compile Pascal source \fC%.o %.c\fP Compile C source \fC% %.sh\fP Make executable program from shell-script \fC% %.r\fP Build executable program from Ratfor source \fC% %.F\fP Build executable program from Fortran source \fC% %.f\fP Build executable program from Fortran source \fC% %.p\fP Build executable program from Pascal source \fC% %.mod\fP Build executable program from Modula source \fC% %.c\fP Build executable program from C source .fi .PP .ta 2.0c For a complete definition of shape's built-in implicit rules, run \fCshape -p\fP. .SH \fBSpecial Purpose Targets\fP Several aspects of shape's operation are controlled by special purpose targets that can be put into the description file. Special purpose targets by convention begin with a period character, and have no associated commands. .PP .nf .ta 3.0c \fBTarget Purpose\fP .fi .IP ".DEFAULT:" 3.0c commands in the rule body of the \fI.DEFAULT\fP target rule are executed for all targets that cannot be derived by explicit or implicit target rules. If no commands at all shall be executed for a rule but \fI.DEFAULT\fP is needed for other targets, that rule can be given an empty command (either a ``\fC;\fP'' at the end of the rule header, or an empty line beginning with \fI\fP). If \fI.DEFAULT\fP has dependencies, and no targets are requested from the command line, these dependencies are treated as if they were targets requested from the command line. .IP ".IGNORE:" causes shape to ignore non zero return codes of invoked commands. Equivalent to the \fB\-i\fR switch .IP ".SILENT:" silent command execution. The command lines are not printed before execution. Equivalent to the \fB\-s\fR switch .IP ".BPOOL:" only the dependencies associated with this target are stored in the derived object cache .IP ".NOBPOOL:" dependencies associated with this target are \fInot\fR stored in the derived object cache. .PP If both, \fI.BPOOL\fP, and \fI.NOBPOOL\fP are defined, only the difference set of both dependency lists will be stored in the derived object cache. .SH \fBVersion Selection Rules\fP When shape builds a target, it uses \fIversion selection rules\fP to bind a unique version to each name of the prerequisite source objects. Version selection rules consist of a name, and an associated set of \fIpredicate lists\fP in the rule body. The format of version selection rules is: .ta 2.0c 3.0c .nf \fI [\fC( \fI\fC, \fI\fC,\fI...\fC)\fI]\fC :- \et\fI[\fC,\fP] \fC(...), \fI \fC(...); \et\fI[\fC,\fP] \fC(...), \fI \fC(...); ... \et.\fR .fi The body of a version selection rule consists of a sequence of \fIalternatives\fP, separated by semicolons. Each of the alternatives is an optional pattern, followed by a comma-separated list of \fIpredicates\fP. The selection rule is terminated by a period character. The semicolon-separated sequence of alternatives in a version selection rule constitutes a logical \fIOR\fP expression. The comma-separated list of predicates in an alternative constitutes a logical \fIAND\fP expression. .PP \fIVersion Binding\fP .PP Version binding is the process of determining exactly one version of a given source object from the set of all available versions. Version binding is said to \fIsucceed\fP if one of the rule alternatives succeeds. An alternative succeeds, if it leads to the identification of exactly one version. It is said to \fIfail\fP otherwise. When shape binds a version to the name of a source object, it tries each alternative with a matching pattern, until the name is unambiguously bound to a version. If the pattern is omitted, the alternative will be tried unconditionally. .PP The functioning of version selection rules is one of shape's most important, yet most subtile aspects. In order to provide a basis for an intuitive understanding of the selection rule mechanism, an example is described. The rule \fImost_recent\fP, below, binds: .br \-\ files that were checked out for modification by the shape-invoking user .br \- versions of files that were recently modified (\(-> status \fIsaved\fP) by the same user .br \- the most recently proposed version (\(-> status \fIproposed\fP) of files modified by other users, .br \- or the file version from the last release. .PP .ta 1.0c 2.0c 2.5c 7.5c .nf \fCLASTRELEASE := `lastrelease` # "lastrelease" returns the name # of the last release most_recent :- eq (status, busy), exists ($+[locked_by($(LOGNAME)):]); ge (status, saved), max (mtime), max (version), eq (author, $(LOGNAME)); ge (status, proposed), max (mtime), max (version); eq (__SymbolicName__, $(LASTRELEASE)); cut ($_rule$: couldn't bind $+ as requested!). locked_by (user_id) :- max (version), eq (locker, $_user_id$). .fi .PP For a more detailed description of version selection rule syntax, semantics, and the list of built-in predicates, see \fBBindRules(7)\fP. .PP \fIActivation of Version Selection Rules\fP .PP A version selection for a certain target is invoked by specifying the name of the selection rule as first dependency of a target, or by supplying a selection rule name as argument to the \fB\-R\fP option. If no selection rule is specified explicitly, shape uses its built-in version selection rule that tries to bind a regular file, or the most recent version to the name of an object. .SH \fBVariants\fP The term \fIvariant\fP refers to the intention to manage a product that must comply with different sets of varying external constraints as a unit. Independently from particular semantics that might be associated with the variant notion, there exists a small number of techniques to implement software variation on a technical level. These techniques are: .PP \fIphysical separation\fP of variant components. This is achieved by maintaining separate copies of components in different directories, or by maintaining variant specific branches in version control systems; .PP \fIsource preprocessing\fP of variant components. With this technique, multiple logical variants of a source component are maintained in a single file that contains preprocessor instructions. Before a particular variant can be accessed, a preprocessor must extract it from the common source. A popular example of this technique is \fIconditional compilation\fP, controlled by the \fC#if\fP, and \fC#ifdef\fP instructions within the domain of C/C++ programming; .PP \fIcomposition variation\fP of complex product variants. This technique addresses the case when different variants of a complex product (such as a program) are composed from different sets of components; .PP \fIderivation variation\fP (or variation of the process) that produces different variants of derived objects from the same set of sources by modifying parameters of the derivation process. A typical example for this case is cross compilation of the same sources for different target platforms, or code instrumentation for various purposes, such as debugging, testing, profiling, or optimization. .PP Depending on the particular needs of a project, all of these techniques may be in simultaneous use, and can occur intermixed as appropriate. Shape allows to associate logical variant names with a set of definitions that control all of the above mentioned techniques, making it possible to request builds of particular system variants (and combinations of compatible variants) without the need to worry about how these variants are realized technically. .SH \fBVariant Definitions\fP Shape derives its flexibility from using \fImacro substitution\fP in the description file wherever possible. Shape variant definitions are basically groups of macro definitions that take effect when the variant is activated for a build. A variant definition has the following format: .PP .ta 2.0c 3.0c .nf \fI\fC :+ \et\fI\fC=\fI ...\fR .fi .PP When a variant is activated, the macro definitions associated with the variant become effective. Any previous definition of a macro made in the description file, or on the command line is replaced by the variant macro substitution. If a macro is defined in several variants that are activated together, the respective values are concatenated. .PP \fILocating physically separate Variant Source Objects\fP .PP Shape provides a special macro, \fIvpath\fP, that is intended to be used in variant definitions. The \fIvpath\fP macro defines shape's search precedence when source version archives are located. If \fIvpath\fP is non-empty, shape tries to find any referenced source object in the vpath directories first. If several activated variants define vpath, the variant search path is concatenated and searched from right to left, i.e. the last variant that has been activated has precedence. Only if a referenced source component cannot be found in any of the vpath directories, the current directory is searched. If a source object has been found, it will be bound by the current version selection rule, and be temporarily installed in the build directory. This means that components which are maintained in a vpath subdirectory are temporarily moved up to the main directory. Thus, it is not necessary to make any reference to a vpath subdirectory path in the target rules. .PP \fIVariant Activation\fP .PP When a product is configured and built, variants are typically activated by supplying a variant name as argument to the \fB\-V\fP options. .PP Variants can also be activated for a given target by specifying respective, ``\fC+\fP''-prefixed variant names as dependencies (see section on Target Rules, above). Variant activations for a target must occur before any real object dependency on the dependency line, and after the optional version selection rule activation. .SH \fBVariant Class Definitions\fP With \fIVariant class definitions\fP, shape offers a construct that allows to define \fIincompatible variants\fP, i.e. variants that cannot be activated simultaneously. Shape variant class definitions have the following format: .PP .nf \fCvclass\fI \fP ::= ( \fI\fP, \fP ...\fC)\fR .fi .PP The same variant name can occur in multiple variant class definitions. If a combination of variants is requested with any two variant names that are member of the same variant class, shape will issue an error message, and terminate. Checking of variant classes can be disabled by specifying the \fB\-novclass\fP switch on the command line. .PP NOTE: variant class definitions must occur in the description file \fIbefore\fP any variant definition referenced in a variant class. Variant classes that are defined after referenced variants cannot enforce mutual exclusion of incompatible variants. .PP \fIAn Example\fP .PP The following example shall illustrate the use of variant definitions, and variant classes: .PP .ta 1.0c 2.0c .nf \fCvclass compiler ::= (gnu, prop) gnu:+ CC = gcc -Wall OPTIMIZE = -O2 -inline-functions DEBUG = -g -g3 PROFILE = -pg -a STDC = -ansi prop:+ CC = cc OPTIMIZE = +O3 DEBUG = -g -z +Y PROFILE = -G STDC = -Aa vclass quality ::= (debug, profile, optimize) debug:+ VARCFLAGS = $(DEBUG) profile:+ VARCFLAGS = $(PROFILE) optimize:+ VARCFLAGS = $(OPTIMIZE) CFLAGS += $(VARCFLAGS)\fR .PP .fi If a variant requires the modification of macros with predefined meaning, it is sometimes a good idea \fInot\fP to redefine the macro itself in the variant section. In such a case it is possible to augment an existing macro value by using shape's additive macro definition facility, and a macro from the variant definition defined for this purpose (e.g. \fIVARCFLAGS\fP in the example above). .SH OPERATION When invoked, shape first parses the command line. Shape records the names of the variants to be activated from the command line via the \fB\-V\fP option. Next, shape initializes the built-in, and special macros. Also, shape's built-in derivation rules are initialized. .PP \fIReading the Description File\fP .PP After that, all macro definitions made on the command line are made effective. Shape then locates and opens its description file. If no description file is specified as argument to the \fB\-f\fP option, shape tries to find one of the files \fIShapefile\fP, \fIshapefile\fP, \fIMakefile\fP, or \fImakefile\fP. For each of these names, shape tries to find a regular file first, and, if no such file exists, to find the most recent version of that file in a version control archive. If no such version can be found, shape tries the next name. .PP When shape reads the description file, it collects all macro definitions, and makes them immediately effective, unless a macro of the same name has been defined on the command line. If the special macro \fIIMPORT\fP is encountered, the listed environment variables are defined as macros. If macros with the same name as an imported environment variable occurs in the description file, it has precedence over the definition from the environment, unless the \fB\-e\fP switch is in effect. .PP When shape reads an \fIinclude\fP directive, it evaluates the rest of the line (i.e. the characters that immediately follow the directive), and interprets each word as the name of a file to be read. Each of the file names is bound to either a regular file, or the most recent version of the file. Shape opens each of the included files, suspends reading the current description file, and continues to read the contents of the included file(s), before it resumes reading of the original control file. If multiple file names are specified in an include directive, shape reads each of the files in turn, starting with the leftmost, and ending with the rightmost file name. If an included file could not be opened, shape issues a warning. .PP While shape reads its description files, version selection rules, and target rules are \fIcollected\fP. They are \fIdefined\fP only after shape has finished reading the description file. Macro\-, variant\-, and variant class definitions are made effective as soon as they have been recognized. .PP \fIThe Build Process\fP .PP After the description file has been read, shape determines which targets have been requested. If targets have been requested from the command line, shape will attempt to build each of them, starting with the leftmost target and proceeding towards the rightmost. If no target has been requested from the command line, shape searches the description file for a target named \fI.DEFAULT\fP. If such a target exists, and there are any dependencies associated with it, shape will attempt to build each of these dependencies, from left to right. If no \fI.DEFAULT\fP target rule has been defined in the description file, shape will attempt to build the \fIfirst target defined in the description file\fP. .PP When shape builds a target, it proceeds as follows: .IP 1) 0.7c determine the names of the source objects for a given target by traversing the dependency graph, using built-in and user supplied target rules. The dependency graph is traversed depth first. The ids of all applied rules are recorded. .IP 2) for each required source object, locate the source version archive in the repository. Locating of source version archives takes the current \fIvpath\fP into account. .IP 3) bind each of the source object's names to an appropriate version as implied by the currently active version selection rule. Record the id of each bound dependency. If a dependency is itself a derived object, use its \fIcache key\fP as id. .IP 4) construct the \fIderivation key\fP for the current target from the target name and the records resulting from steps 1) and 3). .IP 5) search the derived object cache for an object that has a derivation key identical to the key constructed in step 4). .IP 6a) if an appropriate derived object was found, a copy of it is installed in the build directory, rather than deriving it from its sources. .IP 6b) if no appropriate derived object was found, it is created by deriving it from its parts. The resulting derived object is put into the derived object cache, and associated with the derivation key resulting from step 4). .PP Targets with an empty list of dependencies \- and thus an empty derivation key \- are always (re-) derived. .PP When shape determines the dependencies of a requested target, it does so by evaluating either explicit target rules, or by applying \- possibly built-in \- implicit rules. If explicit target rules specify object dependencies but no derivation script in the rule body, shape will attempt to supply an appropriate default derivation script. When searching for such a default derivation script, shape tries to find an applicable implicit rule for the current target. An implicit rule is considered applicable, if it has the current target in its list of targets (after pattern substitution), and all \- explicit, and implied \- dependencies exist. If no implicit rule is found to be applicable, shape looks for the \fI.DEFAULT\fP target rule. If such a rule exists, and if it has an associated derivation script in its rule body, this script will be supplied as default derivation script. If neither of the two possibilities leads to a default derivation script, shape gives up. .PP \fIDerived Object Caching\fP .PP Before the derivation process for a requested target is started, it is attempted to find a suitable derived object in the derived object cache that matches the required properties. Shape is based on the \fIderivation key\fP concept for target objects. The derivation key is constructed according to the algorithm described above. Relevant parameters that go into the derivation key are the \fIlist of dependency ids\fP, the \fItarget rule id\fP, the \fIlist of production ingredients\fP, the \fIbuild platform\fP (usually defined by the macro \fIHOSTTYPE\fP; if this macro is not defined, shape takes the host id as build platform), and the \fIattribute expansion status\fP of each source object. When an object has been derived, shape stores it in the derived object cache, and marks it with the derivation key attribute. For a detailed trace of shape's derived object cache handling, and the use of derivation keys, run shape with the \fB\-D\fP switch. .PP \fICommand Execution\fP .PP When a target needs to be (re-) derived, shape executes the commands associated with the target. Before the commands are executed, shape sets up the command execution context. The version objects of the target's dependencies are installed as regular files in the file system. If necessary, shape retrieves source objects from the version control archive. If a file with the object's name already exists in the place where a version is to be installed, shape will temporarily move it to the \fIAtFS\fP subdirectory. After the command script has completed, shape will restore the original state of all affected directories. .PP Shape executes a command line by starting the program referenced in the \fI$(SHELL)\fP macro, and opening a pipe to the resulting process. The command line is written to the pipe, and thus sent to the \fI$(SHELL)\fP process' standard input. .PP Each of the command lines in a rule body are executed by a separate process. Thus, the execution status of separate commands is not preserved. If multiple commands are needed that rely on the execution status of previous commands, all these commands must occur in a single command line. This is possible with \fIline continuations\fP (see section on \fISyntactical Structure\fP, above). .br NOTE: many command interpreters use the ``\fC$\fP'' character as special symbol (typically as variable reference). Make sure to pass ``\fC$\fP'' characters in commands to the \fI$(SHELL)\fP process by using the ``\fC$$\fP'' special macro (see section on \fIMacro References\fP, above). .SH INCOMPATIBILITIES In order to facilitate migration from \fBmake(1)\fP, shape was designed to be upward compatible with Makefiles. Although most of make's description file features are present in shape, there is a number of incompatibilities that may need to be taken care of. There exists also a number of popular extensions of the original make program (e.g. Sun's Make, HP's Make, GNU Make, nmake etc.) that offer various special features that aren't supported by other make extensions, or by shape. When a migration from make to shape is planned, it should be checked whether special extensions or incompatible features are used. .PP \fIFeatures not supported by shape\fP .IP "\fBDouble colon rules\fP" Double colon rules associate the same target with different derivation scripts. This type of rule is useful to support different derivations for a target depending on which dependencies are out of date. Because shape bases its decision whether to derive on the \fIderivation key\fP, rather than mere modification time stamps of files, this sort of rule makes no sense in shape. .IP "\fBArchive member targets\fP" Archive member targets are objects that live in an archive file (see \fBar(1)\fP) rather than the file system. Within these archives, make bases its decisions on the modification time stamps of source files, and archive entry dates. There is no way for shape to simulate the concept of derivation keys for archive members. Maintenance of archives, however, is easy with shape, because all data for compiled object files is maintained in the derived object cache. If the source for an object that is stored in an archive is modified, shape can rederive this object, and selectively replace the entry in the archive. .IP "\fBSCCS stuff\fP" In order to provide basic support for team oriented development processes, make allows to retrieve the most recent version of source files from SCCS archives. Because of the awkward naming convention for SCCS version archive files, special support for dealing with these archives had to be built into make. Because shape is tightly integrated with the \fIAtFS\fP version object repository, there is no need for any special SCCS support. .IP "\fBSpecial targets\fP" Shape does not recognize the special targets \fI.PRECIOUS:\fP, and \fI.SUFFIXES:\fP. The .PRECIOUS target in Makefiles has the purpose to prevent deletion of expensively derived intermediate targets (by default, make deletes intermediate targets). Because shape stores intermediate targets in the derived object cache, there is no need for the .PRECIOUS feature. To prevent caching of possibly large, useless intermediate targets, use the \fI.NOBPOOL:\fP special target (see section on \fISpecial Targets\fP, above). The .SUFFIXES target in Makefiles has the purpose to introduce new suffix types into make's derivation engine, and to determine the order in which implicit rules (\fIsuffix rules\fP in make terminology) are applied. In shape, new suffix types can be added dynamically, simply by introducing new implicit rules. Moreover, shape has an intelligent algorithm the determines the applicable implicit rule. .PP \fIFeatures with different semantics\fP .PP .IP "\fBEnvironment Variables\fP" Many make programs import the entire set of environment variables as macro definitions into the build process. This can sometimes produce surprising results. In shape, environment variables are explicitly imported with the \fIIMPORT\fP special macro. .IP "\fB? Macro\fP" In make's target rules, the special macro reference \fC$?\fP is substituted by the names of those dependency file names that have been updated since the current target has been derived. Because shape bases its decision whether to derive on the concept of \fIderivation key\fP, rather than mere file modification time stamps, the \fI?\fP macro cannot be correctly defined. Instead, shape substitutes the entire list of dependency names \- updated or not. .SH FILES Shapefile, shapefile, Makefile, makefile, /tmp/shapeXXXXXX, \fI\fP.bct .SH "SEE ALSO" \fBmake(1)\fP, \fPsave(1)\fP, \fPretrv(1)\fP, \fPvadm(1)\fP, \fPvl(1)\fP, \fPvgdb(1)\fP, \fPvbind(1)\fP, \fPafintro(3)\fP, \fPatfstkintro(3)\fP, \fPsttkintro(3)\fP, \fPbindrules(7)\fP .SH "CAVEATS AND BUGS" Macro references containing string substitutions cause a syntax error if used in place of target dependencies. Workaround: use indirect macro substitution. .PP There are probably more bugs in shape. Please report any bug findings to \fIshape-cr@cs.tu-berlin.de\fP. .SH "FURTHER READING" .IP "\fIAxel Mahler:\fP" 2.5c ``Using the Shape Toolkit for Cooperative Software Development \- A Tutorial'', in the toolkit distribution. .IP "\fIAxel Mahler \fPand\fP Andreas Lampen\fP:" ``An Integrated Toolset for Engineering Software Configurations'', Sigplan Notices, Vol. 24, No. 2, or Software Engineering Notes, Vol. 13, No. 5, November 1988. .IP "\fIAndreas Lampen\fP and \fPAxel Mahler\fP:" ``An Object Base for Attributed Software Objects'', Proceedings of the Fall 1988 EUUG Conference. .PP These and other papers are available via anonymous ftp from \fIcoma.cs.tu-berlin.de\fP (pub/shapeTools/papers). .SH AUTHOR \fIShape\fP was designed by the shape project team at Technical University Berlin. The program was originally implemented by Wolfgang Obst (1988). Extensive fixes and modifications were introduced by Axel Mahler (1992). Valuable contributions came from Steve Emmerson. In 1993 most parts of shape were re-implemented by Axel Mahler. The version binding was re-implemented by Andreas Lampen. A complete re-implementation of the Shapefile parser was done by Juergen Nickelsen. .sp Contact: .nf SHAPE Technical University Berlin Sekr. FR 5-6 Franklinstr. 28/29 10587 Berlin .sp General correspondence: shape@cs.tu-berlin.de Bug reports and modification requests: shape-cr@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/atfsit.1100444 2013 145 12225 5414050633 16145 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Authors: Michael Cooper (mcooper@usc-oberon.ARPA) Axel Mahler (Axel.Mahler@cs.tu-berlin.de) $Header: atfsit.1[4.0] Tue Jun 29 16:29:16 1993 andy@cs.tu-berlin.de frozen $ .. .TH atfsit 1 "Tue Jun 29 16:29:16 1993" "atfsit-1.15" "ShapeTools" .SH NAME atfsit \- A program to prepare files for version control .SH SYNOPSIS atfsit [ .B \-cFhfsmM ] [ .B \-qad ] [ \fB-I\fP\fIflags\fP ] [ \fB-R\fP\fIflags\fP ] [ \fB-t\fP\fIdirectory\fP ] file1 ... .SH DESCRIPTION .I Atfsit is a semi-intelligent program to prepare files for .I ShapeTools version control. This involves putting the correct type of headings at the top of the file so that .I retrv will update a header and log changes in the file. .PP By default, .I atfsit will use default headers ``hard-wired'' into itself for each different file type that it ``knows'' about. (See below for list of known file types). .PP If the \-t\fIdirectory\fP option is specified, then .I atfsit will use ``.template.suffix'' files (where ``suffix'' is a suffix that .I atfsit ``knows'' about) found in .I directory. If a directory name is not specified on the command line, then the environment variable TEMPLATES is used. If $TEMPLATES is not set, then the environment variable, HOME is tried. .LP The following template files are recognized: .sp 2 .ta 2c 5c .nf Template Name File Type --------------------------------------- .template.c Standard C .template.h C Include .template.f Fortran .template.sh Shell Script .template.make Makefile .template.man Manual .fi .sp 2 .PP .I Atfsit is ``semi-intelligent'' in that it can guess the type of headers to put in the file by the type of file (C program, C include, makefile, shell script, or manual). It determines the file type by looking at the name of the file. If the name of the file is ``Makefile'' or ``makefile'', then the file type is taken to be for .I make(1). The suffix after the last ``.'' in the file name is then used. The following table shows the suffixes that .I atfsit knows about: .nf .sp 2 .ta 2c 5c Suffix File Type --------------------------------------------- c C Program F C Program (with compile flags) h C Include f Fortran mk \fIMake(1)\fP file sh Shell Script csh Shell Script [1-9] Manual (digits 1 - 9) .fi .PP If the environement variable ``ATFSDIR'' is present, then .I atfsit will attempt to make a link from it to ``AtFS'' in the current directory if the \-\fII\fP option is used and there is no directory called ``AtFS'' already, in the current directory. If the \-\fII\fP option is used and ``ATFSDIR'' is not specified in the environment, then a normal directory called ``AtFS'' will be created. This feature can be overrided with the \-\fId\fP option. .SH OPTIONS .TP 10 .B "c" Force file type to be ``Standard C''. .TP 10 .B "F" Force file type to be ``Standard C''. Add a special header-line for recording of compile-time options in addition to the default header. The inserted line has the form \fCstatic char *ConfFlg = CFFLGS\fP. CFFLGS must be a string value. As it is very inconvenient, to define the proper value of CFFLGS from the command-line, this feature is more intended to be used from within Makefiles. .TP 10 .B "h" Force file type to be ``C Include''. .TP 10 .B "f" Force file type to be ``Fortran''. .TP 10 .B "M" Force file type to be ``Manual''. Note: If you also specify the ``I\fIflags\fP'' option, .I atfsit will run .I vadm(1) to tell ShapeTools what kind of comment string to use for the manual file. .TP 10 .B "s" Force file type to be ``Shell Script''. .TP 10 .B "m" Force file type to be ``Makefile''. Note that this does the same thing as the -s option does. It just prints a different message. .TP 10 .B "t" Do not use any Template files for the headers. .TP 10 .B "q" Be quiet. Don't print out what is going on. Only error messages are printed. .TP 10 .B "d" Do not attempt to make the directory ``AtFS''. See above for more info. .TP 10 .B "a" Turn off auto guessing of file type. .TP 10 .B "I\fIflags\fP" Check In file. Run .I save(1) on the file with ``flags'' being passed onto .I save(1) as the command line arguments. .TP 10 .B "R\fIflags\fP" Run .I vadm(1) with ``flags'' as the command line arguments. .SH FILES /tmp/atfsit* - temporary buffer .br ~/.template.* - template files to use as the header. .br .SH AUTHOR Michael Cooper (mcooper@usc-oberon.ARPA) .br Modified for use with \fIShapeTools\fP by Axel.Mahler@cs.tu-berlin.de .SH SEE ALSO save(1), vadm(1), retrv(1). .SH DIAGNOSTICS Complains about the usual stuff. (i.e. - the specified file doesn't exist, or it can't read it...just things like that.) shapetools-1.4pl6.orig/man/man1/rcs2atfs.1100444 2013 145 16566 5414051317 16416 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Juergen.Nickelsen@cs.tu-berlin.de $Header: rcs2atfs.1[3.0] Tue Jun 29 16:38:28 1993 andy@cs.tu-berlin.de frozen $ .. .de CR \\fC\\$1\\fP\\fR\\$2\\fP .. .de RB \\$1\\fB\\$2\\fP .. .TH rcs2atfs 1 "Tue Jun 29 16:38:28 1993" "rcs2atfs-1.9" "ShapeTools" .SH NAME rcs2atfs \- convert RCS archives to AtFS format .SH SYNOPSIS .B rcs2atfs .RB [ \-o .IR outputfile ] .RB [ .BR \-q ] .IR archive " ..." .br .B rcs2atfs .RB [ \-o .IR outputfile ] .RB [ .BR \-q ] .B \-R .IR directory " ..." .SH DESCRIPTION .B Rcs2atfs converts version histories from RCS archives to ShapeTools' AtFS format. It uses .IR rlog (1) to get information about an RCS archive and issues shell commands (usually through a pipe directly to .CR /bin/sh ) to check out the RCS revisions and check the files in as AtFS versions, trying to keep as many attributes as possible. .LP .B The RCS archives are left unchanged. .LP It is recommended to create a special directory with the name \fCRCS\fP for the RCS archives, but AtFS histories are .I always kept in a special directory .CR AtFS . .LP .B Rcs2atfs treats its arguments as names of RCS archives. These can be the names of the archive files themselves, ending with .CR ,v , or the names of the files stored in the archives. .LP If the .B \-R option is given, the arguments are interpreted as directory names. .B Rcs2atfs recursively descends each directory tree (symbolic links are followed) and converts the RCS archives it finds. The correspondig AtFS archives are created where the RCS archives are found. .LP .B Rcs2atfs tries to keep the revision numbers of the RCS history also as AtFS version numbers. This is impossible if an RCS history contains branches. In this case the revisions are saved as AtFS versions in the order of their check-in date. In either case the RCS revision number is kept as a symbolic name for the corresponding AtFS version, e.g. the AtFS version of RCS revision 1.2 will have the symbolic name ``\fCr1.2\fP''. .SS Attributes that don't change: .IP \(bu 0.3c author .IP \(bu log message .IP \(bu comment leader .IP \(bu description .IP \(bu symbolic names (with the exception of the .I additional symbolic name derived from the RCS revision number) .SS Other attributes: .TP mtime set to the check-in date of the RCS revision .TP state The value of this attribute is given to the AtFS attribute RCSstate. If it has the value .CR Exp , the state of the AtFS version will be .CR saved , if .CR Stab , it will be .CR proposed , if .CR Rel , it will be .CR published . .SH OPTIONS .TP .B \-R (recursive) .br The arguments are treated as directories. .B Rcs2atfs recursively descends the directory tree (symbolic links are followed) and builds an AtFS archive for each RCS archive it finds. .TP .BI \-o " outputfile" .B rcs2atfs writes shell commands to .IR outputfile , not directly to \fC/bin/sh\fP, and no conversion is done. If this shell script is executed from the directory where .B rcs2atfs was invoked, the archives are converted as if .B rcs2atfs had been invoked without .BR \-o . .br The main use of this option is to investigate problems with the conversion of archives. .TP .B \-q (quiet) .br The names and revision numbers of converted archives are not echoed on standard output. .SH EXAMPLES The command .IP \fCrcs2atfs -R $HOME/development\fP .LP traverses the directory tree \fC$HOME/development\fP and converts every RCS archive in it into an AtFS archive. During the conversion, the name of every RCS archive and every revision number is echoed on standard output. .IP \fCrcs2atfs -q RCS/*\fP .LP Each archive in the RCS directory is converted to an AtFS history. The names and revision numbers of the converted archives are not echoed. .SH SEE ALSO sh(1), rcsintro(1), rcs(1), rlog(1), co(1), vcintro(1), save(1), vadm(1), utime(1) .SH DIAGNOSTICS .SS Warnings .TP \fC-R flag not set, directory skipped\fP If the .B \-R flag is not set, directories given as arguments in the command line are ignored. .TP \fClocked version(s) exist\fP A revision of the specified RCS history is locked. This is not really a problem, but perhaps .B rcs2atfs does not convert the most recent version of the file. .TP \fCbranches exist, can't keep revision numbers\fP If the RCS history contains branches, the numbers of AtFS versions cannot be the same as those of the corresponding RCS revisions. .TP \fCsymbolic name to non-existent revision\fP .I rlog has reported a symbolic name of a revision that does not exist in this archive. Probably this never happens (I don't know), but if, the symbolic name is ignored. .SS Errors .TP \fCATFS history exists, file skipped\fP The specified file is already known to AtFS as a history or a busy version. This file will nor be converted. .LP \fCcolon after symbolic name missing, file skipped\fP .br \fCrevision not found, file skipped\fP .br \fCdate not found, file skipped\fP .br \fCauthor not found, file skipped\fP .br \fCstatus not found, file skipped\fP .br \fCrlog information missing, file skipped\fP .IP These messages indicate problems with the .I rlog output, perhaps an old rlog version is used. .RB ( rcs2atfs works correctly with .I rlog version 5.5.) .br The specified file will not be converted. .TP \fCrlog command failed, file skipped\fP For some unknown reason .I rlog returned a non-zero exit status. .I rlog should have provided an explanatory message. .SS Fatal Errors .TP \fCpopen to rlog command failed\fP The .I rlog command could not be invoked. .TP \fCpopen to shell failed\fP The shell could not be invoked. .TP \fCno more core\fP .B Rcs2atfs could not allocate enough memory. The amount of memory in your machine should be increased. .SS Internal Errors .LP \fCOops? Unknown reader state in readin_rcsfile!\fP .br \fCrevision numbers corrupted\fP .br \fCnumber of revisions is wrong!\fP .IP You should never see these error messages. .SH CAVEATS If .B rcs2atfs visits the same RCS archive twice (e.g. because a symbolic link is followed to a directory which is also accessed directly), the check for existing AtFS archives may be done a second time before the conversion commands from the first visit are executed by the shell. This results in lots of annoying messages and duplicate AtFS versions of RCS revisions. To avoid this, make sure that .B rcs2atfs doesn't reach a directory twice. .SH BUGS .B Rcs2atfs is rather slow since it invokes a shell command for every action. .LP Attribute citations in files are not translated from RCS to AtFS (e.g. ``\fC$Header: ... $\fP'' to ``\fC$__\&Header$\fP''). .LP .B Rcs2atfs strongly relies on the format of .IR rlog 's output. Since I don't know any other .I rlog than our version (5.5), it may fail to work with other versions. .LP Due to the lack of serious RCS archives, .B rcs2atfs isn't thoroughly tested yet. (Well, we use ShapeTools. :\-) .SH AUTHOR Juergen.Nickelsen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/utime.1100444 2013 145 2336 5414051306 15756 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Juergen.Nickelsen@cs.tu-berlin.de $Header: utime.1[3.0] Tue Jun 29 16:38:31 1993 andy@cs.tu-berlin.de frozen $ .. .TH utime 1 "Tue Jun 29 16:38:31 1993" "rcs2atfs-1.9" "ShapeTools" .SH NAME utime \- set file times .SH SYNOPSIS .B utime .IR "access_time modification_time file" " ..." .SH DESCRIPTION .B utime sets the access and modification times of the specified files. The access time is set to the first value, the modification time is set to the second value. The times are given in seconds since 00:00:00 GMT Jan 1, 1970. .SH SEE ALSO utime(2) .SH AUTHOR Juergen.Nickelsen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/retrv.1100444 2013 145 23573 5407564616 16042 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. by Axel.Mahler@cs.tu-berlin.de and Andreas.Lampen@cs.tu-berlin.de $Header: retrv.1[5.0] Thu Jun 17 14:03:56 1993 andy@cs.tu-berlin.de frozen $ .. .TH retrv 1 "Thu Jun 17 14:03:56 1993" "retrv-4.5" "ShapeTools" .SH NAME retrv \- retrieve a revision of a file .SH SYNOPSIS .na \fBretrv\fP [ \fIversion binding options\fP ] [ \fIoptions\fP ] files \.\|. .br .IP \fIOptions:\fP \w'\fIOptions:\0\fP'u [\ \fB\-?cfilq\fP\ ] [\ \fB\-help\fP\ ] [\ \fB\-copy\fP\ ] [\ \fB\-dest\fP\ \fIpath\fP\ ] [\ \fB\-fix\fP\ ] [\ \fB\-force\fP\ ] [\ \fB\-intent\fP\ \fImessage\fP\ ] [\ \fB\-lock\fP\ ] [\ \fB\-quiet\fP\ ] [\ \fB\-stdin\fP\ ] [\ \fB\-version\fP\ ] [\ \fB\-xpoff\fP\ ] .sp .IP "\fBvcat\fP [ \fIversion binding options\fP ] [ \fIoptions\fP ] files \.\|." .br .IP \fIOptions:\fP \w'\fIOptions:\0\fP'u [\ \fB\-?q\fP\ ] [\ \fB\-help\fP\ ] [\ \fB\-quiet\fP\ ] [\ \fB\-version\fP\ ] [\ \fB\-xpoff\fP\ ] .RE .ad .SH DESCRIPTION .PP \fBRetrv\fR retrieves a specified, previously saved version of a file from the version object base. The version archive is expected to reside in the AtFS subdirectory. A selected version will by default be retrieved into a file in the directory where it was originally saved. If just a copy of a file version shall be retrieved, this behavior can be overridden with the \fB\-dest\fR option. If a busy version is created with the \fB\-lock\fR option, it must be created in the directory from where it was saved. This is necessary to maintain the spatial relationship between the busy version and the corresponding history archive, residing in the AtFS subdirectory. .PP Retrieve tries to be careful if an attempt is made to overwrite an existing busy-version: unless \fB\-f (-force)\fR is specified, \fBretrv\fR will ask the caller for permission. If no busy version exists, one is created with the same modes as the formerly saved version. If a busy version exists, its modes are preserved. .PP If the program is invoked as \fBvcat\fR, the specified version(s) will be printed on standard output. No status change of the object base will occur in this case. \fBvcat\fR behaves similar to the \fBcat(1)\fR command: if just a filename is given, \fBvcat\fR displays the most recent status of the referenced object. If a \fIbusy version\fR does exist it will be selected as most recent status. If no busy version exists, \fBvcat\fR displays the most recently saved version. .SH ATTRIBUTE CITATIONS .PP It is possible to cite any of a file-version's attributes within the the body of the version. This can be done by using \fIattribute citation expressions\fR. These expressions have the form "\fC$_\|_attributename$\fR". Version attributes that are cited within the text of a stored revision are expanded by default. In this case, the citation expression will be substituted by the cited attribute's value. For a list of predefined attribute names, check the vadm(1) manual page. .PP There are three basic kinds of attribute values: \fIgenuine values\fR, \fIreference values\fR, and \fIexecution values\fR. \fIGenuine\fR values are simply strings that are assigned to an attribute. \fIReference\fR values are pointers to files or AtFS-versions whose contents will be substituted in place of an attribute-citation. Reference values are strings that begin with a circumflex-character, typically followed by pathname, e.g. \fC^/usr/local/lib/std-header[2.4]\fR. \fIExecution\fR values are names of executable programs, whose standard output is substituted in place of an attribute-citation. Execution values are strings that begin with an exclamation-mark character, typically followed by the name of the program, e.g. \fC!/bin/date\fR. Execution values can be used to generate highly dynamic attributes or a primitive form of \fIevent-triggers\fR. .PP When expanding an attribute citation, \fBretrv\fR first looks for an attribute of the mentioned name within the version's set of associated attributes. If no attribute of that name can be found, the environment is searched for a variable of that name. In case the cited attribute exists and has a value, the value is itself searched for attribute-citations that are expanded recursively. If neither an attribute nor an environment variable of the cited name can be found, no substitution takes place and the expression will be left unchanged. The same is true if a referenced object of a reference value does not exist, or an execution value happens to not be executable. Attribute citation expressions are also left unchanged if a revision is retrieved with the \fB\-lock\fR option. Expansion of attribute citation within documents can be controlled by the pseudo-attribute citations "\fC$_\|_xpoff$\fR" and "\fC$_\|_xpon$\fR". .SH OPTIONS .LP For version selection, any \fIversion binding option\fP, as described on the vbind(1) manual page, may be given, or a \fIversion bind directive\fP may be given in brackets added to the file name. .LP .ne 2 Additional options are: .IP "\fB\-?, \-help\fP" print brief instructions about using this program. .IP "\fB\-c, \-copy\fP" Do not check for equality. Usually, retrv checks whether an existing destination file is identical to the version to be retrieved and suppresses copying in this case. This behaviour is mainly for efficiency reasons and may be disabled by the \fI-c\fP switch. .IP \fB\-dest\fI\ path\fR retrieve the specified version from the object base and install a \fIcopy\fR it in the directory denoted by \fIpath\fR. As this directory may be a long way apart from the directory containing the AtFS archives, this copy of the retrieved version is separated from its history and subsequently \fIunrelated\fR to the object history it came from. Proper object histories require a constant spatial relationship of any busy versions and the corresponding archives. This relationship requires the archives to reside in a subdirectory named \fIAtFS\fR. .IP \fB\-fix\fR attempt to reserve the privilege to add a new version to an old \fIgeneration\fR (insert a new minor revision into an old major revision) within the object history. If successful, the user who issued the command holds a \fIgeneration lock\fR. There can be only \fIone\fR lock per generation, preventing simultaneous updates of the generation. The generation lock is, by convention, a revision lock (see \fBvadm \-lock\fR) attached to the version with the highest version number within a generation. .RS .PP The \fB\-fix\fR switch is intended to support concurrency of the main development process and maintenance activities (such as bug fixing) for older releases. When a version is retrieved with the purpose to fix it, it is called the \fIfixpoint\fP version. The fixpoint version accumulates all fixes applied to a baseline version within a generation. One important advantage of this policy is the elimination of the need to create a branch for each fix that must later be merged with the ``mainline'' version, containing previous fixes. So, if \fBretrv\fP is invoked with ``\-fix'' it will restore the fixpoint version (the most recent minor revision within the implied generation) rather than the explicitly referenced version. However, \fBretrv\fP issues a warning, if the baseline- and the fixpoint version are not identical. .PP To insert a fix into an old generation, use the \fB\-fix\fR option of the \fBsave\fR command. When setting a lock on a generation, the requesting user is prompted for an optional description of the planned changes. The \fB\-fix\fR switch is incompatible with \fB\-lock\fR. .RE .IP "\fB\-f, \-force\fP" force the reinstallation of the specified version as busy version without asking the user, even if a writable (possibly unsaved) busy version exists. .IP "\fB\-i\ \fImessage\fR" set \fImessage\fP as intent text describing the changes that are intended to be applied to a \fIbusy version\fR that is installed by \fIretrv\fR. When \fImessage\fP starts with an at sign (@), it is interpreted as filename and the text contained in the file is takes as intent text. If \fImessage\fR is ``\fB\-\fR'', the change intent is read from standard input. The latter case is identical to specifying the command line switch \fI\-stdin\fR. This option requires the \fI\-lock\fR switch to be set in order to be effective. .IP "\fB\-l, \-lock\fP" attempt to reserve the privilege to add a new version to the main development line of an object history, thus preventing multiple programmers working upon the same object base from interfering with each other by saving concurrent updates. When setting a new lock on an object history, prompt the requesting user for an optional description of the planned changes. The \fB\-lock\fR switch is incompatible with \fB\-fix\fR. .IP "\fB\-q, \-quiet\fP" quiet operation. No messages are printed on standard output. If a current busy version exists, it will not be overwritten by the specified version unless \fB\-f\fR is set. This option is useful for batch operation. .IP \fB\-stdin\fR force \fBretrv\fR to read the message describing the change intent from stdin rather than fork an editor. .IP \fB\-version\fR print version identification for this program. .IP \fB\-xpoff\fP Do not expand attribute citations in the restored file. .SH FILES All revisions of documents are retrieved from archive files located in the subdirectory AtFS. .SH SEE ALSO vbind(1), save(1), vadm(1) .SH BUGS Redirection of stdin in conjunction with option \fI\-stdin\fR doesn't work. .SH AUTHOR Axel.Mahler@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/vcat.1100444 2013 145 144 5402651075 15551 0ustar dokoswt.ig $Header: vcat.1[3.0] Tue Jun 1 14:59:22 1993 andy@cs.tu-berlin.de frozen $ .. .so man1/retrv.1 shapetools-1.4pl6.orig/man/man1/save.1100444 2013 145 27224 5414050246 15616 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Authors: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: save.1[8.0] Tue Jun 29 16:27:31 1993 andy@cs.tu-berlin.de frozen $ .. .TH save 1 "Tue Jun 29 16:27:31 1993" "save-4.7" "ShapeTools" .SH NAME save \- save revision of a file .SH SYNOPSIS .na \fBsave\fP [ \fIversion binding options\fP ] [ \fIoptions\fP ] files \.\|. .br \fBSave\fP [ \fIversion binding options\fP ] [ \fIoptions\fP ] files \.\|. .IP \fIOptions:\fP \w'\fIOptions:\0\fP'u [\ \fB\-?fglq\fP\ ] [\ \fB\-help\fP\ ] [\ \fB\-a\fP\ (or\ \fB-alias\fP)\ \fIversion\ alias\fP\ ] [\ \fB\-delta\fP\ ] [\ \fB\-force\fP\ ] [\ \fB\-fix\fP\ \fIgeneration\fP\ |\ \fIalias\fP\ |\ \fIdate\fP\ ] [\ \fB\-newgen\fP\ ] [\ \fB\-lock\fP\ ] [\ \fB\-m\fP\ (or\ \fB\-logmsg\fP)\ \fImessage\fP\ ] [\ \fB\-n\fP\ (or\ \fB\-setvnum\fP)\ \fIversion\ number\fP\ ] [\ \fB\-nodelta\fP\ ] [\ \fB\-quiet\fP\ ] [\ \fB\-setattrs\fP\ \fIfilename\fP\ ] [\ \fB\-stdin\fP\ ] [\ \fB\-version\fP\ ] .ad .SH DESCRIPTION .PP \fBsave\fP takes a snapshot of the current state of the specified files, stores them into corresponding archive files and assigns unique \fIversion numbers\fP to the created versions. The original files will by default be removed and unlocked in order to support a cooperative style of teamwork. Versions of files can be restored as regular files with the \fBretrv\fP command. Versions in archives are inalterable. .PP An archive will be created the first time a file is saved in a subdirectory named \fIAtFS\fP. The AtFS subdirectory must be present. When an archive is created, save asks for a short description of the saved documents purpose. If a subsequent version is saved, the user is prompted for a comment describing the modifications. The \fBsave\fP command requires that the version history of a file that shall be saved is \fIlocked\fP by the user issuing the command. This is to prevent different developers from applying concurrent updates to the same file and thereby invalidating the other developers' modifications. The only exception from this rule is the first time a file is saved, which means that an archive has yet to be created. For more details on locking, see the ShapeTools Tutorial, \fBretrv(1)\fP, and \fBvadm(1)\fP. .PP The \fBsave\fP program assigns unique version ids to each evolving revision of a file. The version id is a pair of integers separated by a dot, identifying the major and minor revision (\fI.\fP) of a version. Subsequent invocations of \fBsave\fP increase the minor revision number, starting with version 1.0. The generation number is increased by invocations of \fBSave\fP (see below). There is no support for explicit branching. The version control toolkit rather encourages a linear model of version evolution. Instead of branching, \fBsave\fP allows to \fIinsert\fP new versions into old generations (see description of \fB\-fix\fP). This allows, for example, to fix bugs in major revision N (version numbers \fIN.x\fP) which may be the currently operational release while development proceeds in generation N+1 (or N+n if you like). .PP Before a file is saved it will be checked whether it has actually changed with respect to the previously saved version. If the file hasn't changed, the user will be asked if it should be saved anyway. The command line option \fB\-f\fP\ (or \fB-force\fP) overrides the prompting. .PP The version control system supports a built-in basic status model for versions. The version status is intended to express different levels of quality, and aims at providing basic project management functionality. State attributes of software objects can help to describe an object's current meaning in the development process (e.g. \fItested\fP, \fIincompletely implemented\fP, \fIsubmitted for evaluation\fP, or \fIshipped to customer\fP). .PP A newly created version will by default be assigned the state \fIsaved\fP. This status marks the lowest level of quality, suggesting that the version is just saved for possible later retrieval but may be inconsistent. Versions that meet higher quality standards (or are part of a release) should be marked by appropriate status (see \fBvadm \-promote\fP, \fBsbmt\fP, or \fBpubl\fP). .PP If the program is invoked as \fBSave\fP (that is with capital-S) a new major revision (\fIgeneration\fP) of the document history is created \- provided the programmer issuing the command has the permission to do this. This option is intended to support a development model where maintenance of an operational release can be performed parallel to \fBthe development of the next release (see \fB\-fix\fP). .SH OPTIONS .LP For version selection, any \fIversion binding option\fP, as described on the vbind(1) manual page, may be given. \fIVersion bind directives\fP in brackets added to the filename are interpreted different to vbind(1). A version number following the name will be treated as if the \fI-n (-setvnum)\fP option was given with this version number as argument. Any other string in brackets will be taken as alias name (see \fI-alias\fP option). .IP "\fB\-?, \-help\fP" print short information about usage of this command. .IP "\fB\-a, \-alias\fP \fIversion alias\fP" assign a version alias (a symbolic name) to the new version. In more detail, an attribute \fI__SymbolicName__\fP is set to the value specified in \fIversion alias\fP. The specified alias name must not be assigned to any other version within the same version history. Alternatively to the -a option, the version alias may be given in brackets following the name of the file to be saved. Check the description of the -n option for an example of this notation. .IP "\fB\-delta\fP" Create delta for internal storage. This is the default. .IP "\fB\-f, \-force\fP" force a revision deposit (i.e. without asking), even if the busy version hasn't changed since the last time it was saved. .IP "\fB\-fix\fP \fIgeneration\fP\ |\ \fIalias\fP\ |\ \fIdate\fP" append a new version after the most recent version within the referenced major revision level. The major revision level (called ``generation'') is either referenced \fIexplicitly\fP, by specifying a number, or \fIimplicitly\fP, by specifying a version alias (e.g. a release name) or a date. The latter form is particularly useful for saving a fix that extends over more than one object. .RS .PP This option is intended to support maintenance of older releases while development proceeds at the logical end of the version chain. In order to insert a (fixed) version into an old generation, one must have a lock on the most recent version of that generation (\fIgeneration lock\fP). This lock must be set with the \fBvadm\fP command. The \fB\-fix\fP option is incompatible with \fB\-setvnum\fP, \fB\-newgen\fP and the \fBSave\fP command option. .RE .IP "\fB\-g, \-newgen\fP" create a major revision of the document. Major revisions are indicated by the first number in the version-id (\fIgeneration\fP). Only the archive administrator is allowed to create major revisions. The archive administrator is the user who owns the AtFS subdirectory where the version archives reside. Use of this switch is identical to calling the program as \fBSave\fP. .IP "\fB\-l, \-lock\fP" Keep the lock on the version history. The saved files will not be removed. .IP "\fB\-m, \-logmsg\fP \fImessage\fP" set \fImessage\fP as descriptive note for all document versions that result from the invocation of \fBsave\fP. When \fImessage\fP starts with an at sign (@), it is interpreted as filename and the text contained in the file is set as descriptive note for all document versions that result from the invocation of \fBsave\fP. .IP "\fB\-n, \-setvnum\fP \fIversion number\fP" set the version number of the newly created revision to \fIversion\fP. The \fIversion\fP must be given in the format \fI.\fP where \fIgeneration\fP and \fIrevision\fP are integers. Example: .sp 0.2c \fCsave -setvnum 4.3 mkattr.c\fP .sp 0.2 The specified \fIversion\fP must be greater than the highest previously assigned version number in a given object history. Only the archive administrator may set version numbers directly. The archive administrator is the user who owns the AtFS subdirectory where the version archives reside. \fB\-setvnum\fP is useful for keeping consistent version numbering across related, physically different object repositories, or for converting archive formats of other revision control systems to this toolkit (see: \fBrcs2atfs\fP). Alternatively to the -n option, the version number may be given in brackets following the name of the file to be saved. The command .sp 0.2c \fCsave mkattr.c[4.3]\fP .sp 0.2 is interpreted the same way as the example above. .RE .IP "\fB\-nodelta\fP" Suppress delta generation .IP "\fB\-q, \-quiet\fP" quiet operation. No messages are printed on standard output. If the busy version is unchanged, it will not be saved unless \fB\-f\fP is set. The user will not be prompted for a descriptive note. If no message or note is supplied with the command line (see options \fB\-m\fP and \fB\-t\fP) the log will remain empty. This option is useful for batch operation. .IP "\fB\-setattrs\fP \fIfilename\fP" read names and values of user defined attributes from the file \fIfilename\fP. The entries in the attribute file must have either of the formats \fINAME=VALUE\fP or \fINAME+=VALUE\fP. \fINAME\fP must be an alphanumeric string (no spaces) immediately followed by the assignment operator. The value may be an arbitrary ASCII string with the exception of control-A and newline characters. There is exactly one attribute definition per line. The file's last character must be a newline character. .RS .PP If the first format (single equal symbol) is used, previously assigned values of user defined attributes are \fIreset\fP with the values defined in the attribute file. The second format (``plus equal'') allows to append additional values to an already existing attribute. If no attribute of a given name exists, it will be created. .PP This way to attach attributes was introduced to allow quick automatic attachment of a large number of attributes to version objects. This interface to the attribute setting facility is mainly intended for tools that invoke \fBsave\fP. .PP If the \fB\-setattrs\fP option is omitted, \fBsave\fP searches the environment for a variable \fISVATTRS\fP. If this variable is absent, no user defined attributes will be assigned to the evolving versions. .RE .IP "\fB\-stdin\fP" force \fBsave\fP to read a descriptive note from stdin instead of forking an editor. A previously set intent-message is printed. .IP "\fB\-version\fP" print the version of the program itself. .SH FILES All revisions of documents are stored in archive files in the subdirectory AtFS. .SH BUGS With the \fI-g (-newgen)\fP option given and an unchanged busy version, save ignores the users answer to the question, if the busy version should be saved anyway. It always assumes a positive answer and goes on with its saving procedure. You can avoid saving by interrupting (Ctrl-C) save during the next question if the unmodified version should be commented anyway. .SH SEE ALSO retrv(1), vbind(1) .SH AUTHOR Axel.Mahler@cs.tu-berlin.de and Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/vdiff.1100444 2013 145 6364 5414052023 15733 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) $Header: vdiff.1[4.0] Tue Jun 29 16:42:06 1993 andy@cs.tu-berlin.de frozen $ .. .TH vdiff 1 "Tue Jun 29 16:42:06 1993" "vc_scripts-2.5" "ShapeTools" .SH NAME vdiff \- display line-by-line differences between versions of files .SH SYNOPSIS \fBvdiff\fR\ [\ \fIdiff-options\fR\ ]\ [\ \fB\-base\ \fIpath\fR\ ]\ [\ \fB\-P\fR\ ]\ files\ \.\|. .SH DESCRIPTION .PP \fBvdiff\fP is a differential comparator for file versions that are stored in \fIshapeTools'\fP object base, \fIAtFS\fR. The functionality of \fBvdiff\fP is very similar to the \fBdiff\fP command on your host. All options and switches that are recognized by \fBdiff\fP can also be specified for \fBvdiff\fP. .PP The arguments to \fBvdiff\fP can either be a single filename, or a pair of \fIversion identifiers\fP. If only a filename is specified, \fBvdiff\fP prints the differences between the specified file and the most recent version of this file that is stored in the AtFS object base. A file can be compared to any stored version by specifying the version as first, and the filename as second argument. If both arguments are version identifiers, the difference between these two versions is printed. .PP Differences between files and versions can be printed in any style that is supported by the local \fBdiff\fP program. .PP Version identifiers consist of the filename, and a version number or alias name for a version, enclosed in brackets. Example: .ce \fCretrieve.c[4.22]\fP or \fCretrieve.c[Rel-4.1]\fP .PP \fBvdiff\fP creates temporary copies of the versions that shall be compared, invokes the \fBdiff\fP command, and finally removes the temporary copies. .SH OPTIONS .IP "\fB\-base\fP\ \fIpath\fP" If \fBvdiff\fP is told to produce a \fIcontext diff\fP, the filenames of the compared objects are mangeled so that the specified \fIpath\fP replaces the path of the current directory in the full pathnames appearing in the diff-header. This is useful to replace an absolute pathname by a relative pathname and makes the produced context-diff easier to digest for the \fBpatch\fP program. .IP \fB\-P\fP With the \fB\-P\fP switch turned on, \fBvdiff\fP won't give up if one of the two objects that shall be compared does not exist. In this case an empty object is substituted for the missing one, causing the diff to be the complete contents of the existing object. This is useful in situations when complex patches are produced that upgrade one release of a software system to a new release, and the system has structurally changed (i.e. new files have been added to the system). .SH SEE ALSO diff(1), vcat(1) .SH AUTHOR Axel.Mahler@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/vadm.1100444 2013 145 51707 5417300261 15610 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Authors: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) Axel Mahler (Axel.Mahler@cs.tu-berlin.de) $Header: vadm.1[10.0] Fri Jul 9 16:30:15 1993 andy@cs.tu-berlin.de frozen $ .. .TH vadm 1 "Fri Jul 9 16:30:15 1993" "vadm-4.10" "ShapeTools" .SH NAME vadm \- manipulate and administer version object base .SH SYNOPSIS .na \fBvadm\fP [ \fIversion binding options\fP ] [\ \fIoptions\fP\ ]\ [\ \fIaction\fP\ ] name\|.\|. .br .IP \fIOptions:\fP \w'\fIOptions:\0\fP'u [\ \fB\-?fq\fP\ ] [\ \fB\-cache\fP\ ] [\ \fB\-force\fP\ ] [\ \fB\-help\fP\ ] [\ \fB\-nomail\fP\ ] [\ \fB\-quiet\fP\ ] [\ \fB\-stdin\fP\ ] [\ \fB\-version\fP\ ] .IP \fIActions:\fP \w'\fIOptions:\0\fP'u [\ \fB\-alias\fP\ \fIversion alias name\fP\ ] [\ \fB\-attr\fP\ \fIattribute\fP\ ] [\ \fB\-chaut\fP\ \fIuser\fP\ ] [\ \fB\-chmod\fP\ \fIprotection\fP\ ] [\ \fB\-chown\fP\ \fIuser\fP\ ] [\ \fB\-delattr\fP\ \fIattribute name\fP\ ] [\ \fB\-d\fP\ (or\ \fB\-delete\fP)\ ] [\ \fB\-l\fP\ (or\ \fB\-lock\fP)\ [\fIversion binding\fP\] ] [\ \fB\-newgen\fP\ ] [\ \fB\-promote\fP\ ] [\ \fB\-set\fP\ \fIdescription\fP\ |\ \fInote\fP\ |\ \fIintent\fP\ ] [\ \fB\-setc\fP\ \fIcomment leader\fP\ ] [\ \fB\-unlock\fP\ [\fIversion\ binding\fP\]\ ] [\ \fB\-unpromote\fP\ ] .br .IP "\fBvattr\fP\ [ \fIversion binding options\fP ] attribute name\|.\|. .br .IP "\fBvrm\fP\ [ \fIversion binding options\fP ] name\|.\|. .br .IP "\fBsbmt\fP\ [ \fIversion binding options\fP ] name\|.\|." .br .IP "\fBpubl\fP\ [ \fIversion binding options\fP ] name\|.\|." .br .IP "\fBaccs\fP\ [ \fIversion binding options\fP ] name\|.\|." .br .IP "\fBfrze\fP\ [ \fIversion binding options\fP ] name\|.\|." .ad .SH DESCRIPTION .LP \fBvadm\fP is a general purpose command to perform all sorts of actions upon parts of an AtFS object repository. It can be used to lock or unlock an AtFS object for modification, to delete a particular object instance, to associate symbolic (alias) names with version objects, to promote or unpromote certain version objects from one status to another, to modify an objects access permissions, to set or modify a descriptive entry of particular version objects, to set or modify an eventual change intention, and to set or unset various object attributes such as the author or any user defined attributes. .LP \fBvattr\fP and \fBvrm\fP are short forms for \fIvadm -attr\fP and \fIvadm -delete\fP. See the descriptions of the \fI\-attr\fP and the \fI\-delete\fP options for details. .LP \fBsbmt\fP, \fBpubl\fP, \fBaccs\fP, and \fBfrze\fP are alternate program names for \fBvadm\fP that represent \fIstatus-change\fP operations for version objects. See the description of option \fB\-promote\fP for details. .LP The typical command invocation is supplemented by one or more \fIcommand options\fP, \fIversion binding options \fP defining the versions to be acted upon, an \fIaction specifier\fP indicating the sort of action to be performed, and a set of \fIobject names\fP defining the initial subset of the object base that's going to be manipulated. .LP Object names may be given in \fIbound version notation\fP, i.e. a notation that identifies a particular version of an object (e.g. \fCmkattr.c[2.4]\fP). It is also possible to use a previously assigned \fIsymbolic name\fP rather than a numerical version identification (e.g. \fCmkattr.c[tools-V4R3]\fP). Make sure to escape the bracket-symbols when using \fBcsh(1)\fP or \fBtcsh(1)\fP because they have meaning to these shells. .SH OPTIONS .LP For version selection, any \fIversion binding option\fP, as described on the vbind(1) manual page, may be given, or a \fIversion bind directive\fP may be given in brackets added to the file name. .IP "\fB\-?, \-help\fP" print brief instructions about using \fBvadm\fP .IP "\fB\-cache\fP" apply the requested operation to objects residing in the \fIderived object cache\fP. The set of actions that may be performed on binary pool objects is limited. .IP "\fB\-f, \-force\fP" don't ask for confirmation when deleting versions from a history. .IP "\fB\-nomail\fP" Suppress the notification mail to the user who holds the lock on a history when breaking this lock (\fI\-unlock\fP option). .IP "\fB\-q, -quiet\fP" suppress any prompts, informal messages and user dialogues. Default values are assumed for everything that might otherwise be inquired interactively. This option is useful for batch operation. .IP "\fB\-stdin\fP" forces \fBvadm\fP to read a descriptive text, note or intent from standard input if action \fB\-set\fP is selected. The note is used for \fIall\fP specified AtFS objects. Otherwise your favorite editor (taken from the EDITOR environment variable) is invoked. .IP "\fB\-version\fP" print version information about the \fBvadm\fP program itself. No action will be performed on the database. .LP \fBvadm\fP will perform all of its operations upon a specified set of AtFS version objects. In case no such set is specified, the operation will be applied to the most recently saved versions of the named object(s). .SH ACTIONS The kind of action to be performed upon a specified set of AtFS objects is indicated by a keyword. The following actions are defined: .IP "\fB\-alias\fP\ \fIversion\ alias\ name\fP" assigns the \fIversion alias name\fP to the specified version. The name works as an alias for the version number, so it must be different from any other symbolic name assigned to any version object in a particular object history. It is, however, possible to assign the same symbolic name to version objects in \fIdifferent object histories\fP. An object history is usually denoted by a name, similarly to a files name. .sp 0.05i The use of alias names is a simple but effective way to associate component members of a \fIsystem configuration\fP. Typical symbolic names will look something like \fIMysystem_Release_4.22\fP, indicating that version objects with this name are part of release 4.22 of the system in question. .IP "\fB\-attr\fP\ \fIattrname\fP Return rthe value of the named attribute. This may be a \fIstandard attribute\fP or a \fIuser defined attribute\fP. Check the list below for a complete list of standard attribute names. .IP "\fB\-attr\fP\ \fIattrname\fP[\fI+\fP|\fI-\fP]=[\fI@\fP|\fI^\fP|\fI!\fP|\fI*\fP]\fIvalue\fP" defines a \fIuser defined attribute\fP with name \fIattrname\fP and sets it to the value \fIvalue\fP for all specified version objects. This option may also be used to set the value of certain \fIstandard attributes\fP (see list below). If \fIattrname\fP is followed by a single equal-symbol, the respective value of the object is set (or reset) to the specified value. Any previous values will be overwritten. If \fIattrname\fP is immediately followed by the symbols ``plus-equal'' (\fC+=\fP), the specified attribute value will be appended to the current value of the referenced attribute. Accordingly, ``minus-equal'' (\fC-=\fP) should remove the specified value from the given attribute. In the current implementation, removal of single values is not supported. .sp 0.05i There are four basic kinds of user defined attribute values: \fIgenuine values\fP, \fIreference values\fP, \fIexecution values\fP, and \fIpointer values\fP. The kind of an attribute value is determined when it is set. If the first character of \fIvalue\fP is an at character (@), the rest of \fIvalue\fP is taken to be the \fIname of a file\fP the contents of which will be taken as the value of the attribute. This substitution takes place immediately, i.e. the attribute has a genuine value. If the filename is specified as ``\-'', the attributes value will be read from standard input. If the first character is a circumflex character (^), the rest of \fIvalue\fP is interpreted as the name of a file whose contents will be substituted for the attribute when it is cited. If the first character of \fIvalue\fP is an exclamation mark character (!), the rest of \fIvalue\fP is interpreted as the \fIname of a program\fP whose standard output will be substituted for the attribute when it is cited. Execution values can be used to generate highly dynamic attributes or even a primitive form of event triggers. An asterisk (*) as first character of \fIvalue\fP indicates a pointer to another version. In this case, the remainder of value must be a valid bound filename. .sp 0.05i User defined attributes may be of arbitrary length. Any sequence of ASCII characters \- with the exception of \e01 (control-A) \- is allowed to make up an attribute value. If \fIattrname\fP was already set to some value, the previous value will be replaced by the newly specified one. .IP "\fB\-attr\fP\ \fI@attrfile\fP" With a \fI@filename\fP argument, the \fI\-attr\fP option reads names and values of user defined attributes from the named file Each entry (each line) in the attribute file must have a format as described above. The files last character must be a newline character. .IP "\fB\-chaut\fP \fIuser\fP" sets \fIuser\fP the author of a particular revision. Normally, the author of a revision is considered the user who saved that revision. However, as certain permissions are tied to the author attribute of a revision, circumstances may occur that make it necessary to change the author. .IP "\fB\-chmod\fP \fIprotection\fP" changes the access permission code of the specified version objects to the supplied three-octal-digit \fIprotection\fP. Currently, the access permissions are centered around UNIX' notions of \fIowner, group,\fP and \fIworld\fP access as well as the access categories \fIread, write,\fP and \fIexecute\fP. These permissions are inherited upon \fBsave\fP from the permissions of the file representing the \fIbusy object\fP of an AtFS history. See \fBchmod\fP(2) for details. .IP "\fB\-chown\fP \fIuser\fP" sets \fIuser\fP the owner of an entire object history. This option is not supported on BSD type systems, as only the superuser may change the owner of a file. .IP "\fB\-delattr\fP \fIattrname\fP" deletes the user defined attribute \fIattrname\fP from the set of attributes associated with the specified version objects. .IP "\fB\-d,\ \-delete\fP" removes the specified version objects from the object base, provided the objects' status is \fIsaved\fP. Any other status indicates that some kind of project interaction concerning this object might be in progress. If the programmer wants to delete such a version object anyway, he has to \fB\-unpromote\fP the respective objects status to \fIsaved\fP before it can actually be deleted. .IP "\fB\-l,\ \-lock\fP [\fIversion binding\fP]" tries to reserve the privilege to add a new version to an objects history, thus preventing multiple programmers working upon the same object base from interfering with each other by saving concurrent updates. If the locking operation succeeds, write permission is given for the corresponding files in the development directory. When setting a new lock on an object history, the requesting user is prompted for an optional description of the planned changes. .sp 0.05i In order to lock an object history successfully, the history must not be locked by any other programmer, and the programmer requesting the lock must have write permission on the AtFS subdirectory hosting the object base. .sp 0.05i As ShapeTools allows locking of single generations within a history, \fI-lock\fP optionally expects an argument denoting a generation. Default is the most recent generation. The argument may be a generation number (e.g. \fI2\fP), a version number (e.g. \fI1.4\fP), or a version alias (e.g. \fIrelease-4.7\fP). .IP "\fB\-newgen\fP" opens a new generation by duplicating the identified version. The version must be locked. Any existing busy versions are ignored by this action. If no version binding is specified, the last saved version is taken by default. .IP "\fB\-promote\fP" assigns the next-better value to the specified objects' \fIstate\fP attribute. There are six states that an object instance can be in: \fIbusy, saved, proposed, published, accessed, \fPand\fI frozen\fP. Version states are intended to relate to visibility and operational restrictions (see for example \fB\-delete\fP) within a complex project environment. .sp 0.05i Due to the current lack of project library support, the version states have very little actual functionality. Implemented to its full extent, certain state transitions may only be triggered by appropriately authorized users. The transitions \fIbusy\(->saved\fP and \fIsaved\(->proposed\fP will be triggered by regular programmers, whereas the remaining transitions have to be initiated by the \fIproject administrator\fP. .sp 0.05i Each transition corresponds to a specific action or interaction within a general software project communication scheme. As these actions/interactions will be functionally supported by the project support system currently under development, the explicit manipulation of object states will no longer be necessary (except, perhaps for manual adjusting of ill situations). .sp 0.05i The following actions relate to the state transitions: .br \fIsave\fP (\fIbusy\(->saved\fP, performed by programmer) .br \fIsbmt\fP (\fIsaved\(->proposed\fP, performed by programmer) .br \fIaccpt\fP (\fIproposed\(->published\fP, performed by project administrator) .br \fIaccs\fP (\fIpublished\(->accessed\fP, performed by any project member) .br \fIrelease\fP (\fIaccessed\(->frozen\fP, performed by project administrator) .sp 0.05i A different interface to the status control facilities of \fBvadm\fP is provided by the program aliases \fBsbmt\fP, \fBpubl\fP, \fBaccs\fP, and \fBfrze\fP. These commands correspond to conceptual project interactions like \fIsubmit\fP, \fIpublish\fP, \fIaccess\fP, and \fIfreeze\fP. .sp 0.05i \fISubmit\fP is the operation performed by a team programmer when a work result (such as a completed change request) is proposed for inclusion into the official system configuration. The associated status is \fIproposed\fP. .sp 0.05i \fIPublish\fP is an operation that is typically performed by members of the quality assurance group, when a work result, as proposed by a team programmer is approved and thus included into the current official system configuration. The associated status is \fIpublished\fP. .sp 0.05i \fIAccess\fP is an operation that is performed during configuration identification, when component versions of a (sub\-)product are incorporated into some other (partial) (sub\-)system configuration. The associated status is \fIaccessed\fP. .sp 0.05i \fIFreeze\fP is an operation that is performed during configuration identification, when a global release of the entire system configuration is established. The associated status is \fIfrozen\fP .IP "\fB\-set \fP[\fIdescription \fP| \fInote\fP | \fIintent\fP]" allows to set or modify the \fIdescriptive text\fP for an AtFS history object (i.e. an entire version history), the \fInote\fP usually describing the differences of a version object with respect to its preceding version, or an entry describing a planned change. (Re-) setting the change intention may be appropriate, if a previously set change intent has been consumed by a \fBsbmt\fP command that retained the lock on an object history. .sp 0.05i \fBvadm\fP will check the callers environment for the \fIEDITOR\fP variable and invoke the program identified therein. If the \fIEDITOR\fP variable is not set, the systems default editor will be activated. The user may write an arbitrary length descriptive or note entry using the editor. When the user leaves the editor, the resulting text is stored with the object history or the specified version objects. .IP "\fB\-setc\fI\ comment_string\fP" sets \fIcommentstring\fP as the (sequence of) character(s) that opens a comment line within the formalism of the document. This comment_string will be prepended to the lines of the log history when the \fC$__log$\fP attribute is expanded within the text of a revision. .IP "\fB\-unlock\fP" gives up the previously reserved privilege to update the history of an AtFS object and clears the write-permission for the corresponding files. \fB\-unlock\fP may be used by the \fIowner\fP of an object history to \fIbreak a lock\fP previously set by any programmer. This option is useful to resolve deadlock situations resulting from careless use of \fB\-lock\fP, or exceptional circumstances that require immediate updating of an object history, even if the lock holder is not present. The previous owner of a broken lock is notified by a mail message. Under some circumstances mail-notifications upon broken locks can be annoying (e.g. when a development tree has been moved to another system or domain with locked busy-versions; in this case the owner must break the locks to check the busy-versions back into the version archives at the new site). To avoid this effect, the switch \fB\-nomail\fP can be used to suppress mail notification. .br An eventually expressed change intention (see \fB\-lock\fP) will be cleared. .sp 0.05i Technically, the owner of an objects history is the owner of the AtFS subdirectory hosting the object base. .IP "\fB\-unpromote\fP" reverses a state transition carried out through a prior \fB\-promote\fP. The same remarks about functional embedding (and thus \fIhiding\fP the state transitions) of state transitions made for \fB\-promote\fP hold for \fB\-unpromote\fP. .SH PREDEFINED ATTRIBUTE NAMES .nf .ta 2c 7.5c 13.5c \fBName Meaning Value \h'-0.5c'Remarks\fP .sp alias version alias names list of alias names, like 1,3 ``vadm-4.2pre7'' or ``ShapeTools-1.4'' .sp 0.2c atime time of last access e.g. ``Tue Jan 14 18:47:06 1992'' 3 .sp 0.2c author user who saved a version user@do.\&ma.\&in (domain name does 1,3 usually not include the hostname) .sp 0.2c cachekey unique key for cached versions compound numeric built from 3 creation date, process id, and a serial number e.g. ``740148430.18469.6'' .sp 0.2c clead comment line leader symbol dependent on file type 1 e.g. ``# '' for Shapefiles .sp 0.2c ctime time of last status change as \fIatime\fP .sp 0.2c Description descriptive text for module multi line text 2 .sp 0.2c dsize size of delta to previous numeric version in bytes .sp 0.2c generation major revision number numeric 1,3 .sp 0.2c Header RCS-style version header text .sp 0.2c Intent change intent multi line text 2 .sp 0.2c host name of current host e.g. ``avalanche'' 3 .sp 0.2c Log cumulative descriptive entries multi line text of all versions from the first up to this one .sp 0.2c lock/locker user who locks a history as \fIauthor\fP 3 .sp 0.2c ltime time of last lock transaction as \fIatime\fP 3 .sp 0.2c mode access pprotection e.g. ``\-rw\-r\-\-r\-\-'' 1 .sp 0.2c mtime time of last modification as \fIatime\fP 3 .sp 0.2c name name part of an object identifier e.g. ``foo'' for ``foo.c'' 3 .sp 0.2c note short note describing the multi line text 1, 2 changes in this version .sp 0.2c owner user who owns the repository in as \fIauthor\fP 1,3 which this version is archived .sp 0.2c pred bound version identifier of e.g. ``foo.c[3.22]'' or ``n/a'' preceding version .sp 0.2c revision minor revision number numeric 1,3 .sp 0.2c rtime last time when history was locked as \fIatime\fP .sp 0.2c self bound version identifier for e.g. ``foo.c[3.23]'' this version .sp 0.2c selfpath bound version identifier for e.g. ``/usr/proj/sample/foo.c[3.23]'' this version including path .sp 0.2c size size of the version in bytes numeric 3 .sp 0.2c state/status version status symbolic integers (busy, 1,3 saved, proposed, published, accessed, and frozen) .sp 0.2c stime time when the version was saved as \fIatime\fP 3 .sp 0.2c succ bound version identifier of as \fIpred\fP successive version .sp 0.2c syspath pathname part of an object e.g. ``/usr/proj/sample'' 3 identifier for ``/usr/proj/sample/foo.c'' .sp 0.2c type suffix part of an object e.g. ``c'' for ``foo.c'' 3 identifier .sp 0.2c unixname UNIX file name of this version e.g. ``foo.c'' .sp 0.2c unixpath UNIX file name of this version e.g. ``/usr/proj/sample/foo.c'' including path .sp 0.2c version compound version number e.g. ``3.22'' 1,3 consisting of generation and revision number .sp 0.2c vtime version time, modification time as \fIatime\fP for busy versions od save time for saved/cached versions .sp 0.2c xpoff pseudo attribute that turns none off subsequent attribute expansions .sp 0.2c xpon pseudo attribute that turns none subsequent attribute expansion on .sp 1 \- may be modified by \fIvadm -attr name=value\fP. 2 \- may be modified by \fIvadm -set \fP. 3 \- recognized by \fIattr*\fP predicates in version bind rules (see bindrules(7)). .fi .SH ENVIRONMENT EDITOR .SH SEE ALSO save(1), retrv(1), vl(1), vbind(1) .SH AUTHORS Uli.Pralle@cs.tu-berlin.de, Axel.Mahler@cs.tu-berlin.de, Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man1/sbmt.1100444 2013 145 143 5402651575 15565 0ustar dokoswt.ig $Header: sbmt.1[7.0] Tue Jun 1 15:03:51 1993 andy@cs.tu-berlin.de frozen $ .. .so man1/vadm.1 shapetools-1.4pl6.orig/man/man1/publ.1100444 2013 145 143 5402651531 15552 0ustar dokoswt.ig $Header: publ.1[7.0] Tue Jun 1 15:03:52 1993 andy@cs.tu-berlin.de frozen $ .. .so man1/vadm.1 shapetools-1.4pl6.orig/man/man1/accs.1100444 2013 145 143 5402651514 15522 0ustar dokoswt.ig $Header: accs.1[7.0] Tue Jun 1 15:03:53 1993 andy@cs.tu-berlin.de frozen $ .. .so man1/vadm.1 shapetools-1.4pl6.orig/man/man1/frze.1100444 2013 145 143 5402651574 15565 0ustar dokoswt.ig $Header: frze.1[7.0] Tue Jun 1 15:03:54 1993 andy@cs.tu-berlin.de frozen $ .. .so man1/vadm.1 shapetools-1.4pl6.orig/man/man1/vrm.1100444 2013 145 142 5402651464 15420 0ustar dokoswt.ig $Header: vrm.1[7.0] Tue Jun 1 15:03:55 1993 andy@cs.tu-berlin.de frozen $ .. .so man1/vadm.1 shapetools-1.4pl6.orig/man/man1/vattr.1100444 2013 145 144 5402651472 15755 0ustar dokoswt.ig $Header: vattr.1[7.0] Tue Jun 1 15:03:56 1993 andy@cs.tu-berlin.de frozen $ .. .so man1/vadm.1 shapetools-1.4pl6.orig/man/man1/vfind.1100444 2013 145 15606 5414051064 15766 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Uli Pralle (Uli.Pralle@cs.tu-berlin.de) $Header: vfind.1[5.0] Tue Jun 29 16:31:49 1993 andy@cs.tu-berlin.de frozen $ .. .TH vfind 1 "Tue Jun 29 16:31:49 1993" "vfind-3.3" "ShapeTools" .SH NAME vfind \- find attributed software objects (ASOs) .SH SYNOPSIS \fBvfind\fP [\ \fIoptions\fP\ ] \fIpathname-list\ expression\fP .PP .SH DESCRIPTION \fBVfind\fP recursively descends the directory hierarchy for each pathname in the pathname-list seeking asos that match a boolean expression written in the primaries given below. In the description, the argument \fIn\fP is used as a decimal integer where \fI+n\fP means more than \fIn\fP, \fI\-n\fP means less than \fIn\fP and \fIn\fP means exactly \fIn\fP. .SH OPTIONS .IP "\fB\-version\fP" print version information about the \fBvfind\fP program itself. No other action given will be performed. .IP "\fB\-?, \-help\fP" print brief instructions about using \fBvfind\fP. .IP "\fB\-cache\fP" match a boolean expression also for aso residing in the \fIderived object cache\fP. .IP "\fB\-cut\fP \fInesting depth\fP" causes \fBvfind\fP to descend the filesystem hierarchy down to nesting depth \fInesting depth\fP. .IP "\fB\-force\fP" \fBVfind\fP normally ignores saved asos iff a AtFS directory is a symbolic link. If the \fB\-force\fP option is given \fBvfind\fP takes also symbolic AtFS directories into consideration. .IP "\fB\-hits\fP" causes \fBvfind\fP to return the number of expressions yielding true during evaluation. .IP "\fB\-xdev\fP" causes \fBvfind\fP not to traverse down into a file system different from the one on which current argument pathname resides. .SH PRIMARIES .IP "\fB\-atime\fP n" True if the aso has been accessed in \fIn\fP days. .IP "\fB\-ctime\fP n" True if status of the aso has been changed in \fIn\fP days. .IP "\fB\-mtime\fP n" True if the aso has been modified in \fIn\fP days. .IP "\fB\-stime\fP n" True if the aso has been saved in \fIn\fP days. .IP "\fB\-ltime\fP n" True if the aso has been locked in \fIn\fP days. .IP "\fB\-exec\fP command" True if the executed command returns a zero value as exit status. The end of the command must be punctated by an ecscaped semicolon. A command argument `{}' is replaced by the system name of the current aso. .IP "\fB\-exit\fP n" Terminates vfind and returns n as the exit status. .IP "\fB\-vl\fP" Always true; causes the current aso to be printed together with its associated statistics. This includes protection mode, \fIAtFS\fP version state, user, host, size in bytes, modification time respectively saving time. The format is identical to that of ``vl -l''. .IP "\fB\-name\fP name" True if the name argument matches the filename component of the current aso. Normal Shell argument syntax may be used if escaped. .IP "\fB\-perm\fP onum" True if the aso permission flags exactly match the octal numer \fIonum\fP. If \fIonum\fP is prefixed by a minus sign, more flag bits (017777) become significant and the flags are compared: \fI(flags&onum)==onum\fP. .IP "\fB\-print\fP" Always true; causes the relative path of the current aso to be printed. .IP "\fB\-prune\fP" Always true; has the side effect of pruning the tree, iff the current file is a directory. .IP "\fB\-SinceName\fP name" True if the current aso is older than the corresponding aso having the symbolic name \fBname\fP. .IP "\fB\-symbolic\fP name" True if the current aso has the symbolic name \fIname\fP. See \fBvadm(1)\fP or \fBsave(1)\fP on how to attach a symbolic name to an aso. .IP "\fB\-state\fP state" True if the state of the current aso matches state \fIstate\fP, where \fIstate\fP is \fBbusy\fP, \fBsave\fP, \fBproposed\fP, \fBpublished\fP, \fBaccessed\fP, or \fBfrozen\fP. .IP "\fB\-type\fP c" True if the type of the current aso is \fIc\fP, where c is \fBb\fP, \fBc\fP, \fBd\fP, \fBf\fP, \fBl\fP, or \fBs\fP for block special file, character special file, directory, plain file, symbolic link, or socket. .IP "\fB\-uda\fP uda" True if the current \fBaso\fP has an user defined attribute matching uda \fIuda\fP, where \fIuda\fP is of the form \fIname[=value]\fP. .IP "\fB\-user\fP user" True if the current aso belongs to user \fIuser\fP, where \fIuser\fP is a login name optinally followed by a domainname (e.g. uli@cs.tu-berlin.de). .IP "\fB\-last\fP" True if the current aso is the last version of the development line. .IP "\fB\-first\fP" True if the current aso is the first version of the development line. .IP "\fB\-locked\fP" True if the current aso is locked. .IP "\fB\-locker\fP user" True if the current aso is locked by user \fIuser\fP, where \fIuser\fP is a login name optionally followed by a domainname. .IP "\fB\-eq\fP vnum" True if the version number of the current aso matches version number \fIvnum\fP, where \fIvnum\fP is \fIgeneration.revision\fP. .IP "\fB\-lt\fP vnum" True if the version number of the current aso is less than the version number \fIvnum\fP. .IP "\fB\-le\fP vnum" True if the version number of the current aso is less equal than the version number \fIvnum\fP. .IP "\fB\-gt\fP vnum" True if the version number of the current aso is greater than the version number \fIvnum\fP. .IP "\fB\-ge\fP vnum" True if the version number of the current aso is greater equal than the version number \fIvnum\fP. .IP "\fB\-newer\fP file" True if the current aso is more recently than the argument file which can be an aso (e.g. vfind.c[1.6]). .IP "\fB\-size\fP n" True if the file is n blocks long (512 bytes per block). .PP The primaries may be combined using the operators \fB(\fP, \fB)\fP for grouping, \fB!\fP for negation, \fB\-a\fP for concatenation (may be omitted) and \fB-o\fP for alternation of primaries. Parentheses and the exclamation mark are special to the Shell and must be escaped. .PP \fBvfind\fP does not descent AtFS directories, so the AtFS archives are never selected. .SH EXAMPLES .PP To find all asos whose state is busy and that have the symbolic name "foobar": .IP vfind / \-state busy \-symbolic foobar \-print .IP .PP To find the latest proposed version of foo.c in the current directory: .IP vfind -prune 0 . -name foo.c -state proposed -last -print .IP .SH SEE ALSO vl(1), find(1) .SH INCOMPATIBILITIES The following \fBfind(1)\fP primaries are not recognized or implemented: -link, -nouser, -group, -nogroup, -inum, and -ok. .SH AUTHOR Uli.Pralle@cs.tu-berlin.de .br Steve Emerson (steve@unidata.ucar.edu) contributed the primary \&'SinceName'. shapetools-1.4pl6.orig/man/man1/vl.1100444 2013 145 25111 5504371143 15274 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Authors: Uli.Pralle@cs.tu-berlin.de, Axel.Mahler@cs.tu-berlin.de and Andreas.Lampen@cs.tu-berlin.de $Header: vl.1[8.0] Fri Dec 17 18:55:05 1993 andy@cs.tu-berlin.de frozen $ .. .TH vl 1 "Fri Dec 17 18:55:05 1993" "vl-5.8" "ShapeTools" .SH NAME vl \- list version information .SH SYNOPSIS .na .ta 1c \fBvl\fR [ \fIversion binding options\fP ] [ \fIoptions\fR ] [ names \.\|. ] .br \fBvlog\fR [ \fIversion binding options\fP ] [ \fIoptions\fR ] [ names \.\|. ] .IP \fIOptions:\fP \w'\fIOptions:\0\fP'u [\ \fB\-?1aAcCdFghlLOqQrRStuvx\fR\ ] [\ \fB\-help\fP\ ] [\ \fB\-all\fP\ ] [\ \fB\-attr\fP\ \fIattribute\fP\ ] [\ \fB\-cache\fP\ ] [\ \fB\-expand\fP\ (or\ \fB\-xpon\fP)\ ] [\ \fB\-fast\fP\ ] [\ \fB\-format\fP\ \fIformat\ string\fP\ ] [\ \fB\-intent\fP\ ] [\ \fB\-locked\fP\ ] [\ \fB\-locker\fP\ ] [\ \fB\-log\fP\ ] [\ \fB\-noexpand\fP\ (or\ \fB\-xpoff\fP)\ ] [\ \fB\-p\fP\ all\||\|\fIattribute\ name\fP\ ] [\ \fB\-version\fP\ ] .ad .SH DESCRIPTION .PP \fBvl\fR prints various information about an AtFS object repository. While its main operation is to list the contents of an object repository in a manner similar to ls(1), \fBvl\fR knows about many options that extract additional information about individual versions or version histories. .PP If \fBvl\fR is invoked without any name arguments, it simply prints the contents of the object repository, including files (\fIbusy versions\fR) and directories in the current directory. Version objects in the object repository are represented as filenames with a bracketed \fIversion identification extension\fR. Generally, \fBvl\fR tries to give the illusion, as were all the versions in the object repository regular files in the current directory. While busy versions \- which are regular files \- may be manipulated by all commands and tools that operate on files, version objects can only be manipulated by special tools (ShapeTools) that operate on the object repository. The tools that operate on the object repository, however, can also access regular files because these are also part of the object repository. .PP With the \fB\-h\fP option given, vl prints out one information item per history rather than per version. Default output in this case is a list of history and directory names with the range(s) of available versions following in brackets. .PP If filenames are given as arguments to \fBvl\fR, similarly to ls(1) only information about these object histories will be printed. Object names may also be given in \fIbound version notation\fR, i.e. a notation that identifies a particular version of an object (e.g. \fCmkattr.c[2.4]\fR). It is also possible to use a previously assigned \fIsymbolic name\fR rather than a numerical version identification (e.g. \fCmkattr.c[tools-V4R3]\fR). Make sure to escape the bracket symbols as these usually have meaning to the shell. For further version binding possibilities (the \fIversion binding options\fP) see the vbind(1) manual page. .PP The program \fBvlog\fR prints the log-entry for specified objects. Log-entries usually describe the reason for a particular change to the design object that led to the creation of the specified revision(s). .SH OPTIONS All options also available in the ls(1) programs are marked on the following list. .IP "\fB\-?, \-help\fP" 2c Print short information about usage of this command. .IP "\fB\-1\fP (ls)" Force single column output. .IP "\fB\-a\fP (ls)" List all entries, even those with a name beginning with a '.' and the 'AtFS' entry. This option is default when vl is called by the super user. .IP "\fB\-all\fP" List all available information. .IP "\fB\-attr\fP\ \fIattribute\fP" Print only information about objects that have the specified attribute with the given values. The attribute value match is done without attribute expansion, even if -expand is set. \fIattribute\fP may also be a standard attribute. For a complete list of standard attributes names see the vadm(1) manual page. .IP "\fB\-A\fP (ls)" Same as \fB-a\fP, but '.', '..', and 'AtFS' are not listed. .IP "\fB\-c\fP (ls)" Sort the list of printed entries by the time of last status change. .IP "\fB\-cache\fP" List entries from the derived object cache too. .IP "\fB\-C\fP (ls)" Force multi column output. This is default when printing just the entry names (no \fB-l\fP and no \fB-p\fP option) and output goes to a terminal. .IP "\fB\-d\fP (ls)" With a directory name given as argument, list the directory itself rather than its contents. .IP "\fB\-expand, \-xpon\fP " Expand attribute values before printing. Attribute values may contain citations of other attributes, or they may start with a special character ('^', '!' or '*') indicating that they need some kind of processing to determine the real attribute value (see vattr(1) for details). With the \fB-expand\fP option given, all citations will be evaluated and the attribute will be evaluated if necessary. .IP "\fB\-fast\fP" Fast operation. Suppresses reader/writer synchronisation on AtFS archive files and ignores non-standard attributes. In combination with \fI-h\fP (histories), a short output is generated, that lists only the names of all histories and not their version ranges. .IP "\fB\-format\fP\ \fIformat\ string\fP" Specify custom-format for information printed about objects. This is a simple report generation facility for the \fIshapeTools\fR toolkit. The \fIformat string\fR can be any string, but typically contains \fIattribute citations\fR (see \fBretrv\fR). As \fIshapeTools\fR attribute citations use a syntax that contains dollar-characters, it is advisable, to specify \fIformat strings\fR in single-quotes to prevent shell from trying to apply variable substitution. .RS .LP \fIFormat strings\fR can contain simple layout specifications (`\fC\en\fP' for newline characters, and `\fC\et\fP' for tabs. `\fC\e\e\fP' is a single backslash.) .LP The format of the output of \fBvl \-l\fP could for example be specified as follows: .sp 0.2c .ce 2 \fCvl -format \'$_\|_mode$ $_\|_state$\t$_\|_author$\t \e $_\|_size$\t $_\|_mtime$ $_\|_self$\\n\'\fP .LP While the example only illustrates use of standard attributes, it is in fact possible to use any object attribute (i.e. user-defined attributes) in the format specification. .RE .IP "\fB\-F\fP (ls)" Append a symbolic file type character to each name. Directories are marked with a `/', sockets with a `=', symbolic links with a `@', executable files with `*', and derived objects with a `$'. If the file is locked a `^' is additionally appended. .IP "\fB\-g\fP (ls)" Print the group of the entry owner (...) . .IP "\fB\-h\fP" Print \fIhistories\fP instead of versions. All versions with the same name are folded together to one printed entry. All version binding options (see vbind(1)) are ignored, when displaying histories. .IP "\fB\-intent\fP" Print message of intention for change. An intention message can be set while retrieving a version using \fBretrv\fR with option -lock. .IP "\fB\-l\fP (ls)" List in long format, giving mode, version state, author, size in bytes, the save date, and version identification. For busy versions the date field will contain the time of last modification rather than the save date. The \fIstatus\fR of a version is printed as: \fBb\fR for busy, \fBs\fR for saved, \fBp\fR for proposed, \fBP\fR for published, \fBa\fP for accessed, \fBf\fR for frozen, and \fB$\fR for derived. .IP "\fB\-lll\fP" Same as \fB-l -locked -locker\fP. .IP "\fB\-locked\fP" Print only locked versions. .IP "\fB\-locker\fP" Print the locker instead of the author and last locking date instead of last modification or save date. .IP "\fB\-log\fP" Print the log entry for each version. .IP "\fB\-L\fP (ls)" Follow symbolic links. If a given name is a symbolic link, list the object referenced by the link rather than the link itself. .IP "\fB\-noexpand, \-xpoff\fP " Do not expand attribute values. This is the default, except when the \fB-format\fP option is set. Check \fB-expand\fP or vattr(1) for more information on attribute expansion. .IP "\fB\-O\fP" Print the version owner instead of the author. .IP "\fB\-p\fP\ \fI""all""\fP\ |\ \fIattribute\ name\fP" Print the value of the given attribute. With the string 'all' given as argument to the \fB-p\fP option, print all non standard attributes. .IP "\fB\-q\fP (ls)" Replace all non graphic character by '?' before printing. This is the default when output goes to a terminal. .IP "\fB\-Q\fP" Quiet Flag. Suppress any output to standard output. Only error messages will be printed to standard error. .IP "\fB\-r\fP (ls)" Reverse the order of the entries printed. .IP "\fB\-R\fP (ls)" Operate recursively visiting all subdirectories encountered. .IP "\fB\-S\fP" Print version states verbosely. .IP "\fB\-t\fP (ls)" Sort the list of printed entries by the modification time. .IP "\fB\-u\fP (ls)" Sort the list of printed entries by time of last access. .IP "\fB\-U\fP" Show user identifications as \fIuser@domain\fP rather than just the user name. .IP "\fB\-v\fP" Print versions. This is the default (counterpart to .IP "\fB\-version\fP" Print only the version identification of this program. .IP "\fB\-x\fP (ls)" Do multi-column output with the entries sorted across rather than down the page. .SH SEE ALSO vattr(1), vbind(1) .SH BUGS When using the version binding options \fI\-since\fP and \fI\-before\fP, the vl output may look confusing. \fI\-since\fP and \fI\-before\fP define a time interval for save dates but \fIvl\fP displays the date of last modification, which may be older than the save date. .LP \&'.' and '..' are always ignored when displaying versions. .LP Several Options are not available when displaying histories (\fI\-h\fP option). These are: \fI\-all\fP, \fI\-attr\fP, \fI\-c\fP, \fI\-format\fP, \fI\-intent\fP, \fI\-locked\fP, \fI\-log\fP, \fI\-n\fP, \fI\-p\fP, \fI\-R\fP, \fI\-t\fP, and \fI\-u\fP. .LP The displayed group name (\fI\-g\fP option) may be wrong for busy versions. .LP \&\-noexpand does not work together with \-format. .LP \fI\-q\fP, and \fI\-F\fP are not implemented. .SH AUTHOR Original version by Uli.Pralle@cs.tu-berlin.de and Axel.Mahler@cs.tu-berlin.de. .br Totally reimplemented by Andreas.Lampen@cs.tu-berlin.de. shapetools-1.4pl6.orig/man/man1/vlog.1100444 2013 145 141 5402627377 15570 0ustar dokoswt.ig $Header: vlog.1[5.0] Tue Jun 1 13:09:44 1993 andy@cs.tu-berlin.de frozen $ .. .so man1/vl.1 shapetools-1.4pl6.orig/man/man1/shape_RMS.1100444 2013 145 50750 5416575451 16515 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: shape_RMS.1[6.0] Wed Jul 7 18:36:24 1993 andy@cs.tu-berlin.de frozen $ .. .TH "SHAPE_RMS" 1 "" \n(dy.\n(mo.\n(yr .SH NAME shape_RMS \(em Introduction to the shapeTools Release Management System .SH SYNOPSIS \fBshape rms\fP \- show synopsis of shapeTools Release Management System Functions .SH DESCRIPTION The \fIshapeTools Release Management System (shape_RMS)\fP helps constructing and keeping track of system releases in complex (multi programmer) software development projects. This introductory manual page gives an overview of the shape_RMS functionality and helps getting started with the release management system. When reading this introduction, you should either be familiar with the basics of the shapeTools version control system and the shape configuration management program, or you should have the shapeTools version control and the shape(1) manual pages at hand. Complementary to this short reference manual page, there is a tutorial introduction to the usage of shapeTools, explaining how to introduce and use the shape-toolkit's functionality cleverly in a multi programmer project. .PP The cooperation and release management model of a software development project is highly dependent on the nature of the project. Factors like the programming language used, the size of the programmer team, the nature of the developed software, or local preferences strongly influence this model. The release management system as currently implemented, will in most cases not fit \fIall\fP your needs. Take it as a prototype to begin with and try to adapt it little by little. In the current state, modifying the release management system requires good skills in Makefile and Shapefile writing and a lot of patience. Think twice about every modification you perform ! Establishing a good cooperation and release model is not as easy as it might look like at the first glance. .PP The shapeTools RMS imposes a general frame for the project structure and the development process within a software development project. This frame is necessary for the release management system to determine it's workpieces and to be able to systematically document the evolution of system configurations. It helps the developer to have all system configuration and building actions performed automatically, so that he can concentrate on his development work, rather than code management activities. .PP All functions of the shapeTools RMS are performed by the shape(1) program. This interprets a description file (the Shapefile) and performs the action associated with a target name given with the shape call. Usually, you may perform a bunch of macro definitions together with the shape call. These definitions overwrite internal default macro settings. Hence, calls of the shape_RMS have the general form \fIshape\ target\ [MACRONAME=value\ ...]\fP. .PP In detail, shape_RMS automatically performs the following actions, each of which is described on the referenced manual page. .IP "\0\0\(bu" 1c System building, installation, and cleaning up (\fIshape_build(1)). .IP "\0\0\(bu" Generation of prereleases of subsystems or the whole system (\fIshape_releas(1)\fP). .IP "\0\0\(bu" Generation of releases of subsystems or the whole system (\fIshape_releas(1)\fP). .IP "\0\0\(bu" Constructing patches to existing releases (\fIshape_patch(1)\fP). .IP "\0\0\(bu" Reinstantiation of old system releases (\fIshape_releas(1)\fP) .IP "\0\0\(bu" Creation of shippable packages (tar or shar files, etc.) (\fIshape_tar(1)\fP). .IP "\0\0\(bu" Determination of file dependencies (\fIshape_depend(1)\fP). .PP Additionally, it provides .IP "\0\0\(bu" 1c Standard version selection rules (\fIshape_stdrul(7)\fP). .IP "\0\0\(bu" A project wide unified variant control raster (\fIshape_stdvar(7)\fP). .IP "\0\0\(bu" Automatic generation of (pre)release identifications. .IP "\0\0\(bu" Storing configuration management specific information with each system component. .IP "\0\0\(bu" Templates for Shapefiles and Makefiles (\fIshape_tmpl(7)\fP). .ne 2c .PP \fBThe Project Structure\fP .PP The general project structure is hierarchical. Each \fInode\fP in the hierarchy consists of a number of \fIcomponents\fP and a number of \fIsubsystems\fP. The top node in the hierarchy represents the whole system. These three terms \- node (or system node), component and subsystem \- will be used throughout all shape_RMS manual pages. A subsystem and a system node are the same thing in principle, consisting of components and subsystems. The notions rather distinguish two different points of view. .PP The hierarchical structure is reflected in a UNIX directory tree with directories representing nodes and files as system components. Not each directory necessarily holds a whole system node. Single nodes may spread across multiple directories forming a subtree. The top directory of this subtree is the representant of the node. Hence, the system structure and the directory tree may differ. .PP The project structure and it's components is described by the \fIsystem model\fP. The system model consists of a interwoven collection of Shapefiles and Makefiles. Each node is equipped with one Makefile and one Shapefile containing node specific system model information. Additional system model information (such as standard version selection rules or project wide variant definitions) is maintained in a project wide central place and accessed through shape's include facility. .PP The functional profile of the system model is reflected by predefined \fIstandard targets\fP in the system model files (Shape- and Makefiles). These targets are defined either in the individual (node specific) Shape- and Makefiles or in one of the included Shapefile fragments maintained project wide Shapefile. A set of \fIstandard macros\fP and implicitly a set of conventions that underlie those macros comprise the data interface between the various modules of the system model. Conformance with the necessary underlying conventions and assumptions is facilitated by templates for Shape- and Makefiles that are provided to the programmers of the various system parts (see shape_tmpl(7)). Using these templates makes writing system model information almost trivial. .PP According to the templates, the Makefile components contain most macro definitions, the usual component dependency definitions and most of the explicit transformation rules. The system of Makefiles is carefully designed to be selfcontained enough to be used without shape(1). This is necessary to provide a build procedure for compiling and installing software system outside the development area (where shape(1) usually is not available). .PP The Shapefile components contain information that is specifically related to shape's special features that are unavailable in make (e.g. version selection, variant handling). The complete system of Shape- and Makefiles is free of redundancy, making them easier to maintain. The Shapefiles, in order to represent a complete system model, contain include directives to include all significant system model information that is stored in other objects, namely the centrally maintained include files and the Makefiles. .PP The development work usually happens in the developers' \fIprivate workspaces\fP, with the results gathered in a central location, the projects \fIsource repository\fP. The source repository is a complete directory tree (complete in the sense of incorporating each developed system node) representing the whole project. Private workspaces and corresponding subdirectories in the source repository are linked together by common \fIAtFS\fP subdirectories (see vcintro(1)) holding all saved work results (versions). This mechanis makes files from a private workspace get visible in the source repository, as soon as the developer saves a copy of a file using the shapeTools version control system. Development work may also happen in the source repository. In this case, even the busy version of each workpiece is visible in the source repository, which doesn't disturb. .PP Each node in the system must contain a release identification file. This file is maintained automatically and should never be modified manually. It is also to be derived from a given template and contains a string citing the node name and the actual release number. With each new release, a new version of the release identification file is generated. In software development, it typically contains a routine returning the release identification string mentioned above. This mechanism automates release identification in software systems. .PP Beside private workspaces and source repository, a project has a \fIpartial release area\fP and a \fIrelease area\fP. Both areas are capable to hold a complete copy of the project's source tree as UNIX files (without version control). The \fIpartial release area\fP holds the most recent (pre-)release of each system node. Every time, a system node gets prereleased or released, a copy of the involved source versions is written to the partial release area. The \fIrelease area\fP holds prereleases and releases of the whole system. It is only filled, when a (pre-)release building procedure is triggered from the top node of the source repository. You find some more details on this topic in the \fIshape_releas(1)\fP manual page. .ne 2c .PP \fBThe Development Process\fP .PP The general development process imposed by the shape release management system is described by the following pattern. .IP "\0\01)" 1c local development and test in private workspaces with local versions (\fIsave\fP) .IP "\0\02)" individual prepublication of single node system (\fInode prerelease\fP) .IP "\0\03)" global integration and integration testing (\fItop prerelease\fP) .IP "\0\04)" incorporation of change requests from global integration into single node systems and final publication of node systems (\fInode release\fP) .IP "\0\05)" global release (\fItop release\fP) .IP "\0\06)" local introduction of bug fixes in the released system (\fInode patch prerelease\fP). .IP "\0\07)" global integration of patches and integration testing (\fItop patch prerelease\fP). .IP "\0\08)" local releases of patched node system releases (\fInode patch release\fP). .IP "\0\09)" generating a global patched release (\fItop patch release\fP). .PP Of course, there may be several loops in the above list. First, the construction of \fInode (pre-)releases\fP happens recursively from the leaves of the system source tree to the top. Second, several iterations of the \fInode/top prerelease\fP mechanism will usually be necessary, to come to a stable final release. .PP Individual development and test happens in private workspaces of individual developers. A developer typically uses local busy versions and the latest released components of all other system parts he needs (e.g. libraries) in order to test his component. Intermediate results of individual development work can be saved into the version base. The corresponding status of emerging versions is \fIsaved\fP. .PP When the developer thinks that a stable state of development is reached or a development transaction has been completed he performs an individual prerelease of his work results. Such a release of work results consists of saving all yet unsaved busy versions into the version base, marking all components of the worked-upon subsystem (i.e. all most recent versions) with a common, unique, and well-defined local releasename, and assigning the status \fIproposed\fP to all these versions. These versions, as residing in the central source repository are globally accessible for the system integrator. .PP Global integration and integration testing is performed by a special user, the integrator. The integrator does typically not do any actual development work himself. In fact the integrator is a conceptual user (i.e. a special userId) who acts in the central source repository and hence has access to all individually released components and subsystems of the developed system. Integration testing gathers all most recent individual prereleases (of components and subsystems) and creates a prerelease of the developed system. All components that are part of a prerelease are marked with a common, unique, and well-defined global prereleasename, and assigned the version status \fIpublished\fP. .PP The purpose of pre-releasing a system prior to actually releasing it, is to make sure that all components interoperate properly, the system installation procedure works properly, the new release does build, install, and run correctly on all supported platforms without the risk of assigning (and thereby wasting) the planned official releasename prematurely. During integration testing, no new features or enhancements should be allowed to be incorporated into the system. The only sort of modification request that shall be processed during this phase are bugs in the installation procedure and portability problems (this includes fixing of bugs that are found during porting). .PP Once the prerelease cycle has produced a stable state of the entire system, it can be officially released. The official release procedure is similar to the prerelease procedure, but marks all components with the planned official releasename, and assigns the version status \fIfrozen\fP to them. .ne 2c .PP \fBSetting up a Project\fP .PP In the following you find two checklists. The first one says, what to do when initiating a project as project administrator. The second one helps , connecting to an established project as developer. .ne 1c .PP Checklist for initial setup: .IP A1) 1c Create a (UNIX) user to be \fIproject owner\fP. This should be a conceptual user, not a natural one. The home directory of this user will be the \fIproject home\fP. .IP A2) Define a \fIproject group\fP (in /etc/group) and add all project participants to this group. .IP A3) Set up the central project \fIsource repository\fP in project owner's home. .RS .IP "\0\0\(bu" Create \fIdevelopment\fP directory .IP "\0\0\(bu" Create \fIbin, lib\fP and \fIinclude\fP directory in development directory. .IP "\0\0\(bu" Install system source tree with \fIsrc\fR directory in the development directory as root. .IP "\0\0\(bu" Create a directory named \fIAtFS\fP in each directory of the system source tree. .RE .IP A4) Set up release and partial release areas by creating the directories \fIrelease\fP and \fIpartial.release\fP in project owner's home. .IP A5) Make \fIall\fP previously created directories group\-writable. .IP A6) Create a directory named \fIshape\fP in development/lib and copy the shape_RMS templates and include files to that directory. .br These are Shapefile.tmpl, Makefile.tmpl, Release.tmpl, release.c.tmpl, stdconf, stdtargets, stdrules and stdvar. .IP A7) Adjust macro default values in \fIMakefile.tmpl\fP and \fIShapefile.tmpl\fP in development/lib/shape according to local installation. The shape_tmpl(7) manual page gives you information about the semantics of each macro definition. The Makefile template defines .RS .IP "\0\0\(bu" base paths for source repository, partial release area, release area, and system installation locations. .IP "\0\0\(bu" a description of the host system environment. .IP "\0\0\(bu" tools and tool options to be used. .IP "\0\0\(bu" libraries to be used. .IP "\0\0\(bu" default build and installation actions. .RE .IP A8) Check the stdvar (project wide variant definitions) file. See shape_stdvar(7) for more information about this. .PP If you stick strictly to the structuring and release model as implemented in the templates and shape include files given in the shapeTools distribution, your job is done now. Additional adaptations require changes to be performed manually on the files in shape/lib. Before you do this, we recommend reading the shapeTools tutorial first. Especially the Makefile template you should set up very carefully. As most make(1) implementations do not support inclusion of external parts into Makefiles, local Makefiles (derived from the template) hold a lot of information that should better be maintained centrally. Modifications to the Makefile template made after having already derived local Makefiles from it, requires patching the changes into each local Makefile. This is a costly and error prone job. We recommend to use patch(1) for this, which definitely isn't what you would desire, but there is no better solution yet. .PP .IP A9) 1c define version selection rules .IP A10) implement additional actions in \fIstdtargets\fP or \fIstdconf\fP. .IP A11) redefine project wide policies in \fIMakefile.tmpl, Shapefile.tmpl\fP, or \fIstdconf\fP. .PP Don't try to find any additional documentation guiding through points A9\-A11. There is none yet. .ne 1c .PP Checklist for developers, when connecting to an existing project: .IP D1) 1c Make sure to be member of the project group .IP D2) Create private development directory/ies .IP D3) Connect to the central \fIsource repository\fP by establishing a link named \fIAtFS\fP from your local development directory to the corresponding directory in the central source repository. This should either be a symbolic link to the AtFS directory there, or, on systems where no symbolic link facility is available, a file with the appropriate pathname as contents. The latter will be interpreted by the shapeTools version control system as surrogate for a symbolic link. .IP D4) Copy \fIMakefile.tmpl\fP from project_home/lib/shape as \fIMakefile\fP to your development direcory and fill in the necessary macro definitions by editing the file. If you already have a Makefile, don't try to use that further. You will be much more lucky with a Makefile derived from the template. .IP D5) Copy \fIShapefile.tmpl\fP as \fIShapefile\fP to your development direcory. Usually, no modifications should be necessary there. .IP D6) Copy one of \fIRelease.tmpl\fP or \fIrelease.c.tmpl\fP as Release, resp. release.c to your local directory. .IP D7) Create an empty \fIDependencies\fP file and run \fIshape depend (1)\fP afterwards. Check, if your project setup supports automatic generation of the Dependencies file. If not, you have to maintain it manually. .IP D8) Run \fIshape rms (1)\fP to get a synopsis of the functions provided by the shapeTools release management system. .SH ATTRIBUTES As the shape toolkit has an \fIAttributed Filesystem (AtFS\fP, see \fIafintro(3))\fP as data storage base, shape_RMS stores it's internal management information as attributes attached to the system components. Attributes consist of name and a list of values. Configuration management related attributes are .IP __SymbolicName__ Each component version in the system carries a set of symbolic names uniquely identifying the (pre-)release(s), it is part of. This list may be empty, when a version was never declared to be part of a (pre-)release. \fI__SymbolicName__\fP is an attribute with a special meaning throughout all programs in shapeTools. For more information see the \fI-symbolic\fP option of \fIvl(1)\fP and \fIvadm(1)\fP. .IP nodename Is the name of the node system, the component version belongs to as defined in the \fINODENAME\fP macro in the subsystem's Makefile. Only the release number generator file carries this attribute. .IP lastrelease The unique name of the last generated prerelease or release. This attribute gets attached only to versions of the release number generator file. In fact, it makes sense only at the most recent version of the release number generator file. .SH FILES .ta 3c Shapefile.tmpl \- Template for subsystem specific Shapefiles .br Makefile.tmpl \- Template for subsystem specific Makefiles .br stdconf \- standard configuration management tagets .br stdrules \- standard version selection rules .br stdtargets \- common basic targets .br stdvar \- project wide variant raster .SH SEE ALSO shape_build(1), shape_depend(1), shape_patch(1), shape_releas(1), shape_tar(1), .br shape_stdrul(7), shape_stdvar(7), shape_tmpl(7) .br Tutorial Introduction to the shape-toolkit .ne 2c .SH AUTHOR Andreas Lampen, Tech. Univ. Berlin (Andreas.Lampen@cs.tu-berlin.de) .sp Technical University Berlin .br Computer Science, Secr. FR 5\-6 .br Franklinstr. 28\|/\|29 .br D\-10587 Berlin, Germany shapetools-1.4pl6.orig/man/man1/shape_build.1100444 2013 145 13215 5412610543 17132 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: shape_build.1[6.0] Fri Jun 25 17:01:43 1993 andy@cs.tu-berlin.de frozen $ .. .TH "SHAPE_BUILD" 1 "" \n(dy.\n(mo.\n(yr .SH NAME shape build \(em shapeTools RMS system building and installation .SH SYNOPSIS .ta 1c 2.2c \fBshape [all] [VERSIONS=] [variants] [macro settings] .sp shape install [VERSIONS=] [INSTALLBASE=] [variants] [macro settings] .sp shape clean [] .sp shape cleancache \0\0[] .sp make [all] [] .sp make install [INSTALLBASE=] [] .sp make clean [] .sp .SH DESCRIPTION \fIShape all\fP, or just \fIshape\fP (as \fIall\fP is the default target), builds the current system node. It performs all necessary actions to derive the main target ($(TARGET) in the Makefile) from the node's source components. Shape all also builds all subsystems of the current node. Before triggering any build action itself, if recursively calls shape for each subsystem. Version selection is driven by the rule given as value to the \fIVERSIONS\fP macro, default is \fImost_recent\fP. The given version selection rule on the command line, if any, is inherited to the recursive calls. .PP \fIShape install\fP installs the build results of the current node in the appropriate locations. Things to be installed are usually binaries and manuals. The target \fIinstalltargets\fP in the Makefile lists all these things as its dependents. Shape install updates all build results in the same way as shape all does, before installing them. Shape install invokes all subsystems of the current node in the installation procedure by recursively calling shape install for each of them. This is done, before it performs any build or install actions itself. The appropriate versions are selected according to the given version selection rule named in the \fIVERSIONS\fP macro. The default rule for shape install is \fIrecent_release\fP selecting the most recent release or prerelease (whichever is newer). The macro \fIINSTALLBASE\fP defines the installation base directory, an absolute pathname pointing to the root of a directory tree, where the build results are to be copied to. Check the Makefile for the default setting of INSTALLBASE and the installation directories defined as relative pathnames starting from the installation base directory. Values of the VERSION and the INSTALLBASE macro set on the command line are inherited to all recursive calls. .PP \fIShape clean\fP removes all derived objects currently established as UNIX files. These are the files listed in the OBJECTS macro in the Makefile, the derived target ($(TARGET)), and the target aliases ($(ALIASES)). The derived objects, established as UNIX files are those being produced from their source or reinstalled from the derived object cache during the last system build. \fIShape cleancache\fP cleans up the derived object cache, will say, it removes all objects stored there. All names listed as dependents of the \fI.BPOOL\fP special macro in the Shapefile are candidates to be cached. When multiple (different) versions of derived objects with the same name arise, the older ones are stored to the derived object cache. Shape cleancache in conjunction with shape clean removes \fIall\fP derived (automatically reproducible) objects. The two cleanup actions are \fInot\fP called recursively. They apply only to the current node. .PP The build and cleanup actions (all, install and clean) of the shape RMS can be performed by \fImake(1)\fP and by \fIshape(1)\fP. The main difference is, that shape is capable of setting up the appropriate source context according to a given version selection rule, while make only regards the regular UNIX files. Make will fail if not every component of the system has a checked out busy version. The intention for maintaining Makefiles suitable for complete system builds aims at system building and installation from a source distribution rather than from the development area. Source distributions are system copies taken from one of the release trees (partial release area or release area). See shape_RMS(1) for details. .PP \fIMake all, make install\fP and \fImake clean\fP behave similar to their shape counterparts. The difference is, that they expect a complete system source context to be set up as UNIX files (see above). .PP Each macro definition in the Make\- or Shapefile may be redefined from the command line. Most of the shape RMS standard macro definitions are inherited to recursive calls of make or shape. Check the shape_tmpl(7) manual page for a list of the standard macros. .SH INCONVENIENCES For technical reasons, each make call recursively invokes make on the same level before performing any actions. This unfortunately restricts the efficacy of command line options. E.g. there is no chance to work with the \fI-f\fP (alternate name for the Makefile) option and the redefinition of macros is restricted to inherited ones. This restriction does not apply to shape calls. .SH FILES Makefile .br Shapefile .SH SEE ALSO shape_stdrul(7), shape_tmpl(7) shapetools-1.4pl6.orig/man/man1/shape_depend.1100444 2013 145 5621 5412610540 17251 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: shape_depend.1[6.0] Fri Jun 25 17:01:44 1993 andy@cs.tu-berlin.de frozen $ .. .TH "SHAPE_DEPEND" 1 "" \n(dy.\n(mo.\n(yr .SH NAME shape depend \(em shapeTools RMS determine source-include dependencies .SH SYNOPSIS \fBshape depend [VERSIONS=] [variants]\fP .sp .SH DESCRIPTION The shape release management system requires for each node system a file named \fIDependencies\fP, listing the source\-derived dependencies of the node components. \fIshape depend\fP automatically determines these dependencies and creates an appropriate Dependencies file. The dependencies have the form of regular Makefile target\-dependents lines without associated build action. .PP .in +1c .ll -1c \fBNote:\fP shape depend only works for development of C programs. It additionally requires a C compiler supporting the \fI-M\fP (generate Makefile dependencies) option. If this is not the case in your development project, you must either rewrite the action associated with the depend target (in $(SHAPELIBPATH)/stdtargets) or maintain the Dependencies files manually. .in -1c .ll +1c .PP The \fIVERSIONS\fP macro defines the version selection rule to be used. Default is \fImost_recent\fP. See shape_stdrul(7) or the $(SHAPELIBPATH)/stdrules file for other possible settings. You may also use self defined version selection rules as VERSIONS rule. .PP If your development environment contains variant definitions, in especially variant definitions that modify the list of source components to be used during a build operation, you may also need to specify one or more \fIvariants\fP to be set. The project wide variant raster is defined in $(SHAPELIBPATH)/stdvar. Check this file and the default variant settings in your Shapefile before invoking shape depend. .SH INCONVENIENCES Regeneration of the Dependencies file due to structural changes of the node system has to be triggered manually. Shape RMS doesn't recognize such changes. .PP Variant specific Dependencies files (necessary when simultaneousky developing structurally different variants) are not supported. In this case you have to run shape depend prior to each build action. .SH FILES $(SHAPELIBPATH)/stdrules .br $(SHAPELIBPATH)/stdtargets .br $(SHAPELIBPATH)/stdvar .SH SEE ALSO shape_RMS (1) shapetools-1.4pl6.orig/man/man1/shape_patch.1100444 2013 145 4752 5412610533 17117 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: shape_patch.1[6.0] Fri Jun 25 17:01:45 1993 andy@cs.tu-berlin.de frozen $ .. .TH "SHAPE_PATCH" 1 "" \n(dy.\n(mo.\n(yr .SH NAME shape patch \(em shapeTools RMS generate patch file .SH SYNOPSIS \fBshape\ patch\ OLDRELEASE=\ NEWRELEASE=\ [PATCHFILE=] .sp .SH DESCRIPTION \fIShape patch\fP generates a patch file for updating \fI$(OLDRELEASE)\fP to \fI$(NEWRELEASE)\fP. Both releases are identified by release names associated with the macros OLD-/NEWRELEASE on the command line. Valid release names are those generated by any of the shape_RMS (pre-)release building procedures (see shape_releas(1)). Performing 'vl -all' with the release identification file as argument usually gives a good overview of existing release names. Patch generation happens recursively over all subsystems being part of the current node. Hence, triggering \fIshape patch\fP from the top node of the central source repository creates a patch file for the whole system. .PP The output of shape patch is stored in a file named \fI+2+.pat\fP. When the PATCHFILE macro is set on the command line, $(PATCHFILE) is taken as output file name instead. Defining PATCHFILE=\- on the command line causes the patch to be written to standard output. \fBNote:\fP For patches invoking multiple subsystems, $(PATCHFILE) should be set to an absolute pathname. If not, the patch generation procedure will leave an equally named patch file for each visited subsystem. .PP The patch is constructed using the \fIvdiff(1)\fP command and can be applied to any installation of $(OLDRELEASE) by invoking \fIpatch(1)\fP. .SH INCONVENIENCES On System V machines, the generated patch file name will almost certainly exceed the 14 characters filename length limit. .SH SEE ALSO shape_releas(1), vdiff(1), patch(1) .SH FILES +2+.pat shapetools-1.4pl6.orig/man/man1/shape_releas.1100444 2013 145 22226 5412610531 17305 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: shape_releas.1[6.0] Fri Jun 25 17:01:47 1993 andy@cs.tu-berlin.de frozen $ .. .TH "SHAPE_RELEAS" 1 "" \n(dy.\n(mo.\n(yr .SH NAME shape releas \(em shapeTools RMS construction of releases and prereleases .SH SYNOPSIS \fBshape prerelease .sp shape release .sp shape plprerelease .sp shape plrelease .sp shape\ extractrelease\ [RELEASENAME=]\ [(PARTIAL)RELEASEBASE=]\fP .sp .SH DESCRIPTION The heart of the shapeTools Release Management System is its mechanism for creating prereleases and releases of the managed software system. These functions can be invoked from any node of the system source repository and from any private workspace. Hence, each node system can be (pre)released independently. Constructing a (pre)release of a non\-leaf node (a node containing no subsystems) requires all subsystems to be (pre)released beforehand and incorporates the existing (pre)releases in the new (pre)release. .PP Prereleases are part of the systematic preparation of a release. They give a glance on how a release will look like in the current development state. They should be used for internal publication and integration testing. When a prerelease has proved to be stable enough to be released to the outside world, it should be declared as new system release. This mechanism allows an arbitrary number of release test cycles without prematurely using the anticipated release number. .PP The general algorithm of the shape_RMS release functions is the following. .IP "1) check release preconditions" 1c Before a release process is sent on its way, the system is checked for releasability. If any of the required preconditions is not met, the system is not releasable and the release process stops. First, each subsystem \- if there are any \- has to be (pre)released beforehand. Release building requires all subsystems to be released, prereleases need the subsystems to be prereleased. The second condition, only applying to prereleases, requires that no foreign update locks are active on any of the components going into the (pre)release. It is advisable, that no changes to any of the node components are unsaved (pending), no matter who is the author. However, if the user who triggered the release process has pending changes on any components to be released, these will be saved automatically and the update locks given up. Pending changes with update locks by other users let the release process fail. .IP "2) generate release name" Each release and prerelease has an identification string, built from the node name and a two part release number. Prerelease names additionally contain a prerelease serial number, Patchlevel releases and prereleases also the patchlevel number. The release number is taken from the node's automatically maintained release identification file. The generated release identification string is tagged to any component being part of the (pre)release. .IP "3) invoke releases of subsystems" Prereleases and releases invoke all subsystems of the current node. Prerelease building includes the most recent prerelease of each subsystem, while release building includes the most recent subsystem releases. Each of the subsystem components get, additionally to the subsystem release name they already have, the freshly build release name tagged on as \fIsymbolic name\fP. Symbolic names may be used as surrogates for version numbers (see vadm(1)). .IP "4) save release components and set attributes" After all components of the included subsystems have been marked, all direct parts of a the released node get the release identification string as symbolic name. In case of building a prerelease, if any of the direct components has a busy version differing from the last saved version (pending changes) and an update lock set by the user who triggered the prerelease building, it is saved automatically before (see also 1. ). All node component versions (from subsystems or direct components) are additionally set to an appropriate version state (see below). .IP "5) install components in release area" The last step is the installation of all marked component versions (subsystem components and node components) in one of the two release areas. Releases and prereleases that have been made from the top node of the source repository are copied to the release area. All other releases, representing only a part of the whole development, are installed in the partial release area. .PP \fIShape prerelease\fP saves the current state of development. According to the algorithm described above, all unsaved node system components are saved and the most recent version of each component is included in the new prerelease. A prerelease additionally invokes the most recent prerelease or release (whichever is the newest) of each subsystem. All component versions going into the prerelease may further be identified by the automatically generated prerelease name, having the form .sp 0.2c \-.pre\ (e.g.\ \fIshapeTools-1.3pre5\fP). .sp 0.2c The prerelease serial number is maintained automatically. It starts with 1. All prerelease component versions are set to the state \fIproposed\fP. Prereleases of the whole system (the prerelease action was invoked from the top node) cause all component versions be set to state \fIaccessed\fP. A copy of the prerelease is extracted from the source repository and established installed in either the release area of the partial release area, depending on whether the prerelease comprises the whole system of or just a part. .PP \fIShape release\fP declares a previously constructed prerelease as new release. The most recent prerelease of the current node is taken as basis. If the node contains subsystems, shape release requires the most recent release of each subsystem to be included. If any subsystem has a prerelease more recent than it's last release, shape gives a warning and asks for confirmation to proceed. Due to technical reasons, it does this for each component. Don't get confused when you have to confirm multiple times. The new release gets a name of the form .sp 0.2c \-.\ (e.g.\ \fIshapeTools-1.3\fP). .sp 0.2c The generation and revision number are derived from the system's automatically maintained release identification file. With each release, a new version of this file is created. Declaring a new generation for the release file (see Save(1)) increases the system generation number. All component versions of the release are set to state \fIpublished\fP, except when a releases of the whole system is constructed (shape release from the system tree top node). In this case, the state of all component versions is set to \fIfrozen\fP. Like prereleases, a copy of the release is extracted from the source repository and written to one of the release area or the partial release area. .PP \fIShape plprerelease\fP and \fIshape plrelease\fP (shape patchlevel(pre)release) are basically the same as prerelease and release. The only difference is the form of the identification string. Patchlevel prereleases are named .sp 0.2c \-.plpre\ (e.g.\ \fIshapeTools-1.3pl5pre2\fP) .sp 0.2c and patchlevel releases .sp 0.2c -.pl\ (e.g.\ \fIshapeTools-1.3pl5\fP). .sp 0.2c The idea of patchlevel releases is to construct releases that are not to be shipped completely but rather as a patch to an existing release. Of course, real releases may also be shipped as patches, so this is rather a naming convention. .PP \fIShape extractrelease\fP extracts a copy of a certain release or prerelease from the project's central source repository and installs it in the release area or the partial release area (depending on whether it is a (pre)release of the whole system or just a part of the system). When called without further settings, it installs the most recent (pre)releases. The installed copy represents a \fIsource distribution\fP of the system or system part. It is totally independent of the development environment. .PP An explicit release identification may be given to shape extractrelease by setting \fIRELEASENAME=\fP on the command line. Setting one of the macros RELEASEBASE or PARTIALRELEASEBASE on the command line redefines the path to the base directory of the release tree. (Pre)releases of the whole system are copied to RELEASEBASE, all others to PARTIALRELEASEBASE. Check your Shapefile for the default settings of these two macros. Subdirectories will be automatically created there as needed. .SH FILES Shapefile .SH SEE ALSO shape_RMS(1) .br shapetools-1.4pl6.orig/man/man1/shape_tar.1100444 2013 145 4173 5412610525 16604 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: shape_tar.1[6.0] Fri Jun 25 17:01:48 1993 andy@cs.tu-berlin.de frozen $ .. .TH "SHAPE_TAR" 1 "" \n(dy.\n(mo.\n(yr .SH NAME shape tar \(em shapeTools RMS bundle up subsystem in a tar or shar archive .SH SYNOPSIS .ta 2c \fB shape tar [VERSIONS=] [ARCHIVE=] .sp shape shar [VERSIONS=] [ARCHIVE=]\fP .sp .SH DESCRIPTION \fIShape tar\fP and \fIshape shar\fP create a tar or a shar archive containing all source components of the current node in the system tree. All source components listed in the \fICOMPONENTS\fP macro in the Makefile and the release identification file (\fIVERSIONFILE\fP) are written to the archive. Components of subsystems are \fInot\fP included in the archive file. .PP The \fIVERSIONS\fP macro may be set to specify a version selection rule to be active during archive file creation. Default is \fImost_recent\fP, selecting the most recent version of each component. See shape_stdrul(7) or the $(SHAPELIBPATH)/stdrules for other possible settings. You may also use self defined version selection rules as VERSIONS. .PP \fIARCHIVE\fP is the base name of the file where the output shall be written to. Default is \fI$(SUBSYSTEMNAME)\fP. The output file gets the filename extension \fI.tar\fP (resp. \fI.shar\fP). When ARCHIVE=\- is given, data will be written to standard output. .SH SEE ALSO shape_RMS(1), shape_stdrul(7) .SH FILES $(SUBSYSTEMNAME).tar $(SUBSYSTEMNAME).shar shapetools-1.4pl6.orig/man/man1/sfind.1100444 2013 145 5625 5412610521 15740 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: sfind.1[6.0] Fri Jun 25 17:01:50 1993 andy@cs.tu-berlin.de frozen $ .. .TH sfind 1 "Fri Jun 25 17:01:50 1993" "shape_RMS-1.15" "ShapeTools" .SH NAME sfind \- shapeTools RMS recursively descend a system hierarchy .SH SYNOPSIS .B sfind .RB [ \-subs | .BR \-comp ] .I directory [\fIcommand\fP] .SH DESCRIPTION .B Sfind recursively descends the system hierarchy of a software system managed by the shapeTools Release Management System (shapeTools RMS). Sfind starts it's search from .I directory downwards. According to the shapeTools RMS conventions, .I directory must contain a Shapefile which lists the subsystems in the variable \fCSUBSYSTEMS\fP and the subsystem components in the variable \fCCOMPONENTS\fP. Each subsystem is visited. .LP If no .I command is specified, sfind echoes the pathnames of the subsystems it finds, or, if the option .B \-comp is given, the pathnames of the components of each subsystem. .LP When a .I command is given, it is executed in the directory of each subsystem. The string ``{}'' in .I command is replaced by the pathname of the subsystem or component. .SH OPTIONS .TP .B \-subs .I command is invoked for each subsystem. This is the default. ``{}'' in .I command is replaced by the pathname of the subsystem. .TP .B \-comp .I command is invoked for each component. ``{}'' in .I command is replaced by the pathname of the component. .SH EXAMPLES List all system components: .IP \fCsfind -comp ~/development\fP .LP Show the pathnames of all versionfiles: .IP \fCsfind ~/development echo -n {}/ \\; shape -echo VERSIONFILE\fP .LP Echo identification of the last release of each subsystem: .IP \fCsfind ~/development vl \-last \-format \\ .in +1cm \\'\\$__lastrelease\\$\\\\n\\' \\ .br \\`shape -echo VERSIONFILE\\` \fP .LP Necessary quoting to echo a pair of curly braces: .IP \fCsfind ~/development echo two \\\\{\\\\} braces\fP .SH SEE ALSO find(1), sh(1), shape(1), shape_RMS(1), shape_tmpl(7) .SH CAVEATS Quoting of shell meta characters can be tough. .SH BUGS The program is slow because shape(1) is called at least once for each subsystem. .LP When .B sfind is interrupted, usually shape(1) displays the message ``shape \- interrupted'', which may be confusing. .SH AUTHOR Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man3/ 40755 2013 145 0 5626416070 14464 5ustar dokoswtshapetools-1.4pl6.orig/man/man3/af_intro.3100444 2013 145 43111 5412536764 16472 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_intro.3[7.0] Fri Jun 25 14:32:56 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_intro 3 "Fri Jun 25 14:32:56 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME introduction to AtFS library functions and error codes .SH SYNOPSIS #include .sp int af_errno .sp .SH DESCRIPTION The following manual pages (named af*) describe the library functions of the \fIAttribute File System\fP (AtFS). .LP AtFS is an extension to the \s-1UNIX\s+1 file system interface that allows the storage of files as complex of content data and an arbitrary number of associated attributes. Attributes are either \fIstandard attributes\fP or \fIuser defined attributes\fP (also called \fIapplication defined attributes\fP). A data complex consisting of contents data and attributes, is called \fIAttributed Software Object\fP (ASO). In the following they are also referred to as \fIobject versions\fP or simply \fIversions\fP. AtFS has a built-in version control system that manages \fIobject histories\fP. A object history consists of an optional \fIbusy version\fP and a number of \fIsaved versions\fP. The busy version is represented by an ordinary alterable \s-1UNIX\s+1 file. It can be accessed via AtFS \fIand\fP \s-1UNIX\s+1 file system operations. Saved versions come into being by making a copy of the current state of the busy version. They can be stored as source versions or as derived versions. .LP \fISource versions\fP are typically composed manually (e.g. by use of a text editor). AtFS stores source versions as immutable objects. Once saved, they cannot be modified any longer. Saved versions are stored in archive files, residing in a subdirectory named \fBAtFS\fP. AtFS maintains two archive files for each history of source versions \- one holding the attributes and the other holding the data. To save disk space, the versions in an archive are stored as deltas, that means, only differences between two successive versions are stored. .LP \fIDerived versions\fP are typically derived automatically (e.g. by a compiler) from a source version and thus be reproducible at any time. They are kept in a \fIderived object cache\fP a data store of limited size that is administered in a cache fashion. When space runs short, old versions are cleaned out of the cache according to a defined policy. Check af_cache(3) for details. .LP AtFS makes no assumptions whether a copy of a busy object shall be stored as source object or as derived object. The application has to decide that by calling the appropriate function (af_saverev \- manual page af_version(3) or af_savecache \- manual page af_cache(3)). .LP The main data types for AtFS applications are: .TP 0.3c \(bu The \fIobject key\fP that uniquely identifies an ASO (version). The structure of this type can be different in different implementations of AtFS. Consequently, application programs should handle this type as opaque type and should not access single fields. .TP \(bu A \fIset descriptor\fP represents a set of object keys. A set descriptor contains information about the size of the set and a list of object keys in the set. .TP \(bu The \fIuser identification\fP represents a user. As AtFS realizes a simple network user concept, it does not identify users by their \s-1UNIX\s+1 user id, but rather by the user \fIname\fP and the \fIdomain\fP where this name is valid. See af_afuser (manual page af_misc(3)) for details. .TP \(bu An \fIattribute buffer\fP is capable to hold all attributes of a software object (standard attributes and user defined attributes). Attribute buffers have two different purposes. First, they can hold a retrieve pattern, i.e. they may be (partially) filled with desired attribute values and then be passed as argument to a retrieve operation (af_find and af_cachefind \- manual page af_retrieve(3)). Second, an attribute buffer is used to return all attributes of an identified ASO on demand. .LP There are several ways for an AtFS application to get an object key pointing to a specific object version. The most important is the function \fIaf_getkey\fP (manual page af_retrieve(3)), that returns a key for an explicitly named version. After having retrieved a key, the data for that object version remains cached in memory as long as the application does not explicitly give the key back. The function \fIaf_dropkey\fP (manual page af_retrieve(3)) gives a key back and releases the object version. A retrieved set of keys has also to be given back by use of \fIaf_dropset\fP (manual page af_retrieve(3)). \fIaf_dropall\fP (manual page af_retrieve(3)) sets all reference counters for cached object versions to zero, that means, it gives all formerly retrieved keys and sets back. In the case, that any attribute, or the contents data of a cached object version is modified on disk by another application, the data in the cache is automatically updated. In that case, a warning is written to the error log file. .LP For handling sets of keys, AtFS provides a full set algebra with functions for adding and deleting single keys, sorting, building subsets, intersections, unions and differences of sets. .LP The built-in version control functionality features a status mode for versions. Each object version has a certain state, one of \fIbusy, saved, proposed, published, accessed\fP and \fIfrozen\fP. The already known \fIbusy version\fP always has the state busy, while when previously referencing a \fIsaved versions\fP we meant a version that can have any state from saved to frozen. AtFS does not enforce any specific semantics with the version state. It is rather a help for applications to implement a classification for versions. Another part of the version control functionality is a locking facility. Adding a new version to an existing object history always requires a lock on the \fImost recent version\fP or the generation to which the version shall be added. Locks can be used for implementing a synchronization mechanism for concurrent updates to one object history. .LP A \fIuser defined attribute\fP (or \fIapplication defined attribute\fP) has the general form \fIname[=value [value [...]]]\fP. It has a name and a (possibly empty) list of values. The name may consist of any characters (even non\-alphanumeric) but an equal sign (\fC=\fP). The equal sign is the delimiter between name and value. The attribute value may not contain Ctrl-A (\e001) characters. Although AtFS promises the storage of an arbitrary number of user defined attributes, the current implementation limits their number to 255. .LP Most of the AtFS calls have one or more error returns. An error is indicated by a return value that is either \-1 or a nil pointer, depending on the return type of the function. If one of the functions returns with an error, the variable \fIaf_errno\fP is set to indicate the appropriate error number. \fIaf_errno\fP is not cleared upon successful calls. .SH ERROR CODES The following is a complete collection of the error numbers defined in \fIatfs.h\fP. The first list contains return values indicating common error conditions like implausible arguments passed to an AtFS function or permission problems. The error codes listed in the second list point to serious trouble, which can either be an internal error in AtFS or a corrupted archive file. The occurrence of an serious problem is recorded in an error protocol (\fI/usr/adm/AtFSerrlog\fP). On machines without \fIsyslog(3)\fP switched on for AtFS, the error protocol is located in a \fI/tmp/AtFSerrlog\fP. .TP AF_ESYSERR (-2) Error during execution of system library command or system call A called system library function or system call returned with an error condition. See \fIerrno\fP for a more precise error specification. .TP AF_EACCES (-3) permission denied An attempt was made to perform an operation (e.g. open a file) without appropriate permissions. .TP AF_EARCHANGED (-4) archive file has changed since last read One of the archive files you are operating on has been modified by another process since your process has read it from disk. In this case, AtFS refuses to store your changes because this would destroy the modifications made by the other process. In order to make your desired changes happen, you have to rerun your application. .TP AF_EBUSY (-7) Specified ASO must not be a busy version Some AtFS-operations cannot be performed on ASOs which have the state \fIAF_BUSY\fP. .TP AF_EDERIVED (-8) Specified ASO must not be a derived object Some AtFS-operations (eg. \fIaf_lock\fP \- manual page af_lock(3), \fIaf_newgen\fP \- manual page af_version(3)) cannot be performed on ASOs stored in derived object caches. .TP AF_EINVKEY (-9) invalid object key An invalid object key (eg. nil pointer) was passed to an AtFS function. .TP AF_EINVSET (-10) invalid set descriptor An invalid set descriptor (eg. nil pointer) was passed to an AtFS function. .TP AF_EINVUSER (-11) invalid user An invalid user structure or user id was passed to an AtFS operation. .TP AF_EINVVNUM (-12) Bad version number An attempt was made to set a version number, that contradicts the AtFS version numbering philosophy, to an ASO. You cannot change the version number of an ASO into a version number that is "smaller" than the one given by the system. .TP AF_EMISC (-15) miscellaneous errors This error code is set when an error occurs that does not fit in any of the other error categories. See your error logging file (\fI/usr/adm/AtFSerrlog\fP of \fI/tmp/AtFSerrlog\fP) for a detailed description of the error. \fIaf_perror\fP (manual page af_error(3)) also gives a diagnostic message explaining the error. .TP AF_EMODE (-16) invalid mode The function \fIaf_setattr\fP (manual page af_attrs(3)) requires a change mode. This error condition complains about an invalid mode given to this function. .TP AF_ENOATFSDIR (-17) AtFS subdirectory missing or not writable There is no place where AtFS can create it's archive files. Either a global archive path should be defined (see \fIaf_setarchpath\fP \- manual page af_misc(3)) or a subdirectory named \fIAtFS\fP should be present and writable. .TP AF_ENOKEY (-18) key does not exist in set A specified key that shall be removed from a keyset does not exist in the concerning set. .TP AF_ENOPOS (-19) invalid position in set A specified position in a keyset (keysets are organized as arrays of object keys) lies beyond the bounds of the concerning set. .TP AF_ENOREV (-20) specified revision does not exist A revision - uniquely identified by a set of attributes (eg. \fIaf_getkey\fP \- manual page af_retrieve(3)) - does not exist in the current search space. .TP AF_ENOTBUSY (-21) specified ASO is not busy version Some AtFS operations (eg. af_setbusy \- manual page af_version(3)) require the key of a busy ASO as input parameter. If you pass key of a non-busy ASO, the function sets this error code. .TP AF_ENOTDERIVED (-22) specified ASO is no derived object An attempt was made to restore an object that in not stored in a derived object cache. .TP AF_ENOTLOCKED (-23) specified ASO is not locked or locked by another user An AtFS operation cannot be performed because the specified ASO is either not locked (see \fIaf_lock(3)\fP) or it is locked by another user. .TP AF_ENOTREGULAR (-24) specified ASO is no regular file With this error number AtFS refuses to generate versions of non-regular \s-1UNIX\s+1 files such as directories, special files and sockets. .TP AF_ENOTVERS (-25) specified ASO has no versions Typically, this error occurs if an operation requiring at least one saved revision (eg. af_newgen \- manual page af_version(3)) is applied on a versionless file. .TP AF_ENOUDA (-26) user defined attribute does not exist A user defined attribute with the given name does not exist. .TP AF_ESAVED (-27) saved versions cannot be modified An attempt was made to open a non-busy version with write access. .TP AF_ESTATE (-28) invalid state transition The \fIAttribute File System\fP's built in revision-states model allows only well defined revision state changes. .TP AF_EWRONGSTATE (-31) wrong state Some AtFS operations can only be performed on ASOs with a specific version state. .LP The error codes indicating real trouble: .TP AF_EDELTA (-32) Error during delta operation Some error occurred during invocation of the delta processor. .TP AF_EINCONSIST (-33) Archive file inconsistent The data in the archive file are corrupted. This may have happened by editing the archive file or by malfunction of an AtFS operation. Try \fIatfsrepair\fP ti fix it. .TP AF_EINTERNAL (-34) internal error Please inform your local trouble shooting service, go to your favorite pub and order a beers. Cheers ! .TP AF_ENOATFSFILE (-35) No AtFS file Archive file lost. .SH LIST OF FUNCTIONS .ta 1.4i 2.8i \fIName Appears on Page Description\fP .sp .nf af_abort af_transact.3 abort transaction af_access af_history.3 test existence of history af_afname af_misc.3 get ASO name from \s-1UNIX\s+1 path af_afpath af_misc.3 get ASO syspath from \s-1UNIX\s+1 path af_aftype af_misc.3 get ASO type from \s-1UNIX\s+1 path af_afuser af_misc.3 get AtFS user from \s-1UNIX\s+1 uid af_allattrs af_attrs.3 get all attributes of ASO af_cachefind af_retrieve.3 find derived objects by attributes af_cachenames af_history.3 return list of names in derived object cache af_cachesize af_cache.3 define object cache size policy af_chauthor af_protect.3 change author of ASO af_chmod af_protect.3 change protection of ASO af_chowner af_protect.3 change owner of ASO af_cleanup af_error.3 do cleanup after error af_close af_files.3 close ASO contents af_commit af_transact.3 commit transaction af_copyset af_sets.3 copy sets af_crkey af_files.3 create object key for \s-1UNIX\s+1\-file af_diff af_sets.3 build difference between two sets of object keys af_dropall af_retrieve.3 drop all accessed object keys af_dropkey af_retrieve.3 drop object key af_dropset af_retrieve.3 drop set of object keys af_errmsg af_error.3 return AtFS- or system error message af_errno af_error.3 global error code variable af_establish af_files.3 establish ASO as UNIX file af_find af_retrieve.3 find ASOs by attributes af_freeattr af_attrs.3 free memory associated with attribute value af_freeattrbuf af_attrs.3 free memory associated with attribute buffer af_getkey af_retrieve.3 get key by unique attributes af_histories af_history.3 return list of history names matching pattern af_initattrs af_retrieve.3 initialize attribute buffer af_initset af_sets.3 initialize set af_intersect af_sets.3 build intersection between two sets of object keys af_isstdval af_attrs.3 check if attribute is from a standard attribute af_lock af_lock.3 set lock on ASO af_newgen af_version.3 increase generation number of ASO af_nrofkeys af_sets.3 return number of keys in set of object keys af_open af_files.3 open ASO contents af_perror af_error.3 report AtFS- or system error af_predsucc af_version.3 get successor or predecessor of version af_restore af_files.3 restore derived ASO af_retattr af_attrs.3 return value of attribute as string af_retnumattr af_attrs.3 return value of numeric attribute af_rettimeattr af_attrs.3 return value of time attribute af_retuserattr af_attrs.3 return value of user attribute af_rm af_files.3 remove ASO af_rnote af_note.3 return note attribute af_savecache af_cache.3 save derived object to cache af_saverev af_version.3 save busy version of source object af_setaddkey af_sets.3 add key to set of object keys af_setarchpath af_misc.3 set path for location of archives af_setattr af_attrs.3 set user defined attribute af_setbusy af_version.3 set version busy af_setgkey af_sets.3 get key from set of object keys af_setposrmkey af_sets.3 remove key (id. by position) from set of object keys af_setrmkey af_sets.3 remove key from set of object keys af_snote af_note.3 modify note attribute af_sortset af_sets.3 sort set of object keys af_sstate af_version.3 set version state af_subset af_sets.3 build subset of set of object keys af_svnum af_version.3 set version number af_testlock af_lock.3 see if ASO is locked af_transaction af_transact.3 begin transaction af_union af_sets.3 build union of two sets of object keys af_unlock af_lock.3 remove lock from ASO af_version af_misc.3 return identification of current AtFS version .fi .SH FILES /var/adm/AtFSerrlog, /tmp/AtFSerrlog .SH SEE ALSO intro(2), intro(3) .sp Andreas Lampen and Axel Mahler .br \fIAn Object Base for Attributed Software Objects\fP .br Proceedings of the Autumn '88 EUUG Conference (Cascais, October 3-7) .br European UNIX System User Group, London 1988 .sp For an outlook on a totally new implementation of the AtFS idea, have a look at: .br Andreas Lampen .br \fIAdvancing Files to Attributed Software Objects\fP .br Proceedings of USENIX Technical Conference (Dallas TX, January 21-25, 1991) .br USENIX Association, Berkeley CA, January 1991 .SH BUGS The built in archive file locking to prevent concurrent updates is very simple and my lead to confusing situations. It may happen that changes will not be saved to disk. See the error conditions AF_EARCHANGED and AF_EARLOCKED for more details. .SH AUTHOR Andreas Lampen, Tech. Univ. Berlin (Andres.Lampen@cs.tu-berlin.de) .sp .ta 1c Technische Universitaet Berlin .br Sekr. FR 5-6 .br Franklinstr. 28/29 .br D\-10587 Berlin, Germany shapetools-1.4pl6.orig/man/man3/af_attrs.3100444 2013 145 16364 5412536757 16510 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_attrs.3[7.0] Fri Jun 25 14:33:00 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_attrs 3 "Fri Jun 25 14:33:00 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_retattr, af_retnumattr, af_retuserattr, af_rettimeattr, af_setattr, af_allattrs, af_isstdval, af_freeattr, af_freeattrbuf \- AtFS attribute handling .SH SYNOPSIS #include .sp .ta 1.5c char *af_retattr (Af_key *aso, char *attrName) .sp int af_retnumattr (Af_key *aso, char *attrName) .sp Af_user af_retuserattr (Af_key *aso, char *attrName) .sp time_t af_rettimeattr (Af_key *aso, char *attrName) .sp int af_setattr (Af_key *aso, int mode, char *attrName) .sp int af_allattrs (Af_key *aso, Af_attrs *attrBuf) .sp void af_freeattr (char *attrValue); .sp void af_freeattrbuf (Af_attrs *attrBuf); .sp int af_isstdval (char *attrValue); .sp .SH DESCRIPTION \fIaf_retattr\fP returns the value of any ASO attribute in string representation. The \fIattrName\fP argument denotes either a standard attribute (according to the list below) or a user defined attribute. Standard attributes are converted to a meaningful string representation if necessary. If the attribute name given to af_retattr contains an equal sign (this may be the case with user defined attributes), only the part before the equal sign will be interpreted as name. If the named attribute is a user defined attribute carrying multiple values, these will be returned in \fIone\fP string, with the values separated by newline ('\en') characters. If the named attribute does not exist, af_retattr returns a null pointer. If the value is empty, an empty string is returned. \fBNote:\fP The result string of af_retattr may reside in static memory which is overwritten on subsequent calls of af_retattr. .LP \fIaf_retnumattr\fP, \fIaf_retuserattr\fP, and \fIaf_rettimeattr\fP return the value of the named attribute as integer, user structure or time value. These functions only apply to standard attributes with a matching type. .LP \fIAf_setattr\fP sets, modifies, or deletes user defined attributes of the ASO identified by \fIaso\fP. The \fIattr\fR parameter is a string of the form: \fIname=value\fP. The name may consist of any characters (even non\-printable) but it may not contain Ctrl-A (\e001) characters. The first equal sign that appears in the string is interpreted as the delimiter between name and value. If the string does not contain an equal sign, it is interpreted as just an attribute name without value. The \fImode\fR parameter is one of the following: .TP 2.5c AF_ADD Attach the given attribute to the identified ASO. If an attribute with the given name already exists, add just the value to the existing attribute. Subsequent calls of af_setattr with the same attribute name construct attributes with multiple (any number) values. .TP AF_REMOVE Remove the named attribute. This mode requires only the attribute name to be given as attr parameter. Removal of single values is not supported. .TP AF_REPLACE Replace an existing user defined attribute. The replacement fails, if no attribute with the given name exists. .LP \fIaf_allattrs\fP returns the complete attribute buffer (\fIattrBuf\fP) of the ASO identified by \fIaso\fP including standard and user defined attributes. The af_retrieve(3) manual page shows the structure of the attribute buffer. .LP \fIaf_freeattr\fP and \fIaf_freeattrbuf\fP release memory eventually allocated during a af_retattr or af_allattrs call. As the result of af_retattr may reside either in static or dynamic (malloc(3)) memory, you should not use free(3) for releasing attribute value memory. .LP \fIaf_isstdval\fP returns TRUE if the given \fIattrValue\fP string is the return value of an af_retattr call where the result was written to static rather than allocated memory. Otherwise it returns FALSE. .SH AtFS STANDARD ATTRIBUTES The following is an alphabetically ordered list of all known standard attributes. AF_ATT... are string constants that may be used as \fIattrName\fP argument for any of the function calls described on this manual page. In parenthesis behind each symbolic constant, the type of the attribute is shown. .TP 4.5c AF_ATTAUTHOR (user) The versions author. .TP AF_ATTATIME (time) The date of last access (read or write) to the version contents. .TP AF_ATTBOUND (string) The version name in bound version notation (e.g. \fIfoo.c[1.2]\fP). .TP AF_ATTBOUNDPATH (string) Absolute pathname of the version in bound version notation (e.g. \fI/usr/andy/foo.c[1.2]\fP). .TP AF_ATTCTIME (time) The date of last status change. Updated, when an attributes value is changed. .TP AF_ATTDSIZE (numeric) The size of the delta if there is any. If the version is not stored as delta, -1 is returned. .TP AF_ATTGEN (numeric) The generation number. .TP AF_ATTHOST (string) The host from where the version was accessed (this attribute is quite useless, as this is always the current host). .TP AF_ATTLOCKER (user) The user who has set a lock on the version (if any). .TP AF_ATTLTIME (time) The date of last lock change. This is empty, when there was never a lock set. .TP AF_ATTMODE (numeric) The version file type and protection. Same as st_mode in struct stat (see stat(2)). .TP AF_ATTMTIME (time) The date of the last contents modification. .TP AF_ATTNAME (string) The AtFS name of the version. This has the filename extension, if there is any, stripped off. .TP AF_ATTOWNER (user) The versions owner. .TP AF_ATTREV (numeric) The revision number. .TP AF_ATTSIZE (numeric) The file size. This may be independent of the real storage size, as most saved versions are stored as deltas (see also AF_ATTDSIZE). .TP AF_ATTSPATH (string) The UNIX pathname leading to the version. This may be different when accessing the version from different hosts. .TP AF_ATTSTATE (numeric) The version state. States are numbered 0 trough 5 from \fIbusy\fP to \fIfrozen\fP. .TP AF_ATTSTIME (time) The save date. This date is not set for busy versions. .TP AF_ATTTYPE (string) The filename extension (the string behind the rightmost period in the versions full name). See af_misc(3) for details. .TP AF_ATTUNIXNAME (string) The full UNIX name (without path). .TP AF_ATTUNIXPATH (string) The full UNIX path. .TP AF_ATTVERSION (string) The complete version number \fIgeneration.revision\fP . .SH SEE ALSO stat(2), free(3), af_misc(3), af_retrieve(3) .SH DIAGNOSTICS Upon error, \-1 or a nil pointer (depending on the return type) is returned and \fIaf_errno\fP is set to the corresponding error number. .SH LIMITS Although AtFS promises the storage of an arbitrary number of user defined attributes, the current implementation limits their number to 255. af_setattr sets the corresponding error condition if the limit is reached. shapetools-1.4pl6.orig/man/man3/af_cache.3100444 2013 145 6360 5422544613 16360 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_cache.3[7.0] Mon Jul 19 18:19:37 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_cache 3 "Mon Jul 19 18:19:37 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_savecache, af_cachesize \- AtFS derived object cache handling .SH SYNOPSIS #include .sp int af_savecache (Af_key *busyAso, Af_key* cachedAso, char *attr, int mode) .sp int af_cachesize (char path, int totalMax, int maxPerName, int maxPerGivenAttr); .sp .SH DESCRIPTION \fIaf_savecache\fP copies a busy attributed software object (\fIbusyAso\fP) to a derived object cache. A key for the resulting cached ASO is returned in the buffer \fIcachedAso\fP. Derived object caches are intended to hold derived objects that can be reproduced at any time. Reproducibility is important, because cached ASOs may be deleted automatically due to storage limitations for derived object caches. A cache allows a certain number of versions per name (see function af_cachesize described below) to be stored. When this number is reached, each time a new version arrives, the oldest version (access date) gets cleaned out. .LP The strategy of cleaning out old versions when space is needed for new ones is influenced by the \fIattr\fP argument. When this is given af_savecache searches for cached versions (with the same name as the new one) carrying the given attribute. If it finds one or more such versions, the oldest (access date) of them will be eliminated. .LP The \fImode\fP argument may have one of the following values .TP 3c AF_STORE_COMPLETE (default) The cached file is stored unmodified. .TP AF_STORE_COMPRESSED The cached file will be stored in a compressed format. .LP ASOs that are saved in derived object caches do not automatically get a version number. By means of \fIaf_svnum\fP (manual page af_version(3)) you can attach any version number to an ASO stored in a derived object cache. .LP \fIaf_cachesize\fP defines the size strategy of the cache in directory \fIpath\fP. It sets the maximum cache size for the whole directory (\fItotalMax\fP), the maximum number of versions per name (\fImaxPerName\fP), and the number of versions allowed simultaneously carrying the elimination attribute (see before). A value less or equal zero given for any of the arguments of af_cachesize will cause this argument to be ignored. .SH DIAGNOSTICS Upon error, \-1 is returned and \fIaf_errno\fP is set to the corresponding error number. .SH BUGS Compression of cached files (mode AF_STORE_COMPRESSED) is not yet supported. .LP af_cachesize cannot shrink derived object caches yet. Values given must be greater or equal the prevoius size. shapetools-1.4pl6.orig/man/man3/af_error.3100444 2013 145 4065 5412536747 16456 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_error.3[7.0] Fri Jun 25 14:33:06 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_error 3 "Fri Jun 25 14:33:06 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_errno, af_perror, af_errmsg, af_cleanup \- AtFS error handling .SH SYNOPSIS #include .sp .ta 1.2c int af_errno .sp void af_perror (char *string) .sp char* af_errmsg (char *string) .sp int af_cleanup (void) .sp .SH DESCRIPTION \fIaf_errno\fP is the global AtFS error number variable. If an AtFS functions returns with an error, \fIaf_errno\fP is set to indicate the appropriate error number. It is not cleared upon successful calls. The af_intro(3) manual page gives an overview of all error codes. .LP \fIaf_perror\fP produces a short error message of the form described in perror(3). This message will be written to standard error. If the last error encountered during an AtFS application was an AtFS\-specific error, a corresponding message is generated, otherwise af_perror calls perror(3). .LP \fIaf_errmsg\fP does the same as af_perror but returns the message rather than writing to standard error. The result string resides in static memory and hence will be overwritten on subsequent calls of af_errmsg. .LP \fIAf_cleanup\fP serves as cleanup routine upon premature termination of an AtFS application. It removes temporary files and frees all allocated memory. .SH SEE ALSO intro(2), af_intro(3), perror(3) shapetools-1.4pl6.orig/man/man3/af_files.3100444 2013 145 10025 5412536743 16434 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_files.3[7.0] Fri Jun 25 14:33:07 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_files 3 "Fri Jun 25 14:33:07 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_crkey, af_open, af_close, af_rm, af_establish, af_restore \- AtFS file system operations .SH SYNOPSIS #include .br #include .sp int af_crkey (char *syspath, char *name, char *type, Af_key *aso) .sp FILE *af_open (Af_key *aso, char *mode) .sp int af_close (FILE *stream) .sp int af_rm (Af_key *aso) .sp int af_establish (Af_key *aso, char *filename) .sp int af_restore (Af_key *aso, Af_key *restoredAso) .sp .SH DESCRIPTION \fIaf_crkey\fP creates an object key for a regular \s-1UNIX\s+1 file identified by name, type and system path. \fIsyspath\fP is an either absolute or relative directory name. An empty syspath refers to the current directory. By convention, AtFS interprets the filename suffix of a \s-1UNIX\s+1 file as \fItype\fP and the filename without suffix as \fIname\fP attribute. To give an example, the path name .LP .RS .nf \fB/usr/andy/foo.c\fP is split up in \fB/usr/andy\fP (syspath) \fBfoo\fP (name) \fBc\fP (type) .fi .RE .LP A period as first character in the filename is always considered as part of the name. Hence \fB.cshrc\fP has a name but no type. "." and ".." are recognized as names too. If the named \s-1UNIX\s+1 file does not exist, af_crkey creates an empty file. The created key remains accessible until it is explicitly given up by af_dropkey (manual page af_retrieve(3)). .LP \fIaf_open\fP opens the contents of the ASO pointed to by \fIaso\fP and associates a stream with it. A pointer to the FILE structure associated with the stream is returned. \fIMode\fP is a character string that is either "r[+]", "w[+]" or "a[+]". See fopen(3) for further details. Upon error, af_open returns a NULL pointer. Non-busy ASOs can only be opened with mode "r". If a non-busy ASO is opened, it's contents will be placed in a temporary \s-1UNIX\s+1 file due to storage of versions as deltas. .LP \fIaf_close\fP closes a stream previously opened by af_open (see fclose(3)). Temporary files created by af_open, holding the contents of a saved versions are unlinked right after being opened so that they will automatically disappear on closing. .LP \fIaf_rm\fP removes the specified ASO. The application has to have a lock (see af_lock(3)) set on the ASO that shall be deleted by af_rm. ASOs with the state attribute set to \fBaccessed\fP or \fBfrozen\fP cannot be removed. If you keep multiple keys of one object (perhaps in different sets) af_rm invalidates all keys of the removed object. As AtFS does not support multiple links to saved ASOs, af_rm on a saved version always does a physical removal. .LP \fIaf_establish\fP establishes the contents of the saved version, pointed to by \fIaso\fP in a file named \fIfilename\fP. The resulting file gets the version's modification and access date. .LP \fIaf_restore\fP is used to restore formerly saved derived ASOs into their old file location. It also restores the file modification and access date. This function cannot be applied to source objects. af_restore returns the key of the restored version in the buffer \fIrestoredAso\fP. .SH SEE ALSO fopen(3), fclose(3), af_retrieve(3), af_lock(3) .SH DIAGNOSTICS Upon error, \-1 or a nil pointer (depending on the return type) is returned and \fIaf_errno\fP is set to the corresponding error number. shapetools-1.4pl6.orig/man/man3/af_history.3100444 2013 145 4516 5412536740 17020 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_history.3[7.0] Fri Jun 25 14:33:09 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_history 3 "Fri Jun 25 14:33:09 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_histories, af_access \- AtFS history functions .SH SYNOPSIS #include .sp .ta 1.5c char** af_histories (char *path, char *pattern) .sp char** af_cachenames (char *path, char *pattern); .sp int af_access (char *path, char *name, char *type, int mode) .sp .SH DESCRIPTION \fIaf_histories\fP returns a list of source history names from the directory pointed to by \fIpath\fP, that match the given \fIpattern\fP. Histories in a directory are represented by at least one version. The pattern must be ed(1) patterns, processable by re_comp(3) and re_exec(3). The resulting list of af_histories resides in allocated memory. Use free(3) to free the memory for further allocation. af_histories returns an empty list (not a NULL pointer !), when no histories are found. .LP \fIaf_cachenames\fP does the same as af_histories but on derived object caches. .LP \fIaf_access\fP determines the existence of an object history. If any ASO (any version) with the given \fIpath\fP, \fIname\fP and \fItype\fP attributes exists, af_access returns zero, otherwise \-1. The \fImode\fP argument can either be .TP 2.5c AF_CLASS_SOURCE indicating that only source objects shall be searched or .TP AF_CLASS_DERIVED which means that only the derived object cache shall be searched for existence of a matching ASO. .SH SEE ALSO ed(1), re_comp(3), re_exec(3), free(3) .SH DIAGNOSTICS Upon error, \-1 or a null pointer (depending on the return type) is returned and \fIaf_errno\fP is set to the corresponding error number. shapetools-1.4pl6.orig/man/man3/af_lock.3100444 2013 145 5461 5412536733 16251 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_lock.3[7.0] Fri Jun 25 14:33:11 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_lock 3 "Fri Jun 25 14:33:11 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_lock, af_unlock, af_testlock \- mechanism for reserving update rights in AtFS .SH SYNOPSIS #include .sp Af_user *af_lock (Af_key *aso, Af_user *locker) .sp Af_user *af_unlock (Af_key *aso) .sp Af_user *af_testlock (Af_key *aso) .sp .SH DESCRIPTION This manual page describes the interface to the AtFS locking mechanism. Locks are used to avoid conflicting updates to one object history. After a user has reserved the update rights, no other user may add new versions to the reserved history. Reserving the update rights happens by locking the \fImost recent version\fP of the history. As AtFS allows adding new versions to each generation in a history, each generation may be locked separately. Reserving update rights for old generations (with generation numbers smaller than the newest generation) are performed by locking the most recent version of the corresponding generation. Removing an ASO (af_rm \- manual page af_files(3)) and changing an ASO's version number (af_svnum \- manual page af_version(3)) also requires a lock on the corresponding ASO. .LP \fIaf_lock\fP reserves the update permission for the user identified by \fIlocker\fP. On successful completion, a buffer identical to locker is returned, a NULL pointer otherwise. .LP \fIaf_unlock\fP cancels a formerly established reservation of update rights. Only the owner or the locker of an ASO (identified by the Af_user structure that was given to the corresponding call of af_lock) are allowed to do this. On successful completion, af_unlock returns a buffer containing the identification of the former locker. This may be empty, if the ASO was not locked. Upon error, a NULL pointer is returned. .LP \fIaf_testlock\fP returns a buffer containing an identification of the current locker of the specified ASO. It returns an empty buffer, if no lock is set. .SH SEE ALSO af_version(3), af_files(3) .SH DIAGNOSTICS af_lock and af_unlock return \-1 on error and \fIaf_errno\fP is set to indicate the error number. shapetools-1.4pl6.orig/man/man3/af_misc.3100444 2013 145 6236 5412536727 16260 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_misc.3[7.0] Fri Jun 25 14:33:12 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_misc 3 "Fri Jun 25 14:33:12 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_afname, af_afpath, af_aftype, af_afuser, af_setarchpath, af_version \- miscellaneous AtFS functions .SH SYNOPSIS #include .sp .ta 1.5c char *af_afname (char *path) .sp char *af_afpath (char *path) .sp char *af_aftype (char *path) .sp Af_user *af_afuser (uit_t uid) .sp char *af_setarchpath (char *path) .sp char *af_version (void) .sp .SH DESCRIPTION The functions \fIaf_afname, af_afpath\fP and \fIaf_aftype\fP extract name, syspath or type from a given (operating system dependent) file identification. In an \s-1UNIX\s+1 environment, a given pathname of the form .LP .RS .nf \fB/usr/lib/libatfs.a\fP leads to afname \fBlibatfs\fP, afpath \fB/usr/lib\fP and aftype \fBa\fP. .fi .RE .LP If no path (eg. \fBotto.c\fP), or no type (eg. \fB/usr/hugo/Makefile\fP) is given, the corresponding routine returns an empty string. A period as first character in a filename is always considered to be part of the name (e.g. \fB.cshrc\fP has the name \fB.cshrc\fP and an empty type string). "\fB.\fP" and "\fB..\fP" are recognized as names. Archive file extensions and AtFS specific path extensions are stripped from the resulting name resp. pathname. .br \fBNote:\fP af_afname, af_afpath and af_aftype use static memory for the returned results. Subsequent calls of the same function overwrite former results. .LP \fIaf_afuser\fP returns an AtFS user identification which consists of the login name of the user identified by \fIuid\fP, the current host and the current domain. \fIUid_t\fP is defined according to the return type of \fIgetuid (2)\fP on your system. The \fIAf_user\fP type has the following structure .RS .sp 0.1i .nf typedef struct { char af_username[\s-1MAXUSERNAMELEN\s+1]; char af_userhost[\s-1MAXHOSTNAMELEN\s+1]; char af_userdomain[\s-1MAXDOMAIN+1\s+1]; } Af_user; .fi .sp 0.1i .RE .LP \fIaf_setarchpath\fP defines the location of the AtFS archive files. A nil-pointer given as \fIpath\fP-argument clears the former setting of the global archive path. af_setarchpath returns the old global archive path. Initially, no global archive path is set. In this case, all archive files are stored in a subdirectory called \fBAtFS\fP, relative to the directory where corresponding busy version resides. .LP \fIaf_version\fP returns a string that names the version and the creator of the currently used AtFS library. .SH SEE ALSO getuid(2) shapetools-1.4pl6.orig/man/man3/af_note.3100444 2013 145 3126 5412536723 16261 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_note.3[7.0] Fri Jun 25 14:33:14 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_note 3 "Fri Jun 25 14:33:14 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_note \- read and modify note attribute .SH SYNOPSIS #include .sp .ta 1.5c in af_snote (Af_key *aso, char *buf) .sp char *af_rnote (Af_key *aso) .SH DESCRIPTION \fIaf_snote\fP sets the given text (in \fIbuf\fP) as change note of the specified ASO. Text must be null terminated. af_snote requires a lock (see af_lock(3)) set on the specified ASO. .LP \fIAf_rnote\fP returns a pointer to the note attribute of the specified ASO. The note text is returned in memory allocated by malloc(3). Use free(3) to make the space available for further allocation. .SH SEE ALSO af_lock(3), free(3) .SH DIAGNOSTICS Upon error, \-1 or a nil pointer (depending on the return type) is returned and \fIaf_errno\fP is set to the corresponding error number. shapetools-1.4pl6.orig/man/man3/af_protect.3100444 2013 145 3450 5412536717 16777 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_protect.3[7.0] Fri Jun 25 14:33:16 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_protect 3 "Fri Jun 25 14:33:16 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_chowner, af_chauthor, af_chmod \- AtFS protection handling .SH SYNOPSIS #include .sp int af_chowner (Af_key *aso, Af_user *owner) .sp int af_chauthor (Af_key *aso, Af_user *author) .sp int af_chmod (Af_key *aso, int mode) .sp .SH DESCRIPTION \fIaf_chowner\fP and \fIaf_chauthor\fP modify the owner and author attribute of an ASO. Only the superuser may change the owner of an object history. The author attribute of an ASO can only be changed by it's owner. The Af_user structure has the following form .LP .RS .nf typedef struct { char af_username[\s-1MAXUSERNAMELEN\s+1]; char af_userhost[\s-1MAXHOSTNAMELEN\s+1]; char af_userdomain[\s-1MAXDOMAIN+1\s+1]; } Af_user; .fi .RE .LP \fIaf_chmod\fP changes the mode of an ASO. See chmod(3) for further details. .SH SEE ALSO chown (2), chmod (2) .SH DIAGNOSTICS Upon error, \-1 is returned and \fIaf_errno\fP is set to the corresponding error number. .SH BUGS \fIaf_chowner\fP does not work. shapetools-1.4pl6.orig/man/man3/af_retrieve.3100444 2013 145 14103 5412536713 17155 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_retrieve.3[7.0] Fri Jun 25 14:33:18 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_retrieve 3 "Fri Jun 25 14:33:18 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_find, af_cachefind, af_initattrs, af_getkey, af_dropkey, af_dropset, af_dropall \- AtFS retrieve interface .SH SYNOPSIS #include .sp int af_find (Af_attrs *attrbuf, Af_set *resultset) .sp int af_cachefind (Af_attrs *attrbuf, Af_set *resultset) .sp int af_initattrs (Af_attrs *attrbuf) .sp int af_getkey (char *syspath, char *name, char *type, int gen, int rev, Af_key *aso) .sp int af_dropkey (Af_key *key) .sp int af_dropset (Af_set *set) .sp int af_dropall (void) .sp .SH DESCRIPTION \fIaf_find\fP and \fIaf_cachefind\fP retrieve ASOs by given attributes. af_find operates on source objects and af_cachefind only on derived objects. The keys of all found ASOs are returned in \fIresultset\fP. The keys returned in resultset are randomly ordered. af_find and af_cachefind expect resultset to be a pointer to an empty set structure. Both functions return the number of found ASOs. .LP The retrieve arguments are passed in an attribute buffer (\fIattrbuf\fP). Attrbuf should be initialized by \fIaf_initattrs\fP before calling af_find (resp. af_cachefind). af_initattrs disables all fields in the attribute buffer. The application may then enable single fields by setting a desired attribute value. The initial settings of the single fields are listed below with the structure of the attribute buffer. .LP Setting one of the Af_user fields in the attribute buffer to AF_NOUSER causes only ASOs to be selected, where the corresponding user attribute is \fInot\fP set. This makes only sense for \fIaf_locker\fP, when the selection of ASOs that are not locked is desired. .LP On the \fIaf_mode\fP field, a bitwise comparison is performed. In this case, all ASOs will be selected that have \fIat least\fP all required mode bits (given in af_mode) set in their mode field. An exact match is not required. .LP The first two fields in the attribute buffer denote the search space. Generally, the search space for a retrieve operation is a directory. The directory name is given in the \fIaf_syspath\fP field in the attribute buffer. If no system path is given, the current directory is searched. The fields \fIaf_host\fP in the attribute buffer is ignored in the current implementation. .LP The structure of the attribute buffer is the following: .nf .ta 0.4i 1i 3i 5i typedef struct { initial value char af_host[\s-1MAXHOSTNAMELEN\s+1]; /* hostname (ignored) */ "" char af_syspath[\s-1MAXPATHLEN+1\s+1]; /* system path */ "" char af_name[\s-1MAXNAMLEN+1\s+1]; /* filename */ "*" char af_type[\s-1MAXTYPLEN\s+1]; /* filename extension (type) */ "*" int af_gen; /* generation number */ -1 int af_rev; /* revision number */ -1 int af_state; /* version state */ -1 Af_user af_owner; /* owner */ { "", "", "" } Af_user af_author; /* author */ { "", "", "" } off_t af_size; /* size of file */ -1 u_short af_mode; /* protection */ 0 Af_user af_locker; /* locker */ { "", "", "" } time_t af_mtime; /* date of last modification */ -1 time_t af_atime; /* date of last access */ -1 time_t af_ctime; /* date of last status change*/ -1 time_t af_stime; /* save date */ -1 time_t af_ltime; /* date of last lock change */ -1 char *af_udattrs[AF_MAXUDAS]; /* user defined attributes */ } Af_attrs; .fi .LP It is possible to pass a list of user defined attributes as retrieve arguments. The list of pointers \fIaf_udattrs\fP in the attribute buffer can be filled with strings of the form name[=value]. The list must be terminated by a nil pointer. .LP The user defined attributes are interpreted in the following way: .TP 5.5c \fIempty list\fP (first entry is a nil pointer) matches every ASO. .TP \fI""\fP (first entry is an empty string) matches every ASO that has \fBno\fP user defined attributes. .TP \fIname\fP[\fI=\fP] matches, if a user defined attribute with the given name is present. .TP \fIname=value\fP matches all ASOs that have a corresponding user defined attribute, that has at least the given value. .LP \fIaf_getkey\fP builds up an object key by a combination of attributes (pathname, name, type, generation number, revision number and variant name) uniquely identifying a source ASO. Upon successful completion, the found object key is returned in the buffer \fIkey\fP. Instead of explicit version numbers, you can pass the pseudo-numbers AF_BUSYVERS, AF_FIRSTVERS or AF_LASTVERS to af_getkey. af_getkey works only on source objects. The call .LP .RS \fBaf_getkey\ ("",\ "otto",\ "c",\ AF_BUSYVERS,\ AF_BUSYVERS,\ key)\fP .RE .LP leads to the key of the file (busy version) named otto.c in the current directory. .LP .RS \fBaf_getkey ("", "otto", "c", AF_LASTVERS, AF_LASTVERS,\ key)\fP .RE .LP delivers the last saved version (if present) of the history of otto.c. .LP After having retrieved a key or a set of keys, the data for the corresponding object version(s) remains cached in memory as long as the application does not explicitly give the key back. The function \fIaf_dropkey\fP gives a key back and releases the object version. A retrieved set of keys has to be given back by use of \fIaf_dropset\fP. \fIaf_dropall\fP sets all reference counters for cached object versions to zero, that means, it gives all formerly retrieved keys and sets back. .SH DIAGNOSTICS af_find returns the number of found ASOs. Upon error, -1 is returned and \fIaf_errno\fP is set to the corresponding error number. shapetools-1.4pl6.orig/man/man3/af_sets.3100444 2013 145 12603 5412536707 16314 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_sets.3[7.0] Fri Jun 25 14:33:20 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_sets 3 "Fri Jun 25 14:33:20 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_initset, af_nrofkeys, af_setgkey, af_setaddkey, af_setrmkey, af_setposrmkey, af_sortset, af_subset, af_copyset, af_intersect, af_union, af_diff \- AtFS operations on key sets .SH SYNOPSIS #include .sp int af_initset (Af_set *set) .sp int af_nrofkeys (Af_set *set) .sp int af_setgkey (Af_set *set, int position, Af_key *key) .sp int af_setaddkey (Af_set *set, int position, Af_key *key) .sp int af_setrmkey (Af_set *set, Af_key *key) .sp int af_setposrmkey (Af_set *set, int position) .sp int af_sortset (Af_set *set, char *attrname) .sp int af_subset (Af_set *set, Af_attrs *attrbuf, Af_set *subset) .sp int af_copyset (Af_set *source, Af_set *destination) .sp int af_intersect (Af_set *set1, Af_set *set2, Af_set *newset) .sp int af_union (Af_set *set1, Af_set *set2, Af_set *newset) .sp int af_diff (Af_set *set1, Af_set *set2, *Af_set newset) .sp .SH DESCRIPTION Sets in AtFS are ordered collections of keys. The structure of sets is the following .LP .RS .nf typedef struct { int af_nkeys; int af_setlen; Af_key *af_klist; } Af_set; .fi .RE .LP The list of keys in a set is a linear list, residing in allocated memory. The list has no holes, so that positions \fI0\fP through \fIaf_nkeys-1\fP are occupied with valid keys. Set functions returning a set require a pointer to an empty set structure as argument. .LP \fIaf_initset\fP initializes a set. .LP \fIaf_nrofkeys\fP returns the number of valid keys in the given \fIset\fP. .LP \fIaf_setgkey\fP delivers the filekey, stored at position \fIposition\fP in the identified set. The result is passed in the buffer \fIkey\fP. Typically you use af_setgkey to run through a set and perform a special action on each key. The following code sequence does this job: .nf \fCAf_key key; Af_set set; af_initset (&set); ... for (i = 0; i < af_nrofkeys (&set); i++) { af_setgkey (&set, i, &key); /* process key */ ... }\fP .fi .LP \fIaf_setaddkey\fP introduces a new filekey to an existing set at the given position. All following keys are moved back by one position. The constant AF_LASTPOS given as \fIposition\fP argument leads to adding the new filekey at the end of the set. .LP \fIaf_setrmkey (af_setposrmkey)\fP removes the given filekey (the filekey at position \fIposition\fP) from the specified set. Holes generated by deleting single keys from a set are eliminated by condensing the set. All following keys are moved one position forth in the set. .LP \fIaf_sortset\fP sorts a given set of object keys by the values of the named attribute. The set is sorted in increasing order. Increasing order means, that the lowest value occurs first in the set. Af_user structures are compared by username first and by userdomain, if the names are equal (user host will not be taken into account). Version numbers are ordered in natural order, busy versions first. .LP In \fIatfs.h\fP you can find a list of attribute names naming the standard attributes. All other attribute names are presumed to be user defined attributes. While sorting by the values of an user defined attribute, all ASOs that do not have the named attribute are added at the end of the resulting (sorted) set. Sorting of user defined attributes with multiple values bases on simple text comparison with the order of the values taken as it is. The length of the given attribute name is limited. This limit is defined by the constant AF_UDANAMLEN in atfs.h. .LP \fIaf_subset\fP does a retrieve operation (similar to af_find \- manual page af_retrieve(3)) on a given set of object keys. Af_subset takes an attribute buffer (\fIattrbuf\fP) with all desired attributes set to an appropriate value as argument. The attribute buffer should be initialized by \fIaf_initattrs\fP (manual page af_retrieve(3)) beforehand. af_subset returns it's result in a new set, the original set remains unchanged. .LP \fIaf_copyset\fP for copying sets (really! =:-). .LP \fIaf_intersect\fP, \fIaf_union\fP and \fIaf_diff\fP build intersections, unions, and differences between two sets. The result is a new set, where all keys taken from the first argument set (\fIset1\fP) occur first, and the keys from the second argument set (\fIset2\fP) afterwards. You may gibe one of set1 or set2 as \fIresultset\fP. In that case, the original set get lost and is dropped implicitely. .LP Sets generated by af_copyset, af_subset, af_intersect, af_union, or af_diff should be released by \fIaf_dropset\fP as soon as they are not used any longer. .SH SEE ALSO af_retrieve(3) .SH DIAGNOSTICS Upon error, \-1 or a nil pointer (depending on the return type) is returned and \fIaf_errno\fP is set to the corresponding error number. shapetools-1.4pl6.orig/man/man3/af_transact.3100444 2013 145 4523 5412536703 17133 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_transact.3[7.0] Fri Jun 25 14:33:21 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_transact 3 "Fri Jun 25 14:33:21 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_transaction, af_commit, af_abort \- a simple transaction mechanism for AtFS .SH SYNOPSIS #include .sp int af_transaction (void) .sp int af_commit (void) .sp int af_abort (void) .sp .SH DESCRIPTION These functions implement a simple transaction mechanism for AtFS. A transaction starts with calling \fIaf_transaction\fP. All changes to existing ASOs performed hereafter have no immediate permanent effect. They rather get into effect, when the transaction is ended. Calling \fIaf_commit\fP ends the transactions and causes all changes to be saved to disk. \fIaf_abort\fP aborts the transaction without saving the changes. These will then be discarded. .LP Only modification of the state of existing source ASOs will be deferred. Creation or deletion of ASOs have immediate effect, regardless if a transaction is in effect or not. Additionally, all operations on derived ASOs (all operations on the derived object cache) are not affected by the transaction. .LP All archive files that are to be changed when the transaction is finished are locked until the end of the transaction. The lock prevents all other applications to perform any modifications on the archive file. You should make sure, that ending a transaction should never be dependent on the successful termination of another application (deadlock danger). .SH DIAGNOSTICS Upon error, \-1 is returned and \fIaf_errno\fP is set to the corresponding error number. .SH BUGS Changes to the contents of busy versions have immediate effect. shapetools-1.4pl6.orig/man/man3/af_version.3100444 2013 145 14126 5412536672 17026 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_version.3[7.0] Fri Jun 25 14:33:23 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_version 3 "Fri Jun 25 14:33:23 1993" "AtFS-1.71" "Attribute Filesystem (AtFS)" .SH NAME af_saverev, af_newgen, af_setbusy, af_sstate, af_svnum \- version control in AtFS .SH SYNOPSIS #include .sp int af_saverev (Af_key *busyAso, Af_key *saveAso, int generation, int storeType) .sp int af_newgen (Af_key *aso, Af_key *newAso) .sp int af_setbusy (Af_key *busyAso, Af_key *aso, Af_key *prevAso) .sp int af_sstate (Af_key *aso, int state) .sp int af_svnum (Af_key *aso, int gen, int rev) .sp int af_predsucc (Af_key *inAso, int mode, Af_key *outAso) .sp .SH DESCRIPTION \fIaf_saverev\fP makes a copy of the ASO identified by \fIbusyAso\fP. This new ASO gets the status \fIsaved\fP and a version number according to the following scheme: .sp .RS The initial revision is numbered by generation number 1 and revision number 0. All other saved versions get version numbers built from these of their predecessors by preserving the generation number and increasing the revision number by 1. .RE .sp Usually, versions are added to the most recent generation. This is indicated by giving the \fIgeneration\fP parameter \fIAF_LASTVERS\fP. It is also possible to add the new version to an older generation, indicated by an explicit \fIgeneration\fP number. In this case, the predecessor of the new version is the most recent version of the named generation and the version number is built accordingly. .LP The \fIstoreType\fP argument says, whether the new version shall be stored as delta (difference) to its predecessor version or completely. Valid values are AF_STORE_DELTA (default) and AF_STORE_COMPLETE. .LP All attributes except version status and version number (including user defined attributes) are inherited from the busy version. The key of the generated ASO is returned in \fIsaveAso\fP. Use \fIaf_dropkey\fP to free the allocated memory associated with saveAso. .LP Creating a new version in the most recent generation of a history requires reserving the update permissions by setting a lock on the most recent version (see af_lock(3)). For adding a new version to an old generation, a version lock on the most recent version of the concerned generation is needed. Subsequent calls of af_saverev for the same object history each need a new lock, as the \fImost recent version\fP becomes a new one with every call of af_saverev. .LP \fIaf_newgen\fP opens a new generation in a object history. The last saved version will be duplicated. This creates a new ASO, that is numbered by a new generation number (increased by 1) and the initial revision number (0). All other attributes remain unchanged. af_newgen requires a lock (see af_lock(3)) set on the ASO specified by \fIaso\fP. .LP With \fIaf_setbusy\fP an application can inform AtFS, that the data file of a busy version (a busy versions data always sits in a UNIX file) has been exchanged. This is usually the case, after having reinstalled an old version to be basis for further development. The argument \fIaso\fP denotes the version, from which the new contents of the busy version was taken. \fIbusyAso\fP points to the current busy version, if there is any. It may also be omitted by giving a NULL pointer. af_setbusy returns \fIprevAso\fP the key of the version that previously was set as origin of the busy version. .LP \fIaf_sstate\fP sets the state of the identified ASO. Only state transitions from one state to the next or previous state (according to the list below) are allowed. Possible states are: .TP 2c \fIbusy\fP The version is under development and its contents may be changed. .TP \fIsaved\fP The version is saved and may be used for later backup. .TP \fIproposed\fP The version has been submitted for publication by the developer but still needs formal approval by a quality assurance board to become publicly visible and accessible in the official database. .TP \fIpublished\fP The version has passed the formal approval and is now accessible to every member of the project. It is not yet accessed and may therefore be withdrawn if necessary. .TP \fIaccessed\fP The version has been published, and is now accessed by some members of the project. .TP \fIfrozen\fP The version may be part of a system configuration that has been released to the outside world. This means it must, under no circumstances, be destroyed. .LP \fIaf_svnum\fP sets the version number of the identified ASO to the given generation (\fIgen\fP) and revision (\fIrev\fP) number. The version number of source objects can only be increased \- the version number of derived objects can be set to any value. af_svnum requires a lock (see af_lock(3)) set on the ASO specified by \fIaso\fP. .LP \fIaf_predsucc\fP returns the predecessor or successor version of \fIinAso\fP. The result is passed in the buffer \fIoutAso\fP. The value for the \fImode\fP parameter may be one of the following .TP 2.5c AF_LOGICAL_SUCC logical successor AF_LOGICAL_PRED logical predecessor AF_PHYSICAL_SUCC physical successor AF_PHYSICAL_PRED physical predecessor .SH SEE ALSO af_intro (3), af_lock(3) .SH DIAGNOSTICS Upon error, \-1 is returned and \fIaf_errno\fP is set to the corresponding error number .SH BUGS Due to limitations in the \s-1UNIX\s+1 filesystem, only the creator (author) of a derived object may save ASOs to a derived object cache. .LP Empty files cannot be inserted in a derived object cache. .LP The modes AF_LOGICAL_PRED and AF_LOGICAL_SUCC for af_predsucc are not yet impelmented.shapetools-1.4pl6.orig/man/man3/sttkintro.3100444 2013 145 6522 5412345514 16706 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: sttkintro.3[4.0] Thu Jun 24 17:43:28 1993 andy@cs.tu-berlin.de frozen $ .. .TH sttk_intro 3 "Thu Jun 24 17:43:28 1993" "sttk-1.7" "ShapeTools Toolkit Library" .SH NAME sttk_intro \- introduction to the ShapeTools Toolkit Library .SH SYNOPSIS #include .br #include .sp char* stVersion (void); .sp .SH DESCRIPTION The ShapeTools Toolkit library (sttk) is a set of functions to be used in various parts of the ShapeTools configuration management toolkit. .LP Inclusion of \fIconfig.h\fP may be omitted when \fIatfs.h\fP is included. .LP \fIstVersion\fP returns a version identification string for the ShapeTools Toolkit library. .SH LIST OF FUNCTIONS AND VARIABLES .ta 3.5c 7c \fIName Appears on Page Description\fP .sp .nf stAbortThis sttransaction.3 abort transaction stAskConfirm stuserio.3 ask user for confirmation stCallCmd stcall.3 call command stCallCmdErrno stcall.3 error code returned by command (variable) stCallEditor stcall.3 call editor with default contents stCatchSigs stsignal.3 catch signals stCleanup stsignal.3 do cleanup (remove temporary files etc.) stConvertPattern ststring.3 convert sh(1) pattern to regex pattern stExit stsignal.3 stop program execution stFindProgram stcall.3 check if file exists and is executable stGetFromStdin stuserio.3 read text from standard input stGetTermWidth stuserio.3 get current terminal width in columns stInterruptAction stsignal.3 address of signal handler for SIGINT (variable) stLog stuserio.3 print message stMessage stuserio.3 buffer for constructing messages (variable) stMktime sttime.3 parse time string stParseArgs stparseargs.3 parse command line arguments stProgramName stuserio.3 name how program was called stQuietFlag stuserio.3 suppress normal messages (no error messages) (variable) stQuitAction stsignal.3 address of signal handler for SIGQUIT (variable) stRegisterFile sttmpfiles.3 register file stRmRegisteredFiles sttmpfiles.3 remove all registered files stShortUsage stparseargs.3 print usage string stShutupFlag stuserio.3 supress all messages (variable) stStrEnter ststring.3 enter string to string table stStrtok ststring.3 tokenize string stSubstituteString ststring.3 replace parts of a string by new string stTermAction stsignal.3 address of signal handler for SIGTERM (variable) stThisTransaction sttransaction.3 current transaction (variable) stTmpFile sttmpfiles.3 return unique name for temporary file stUnRegisterFile sttmpfiles.3 unregister file stVersion sttkintro.3 print version identification string stWriteTime sttime.3 generate time string .fi .SH SEE ALSO Andreas Lampen and Axel Mahler (Eds.) .br \fIShapeTools\fP, Technical Report No. 92-14, Technische Universität Berlin, May 1992 shapetools-1.4pl6.orig/man/man3/stcall.3100444 2013 145 10317 5412345466 16152 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Authors: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: stcall.3[4.0] Thu Jun 24 17:43:29 1993 andy@cs.tu-berlin.de frozen $ .. .TH stcall 3 "Thu Jun 24 17:43:29 1993" "sttk-1.7" "ShapeTools Toolkit Library" .SH NAME stCallEditor, stCallCmd, stCallCmdErrno, stFindProgram \- call command processor with command string .SH SYNOPSIS #include .br #include .sp .ta 1c int stCallEditor (char *editor, char *file, char *contents, char **newcontents); .sp int stCallCmd (char *commandProcessor, char *commandString); .sp int stCallCmdErrno; .sp char* stFindProgram (char *fileName) .sp .SH DESCRIPTION \fIstCallEditor\fP calls editor \fIeditor\fP with file \fIfile\fP and returns its contents after the editor session in \fInewcontents\fP. Return value is the length of the new text. On failure, 0 is returned to indicate the error. Newcontents is \fInot\fP updated and points to nowhere. On error the file will be removed. If \fIcontents\fP points to a valid text, this text is put (not appended) into the temporary file before editor starts. Contents must be NULL terminated, otherwise strange things will happen. .LP \fIstCallCmd\fP invokes \fIcommandProcessor\fP as a child process and writes \fIcommandString\fP to its standard input. The current process waits for termination of the child process. stCallCmd returns the exit status of the child process reported by wait(2). The commandProcessor string may contain command line arguments to the command processor, separated by whitespace. (This is necessary for some programs to make them read commands from standard input.) The command processor program is searched for in the directories given in the environment variable PATH. If commandString does not end with a newline, a newline is added. .LP \fIstFindProgram\fP returns the full pathname of \fIprogramName\fP if program is found and executable. Otherwise NULL. .SH ENVIRONMENT .TP PATH List of colon-separated directoriy names where execvp(3) searches for the program to execute (default /bin:/usr/bin:/usr/ucb). .SH SEE ALSO wait(2) .SH DIAGNOSTICS On a successful call stCallCmd returns the exit status of the child process. If an error occured, stCallCmd returns a negative number as defined in sttk.h: .TP 3.5c CMDPROC_EMPTY An empty or NULL string has been supplied for commandProcessor. .TP NO_MORE_CORE A call to malloc(3) or calloc(3) returned a NULL pointer. .TP FORK_FAILED fork(2) could not create a child process. .TP PIPE_FAILED A call to pipe(2) failed. .TP WAIT_ERROR A call to wait(2) failed. .TP EXEC_FAILED execvp(3) could not execute commandProcessor. .TP CHILD_KILLED The child process was killed by an uncaught signal. .TP WRITE_FAILED write(2) could not write commandString to the pipe. This usually happens when commandProcessor does not read its standard input and terminates before commandString is written. .TP NO_PROGRAM commandProcessor could not be found. .LP For the most error conditions the integer variable \fIstCallCmdErrno\fP (declared in sttk.h) contains additional information about the error condition, usually the contents of errno(3) after a failed system call. .br In the case of CHILD_KILLED, stCallCmdErrno contains the statßus of the child process as reported by wait(2). .SH BUGS On systems where no useable vfork(2) is available, the value of stCallCmdErrno does not make sense in case of EXEC_FAILED. .LP Under IRIX stCallCmd sometimes (or always?) returns WAIT_ERROR where it should be EXEC_FAILED, NO_PROGRAM, or WRITE_FAILED. .SH AUTHORS Jürgen Nickelsen and Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man3/stparseargs.3100444 2013 145 7703 5412345411 17201 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: stparseargs.3[4.0] Thu Jun 24 17:43:31 1993 andy@cs.tu-berlin.de frozen $ .. .TH stparseargs 3 "Thu Jun 24 17:43:31 1993" "sttk-1.7" "ShapeTools Toolkit Library" .SH NAME stParseArgs, stShortUsage \- parse command line arguments .SH SYNOPSIS #include .br #include .sp .ta 1c int stParseArgs (int argCount, char *argVector, .br \h'\w'stParseArgs ('u'int newArgCount, char *(*newArgVector[]), OptDesc optionList[]); .sp void stShortUsage (char *programName, OptDesc optionList[], char *extraText); .sp .SH DESCRIPTION \fIstParseArgs\fP parses the command line for options previously declared in an option desription list. The programs argument count and argument vector are passed as \fIargCount\fP and \fPargVector\fP, and the option description list as \fIoptionList\fP to stParseArgs. This filters out all known (from the option list) options and their arguments and returns the remaining tokens from the command line in \fInewArgVector\fP with \fInewArgCount\fP. Options on the command line must be preceeded by a minus sign, otherwise they will not be recognized. The first entry in the argument vector, the program name, passes the function without any damage. stParseArgs may be invoked multiple times with different option lists. .LP The option list is an array of option definitions of the following form: .nf \fCtypedef struct { char *OptName; int OptKind; int (*OptFunc)(); int *OptVar; char *OptStr; } StOptDesc;\fP .fi The array is finished by an option definition containing only null entries. \fIOptName\fP is the name of the option how it appears on the command line, without the leading minus sign. The \fIOptKind\fP is a flag field defining the option type and the kind of action to be performed. Valid option types are .TP 2c PSWITCH The option is a switch and has no argument (default) .TP PARG The option has an argument immediately following the option on the command line. .TP POARG The option has an optional argument. .LP The action to be prformed on occurence of an option on the command line refers either to \fIOptFunc\fP, a function to be defined by the application or to \fIOptVar\fP, an application variable, associated with the option. The different kinds of action to be performed are .TP 2c PCALL Call the function OptFunc (default). .TP PSET Set the variable OptVar to 1 (TRUE). .TP PCLEAR Set the variable OptVar to 0 (FALSE) .TP PTOGGLE Toggle the value of the variable OptVar between 1 (TRUE) and 0 (FALSE). .TP PUSAGE Call stShortUsage (see below). .TP PFAIL Call stShortUsage (see below) and terminate program execution with return code 1. .LP .ne 8 The following example shows some typical option definitions .nf \fCStOptDesc bindOptions[] = { { "help", PFAIL, NULL, NULL, NULL }, { "trace", PSWITCH|PSET, NULL, &atBindTrace, NULL }, { "since", PCALL|PARG, handleBaseline, NULL, NULL }, { "version", PCALL, printVersion, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL }, };\fP .fi .LP \fIstShortUsage\fP generates a short usage message from the given \fIoptionList\fP. The message starts with the \fIprogramName\fP and lists all option in the option list. At the end, \fIextraText\fP is added, if given. The message is written to standard error. shapetools-1.4pl6.orig/man/man3/stsignal.3100444 2013 145 4451 5412345405 16467 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: stsignal.3[4.0] Thu Jun 24 17:43:32 1993 andy@cs.tu-berlin.de frozen $ .. .TH stsignal 3 "Thu Jun 24 17:43:32 1993" "sttk-1.7" "ShapeTools Toolkit Library" .SH NAME stCatchSigs, stInterruptAction, stQuitAction, stTermAction, stCleanup, stExit \- signal handling .SH SYNOPSIS #include .br #include .sp .ta 1.3c void stCatchSigs (void); .sp Sfunc_t (*stInterruptAction)(); .sp Sfunc_t (*stQuitAction)(); .sp Sfunc_t (*stTermAction)(); .sp void stCleanup (void); .sp void stExit (int exitCode); .sp .SH DESCRIPTION \fIstCatchSigs\fP activates a number of interrupt handlers, defined internally in the ShapeTools toolkit library. Interrupt handlers are defined for the signals SIGINT, SIGQUIT, SIGFPE, SIGBUS, SIGSEGV, and SIGTERM. All interrupt handlers, except the one for SIGINT, cause program termination after having done some cleanup work. The cleanup consists of removing all temporary files by calling stRmRegisteredFiles(3). .LP Some of the signal handlers are capable to execute functions defined by the application, while handling the interrupt. This mechanism is activated by assigning a functions address to the appropriate variable. The following is a complete List. .TP 2c Signal Variable .TP SIGINT \fIstInterruptAction\fP .TP SIGQUIT \fIstQuitAction\fP .TP SIGTERM \fIstTermAction\fP .LP \fIstCleanup\fP calls stRmRegisteredFiles(3) to remove all temporary files and the AtFS function af_cleanup(3) that orders AtFS's affairs. .LP \fIstExit\fP does the same as stCleanup and additionally end the program execution returning \fIexitCode\fP. .SH SEE ALSO signal (3), stRmRegisteredFiles(3), af_cleanup(3). shapetools-1.4pl6.orig/man/man3/ststring.3100444 2013 145 5622 5412345372 16524 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: ststring.3[4.0] Thu Jun 24 17:43:33 1993 andy@cs.tu-berlin.de frozen $ .. .TH ststring 3 "Thu Jun 24 17:43:33 1993" "sttk-1.7" "ShapeTools Toolkit Library" .SH NAME stConvertPattern, stSubstituteString, stStrtok, stStrEnter \- string handling .SH SYNOPSIS #include .br #include .sp char* stConvertPattern (char *pattern); .sp char* stSubstituteString (char *original, char *old, char *new); .sp char* stStrtok (char *string); .sp char* stStrEnter (char *string); .sp .SH DESCRIPTION \fIstConvertPattern\fP converts sh(1) filename generation patterns to ed(1) string patterns. .TP 2c question (?) gets converted to period (.) .TP asterisk (*) gets converted to a period followed by an asterisk (.*) .TP period (.) will be escaped by a backslash character (\e.). .TP exclam (!) gets converted to circumflex (^) if it follows an left bracket ([). Otherwise it remains unmodified. .LP The whole pattern will be enclosed in a circumflex (^) as leftmost an a dollar sign ($) as rightmost character. .LP \fIstSubstituteString\fP replaces all occurrences of substring \fIold\fP in \fIoriginal\fP by string \fInew\fP. It returns a pointer to an allocated string that is the result of this operation. Returns NULL if anything goes seriously wrong. .LP \fIstStrtok\fP considers the string \fIstring\fP to consist of a sequence of zero or more text tokens separated by whitespace. The first call (with pointer string specified) returns a pointer to the first character of the first token, and will have written a null character into string immediately following the returned token. The function keeps track of its position between separate calls, so that subsequent calls (which must be made with the string argument set to NULL) will work through the string immediately following that token. In this way subsequent calls will work through the string until no tokens remain. When no token remains in string, a NULL pointer is returned. .LP \fIstStrEnter\fP adds the given \fIstring\fP to an internal string table and returns a pointer to appropriate string table entry. Equal strings are mapped to equal locations in the table. Equality of two strings in the string table can be checked by simple pointer comparison. .SH SEE ALSO sh (1), ed (1) shapetools-1.4pl6.orig/man/man3/sttime.3100444 2013 145 4565 5412345366 16164 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: sttime.3[4.0] Thu Jun 24 17:43:35 1993 andy@cs.tu-berlin.de frozen $ .. .TH sttime 3 "Thu Jun 24 17:43:35 1993" "sttk-1.7" "ShapeTools Toolkit Library" .SH NAME stMktime, stWriteTime \- date and time handling .SH SYNOPSIS #include .br #include .sp .ta 1.2c time_t stMktime (char *string); .sp char* stWriteTime (time_t date); .sp .SH DESCRIPTION \fIstMktime\fP scans the given \fIstring\fP and tries to read a date and time from it. It understands various formats of date strings. The following is a list of all valid formats, optional parts in brackets. .TP 3.5c [Tue] Jan 5[,] [19]93 This includes the standard asctime(3) format. .TP Jan 5 With no year given, the year defaults to the current year. .TP [19]93/01/05 This notation requires month and day represented by exactly two digits. .TP 5.1.[19]93 This is the usual German notation. .TP 5.1. German notation referencing the current year. .LP A certain time, given together with the date must always have the following form. .TP 4c hours:minutes[:seconds] Each of the fields must be an integer value within the proper range (hours: 0-23, minutes and seconds: 0-59). Values below 10 may be written as one digit numbers. .LP The time value may be placed anywhere in the date string: at the beginning, at the end, or somewhere in the middle. Any amount of whitespace may be given between a field of the time value and the separating colon. The time is always considered to be local time. .LP \fIstWriteTime\fP generates a time string similar to asctime(3) from its \fIdate\fP argument. .SH SEE ALSO asctime(3) .SH BUGS Time Zone Names within the time string (like `MET') are not handled properly. In most cases they will cause a failure. shapetools-1.4pl6.orig/man/man3/sttmpfiles.3100444 2013 145 5052 5412345356 17040 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: sttmpfiles.3[4.0] Thu Jun 24 17:43:36 1993 andy@cs.tu-berlin.de frozen $ .. .TH sttmpfiles 3 "Thu Jun 24 17:43:36 1993" "sttk-1.7" "ShapeTools Toolkit Library" .SH NAME stTmpFile, stRegisterFile, stUnRegisterFile, stRmRegisteredFiles \- temporary files handling .SH SYNOPSIS #include .br #include .sp .ta 1c char* stTmpFile (char *path); .sp void stRegisterFile (char *fileName); .sp void stUnRegisterFile (char *fileName); .sp void stRmRegisteredFiles (void); .sp .SH DESCRIPTION \fIstTmpFile\fP creates a unique filename for a temporary file, registers it (see stRegisterFile below), and returns it. The return value resides in static memory and will be overwritten on the next call of stTmpFile. The temporary file is located in the \fI/tmp\fP directory. .LP \fIstRegisterFile\fP adds the given \fIfileName\fP to an internal static list of file names. This list helps to keep track of the names of all temporary files to be deleted until the end of the program execution. On abnormal program termination (signal), the termination handler may call \fIstRmRegisteredFiles\fP to delete all registered files. This avoids bogus temporary files to survive abnormal program termination. .LP \fIstUnRegisterFile\fP removes \fIfileName\fP from the internal list of file names. It should be called when the corresponding file was removed due to the regular control flow. .LP \fIstRmRegisteredFiles\fP removes all files named in the internal list set up by stTmpFile and stRegisterFile and clears the list. Bogus entries in the list (names without a correponding file) are ignored. Invoking stCatchSigs(3) causes stRmRegisteredFiles to be called on occurence of the signals SIGQUIT, SIGFPE, SIGBUS, SIGSEGV, and SIGTERM. stCleanup(3) also calls stRmRegisteredFiles. .SH SEE ALSO stCatchSigs(3), stCleanup(3) .SH LIMITS The maximum number of temporary files to be registered is 16. shapetools-1.4pl6.orig/man/man3/stuserio.3100444 2013 145 6411 5412345337 16522 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: stuserio.3[4.0] Thu Jun 24 17:43:39 1993 andy@cs.tu-berlin.de frozen $ .. .TH stuserio 3 "Thu Jun 24 17:43:39 1993" "sttk-1.7" "ShapeTools Toolkit Library" .SH NAME stLog, stQuietFlag, stShutupFlag, stProgramName, stMessage, stGetFromStdin, stAskConfirm, stGetTermWidth \- user interaction .SH SYNOPSIS #include .br #include .sp .ta 1c void stLog (char *logMsg, int logType); .sp int stQuietFlag; .sp int stShutupFlag; .sp char* stProgramName; .sp char stMessage[]; .sp char* stGetFromStdin (int termChar); .sp int stAskConfirm (char *message, char *defaultAnswer); .sp int stGetTermWidth (int fdes); .sp .SH DESCRIPTION These functions do the dialogue with the user. \fIstLog\fP outputs a message to the user's terminal. The message text is given in the \fIlogMsg\fP buffer. \fIlogType\fP is one of .TP 3.5c ST_LOG_MSG Message to be sent to standard output. .TP ST_LOG_MSGERR Message to be sent to standard error. .TP ST_LOG_WARNING Warning message, preceeded by the string `programName - warning:', going to standard error. .TP ST_LOG_ERROR Error message, preceeded by the string `programName - error:', going to standard error. .LP Additionally, when the flag .TP 3.5c ST_LOG_NONL is \fIor\fPed to the message type (e.g. `ST_LOG_MSG | ST_LOG_NONL'), the message is printed without adding a newline character. Otherwise, a newline is always added. .LP Whether a message really makes it's way to the user, depends on the variables \fIstQuietFlag\fP and \fIstShutupFlag\fP. When \fIstQuietFlag\fP is set to a non null value, all messages except error messages (ST_LOG_ERROR) will be suppressed. With the stShutupFlag set to a null value, \fIall\fP messages will be suppressed. Initially, both flags are set to NULL. .LP The \fIstProgramName\fP pointer should be set pointing to a buffer containing the name how the program was called. It is used for composing proper error messages and warnings (see above). .LP \fIstMessage\fP is a buffer for constructing messages using sprintf(3). It is designed to be large enough to hold a file's pathname and an additional short message. It's size is MAXPATHLEN+128. .LP \fIstGetFromStdin\fP reads from stdin a text terminated by ^D or by the specified single charcter \fItermChar\fP at the beginning of a new line. If termChar is -1 text is terminated by ^D. .LP \fIstAskConfirm\fP returns true if the answer is equivalent to \fIdefaultAnswer\fP (assumption). .LP \fIstGetTermWidth\fP returns the actual with of the user's termainal in columns. .SH BUGS stGetTermWidth will not work on all machines properly. In it's current implementation, it is quite SUN specific. shapetools-1.4pl6.orig/man/man3/sttransaction.3100444 2013 145 4666 5412345351 17547 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: sttransaction.3[4.0] Thu Jun 24 17:43:37 1993 andy@cs.tu-berlin.de frozen $ .. .TH sttransaction 3 "Thu Jun 24 17:43:37 1993" "sttk-1.7" "ShapeTools Toolkit Library" .SH NAME stAbortThis, stThisTransaction \- simple transaction handling .SH SYNOPSIS #include .br #include .sp .ta 3.2c void stAbortThis (int domsg); .sp struct stTransaction stThisTransaction; .sp .SH DESCRIPTION \fIstAbortThis\fP is part of a simple transaction mechanism on the basis of setjmp(3) and longjmp(3). A transacion is started by setting a return point calling setjmp(3) and may be aborted by calling stAbortThis. This outputs a short abort message, cleans up the temporary files (stRmRegisteredFiles(3)) and performs a longjmp(3) operation, returning to the transaction start point. .LP The structure variable \fIstThisTransaction\fP carries information about the current transaction. It has the following fields: .nf \fCstruct stTransaction { char tr_fname[MAXPATHLEN+1]; int tr_done; int tr_seqno; int tr_rc; jmp_buf tr_env; };\fP .fi .LP When setting the transaction return point by calling setjmp(3) the \fItr_env\fP field must be used as argument to setjmp. The name of the concerned file should be stored in \fItr_fname\fP field and the \fItr_done\fP flag should be cleared. \fItr_seqno\fP is the serial number of the current transaction and must be increased at the beginning of each new transaction. The \fItr_rc\fP return code can be set to an appropriate return code when something went wrong and the transaction was aborted. When not set by the application, \fItr_rc\fP will be set nun null by stAbortThis on abortion of the transaction. On successful completion, \fItr_done\fP should be set TRUE. .SH SEE ALSO stRmRegisteredFiles(3), setjmp(3), longjmp(3). shapetools-1.4pl6.orig/man/man3/atfstkintro.3100444 2013 145 13112 5412605226 17225 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atfstkintro.3[7.0] Fri Jun 25 16:39:27 1993 andy@cs.tu-berlin.de frozen $ .. .TH atfstk_intro 3 "Fri Jun 25 16:39:27 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME introduction to the AtFS (Attribute Filesystem) Toolkit Library .SH SYNOPSIS #include .br #include .sp char* atVersion (void); .sp void atError (int code; char *msg); .br int atErrno; .br char *atErrMsg; .sp int atBindError; .br char atBindErrorMsg[]; .sp .SH DESCRIPTION The AtFS Toolkit library (AtFStk) is a library of functions defined on top of the Attribute Filesystem (AtFS). It is designed to facilitate the contruction of AtFS application programs. .LP \fIatVersion\fP returns a version identification string for the AtFS Toolkit library. .LP \fIatError\fP assigns the given error \fIcode\fP and the error message \fImsg\fP to the global variables \fIatErrno\fP and \fIatErrMsg\fP. Note: The given error message string (\fImsg\fP) is not copied. \fIatError\fP just assigns its address to \fIatErrMsg\fP. The application has to care about the persistence of the message buffer assigned to atErrMsg. .LP \fIatBindError\fP is a flag indicating that something went wrong during the execution of a function from the version binding subsystem (see atbind(3) and atbindrule(3)). When atBindError is set TRUE, \fIatBindErrorMsg\fP holds an explaining error message. The atBindError flag is cleared upon successfull calls, the message buffer remains unchanged. .SH LIST OF FUNCTIONS AND VARIABLES .ta 3.5c 7c \fIName Appears on Page Description\fP .sp .nf atAttrName atattribute.3 return name part of attribute atAttrValue atattribute.3 return value part of attribute atBindAddRule atbindrule.3 add version binding rule to internal database atBindCache atbind.3 perform version binding on object cache atBindDelRule atbindrule.3 delete version binding rule from internal database atBindDisplayErrors atbindrule.3 report errors while parsing version binding rules (variable) atBindError atfstkintro.3 Version binding error flag (variable) atBindErrorMsg atfstkintro.3 Version binding error message (variable) atBindExpandMacro atbind.3 external function for macro expansion (variable) atBindListRules atbindrule.3 list names of all known version binding rules atBindModeOption atbind.3 version binding mode (variable) atBindNoMsg atbind.3 suppress output from version binding rules (variable) atBindOptions atbind.3 parse version binding options from command line atBindRuleFile atbindrule.3 evaluate file containing version binding rules atBindSet atbind.3 perform nonunique version binding atBindSetArgv atbind.3 perprocess command line with version binding atBindShowRules atbindrule.3 dump internal database of version binding rules atBindTestRule atbindrule.3 test existence of version binding rule atBindTrace atbind.3 trace version binding (variable) atBindUsage atbind.3 print usage for version binding options atBindVersion atbind.3 perform unique version binding atCacheKey atcache.3 return unique key attribute atDelVersAlias atversion.3 delete version alias name atErrno atfstkintro.3 AtFStk error code (variable) atError atfstkintro.3 set AtFStk error code and message atErrMsg atfstkintro.3 AtFStk error message (variable) atExpand atexpand.3 switch attribute expansion on/off (variable) atExpandAttrs atexpand.3 expand attribue citations in string atFileClassExt atclass.3 return file class symbol atFreeAttr atattribute.3 recycle memory of attribute string atGen atversion.3 get generation number from compact representation atIsDerived atclass.3 check if object is from a derived object cache atLocalPath atnetwork.3 map network path to local path atMatchAttr atattribute.3 check if attribute value matches given pattern atNetworkPath atnetwork.3 generate network wide path atRev atversion.3 get revision number from compact representation atRetAttr atattribute.3 return attribute value atSaveCache atcache.3 save object to derived object cache and attach key atScanBinding atbind.3 scan version bind directive atScanStatus atprint.3 scan status string atScanUser atuser.3 scan user name atSetAttr atattribute.3 set or modify attribute atSetAttrFile atattribute.3 set or modify attributes with input from file atSetComment atlog.3 set description, intent or log text atSetVersAlias atversion.3 set version alias name atUnlock atlog.3 unlock attributed software object atUserName atuser.3 get user name from user name atUserUid atuser.3 get user id from user structure atUserValid atuser.3 test if user structure is valid atVersion atfstkintro.3 return AtFStk version identification string atVno atversion.3 generate compact version number representation atWriteDate atprint.3 generate string representation of date attribute atWriteMode atprint.3 generate string representation of mode attribute atWriteName atprint.3 write name and path attribute atWriteStatus atprint.3 generate string representation of status attribute .fi .SH SEE ALSO afintro(3) .SH AUTHOR Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man3/atattribute.3100444 2013 145 20430 5413625335 17212 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atattribute.3[7.0] Tue Jun 29 16:16:22 1993 andy@cs.tu-berlin.de frozen $ .. .TH atattribute 3 "Tue Jun 29 16:16:22 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atRetAttr, atSetAttr, atAttrName, atAttrValue, atAllAttrs, atFreeAttrs \- attribute handling .SH SYNOPSIS #include .br #include .ta 1.2c .sp char* atRetAttr (Af_key *aso, char *attributeName); .sp void atFreeAttr (char *attributeValue); .sp int atSetAttr (Af_key *aso, char *attribute, int mode); .sp int atSetAttrFile (Af_key *aso, char *filename); .sp char* atAttrName (char *attribute); .sp char* atAttrValue (char *attribute); .sp int atMatchAttr (Af_key *aso, char *attribute); .sp .SH DESCRIPTION The AtFS Toolkit Library extends the AtFS attribute handling. It introduces additional standard attribute names and a list of attribute value types. .LP \fIatRetAttr\fP returns a string representation of the value(s) of the \fIaso\fP attribute named \fIattributeName\fP. If the attribute value is preceded by a value special character (see list below), it will be evaluated accordingly. When the evaluation fails, the original attribute value, including value special character, is returned. When the attribute value is empty, an empty string is returned. When the attribute does not exist or on any other error condition, a null pointer is returned. .LP Attribute citations (like \fC7.0\fP) in attribute values will always be expanded by atRetAttr. There is no way to disable attribute expansion. If you need the raw, unexpanded attribute value, use af_retattr (manual page af_attrs(3)). .LP The attribute value returned by atRetAttr either resides in static memory (in case of AtFS standard attributes) or in allocated memory. Use \fIatFreeAttr\fP on each attribute value returned by atRetAttr when this not needed any longer. This will recycle allocated memory if possible. .LP \fIatSetAttr\fP sets the attribute \fIattribute\fP for \fIaso\fP. It calls af_setattr (manual page af_attrs(3)) and hence understands the \fImode\fPs AF_ADD, AF_REMOVE, and AF_REPLACE. Alternatively, the mode argument is ignored, when the equal sign between attribute name and value is preceded by either a plus (+) or a minus (-) sign for adding and deleting attribute values. The value special character \fIat\fP (@) will also be evaluated. atSetAttr opens the file and reads its contents. If either the opening or reading fails, the attribute setting is aborted and returns FALSE. On successful execution, atSetAttr returns TRUE, otherwise FALSE. .LP \fIatSetAttrFile\fP evaluates a file containing attributes. If opens the named file (\fIfilename\fP) and interprets each line in the file as attribute argument to atSetAttr. .LP \fIatAttrName\fP fills a static memory buffer with the name of the given \fIattribute\fP and returns a pointer to this buffer. Subsequent calls of atAttrName overwrite previous results. .LP \fIatAttrValue\fP returns a pointer to the value part of \fIattribute\fP. .LP \fIatMatchAttr\fP checks if \fIaso\fP has the given \fIattribute\fP. Result values are TRUE or FALSE. If just an attribute name is given, atMatchAttr returns a positive result if the attribute exists in the asos attribute list or, in the case that it is a standard attribute, if it's value is non null. A full attribute (name and value) must match an attribute in the asos attribute list. The value of the given attribute argument may be a (sh(1)) pattern. .SH ATTRIBUTE FORMAT Attributes have the general format \fCname=value\fP. Additionally, a plus or minus sign may precede and a value special character may follow the equal sign (\fC[+-]=[^@!*]\fP). .TP 2.2c plus (+) A plus sign preceding the equal sign indicates, that the value shall be added to existing values (no matter if there are any). .TP minus (-) With the minus sign, the value shall be removed from the list of values, if it exists. .LP The following is the complete list of value special characters recognized by AtFStk. .TP 2.2c circumflex (^) The value is regarded as a \fIreference\fP to a file or ASO carrying the real attribute value as contents. .TP at (@) An attribute value starting with an at (@) is considered to be a file name from where the real attribute value is to be taken. In contrary to the circumflex notation above, this causes the file read only once, when setting the attribute value. .TP exclam (!) This introduces \fIexecution\fP attributes. The attribute value is regarded as command to be passed to a shell process. On access, the command will be executed and its output will be catched as real attribute value. .TP asterisk (*) This denotes a pointer attribute modeling relationships between attributed software objects. When atSetAttr finds an attribute value with an asterisk as first character it interprets the remaining value string as version identifier and tries to bind it using atBindVersion (manual page atbind(3)). On success, the network path (see atNetworkPath(3)) of the identifies ASO will be stored as attribute value together with the leading asterisk. atRetAttr maps pointer attributes to local pathnames using atLocalPath (manual page atnetwork(3)). .SH STANDARD ATTRIBUTES There are a number of \fIstandard attributes\fP defined by the AtFS toolkit library and by AtFS (Attribute Filesystem) for each ASO. For a list of the AtFS standard attributes see the af_attrs(3) manual page. This is a list of all standard attribute names defined in AtFStk. .TP 2c Header A compound attribute consisting of a \fI$Header:\fP Label followed by the bound file name (AF_ATTBOUND), the version date (vtime \- see below), the versions author and state and a trailing dollar sign ($). Example: .br \f(CB\s-2$Header: attrs.c[1.1] Tue Dec 1 17:01:10 1992 andy@cs.tu-berlin.de proposed $\s+2\fP .TP Log The versions modification history from the very beginning. This might be long. .TP note The modification note of the version as set by the author. .TP pred, succ The physical predecessor/successor version as stored in AtFS. If there is none, the string \fIn/a\fP (not available) is returned. .TP vtime The version date. For busy versions, this is the date of last modification, for saved versions, it is the saving date. .TP xpon, xpoff Pseudo attribute turning attribute expansion on and off (see above). .LP Some other names are mapped to the appropriate AtFS standard name: .nf .ta 0.5c 3c 8c 10.5c .sp 0.2c \fIAtFStk name AtFS name (constant definition) AtFStk name AtFS name (constant definition)\fP .sp 0.2c atime AF_ATTATIME revision AF_ATTREV author AF_ATTAUTHOR self AF_ATTBOUND ctime AF_ATTCTIME selfpath AF_ATTBOUNDPATH dsize AF_ATTDSIZE size AF_ATTSIZE generation AF_ATTGEN state AF_ATTSTATE host AF_ATTHOST stime AF_ATTSTIME lock AF_ATTLOCKER syspath AF_ATTSPATH ltime AF_ATTLTIME type AF_ATTTYPE mtime AF_ATTMTIME unixname AF_ATTUNIXNAME name AF_ATTNAME version AF_ATTVERSION owner AF_ATTOWNER .fi .LP atSetAttr may also be used to set standard attributes where possible. Attributes that may be altered are .nf .ta 0.5c 5.5c .sp 0.2c \fIAttribute\fP \fIMapped to AtFS function\fP .sp 0.2c author af_chauthor (af_protect(3)) generation, revision, version af_svnum (af_version(3)) mode af_chmod (af_protect(3)) owner af_chowner (af_protect(3)) state af_sstate (af_version(3)) note af_snote (af_note(3)) .fi .SH RETURN VALUES On error, the \fIatError\fP variable is set to a nun null value, and \fIatErrMsg\fP holds a diagnostic message. \fIatRetAttr\fP returns a null pointer on error, or if the desired attribute does not exist. \fIatSetAttr\fP and \fIatSetAttrFile\fP return FALSE on any error condition. \fIatMatchAttr\fP returns FALSE if an error occurred or if the attribute does not match. .SH SEE ALSO af_attrs(3), atbind(3), atnetwork(3) shapetools-1.4pl6.orig/man/man3/atbind.3100444 2013 145 21003 5412605211 16106 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atbind.3[7.0] Fri Jun 25 16:39:30 1993 andy@cs.tu-berlin.de frozen $ .. .TH atbind 3 "Fri Jun 25 16:39:30 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atBindVersion, atBindSet, atBindCache, atBindNoMsg, atScanBinding, atBindTrace, atBindExpandMacro, atBindOptions, atBindModeOption, atBindSetArgv, atBindUsage \- version binding .SH SYNOPSIS #include .br #include .sp .ta 1.2c Af_key *atBindVersion (char *name, *binding); .sp Af_set *atBindSet (char *pattern, char *binding, int bindMode); .sp Af_set *atBindCache (char *pattern, *binding); .sp int atBindNoMsg; .sp int atScanBinding (char *binding, char **resultStr, int *resultGen, int *resultRev, time_t *resultDate); .sp int atBindTrace; .sp char *(*atBindExpandMacro)(char *inputString); .sp int atBindOptions (int argc, char **argv, int newArgc, char *(*newArgv[])); .sp int atBindModeOption; .sp int atBindSetArgv (int *argc, char *(*argv[])); .sp void atBindUsage (char *extraText); .sp .SH DESCRIPTION \fIatBindVersion\fP performs a version binding, that means, it selects a unique version from a named history. It expects \fIname\fP to be either a string of the form \fIhistoryName[binding]\fP or a plain name. With a version bind directive (binding) given in brackets after the history name, the second argument is ignored. Otherwise the second argument is taken as version bind directive. With no binding given, atBindVersion performs the default binding. This may be explicitly defined by afBindOptions (see below), or it selects the most recent (modification/saving date) version. See below a list of different forms of version bind directives. \fIatBindVersion\fP returns the appropriate version key, if the bind operation leads to a unique version selection, otherwise NULL. .LP \fIatBindSet\fP works similar to atBindVersion, with the difference that the first argument may be a name \fIpattern\fP (a sh(1) pattern to be precise) instead of a unique file name. It uses the af_histories (manual page af_history(3)) call, to generate a list of history names from the given pattern. After that, it performs a version binding for each name with a version bind directive given either in square brackets or as \fIbinding\fP argument (see above). atBindSet returns a set of version keys containing all found versions, or a NULL pointer if something went wrong. .LP Another option of \fIatBindSet\fP is nonunique version selection within a history. In this case, multiple versions from one history may be included in the result set. In detail atBindSet supports four options: .TP 3.5c AT_BIND_UNIQUE Behave like atBindVersion for each name generated from \fIpattern\fP. Generates no error condition in case of nonunique or empty selection. .TP AT_BIND_SET (default) Do not require uniqueness. If more than one version from a history meets the binding specifications, all these versions will be included in the result set. .TP AT_BIND_LAST Selects the last (modification/saving date) version from the binding hit set of each history. The resulting hit set contains at most one version of each history involved in the bind operation. .TP AT_BIND_LASTSAVED Similar to AT_BIND_LAST but ignores busy versions. .LP \fIatBindCache\fP tries to bind versions from the derived object cache. It expects a \fIpattern\fP and \fIbinding\fP argument similar to atBindSet. .LP The \fIatBindNoMsg\fP switch allows the output of version binding rules, generated by predicates like 'msg` or 'confirm`, to be suppressed. This can be done by setting atBindNoMsg TRUE. Initially, it is set FALSE. When evaluating a 'confirm` predicate, where user input is expected, with atBindNoMsg set true, the version binding algorithm proceeds without halting as if the user had accepted the default input. .LP \fIatScanBinding\fP scans the version bind directive \fIbinding\fP. It returns the binding type, which is one of .TP 3.5c AT_BIND_ALIAS A version alias (symbolic name). Example \f(CBfoo[release-2]\fP. The alias name returned in \fIresultStr\fP resides in allocated memory. .TP AT_BIND_CACHEKEY A unique identifier for cached objects. This is automatically generated for each cached object and consists of three numbers (\f(CBlike foo.o[739564427.16390.22]\fP). .TP AT_BIND_DATE A date specification. (see stMktime (manual pape sttime(3)) for a list of valid date formats) Examples: \f(CBfoo[Jan 8, 1993]\fP, \f(CBfoo[8.1.93]\fP. The date is returned in \fIresultDate\fP. .TP AT_BIND_DEFAULT Default binding. This is the case when either an empty binding was given or something like \f(CBfoo[]\fP. .TP AT_BIND_RULE Version bind Rule. Example \f(CBfoo[bind_rule:]\fP. A rule may also have the form \f(CBfoo[bind_rule(arg1,arg2,...argN):]\fP additionally passing the given arguments to bind rule evaluation. The rule name returned in \fIresultStr\fP resides in allocated memory. .TP AT_BIND_VNUM Version number. Example \f(CBfoo[1.2]\fP. The resulting generation and revision number are returned in \fIresultGen\fP and \fIresultRev\fP. .LP One important issue is, that each version alias will also be tried as rule name, if it turns out to be no known symbolic name. This implies that rule names may also be given without the trailing colon, when there are no naming conflicts with version aliases. .LP The \fIatBindTrace\fP switch enables tracing of each version bind operation when set TRUE. Trace output is sent to standard error. Initially, its value is FALSE. .LP The atBind module provides a hook for an external macro processor to preprocess any version bind rule just before applying it. The bind rule text may contain macro citations of the form \fI$C\fP or \fI$(macroName)\fP (like in Make-/Shapefiles) to be expanded by the external macro processor. This should expect any string containing macro citations as input and return a string with expanded macros. When assigned to the function variable \fIatBindExpandMacro\fP, the macro expansion routine will be invoked for each evaluated rule. .LP \fIatBindOptions\fP calls stParseArgs (manual page atparseargs(3)) with an internally defined standard option vector for command line version binding options. The vbind(1) manual page contains a description of these options. atBindOption should be called before parsing the application specific options It fetches the version binding options off the command line (input arguments \fIargc\fP and \fIargv\fP) and returns all remaining tokens (output arguments \fInewArgc\fP and \fInewArgv\fP). Return value is the number of erroneous options (e.g. with argument missing) found. A negative return value indicates an internal error, zero is returned un success. .LP atBindOptions defines the default version selection policy as given on the command line for the whole application. Each subsequent call of atBindVersion and atBindSet (see above) will conform to this policy unless an explicit version bind directive is given. .LP \fIatBindSetArgv\fP preprocesses a command line (arguments \fIargc\fP and \fIargv\fP) by evaluating and fetching off version binding options and replacing all filename arguments by bound filenames (e.g. \fCfoo[1.4]\fP). It returns the number of arguments remaining on the command line. .LP \fIatBindUsage\fP calls stShortUsage (manual page atparseargs(3)) with the current program name, the bind standard options vector, and the given \fIextraText\fP. Result is a short usage description written to standard error. .SH DIAGNOSTICS Upon error, the version binding functions (atBindVersion, atBindSet and atBindCache) return a null pointer. atScanBinding has no error conditions. atBindOptions and atBindSetArgv return -1 on error and a value greater or equal null on success. On any error, the variable \fIatBindError\fP is set true (non-zero), and an explaining message is copied to the \fIatBindErrorMsg\fP string buffer. The atBindError variable is cleared upon successfull calls, the message buffer remains unchanged. .SH FILES $SHAPETOOLS/BindRules .SH SEE ALSO atfstkintro(3), vbind(1), stparseargs(3) shapetools-1.4pl6.orig/man/man3/atbindrule.3100444 2013 145 7070 5413606676 17007 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atbindrule.3[7.0] Tue Jun 29 16:16:26 1993 andy@cs.tu-berlin.de frozen $ .. .TH atbindrule 3 "Tue Jun 29 16:16:26 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atBindAddRule, atBindDelRule, atBindRuleFile, atBindDisplayErrors, atBindTestRule, atBindShowRules, atBindListRules \- version bind rule handling .SH SYNOPSIS #include .br #include .sp .ta 1.2c int atBindAddRule (char *ruleName, char *ruleBody, char *srcFile, int srcLine); .sp int atBindDelRule (char *ruleName); .sp int atBindRuleFile (char *fileName); .sp int atBindDisplayErrors; .sp int atBindTestRule (char *ruleName); .sp int atBindShowRules (void); .sp char** atBindListRules (void); .sp .SH DESCRIPTION The atBind module maintains an internal database storing all known version bind rules. .LP The \fIatBindAddRule\fP function stores a new rule in the internal database. It expects the rule name, optionally including parameter definitions, and the rule body as string arguments. Additionally, the filename (\fIsrcFile\fP) of the file, where the rule is read from, and the line within that file (\fIsrcLine\fP), may be given. This is used for producing proper error messages. atBindAddRule returns -1 on error, 0 otherwise. .LP \fIatBindDelRule\fP removes a previously defined rule from the internal database. It returns a negative return value (-1), when no rule with the given name was not found in the internal database. .LP The \fIatBindRuleFile\fP function scans a file containing version bind rules and adds all contained rules to the internal database. It returns the number of version bind rules successfully added to the internal database. A zero return value may also indicate an error. .LP The switch \fIatBindDisplayErrors\fP may be set TRUE to enable error reporting during parsing of version binding rules. Error messages will be written directly to standard error. Initially, atBindDisplayErrors is set FALSE. .LP \fIAtBindTestRule\fP reports whether \fIruleName\fP is defined as version binding rule or not. It returns a non zero (TRUE) value when the name is defined, otherwise FALSE. .LP \fIatBindShowRules\fP dumps the internal database to the standard output. Return value is always TRUE. .LP \fIatBindListRules\fP returns all known bind rule names in a list. The list memory is allocated by use of malloc(3). On error, atBindListRules returns a null pointer. .SH DIAGNOSTICS Upon error, each routine returns a null value, the variable \fIatBindError\fP is set true (non-zero), and an explaining message is copied to the \fIatBindErrorMsg\fP string buffer. The atBindError variable is cleared upon successful calls, the message buffer remains unchanged. .SH ENVIRONMENT \fISHAPETOOLS\fP \- list of path names as search space for files containing version bind rules. The bind rule files must be named \fIBindRules\fP. Default path is \fI/usr/local/lib/shape\fP. .SH FILES $SHAPETOOLS/BindRules .SH SEE ALSO atbind(3) shapetools-1.4pl6.orig/man/man3/atcache.3100444 2013 145 3570 5412605202 16226 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atcache.3[7.0] Fri Jun 25 16:39:33 1993 andy@cs.tu-berlin.de frozen $ .. .TH atcache 3 "Fri Jun 25 16:39:33 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atSaveCache, atCacheKey \- derived object cache handling .SH SYNOPSIS #include .br #include .sp .ta 1.2c int atSaveCache (Af_key *aso, Af_key *cachedAso, char *uniqAttribute, int storeType); .sp char* atCacheKey (Af_key *aso); .sp .SH DESCRIPTION \fIatSaveCache\fP adds the given busy object \fIaso\fP to the current derived object cache. It does this by calling af_savecache (manual page af_cache(3)). Prior to that, atSaveCache attaches a key attribute with the name \fI__CacheKey__\fP to \fIaso\fP, by which the resulting cached object can be uniquely identified within the cache. Return values are the same as from af_savecache (manual page af_cache(3)). .LP \fIatCacheKey\fP returns an attribute string consisting of the attribute name \fI__CacheKey__\fP and an attribute value built of the \fIaso\fP modification date, the process number and a (per process unique) serial number. This attribute can (and will) be used to uniquely identify attributed software objects in derived object caches. .SH SEE ALSO af_cache(3) shapetools-1.4pl6.orig/man/man3/atclass.3100444 2013 145 3313 5412605177 16276 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atclass.3[7.0] Fri Jun 25 16:39:35 1993 andy@cs.tu-berlin.de frozen $ .. .TH atclass 3 "Fri Jun 25 16:39:35 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atFileClassExt, atIsDerived \- ASO class handling .SH SYNOPSIS #include .br #include .sp .ta 1.2c char* atFileClassExt (Af_key *aso); .sp int atIsDerived (Af_key *aso); .sp .SH DESCRIPTION \fIatFileClassExt\fP returns a short string (one or two characters long), visualizing the attributed software objects (\fIaso\fP) class. This is a superset of the file class symbols added to filenames by the \fIls -F\fP command. .TP \fB/\fP Directory. .TP \fB@\fP Symbolic Link. .TP \fB=\fP Socket. .TP \fB*\fP Executable. .TP \fB$\fP Derived. .TP \fB^\fP Locked. .LP Some combinations are possible. In espacially the circumflex (^) may be combined with any other symbol, resulting in a two letter string. .LP \fIatIsDerived\fP checks whether the denoted \fIaso\fP is in a derived object cache (return value TRUE) or not (return value FALSE). .SH SEE ALSO ls(1) shapetools-1.4pl6.orig/man/man3/atexpand.3100444 2013 145 5732 5412605173 16453 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atexpand.3[7.0] Fri Jun 25 16:39:36 1993 andy@cs.tu-berlin.de frozen $ .. .TH atexpand 3 "Fri Jun 25 16:39:36 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atExpandAttrs, atExpand \- attribute expansion .SH SYNOPSIS #include .br #include .sp int atExpandAttrs (Af_key *aso, char *buf, size_t bufSize, FILE *dest, size_t destSize, int mode); .sp int atExpand; .SH DESCRIPTION \fIatExpandAttrs\fP scans the char buffer \fIbuf\fP to the extent of \fIbufSize\fP for strings of the form \fI$__attributeName\fP optionally followed by a delimiting (second) dollar sign ($). If such a string is found, the buffer contents up to the character preceding the first dollar sign will be sent to the destination output \fIdest\fP. If an attribute with name attributeName is set for the current attributed software object \fIaso\fP, the citation-string will be substituted by the value of that attribute and appended to the output. Output of buf contents resumes with the first character after the whitespace character or dollar sign delimiting attributeName. .LP Despite the type of the \fIdest\fP argument (pointer to file structure), atExpandAttrs may be caused to copy it's output to a string buffer rather than an open file. In this case, the constant AT_EXPAND_STRING must be given as \fImode\fP argument and \fIbufSize\fP must be set to indicate the length of the destination buffer \fIdest\fP (will be casted to character pointer). If destSize is to small to hold the result string, atExpandAttrs returns a negative value. In the regular case, where output shall be written to a file, the mode parameter must be AT_EXPAND_FILE. .LP The \fIatExpand\fP variable suppresses attribute expansion when set FALSE. The variable may be set either directly from the application program if indirectly by evaluation of the pseudo attribute citation \fI$__xpoff\fP in any buffer scanned by atExpandAttrs. Another pseudo attribute citation \fI$__xpon\fP cancels the effect of a previous $__xpoff and switches attribute citation on again. It does not, however, enable attribute citation if this was disabled explicitly by the application program. .SH DIAGNOSTICS atExpandAttrs returns -1 on error. Additionally, the \fIatError\fP variable is set and \fIafErrMsg\fP holds a diagnostic message. .SH SEE ALSO atattribute(3) shapetools-1.4pl6.orig/man/man3/atlog.3100444 2013 145 5417 5412605170 15752 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atlog.3[7.0] Fri Jun 25 16:39:38 1993 andy@cs.tu-berlin.de frozen $ .. .TH atlog 3 "Fri Jun 25 16:39:38 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atSetComment, atUnlock \- log and lock handling .SH SYNOPSIS #include .br #include .sp int atSetComment (Af_key *aso, int commentType, char *commentText, int mode); .sp int atUnlock (Af_key *aso); .sp .SH DESCRIPTION \fIatSetComment\fP sets a comment attribute for the attributed software object \fIaso\fP. Valid \fIcommentType\fPs are .TP 3c AT_COMMENT_INTENT for expressing a change intent describing planned modifications. .TP AT_COMMENT_DESCR for issuing a descriptive text expressing the purpose of the document. .TP AT_COMMENT_LOG for writing a change log describing the changes made. .LP With the argument \fIcommentText\fP, a default text may be given. According to the mode (see below), the user will be asked for entering the comment attribute value. When a default text is given, this will be offered for modification. With an commentText argument, the previous of the according comment attribute is taken as default text. .LP With the \fImode\fP field, the behavior of atSetComment can be influenced. Three flags may me set: .TP 3c AT_FROMSTDIN advises atSetComment to read the user input from standard input, otherwise an editor will be started. .TP AT_REUSE causes reuse of the comment text expressed during the previous invocation of atSetComment, if there was any. .TP AT_CONFIRM lets the user confirm, that an comment shall be expressed. Otherwise, atSetComment asks for the comment text without prior confirmation. This flag is ignored, when AT_FROMSTDIN is set and the change comment is taken from standard input. .LP \fIatUnlock\fP unlocks \fIaso\fP by calling af_unlock (manual page af_lock(3)). If a change intent was previously set for \fIaso\fP, this will be eliminated. .SH DIAGNOSTICS atSetComment and atUnlock return FALSE (zero) on error. Additionally, the \fIatError\fP variable is set and \fIafErrMsg\fP holds a diagnostic message. .SH ENVIRONMENT EDITOR \- the default editor to be called. .SH SEE ALSO af_lock(3) shapetools-1.4pl6.orig/man/man3/atnetwork.3100444 2013 145 4320 5412605163 16654 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atnetwork.3[7.0] Fri Jun 25 16:39:40 1993 andy@cs.tu-berlin.de frozen $ .. .TH atnetwork 3 "Fri Jun 25 16:39:40 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atNetworkPath, atLocalPath \- network path handling .SH SYNOPSIS #include .br #include .sp char* atNetworkPath (Af_key *aso); .sp char* atLocalPath (char *networkPath); .sp .SH DESCRIPTION \fIatNetworkPath\fP returns a network wide unique pathname for \fIaso\fP. The pathname has the following structure .ce \f(CB:@\fP. Hostname is the name of the host controlling the device, where \fIaso\fP is stored. the canonical pathname is the real pathname (without symbolic links), where the object is located on that host. The version number, including the introducing at-sign (@) is optional. For busy versions, it may be missing or the string \fCbusy\fP .LP \fIatLocalPath\fP maps a network path name to a local path name. When the host information in the network path denotes a remote host, atLocalPath looks up /etc/mtab for a mapping of the network canonical pathname to a local path. The resulting pathname is a local pathname in bound notation .ce \f(CB[version]\fP with the version number added in brackets. It may be converted into an ASO descriptor by calling atBindVersion (manual page atbind(3)). .SH RETURN VALUE Both functions return the resulting string in static memory. The result will be overwritten on a subsequent call. On failure, a null pointer is returned. .SH SEE ALSO atbind(3) .SH FILES /etc/mtabshapetools-1.4pl6.orig/man/man3/atprint.3100444 2013 145 5275 5412605160 16326 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atprint.3[7.0] Fri Jun 25 16:39:43 1993 andy@cs.tu-berlin.de frozen $ .. .TH atprint 3 "Fri Jun 25 16:39:43 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atWriteStatus, atWriteMode, atWriteDate, atWriteName, atScanStatus \- print and scan special attribute values .SH SYNOPSIS #include .br #include .sp .ta 1.2c char* atWriteStatus (Af_key *aso; int verbose); .sp char* atWriteMode (Af_key *aso); .sp char* atWriteDate (Af_key *aso, char *dateAttribute); .sp char* atWriteName (Af_key *aso, char *path); .sp int atScanStatus (char *statusStr); .sp .SH DESCRIPTION \fIatWriteStatus\fP returns a string representation of \fIAso\fPs AF_STATE attribute. With the \fIverbose\fP argument TRUE, atWriteStatus returns a long (8 character) status name. Otherwise, on FALSE, it returns a one character short representation. The result value is a statically defined string in any case. .LP \fIatWriteMode\fP generates a ls -l(1) like (e.g. \fC-rwxr-xr-x\fP) string representation of the AF_MODE attribute. It returns its result in static memory, which will be overwritten on subsequent calls. .LP \fIatWriteDate\fP produces a date string from the given \fIdateAttribute\fP to be used for ls -l(1) like output (e.g. \fCJan\ \ 8\ 11:07\fP or \fCJul\ 10\ \ 1992\fP). The format of the date string depends on the value of the date attribute. The string is always 12 characters long and begins with the month and day. For dates younger than 6 months, the third field is the time, for dates older than 6 months, the year. The result string resides in static memory, which will be overwritten on subsequent calls. .LP \fIatWriteName\fP generates a bound pathname from \fIpath\fP and \fIaso\fP. .LP \fIatScanStatus\fP converts an status string to an internal numeric status value. It understands various abbreviations, including the one character status strings generated by atWriteStatus. .BUGS The format switch in afWriteDate (for dates older than six months) does not happen at exactly the right time. It may be a few days later. shapetools-1.4pl6.orig/man/man3/atread.3100444 2013 145 7050 5412605152 16077 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Juergen Nickelsen (Juergen.Nickelsen@cs.tu-berlin.de) $Header: atread.3[7.0] Fri Jun 25 16:39:47 1993 andy@cs.tu-berlin.de frozen $ .. .TH atReadExpand 3 "Tue Feb 16 20:33:25 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atOpenExpand, atReadExpand, atCloseExpand \- read version objects with attribute citations expanded .br atGetWriteName \- get bound version name of a version object opened with atOpenExpand .SH SYNOPSIS #include .br #include .sp int atOpenExpand(char *version, int expand_busy) ; .sp int atReadExpand(int desc, char *bufp, int nbytes) ; .sp void atCloseExpand(int desc) ; .sp char *atGetWriteName(int desc) ; .sp extern int atBindError ; .br extern char atBindErrorMsg[] ; .SH DESCRIPTION .IR atOpenExpand , .IR atReadExpand , and .I atCloseExpand are designed as a nearly plug-compatible replacement for the system calls .IR open (2), .IR read (2), and .IR close (2) for reading of AtFS version objects with attribute citations expanded. .LP .I atOpenExpand opens the file or AtFS version object .I version for reading with .IR atReadExpand . .I Version points to the pathname of a file or AtFS version object. If the flag .I expand_busy is non-zero, attribute citations are expanded in busy versions also. .I atOpenExpand returns a descriptor that is valid as argument to successive calls to .I atReadExpand and .IR atCloseExpand . .LP .I atReadExpand attempts to read .I nbytes of data from the object referenced by the descriptor .I desc into the buffer pointed to by .IR bufp . If .I desc is zero, .I atReadExpand reads from the standard input. .I atReadExpand returns the number of bytes actually read. .LP .I atCloseExpand frees the resources associated with the descriptor .IR desc . .LP .I atGetWriteName returns a pointer to the bound version name of the version object for which .I atOpenExpand returned the descriptor .IR desc . .SH DIAGNOSTICS On error .I atOpenExpand and .I atReadExpand return \-1 and set .I errno appropriately. If one of these returns an error and .I errno is set to ENOMEM, the application may retry the operation, possibly after freeing some memory. .LP If .I atOpenExpand returns an error and .I atBindError has a non-zero value, the string .I version did not select a version object or not a unique version object. In this case .I atBindErrorMsg contains an appropriate error message. .LP Possible Values of errno after a call to .IR atOpenExpand : .in .TP ENOMEM Not enough memory could be allocated. .TP EMFILE All available descriptors are in use. .LP All errno values returned by .IR open (2) or .IR read (2). .LP Possible Values of errno after a call to .IR atReadExpand : .TP ENOMEM Not enough memory could be allocated. .TP EBADF Invalid descriptor. .SH BUGS Since .I atOpenExpand reads the complete contents of .I version into memory, it fails on very large version objects. .SH SEE ALSO intro(2), open(2), read(2), close(2), errno(3), atattribute(3), atbind(3). shapetools-1.4pl6.orig/man/man3/atuser.3100444 2013 145 5256 5412604745 16157 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atuser.3[7.0] Fri Jun 25 16:39:50 1993 andy@cs.tu-berlin.de frozen $ .. .TH atuser 3 "Fri Jun 25 16:39:50 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atUserValid, atScanUser, atUserName, atUserUid \- user handling .SH SYNOPSIS #include .br #include .sp void atScanUser (char *userName; Af_user *resultUser); .sp char* atUserName (Af_user *user); .sp Uid_t atUserUid (Af_user *user); .sp int atUserValid (Af_user *user); .sp .SH DESCRIPTION \fIatScanUser\fP scans the given string \fIuserName\fP and tries to derive an AtFS user identification (\fIresultUser\fP) from it. It does \fInot\fP verify the existence of a corresponding UNIX (/etc/passwd) user entry. Use atUserUid to test that. atScanUser understands the following formats: .TP 3c \fIuser\fP When the string does not contain an at sign, it is considered to be a plain user name from the current host and domain. .TP \fIuser@host\fP In the case that the part after the at sign doe not contain a period, it is assumed to be a hostname. Domain is the current domain. .TP \fIuser@host.domain\fP This format can only be recognized, when the given domain is equal to the current domain, and the hostname remains as \fIrest\fP between the at sign and domain name. .TP \fIuser@domain\fP An user identification string with a domain name different to the local domain is treated as user@domain, although this might be wrong. .LP \fIatUserName\fP returns a string of the form \fIuser@domain\fP generated from the given \fIuser\fP structure. If no domain name is given in the structure, it returns \fIuser@host\fP instead. With no host and no domain name, just \fIuser\fP is returned. The result string resides in static memory and will be overwritten on subsequent calls. .LP \fIatUserUid\fP tries to map the given \fIuser\fP structure to a UNIX user identification. It returns the uid on success, -1 otherwise. .LP \fIatUserValid\fP checks the given \fIuser\fP structure for plausibility. It returns FALSE on fauilure, a non null value on success. shapetools-1.4pl6.orig/man/man3/atversion.3100444 2013 145 4233 5412614005 16646 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: atversion.3[7.0] Fri Jun 25 17:21:56 1993 andy@cs.tu-berlin.de frozen $ .. .TH atversion 3 "Fri Jun 25 17:21:56 1993" "AtFStk-1.12" "AtFS Toolkit Library" .SH NAME atSetVersAlias, atDelVersAlias, atVno, atGen, atRev \- version handling .SH SYNOPSIS #include .br #include .sp .ta 1.2c int atSetVersAlias (Af_key *aso; char *aliasName); .sp int atDelVersAlias (Af_key *aso; char *aliasName); .sp int atVno (Af_key *aso); .sp void atGen (int versionNumber) .sp void atRev (int versionNumber) .sp .SH DESCRIPTION \fIatSetVersAlias\fP sets a version number alias (a unique symbolic name for a version) for \fIaso\fP. The function checks, whether \fIaliasName\fP is unique within the ASOs history and complains, if not. It returns TRUE on success and FALSE otherwise. The case that the version already had the alias name is considered as success. .LP \fIatDelVersAlias\fP deletes the given \fIaliasName\fP from the list of version aliases attached to \fIaso\fP. It returns TRUE on success and FALSE otherwise. It also returns TRUE, when the alias name did not exist. .LP \fIatVno\fP returns a compact representation of \fIaso\fPs generation and revision number, packed into a single integer. \fIatGen\fP extracts the generation number, and \fIatRev\fP the revision number from a \fIversionNumber\fP in compact representation. .SH DIAGNOSTICS On error, the \fIatError\fP variable is set to an appropriate error code, and \fIatErrMsg\fP holds a diagnostic message. shapetools-1.4pl6.orig/man/man5/ 40755 2013 145 0 5626415727 14476 5ustar dokoswtshapetools-1.4pl6.orig/man/man5/af_archive.5100444 2013 145 10215 5412536656 16763 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: af_archive.5[7.0] Fri Jun 25 14:33:24 1993 andy@cs.tu-berlin.de frozen $ .. .TH af_archive 5 "" \n(dy.\n(mo.\n(yr .SH NAME af_archive -- format of archive files in the \fIAttribute Filesystem\fR .SH SYNOPSIS \fB#include .br #include .SH DESCRIPTION AtFS archive files are used to store the data and attributes of non-busy ASOs. Beside these, some attributes (including all user defined attributes) of busy ASOs are stored in AtFS archive files. .PP AtFS maintains two archive files for each line of development, one to hold the standard- and the user defined attributes and the other to hold the data and change notes. These files are stored either in a subdirectory named \fCAtFS\fR or in a explicitly named directory somewhere in your file system. The two archive files are named .br \fCAttr/\fR (attributes) and .br \fCData/\fR (data). .PP This manual contains a short, exemplary description of the archive structure. All data in AtFS-archives are stored as ASCII-strings. The archives contain keywords and keyletters. These are set in \fBboldface\fR in the following description. Strings of the form \fI\fR describe the purpose of the appropriate field in the archive. .PP Here's the structure (the attributes file first): .sp .ce The Header, ... .nf .sp \fB^BARHD\fR .sp .ce \&... the name .. .sp \fB^BI\fR .sp .ce \&... and the owner .. .sp \fB^BO\fR .sp .ce \&... followed by some attributes for the busy version ... .sp \fB^BP\fR .br \fB^BL\fR .sp .ce 2 \&... and the revision list, that contains all standard attributes for non-busy versions. ... .sp \fB^BR\fR .br \fB^BA\fR <_host> <_domain> <_host> <_domain> .br \fB^BT\fR <_last_access> <_last_status_change> ... .in +3.3i \&... <_saving> <_locking> .in -3.3i \fB^BM\fR ... .br ... .br \fB^BR ...\fR .br \fB^BR ...\fR .sp .ce 2 \&... Now follows the list of lists of user defined attributes ("-2 -2" indicates the busy version; "\fC@\fR" stands for a null byte). ... .sp \fB^BUSEG\fR \fB^BU -2 -2\fR \fCmachine=vax@data=fs@@\fR \fB^BU\fR \fCname=value@@\fR \fB^BU ...\fR .sp 0.5i The structure of the datafile: .sp Data are represented either by deltas or by complete data-chunks... .sp \fB^BDATA\fR .sp \fB^BN\fR \fC--- empty log message ---\fR .sp \fB^BD\fR \fCA typical delta looks like:\fR \fC@67723@@@@44@67756@^A14@some text@6635@ and so on.\fR \fCDeltas are indicated by a "1" at the "kind_of_representation" field. .sp \fB^BN\fR \fCThis is a log message\fR .sp \fB^BD\fR \fCA "0" at the "kind_of_representation" field indicates that this version is stored completely.\fR .sp \fB^BN ...\fR .sp \fB^BD ...\fR .fi .SH AUTHOR Andreas Lampen, Tech. Univ. Berlin (andy@cs.tu-berlin.de) shapetools-1.4pl6.orig/man/man7/ 40755 2013 145 0 5626416524 14474 5ustar dokoswtshapetools-1.4pl6.orig/man/man7/bindrules.7100444 2013 145 76671 5414046131 16673 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: bindrules.7[7.0] Tue Jun 29 16:16:30 1993 andy@cs.tu-berlin.de frozen $ .. .TH BindRules 7 "Tue Jun 29 16:16:30 1993" "AtFStk-1.12" "ShapeTools" .SH NAME BindRules \- ShapeTools version bind rules .SH DESCRIPTION The ShapeTools version binding subsystem (see vbind(1)) provides a mechanism for expressing \fIgeneral version bind rules\fP. These rules describe on an abstract level version properties, which will be matched against the properties of concrete versions during the version bind procedure. The goal is to select one or more versions from a named history in order to provides access to these version(s). A version bind operation is always performed for exactly one history at a time. Version bind rules express something like .LP .nf \fISelect the most recent saved version.\fP \fIIf there is no saved version, select the busy version.\fP .fi .LP ShapeTools however needs rules in a more formal notation to be able to interpret them. Let's see, how the rule above is translated into the formal notation. .LP Version bind rules consist of a list of attribute expressions evaluated one after another until one of the expressions leads to a unique version identification. The expressions are separated by semicolons, the last expression ends with a period. The rule from above will now read: .LP .nf \fISelect the most recent saved version\fP \f(CB;\fP \fISelect the busy version\fP \f(CB.\fP .fi .LP Each attribute expression consist of a list of predicates, separated by commas. The predicates are evaluated from left to right resulting in a \fIhit set\fP, a set of versions fulfilling all predicates evaluated so far. The initial hit set for an attribute expression contains all versions of the name to be bound. Each predicate potentially narrows the hit set. The predicates in our rule are: .LP .nf \fIall saved versions\fP \f(CB,\fP \fImost recent version\fP \f(CB;\fP \fIbusy version\fP \f(CB.\fP .fi .LP Remember, that each predicate bases it's selection on the hit set left by the predicate before. Hence exchanging the two predicates in the first attribute expression may lead to different results. We will give more information on this topic in the section about the evaluation algorithm below. We now reach the final form of ShapeTools version bind rules. The predicates must be taken from a list of predefined names and be equipped with arguments: .LP .nf \fCge (status, saved) \f(CB,\fP max (stime)\fP \f(CB;\fP \fCeq (status, busy)\fP \f(CB.\fP .fi .LP That's it so far. This is a rule how ShapeTools understands it. It does however illustrate just a small piece of the world of version bind rules. We will go on in this manual page with a detailed description of version bind rules divides into the sections .IP "RULE HEAD" 5c Description of the structure of rule heads. .IP "EVALUATION ALGORITHM" The Algorithm how version bind rules are evaluated. .IP "NAME PATTERNS" Name patterns as first predicate in attribute expressions. .IP "PREDICATES" List of valid predicates. .IP "ATTRIBUTES" A List of predefined attribute names and some word about the ordering relationship between attribute values. .IP "EXPANSION" Description of the various types of expansion such as parameter substitution, attribute and macro expansion, and command substitution. .IP "LEXICAL STRUCTURE" Lexical constraints for names and strings in version bind rules. .IP "TIPS, TRICKS, AND TRAPS" Some common problems. .IP "GRAMMAR" A complete grammar for version bind rules. .LP .SH RULE HEAD A version bind rule consists of a rule head and a rule body. The example above shows only the rule body. The rule head defines a name for the rule and optionally a parameter list. The name is a string consisting of any printable non-whitespace character except colon and parentheses. It is followed by an optional parameter list in parentheses and a colon, delimiting the rule head. Multiple parameters in the list are separated by comma. Examples are .LP .nf \fCmost_recently_released:\fP .sp \fCfrom_release (release_name):\fP .sp \fClast_released (library_path, include_path):\fP .fo .LP .SH EVALUATION ALGORITHM The basic idea of the rule evaluation algorithm is, that in every state of processing a \fIhit set\fP exists, a set of versions reflecting the current rule evaluation result. The hit set is initialized with all versions of the given name at the beginning of each attribute expression. The attribute expressions predicates are processed from left to right in the order they occur. Each predicate imposes requirements to the versions in the hit set and eliminates all versions not fulfilling these requirements. So, the hit set becomes smaller and smaller during attribute expression evaluation. The following figure illustrates this process together with the rule \fCmost_recently_released\fP defined above and the file foo existing as busy version and as versions 1.0 through 1.2. .LP .nf .ta 1c 6c Initial hit set: ( foo[busy], foo[1.0], foo[1.1], foo[1.2] ) .sp Evaluate Predicate: \fCge (status, saved),\fP .sp New hit set: ( foo[1.0], foo[1.1], foo[1.2] ) .sp Evaluate Predicate: \fCmax (stime);\fP .sp Final hit set: ( foo[1.2] ) .fi .LP When the hit set becomes empty, that is when no version meets all the predicates evaluated so far, the attribute expression \fIfails\fP and processing is finished immediately. All remaining predicates will not be evaluated. Even remaining predicates without influence on the hit set (for example message predicates) will not be processed. Processing continues with the next attribute expression. If all attribute expressions finish prematurely, the whole version binding fails. In the following example, the first attribute expression fails and the second alternative leads to success. .LP .nf .ta 1c 6c Initial hit set: ( bar[busy] ) .sp Evaluate Predicate: \fCge (status, saved),\fP .sp New hit set (empty): ( ) .sp Evaluate next attribute expression starting with initial hit set again: ( bar[busy] ) .sp Evaluate Predicate: \fCeq (status, busy);\fP .sp Final hit set: ( bar[busy] ) .fi .LP When evaluation reaches the end of an attribute expression without the hit set being empty, two cases are possible. First, the hit set contains exactly one version and everything is fine. This is usually the desired state and rule evaluation returns the remaining version as bind result. Second, the hit set may contain more than one version. In this case, the evaluation algorithm depends on the expected result. When a unique version binding is expected, this is treated as failure and evaluation goes on with the next attribute expression. Non-unique version binding regards this as success and returns the whole hit set. .LP Extending the hit set during evaluation of an attribute expression is not possible. This would be against the nature of the version bind rules and would make them much more difficult to understand. Hit set extension may only happen by letting the current attribute expression fail and begin with a new one and the maximum hit set. .LP Failure of an attribute expression must not necessarily be caused by an empty hit set. It may also be caused by user interaction or by external constraints. The following rules exemplify user interaction: .LP .nf \fCeq (state, busy), confirm (select busy version ?, y);\fP \fCge (state, busy), max (version).\fP .fi .LP where the user will be asked for confirmation to select the busy version, and external constraints: .LP .nf \fCexists (otto, 1.0), eq (state, busy);\fP \fCge (state, busy), max (version).\fP .fi .LP where selection of the busy version happens only, when version 1.0 of \fCotto\fP exists (this example is somewhat silly). Predicates like \fCconfirm\fP and \fCexists\fP don't care about the hit set. They provide the possibility to impose external control on the evaluation of version bind rules. An attribute expression may be finished prematurely and control switches to the next one. .LP There is another operator, the \fCcut\fP operator, that forces the whole bind operation to finish (and fail). Typically the cut operator stands at the end of an attribute expression that should never succeed. The following is a typical example for use of this. Version binding fails, if there is an update lock set on the most recent version. .LP .nf \fCmax (version), hasattr (locker), cut (history is locked !);\fP \fCmax (version).\fP .fi .LP The cut operator accepts a string argument that will be written to the standard output. .SH NAME PATTERNS Each attribute expression may start with a pattern, against which the name to be bound is matched. Only when the name matches the pattern, the corresponding attribute expression will be evaluated. If not, the attribute expression will be skipped. When the pattern is omitted in the attribute expression (as in our example above), the expression is evaluated for each name. .LP The patterns are the same as those recognized by sh(1) for filename generation on the command line. Magic cookies are: .IP \f(CB*\fP 2c matching any string, including the empty string, .IP \f(CB?\fP matching any single character, .IP \f(CB[c...]\fP matching any one of the characters enclosed in the square brackets, .IP \f(CB[l-r]\fP matching any character lexically between the left (\f(CBl\fP) and the right (\f(CBr\fP) character, inclusive, and .IP \f(CB[!c...]\fP .IP \f(CB[!l-r]\fP matching any character not recognized by their counterparts above. .LP A rule with name patterns for example looks like: .LP .nf .ta 1c 3c \fCxyyz.h, eq (version, 1.3);\fP \fC*.c, eq (generation, 2), max (revision);\fP \fC*.h, eq (generation, 3), max (revision).\fP .fi .LP In this example, version binding for C source files (most recent version from generation 2) is different from version binding for header files (most recent version from generation 3). Additionally, the name \fCxyyz.h\fP will always be bound to version 1.3. .LP If the name to be bound is given together with a (absolute or relative) pathname, this will \fInot\fP be cut off. The match is always performed lexically for the whole name given. Hence, the name pattern may also contain path names, like .LP .nf .ta 1c 4c \fCvariant1/*, eq (alias, var1-1.4);\fP \fCvariant2/*, eq (alias, var2-1.2);\fP \fC/usr/sample/include/*.h, max (revision).\fP .fi .LP Usually, the version bind subsystem does not check, if different path prefixes in the name pattern and the given name to be bound lead to the same location. The match is done lexically and must fit exactly. An exception is, when the name pattern is given as network path name as in atnetwork(3). A network pathname consists of the name of the host, controlling the device where a version is stored, the canonical pathname to the version and a version binding (e.g. version number, version alias, or date) either in brackets or separated from the name by an at (\fC@\fP) sign. Examples are .LP .nf .ta 1c \fCdesaster:/usr/sample/project/foo.c[1.0];\fP \fCdesaster:/usr/sample/project/variant1/bar.c[var1-1.4];\fP \fCdesaster:/usr/sample/project/xyyz.h@1.3;\fP \fCdesaster:/usr/sample/project/bar.c@Fri Jun 18 13:40:58 MET DST 1993.\fP .fi .LP Network pathnames are mapped to canonical local pathnames before being processes and in this case, the given name to be bound will also be mapped to a canonical local pathname. .LP The technique using network pathnames is especially useful when storing the result of a successful version selection persistently. This makes the version selection easily reproducible from anywhere in the local areas network. shape(1) uses this mechanism when generating its \fIbound configuration threads\fP. .SH PREDICATES This is the complete list of valid predicate names and a synopsis of their arguments. The list is divided into several parts, each describing a certain class of predicates. .LP The first class are predicates working independently on each element of the current hit set. They impose certain requirements to the attributes of each version and eliminate those, not fulfilling the requirements. .IP "\fCeq (\fIattrName\fP,\fIattrValue\fP)\fR" The named attribute must exist in the versions attribute list and it must have exactly the given value. When the corresponding version attribute has multiple values, at least one of the values must match exactly. .IP "\fChasattr (\fIattrName\fP)\fR" The named attribute must exist in the versions attribute list. When applied to a standard attribute, hasattr requires a value to be associated with the standard attribute. In case of user defined attributes, the attribute value is not regarded. .IP "\fCne (\fIattrName\fP,\fIattrValue\fP)\fR" The named attribute, when existing in the versions attribute buffer, must not have the given attribute value. When the attribute does not exist, everything is fine. If the attribute has multiple values, it is required, that none of the values matches the given \fIattrValue\fP. .IP "\fC{ge,gt,le,lt} (\fIattrName\fP,\fIattrValue\fP)\fR" The named version attribute must have a value, that is greater or equal / greater than / less or equal / less than the given attribute value. The named attribute must exist in the versions attribute buffer, otherwise the version is eliminated from the hit set. For attributes with multiple values, only one of the values must meet the required property. .LP The second class are predicates that do not operate on single version but rather on the complete hit set. They express relations between different versions in the hit set and base their selection on comparison of different versions. Usually, they are used to get a unique version binding, by ordering the hit set and selecting one of the extremes. .IP "\fCmin (\fIattrName\fP)\fR" Retain the version(s) with the lowest value for the named attribute in the hit set. String values are compared literally, others "naturally" (see the list of known attributes below for an explanation of that). Versions not carrying the named attribute or having no value associated with the attribute name are eliminated from the hit set. .IP "\fCmax (\fIattrName\fP)\fR" Retain the version(s) with the highest value for the named attribute in the hit set. String values are compared literally, others "naturally" (see the list of known attributes below for an explanation of that). Versions not carrying the named attribute or having no value associated with the attribute name are eliminated from the hit set. .LP The next two predicate groups have no direct influence on the hit set. They can invalidate the hit set and cause the rule evaluation to go on with the next attribute expression, but they do never modify the hit set. These predicates are activated, when the evaluation of the attribute expression reaches them, i.e. when the hit set is not empty. .IP "\fCmsg (\fImsgString\fP)\fR" Print the given message to standard output and retain the current hit set. .IP "\fCcut (\fImsgString\fP)\fR" Force the current rule binding to fail and print the given message to standard output. Printing is omitted, when the message string is empty. Rule processing is stopped immediately and the returned hit set is empty. .IP "\fCconfirm (\fImsgString\fP,\fIexpectedAnswer\fP)\fR" Ask the user for confirmation to go on with the evaluation of the current attribute expression. The given message string is printed to standard output with the expected answer appended in square brackets. After that, user input is read. When the user confirms the expected answer (empty input) or his/her input matches the expected answer, evaluation of the current attribute expression continues. Otherwise, the current hit set is invalidated and processing goes on with the next attribute expression. .IP "\fCbindrule (\fIruleName\fP)\fR" Abort evaluation of current attribute expression and switch to another version bind rule. This predicate makes only sense as last predicate in an attribute expression, as following predicates will never be evaluated. Evaluation of the target rule (\fIruleName\fP) happens as if the rule has been invoked directly, no influence on the initial hit set is taken. When the target rule fails, the evaluation algorithm switches back to the source rule and goes on with the next attribute expression. .LP The last predicate group are external constraints. Their task is to influence the evaluation process by examining conditions outside the handled version history. Each of the following predicates has either a positive or a negative result. Positive results have no effect on the hit set and the evaluation process, while negative results invalidate the hit set and cause evaluation to go on with the next attribute expression. .IP "\fCexists (\fIname[binding]\fP)\fR" Version binding with the given name (usually another one than the current target name) and the given version binding must lead to at least one version. The result is not required to be unique. .IP "\fCexistsnot (\fIname[binding]\fP)\fR" Version binding with the given name and rule must fail. .IP "\fCexistsuniq (\fIname[binding]\fP)\fR" Version binding with the given name and rule must lead to a unique selection. .IP "\fCcondexpr (\fIprogram\fP,\fIexpression\fP)\fR" An external program, named in the program argument, is activated to evaluate the given expression. The expression string is written to the standard input of the external program. A zero result code is considered to be positive, all others negative. .SH OBSOLETE PREDICATE NAMES There are a number of known predicate names from former versions of the bind rules machinery. They are internally mapped to the new predicate names. These names are obsolete and should not be used any longer. .LP .ta 1c 4c \fIObsolete name\fP \fImapped to\fP - cut attr eq attrex hasattr attrge ge attrgt gt attrle le attrlt lt attrmax max attrmin min attrnot ne condex exists condnot existsnot conduniq existsuniq .SH ATTRIBUTES All predicates with effect on the contents of the hit set work on version attributes. These attributes are either standard attributes with a defined meaning or user defined attributes. The following is a list of attribute names recognized as standard attributes. All other names are considered to be user defined attributes. .IP \fCalias\fP 2.7c Version alias name (symbolic version identification name). .IP \fCatime\fP The date of last access (read or write) to the versions contents. .IP \fCauthor\fP The version author in the form \fIusername\fC@\fPdomain\fP. .IP \fCcachekey\fP A unique key for cached versions built from the creation date, the id of the creating process and a serial number (e.g. \fI740148430.18469.6\fP). .IP \fCctime\fP The date of the last status change. This date is updated, when an attribute is added or deleted, or an attribute value is changed. .IP \fCgeneration\fP The generation number. The value for this attribute is plain numeric. .IP \fChost\fP The name of the host from where the version was accessed. This attribute may have different values at one time, when the version is accessed from different hosts. .IP \fClocker\fP The user who has set a lock on the concerned version. This attribute has an empty value, when no lock is active. The attribute value is given in the form \fIusername\fC@\fPdomain\fP. .IP \fCltime\fP The date of last lock change (set or give up update lock). This has an empty value is empty, when there was never a lock set on the version. .IP \fCmtime\fP The date of the last modification of the versions contents. .IP \fCname\fP The name (without suffix) of the version. For example \fIfoo\fP for \fIfoo.c\fP. .IP \fCowner\fP The version owner in the form \fIusername\fC@\fPdomain\fP. .IP \fCrevision\fP The revision number. As for generation, only numeric values are accepted. .IP \fCsize\fP The size of the versions contents in bytes. .IP \fCstatus\fP The version status. This is one of \fCbusy\fP, \fCsaved\fP, \fCproposed\fP, \fCpublished\fP, \fCaccessed\fP, or \fCfrozen\fP. .IP \fCstime\fP The save date. This attribute has an empty value for busy versions. .IP \fCsyspath\fP The absolute pathname through which the version was accessed. This attribute may have different values at one time, when the version is accessed by different pathnames (e.g. symbolic links). .IP \fCtype\fP The suffix part of the versions name. For example \fIfc\fP for \fIfoo.c\fP. .IP \fCversion\fP The version number in the form \fIgeneration.revision\fP. A special value is the string \fCbusy\fP instead of a version number. As busy versions have no version number, this value is used for identifying the busy version of a history. .LP Some predicates (like \fIge\fP or \fImax\fP) require an ordering relationship between attribute values. For user defined attributes, ordering bases on alphabetical (ASCII) comparison of the values. User defined attributes with multiple values are compared by their first values, if these are identical by their second values and so on. No value is considered smaller than any other value. For example .LP .nf .ta 2c 6.2c 10c \fCattr1 = anton\fP \fCattr2 = berta\fP \fC berta\fP is smaller than \fC anton\fP \fC karl\fP .fi .LP but .nf .ta 2c 6.2c 10c \fCattr1 = anton\fP \fCattr2 = anton\fP \fC berta\fP is bigger than \fC berta\fP \fC karl\fP .nf .LP For some of the standard attributes listed above, we need special regulations. .IP "Version numbers (\fIgeneration.revision\fP)" 2.8c are ordered by generation number first and revision number secondary (e.g. \fC1.2\fP is smaller than \fC2.1\fP). \fCBusy\fP is smaller than any version number. .IP "Alias Names" are ordered by the version numbers (see above) of the identified versions. .IP "Cache keys" are ordered by simple text comparison. This has the effect that the youngest cache key is considered the biggest. .IP "Version states" are ordered in the sequence as listed above. \fCBusy\fP is the lowest and \fCfrozen\fP the highest state. .IP "User attributes" The order of user attributes bases on alphabetical comparison of the string \fIusername\fC@\fPdomain\fR. .IP "Time attributes" Time comparison assumes older dates to be smaller than newer ones. .SH EXPANSION During evaluation of version bind rules, four different kinds of expansion are possible. These are \fIparameter substitution\fP, \fIattribute expansion\fP, \fIexternal macro expansion\fP and \fIcommand substitution\fP. Expansion happens, when a magic pattern is found in the rule text, starting with either a dollar sign (\fC$\fP) or, in case of command substitution, with a backward quote character (\fC`\fP). .LP Generally, expansion in version bind rules happens only within patterns and within predicate arguments. Bind rule syntax or predicate names cannot be introduced by substituted strings. Expansions outside patterns and predicate arguments are ignored and usually lead to an error message. .SS Parameter Substitution A parameter substitution string is usually introduced by the pattern \fC$_\fP followed by the parameter name (an exception is \fC$+\fP as shown below). The parameter name is optionally delimited by a dollar sign. This is necessary, when there is no whitespace character following. The parameter name may be any of the names specified in the rule head or one of the following predefined names. .IP "\fC$_rule$\fP" 3.5c The current rule name. .IP "\fC$_target$\fP or \fC$+\fP" The current target file name to be bound. .IP "\fC$_\fIparameter\fC$\fR" Any other parameter. .LP A parameter may have the same name as a citeable attribute (see below). In this case, the parameter citation hides the attribute citation. There is no way to cite the value of an attribute when there is an equally named rule parameter. The reserved names \fCrule\fP, \fCtarget\fP, and \fChits\fP are not allowed as parameter names. .SS Attribute Expansion An attribute expansion string looks exactly like a parameter substitution string. It is introduced by the pattern \fC$_\fP followed by the attribute name which is optionally delimited by a dollar sign, when a non-whitespace character follows immediately. Attribute names may be built of any printable characters except '#'. Besides, it makes no sense to cite attributes with an equal sign ('=') in the attribute name, as the Attributed Filesystem (AtFS) doesn't allow this. .LP The value by which the attribute expansion string will be replaced depends on the current state of processing. This may cause different values to be inserted for the same citation in different processing states. Attribute expansion happens as late as possible, it is done right before the evaluation of the concerned pattern or predicate. With one exception, \fC$_hits$\fP, attribute expansions will only be substituted, if the current hit set cardinality is 1. .IP "\fC$_hits$\fP or \fC$=\fP" 3.5c The number of versions satisfying the binding conditions expressed so far (the cardinality of the hit set). This value continuously changes during rule evaluation. .IP "\fC$_\fIattribute\fC$\fR" The value of any attribute of a uniquely selected version. .LP Attribute citations may be overloaded by parameter citations (see above). .SS External Macro Expansion External macros are evaluated by an external macro processor. If no such macro processor is available, external macros remain unchanged. They have the form: .IP "\fC$C\fP" where \fCC\fP is any printable non-whitespace character except '+', '=', '_', ':', or '#' .IP "\fC$(\fImacroName\fP)\fR or \fC${\fImacroName\fP}\fR" Macro names may not contain '#' characters. Other limitations may be imposed by the external macro definition and processing facility. .SS Command Substitution A command enclosed in back quotes occuring in a bind rule quotes will be replaced by its output. No modifications are done to the command output, hence it may contain newline characters. .SH LEXICAL STRUCTURE There are some characters with special meaning when occurring in version bind rules. These are the syntactical characters colon (\fC:\fP), comma, (\fC,\fP), semicolon (\fC;\fP), period (\fC.\fP), and parentheses (\fC(\fP and \fC)\fP), the comment symbol (\fC#\fP), the dollar sign (\fC$\fP) or the back quote (\fC`\fP) introducing expansion strings (\fC$\fP), quotes (\fC"\fP and \fC'\fP), and the escape symbol (\fC\e\fP). .LP Comments are handled somewhat rigorously. A comment symbol (\fC#\fP) occurring anywhere in the rule name or rule body has effect as long as it is not escaped by a backslash (\fC\e\fP) character. Comments range from the comment symbol (inclusive) to the end of the line. Newline characters within comments may also be escaped by a backslash character, continuing the comment on the next line. .LP Nesting of parentheses and quotes is not supported. .LP The following is a list of lexical constraints for each part of a version bind rule. .IP "Rule names and rule parameters" 2c Rule names may consist of any printable non-whitespace character except colon and parentheses. The leftmost colon or opening parentheses delimits the rule name. .br Rule parameter names follow the same lexical rule, but additionally must not contain comma characters, as this in the delimiter between parameters. .IP "Patterns" In principle, name patterns may consist of any printable character. Comma and semicolon characters occurring in a name pattern must be escaped by a backslash character. A period occurring in a name pattern needs \fInot\fP to be escaped as long as it is not the last character (ignoring trailing whitespace) in the rule body. Period as last character is \fIalways\fP considered to be end of rule sign. Name patterns may contain macro or parameter citations and command substitutions. .IP "Predicates" Each predicate name must be one of the reserved names listed previously in this paper. Predicate arguments consist of any printable character including whitespace. Comma, parenthesis or quoting characters must be escaped. Any argument may be quoted by single or double quotes. Quoting exceeds line limits. .br Predicate arguments may contain macro, attribute or parameter citations leaded by a dollar sign, or command substitutions enclosed in back quotes. When quoted in single quotes, dollar signs and back quotes occurring in a predicate argument are not taken by their special meaning and no citations happen. Double quotes do \fInot\fP hide citations. .SH TIPS, TRICKS, AND TRAPS \fIWhy doesn't the bind rule select version xyz although I think it should ?\fP. An important facility to find an answer to this question is the \fItrace option\fP provided by the vbind(1) command. It shows the evolution of the hit set during rule evaluation. .LP Typing errors in standard attribute names may lead to confusing situations. They cannot be recognized by the evaluation machinery, as any unknown attribute name is considered to be an user defined attribute. .LP A minus sign (\fC-\fP) as first character in an alternative is considered as part of the pattern and not as (old style) cut operator. Hence .br \fC-;\fP (\fC-\fP as pattern) .br and .br \fC,-;\fP (default pattern followed by cut) .br make a big difference. We recommend the use of \fCcut()\fP in any case. The short form (\fC-\fP) is supported only for compatibility with older versions. .SH GRAMMAR .LP .nf .ta 2.2c 4c \fIbind_rule\fP ::= \fIbind_rule_head\fP \f(CB:\fP[\f(CB-\fP] \fIbind_rule_body\fP . \fIbind_rule_head\fP ::= \fIrule_name\fP | \fIrule_name\fP \f(CB(\fP \fIrule_arg_list\fP \f(CB)\fP . \fIrule_arg_list\fP: \fIrule_name\fP { \f(CB,\fP \fIarg_name\fP }* . \fIbind_rule_body\fP ::= \fIattr_expression\fP { \f(CB;\fP \fIattr_expression\fP}* \f(CB.\fP . \fIattr_expression\fP ::= \fIname_pattern\fP { \f(CB,\fP \fIpredicate\fP }* | \fIpredicate\fP { \f(CB,\fP \fIpredicate\fP }* | . \fIname_pattern\fP ::= { \fI\fP }+ \fIpredicate\fP ::= \fIattr_value_predicate\fP \f(CB(\fP \fIattr_name\fP \f(CB,\fP \fIstring\fP \f(CB)\fP | \fIattr_name_predicate\fP \f(CB(\fP \fIattr_name\fP \f(CB)\fP | \fIbind_rule_predicate\fP \f(CB(\fP \fIrule_name\fP \f(CB)\fP | \fImsg_predicate\fP \f(CB(\fP \fIstring\fP \f(CB)\fP | \fImsg_answer_predicate\fP \f(CB(\fP \fIstring\fP \f(CB,\fP \fIstring\fP \f(CB)\fP | \fIcond_rule_predicate\fP \f(CB(\fP \fIstring\fP \f(CB,\fP \fIbind_rule_head\fP \f(CB)\fP | \fIcond_expr_predicate\fP \f(CB(\fP \fIstring\fP \f(CB,\fP \fIstring\fP \f(CB)\fP | \fIcut_predicate\fP. \fIattr_value_predicate\fP ::= \fCeq\fP | \fCge\fP | \fCgt\fP | \fCle\fP | \fClt\fP | \fCne\fP . \fIattr_name_predicate\fP ::= \fChasattr\fP | \fCmax\fP | \fCmin\fP . \fIbind_rule_predicate\fP ::= \fCbindrule\fP . \fImsg_predicate\fP ::= \fCcut\fP | \fCmsg\fP . \fImsg_answer_predicate\fP ::= \fCconfirm\fP . \fIcond_rule_predicate\fP ::= \fCexists\fP | \fCexistsnot\fP | \fCexistsuniq\fP . \fIcond_expr_predicate\fP ::= \fCcondexpr\fP . \fIcut_predicate\fP ::= \f(CB-\fP . \fIattr_name\fP ::= arg_name | \fCauthor\fP | \fCatime\fP | \fCctime\fP | \fCgeneration\fP | \fClocker\fP | \fCltime\fP | \fCmtime\fP | \fCowner\fP | \fCrevision\fP | \fCsize\fP | \fCstate\fP | \fCstime\fP | \fCversion\fP . \fIrule_name\fP ::= { \fI\fP } . .fi .SH FILES $SHAPETOOLS/BindRules .SH SEE ALSO vbind(1), vadm(1), atnetwork(3), shape(1) .SH AUTHOR Andreas.Lampen@cs.tu-berlin.de shapetools-1.4pl6.orig/man/man7/shape_stdrul.7100444 2013 145 6122 5412610515 17342 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: shape_stdrul.7[6.0] Fri Jun 25 17:01:51 1993 andy@cs.tu-berlin.de frozen $ .. .TH "SHAPE_STDRUL" 7 "" \n(dy.\n(mo.\n(yr .SH NAME shape stdrul \(em shapeTools RMS general version selection rules .SH DESCRIPTION The shape release management system requires a set of standard version selection rules to be accessible project wide. These are defined in the \fIstdrules\fP file, which is to be included into the Shapefiles of any part of the system controlled by the shapeTools release management system. Version selection rules drive the binding of component names in the Shapefile to specific versions during a build or release process (or better: any process performed by invocation of shape(1) ). Some functions of shape_RMS allow definition of the version binding rule being active by defining the VERSIONS macro on the command line. This may be set to any of the rule names listed below. .PP If you want to introduce new version selection rules for project wide use, you may add them to the stdrules file. You should be very careful, when altering this file. Do not remove any of the rules defined in the original version of stdrules (as it comes from the shapeTools distribution tape) because these are essential for the release management system. When altering one of the original selection rules, you should be very concious of what you are doing, as you may affect the operationality of shape RMS. For a description of the syntax of rule definitions, see the shape(1) manual. .PP The standard version selection rules are: .IP most_recent 1i For each component select a busy version if available, the most recent saved version otherwise. .IP last_proposed Use the last proposed version of each component. This rule fails, if no proposed version is available .IP last_released Select versions from the last generated release. .IP last_prereleased Select versions from the last generated prerelease. .IP recent_release Select versions included in the last release or prerelease, whichever is newer. .IP from_release Select versions from a specific release or prerelease. When using this rule the value of the macro \fIRELEASENAME\fP has to be set to the name of the desired (pre)release. .IP extern Always select a busy version (a regular UNIX file). This rule should be applied to all extern components that are not under control of the shapeTools version control system. .SH FILES $(SHAPELIBPATH)/stdrules .SH SEE ALSO shape_RMS(1), shape(1) shapetools-1.4pl6.orig/man/man7/shape_stdvar.7100444 2013 145 4006 5412610507 17330 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: shape_stdvar.7[6.0] Fri Jun 25 17:01:52 1993 andy@cs.tu-berlin.de frozen $ .. .TH "SHAPE_STDVAR" 7 "" \n(dy.\n(mo.\n(yr .SH NAME shape stdvar \(em shapeTools RMS project wide variant definitions .SH DESCRIPTION This file contains common variant definitions to be used in a software development project supported by the shape release management system. The stdvar file defines a variant raster for a whole development project. This central definition facility unifies the naming and semantics of supported system variants. .PP \fIStdvar\fP is to be included into the Shapefiles of any part of the developed system via shape's include mechanism. The definitions in stdvar should be carefully designed and maintained for each supported project. They usually concern variant control for all hardware/operating system platforms to be supported or variant settings to produce different qualities of generated code (debug or optimized). .PP Enclosed in the shapeTools distribution, you find the stdvar file used in the development of the shape toolkit itself. This may be a good starting point for developing an own variant raster. At least, it helps you learning the definition syntax. Otherwise, for a description on the syntax of variant definition parts see the shape(1) manual. .SH FILES $(SHAPELIBPATH)/stdvar .SH SEE ALSO shape_RMS(1), shape (1) shapetools-1.4pl6.orig/man/man7/shape_tmpl.7100444 2013 145 31112 5412610500 17010 0ustar dokoswt.ig Copyright (C) 1993,1994 by the author(s). This software is published in the hope that it will be useful, but WITHOUT ANY WARRANTY for any part of this software to work correctly or as described in the manuals. See the ShapeTools Public License for details. Permission is granted to use, copy, modify, or distribute any part of this software but only under the conditions described in the ShapeTools Public License. A copy of this license is supposed to have been given to you along with ShapeTools in a file named LICENSE. Among other things, this copyright notice and the Public License must be preserved on all copies. Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de) $Header: shape_tmpl.7[6.0] Fri Jun 25 17:01:54 1993 andy@cs.tu-berlin.de frozen $ .. .TH "SHAPE_TMPL" 7 "" \n(dy.\n(mo.\n(yr .SH NAME Shapefile.tmpl, Makefile.tmpl, Release.tmpl, release.c.tmpl \(em templates in the shapeTools RMS .SH DESCRIPTION When working with the shapeTools Release Management System, all system model files (Shape\- and Makefiles) must be derived from templates, namely \fIShapefile.tmpl\fP and \fIMakefile.tmpl\fP. The templates define a certain number of standard macros names used througout the shapeTools RMS. Deriving system model files from the templates is mainly filling in the appropriate macro values. The following section gives an overview of all macro names defined in the templates and a short explanation on the semantics of each macro. .PP \fIRelease.tmpl\fP and \fIrelease.c.tmpl\fP are templates for release identification files. They do not need to be adapted in any way. .SH MACROS The following is a list of macros that occur in the Shape- and Makefile templates. Most of them are defined in the Makefile. As Makefiles are included in the Shapefiles, these are used by both, calls of make and calls of shape. Some shape specific macros (defined in the Shapefile template) are described at the end of this section. .PP As the shapeTools RMS performs recursive calls of shape (resp. make), some of the standard macro settings get inherited to a recursively called sub\-build\-process. The macros are marked in the list accordingly. The inheritance mechanism allows installation dependent macros (eg. BASE) to be set for the whole project by only modifying the value in the top level Shape\-/Makefile. .PP \fBLocations and General Macros\fP .PP .IP "BASE (inherited)" The base directory of the project's central source repository. .IP NODEPATH The relative path name of a system node within the project's source repository. In the top node, this macro has an empty value. For subsystems, it is to be set to the path relative to $(BASE) (eg. "/subsystem/library"). .IP NODENAME A short name for the developed system node. This name will also to be used for generating release identification strings having the form \fI-\fP. .IP "HOSTSYSTEM (inherited)" The underlying operating system. The value of the HOSTSYSTEM macro is built after the schema \fCs-\fP. This macro has different meanings in make and in shape. .br \fIMake\fP treats it as an an extension to a known base path for accessing the appropriate versions of operating system dependent files. The base path points to a directory containing subdirectories for each supported operating system type. All subdirectories carry the same list of filenames with in each case different (operating system specific) contents. .br For \fIshape\fP, the HOSTSYSTEM macro is treated as variant definition. With the corresponding variant definition defined in the variant definitions include file (see shape_stdvar(7)), a whole bunch of macros is set (resp. modified). .IP "HOSTTYPE (inherited)" The machine architecture. This macro should be used for installing different binaries (for different machine architectures) compiled from the same program source in a heterogeneous network. On systems containing the \fIarch\fP command, HOSTTYPE may be dynamically set by HOSTTYPE=`arch`. This macro is currently not supported in the default installation setup. .IP "SWITCHES (inherited)" Preprocessor switches for conditional compilation. This macro may be used for system wide switching on/off certain program behavior. The SWITCHES are passed as arguments to the language preprocessor. .IP "INSTALLBASE (inherited)" Locations and modes for installation of executables, header files, libraries, and manuals. The INSTALLBASE macro eases the definition and redefinition of the following installation path macros, as the values of these may cite INSTALLBASE. Each of the installation path macros may also be set to a value independent of INSTALLBASE. .nf INSTALLBINPATH (inherited) \- installation directory for executables INSTALLBINMODE (inherited) \- file protection mode to be set for installed executables INSTALLINCPATH (inherited) \- installation directory for include files INSTALLINCMODE (inherited) \- file protection mode to be set for installed include files INSTALLLIBPATH (inherited) \- installation directory for libraries INSTALLLIBMODE (inherited) \- file protection mode to be set for installed libraries INSTALLMANPATH (inherited) \- installation directory for manuals INSTALLMANMODE (inherited) \- file protection mode to be set for installed manuals .fi Installimn manuals using the INSTALLMANPATH macro expects appropriate manX (man1, ...) subdirectories there. .IP "LIBPATH (inherited)" The directory, where local libraries, developed within the project, shall be installed for project wide use. .IP "INCLUDEPATH (inherited)" Similar to LIBPATH. The location of project internal header files. .PP \fBThe System Components\fP .PP .IP TARGET The name of the main target to be built. This can be a program, a library, or anything else to be produced. If the construction of the main target does not require any real transformation (if eg. only subsystems are to be built), it is advisable to have a file $(SUBSYSTEMNAME).date as main target. The system building action should just touch this file, so that it's modification date shows, when the last system building action happened. If the managed system consists of multiple programs, this macro should be multiplied (eg. TARGET_1 TARGET_2 ... TARGET_N). In that case, all places in the Makefile, where $(TARGET) occurs have to be modified accordingly ! .IP VERSIONFILE The name of a file, used as release number generator. With each new release, a new version of this file is generated automatically. When developing a program, this file ideally contains exactly one function returning a version identification string. When using the ShapeTools version control system's attribute citation mechanism, the contents of such a file needs only to be written once and never be changed afterwards. There are different prototypes for such a file in $(LIBPATH)/shape. For system parts not incorporating an executable program, any other source file could be chosen as release number generator. In any case should $(VERSIONFILE) never be saved explicitly by the user. .IP VERSIONOBJECT The object file (.o file) derived from VERSIONFILE. This macros is only to be set, when VERSIONFILE contains program text. .IP SUBSYSTEMS All subdirectories, where additional parts of the system wait for being built. For each subtarget, a recursive shape (resp. make) call is performed with the current macro settings getting inherited. The SUBSYSTEMS will be build before TARGET. This macro may also be empty. .IP ALIASES This is a list of aliases for TARGET. This macro is to be set, when TARGET should be accessible by multiple names (eg. a program to be activated under different names). .IP SOURCES A list of all programming language source files belonging to the system. In the case of C development, these are the \fI.c\fR files .IP HEADERS The header files belonging to the system. The \fI.h\fP files in case on C development. .IP AUXSOURCES Auxiliary source files. These are source files that shall also be processed when building the system, but that are not genuine part of the system. These are for example sources of auxiliary test programs, needed to perform test in the development area. .IP AUXHEADERS Auxiliary header files, similar to auxiliary sources. .IP VARIANTSOURCES .IP VARIANTHEADERS Equally named source and header files, located in subdirectories, each named after a certain variant. For system building, only one of the directories is used, according to the specified HOSTSYSTEM. In the shape_RMS environment, the subdirectory names should be chosen from the value set of the HOSTSYSTEM macro (for more details, see the description of the HOSTSYSTEM macro above). .IP MANUALS The manual files for the system, distinguished by categories. .IP COMPONENTS All source components belonging to the system. These are the source files (SOURCES), the include files (HEADERS), the manuals (MANUALS), the Shapefile, the Makefile and a (generated) file named \fBDependencies\fP. .IP OBJECTS All files, automatically produced during a build process except TARGET. These are usually the .o files. .PP \fBTools, Flags and Libraries\fP .PP .IP "MAKE (inherited)" The make program. This macro is used for recursive calls of make. During execution of shape, this macro is explicitly (in the Shapefile) set to the value of the SHAPE macro. This causes recursive builds also to be performed by shape. .IP "SHELL (inherited)" The shell to be used by make, resp. shape for interpreting the build actions in the Makefile or Shapefile. .IP "CC (inherited)" The C compiler to be used. .IP "CFLAGS (inherited)" The C compilation flags (see SWITCHES for additional compilation flags). .IP "LDFLAGS (inherited)" The linker flags. .IP "RANLIB (inherited)" The program for adding a table of contents to archives. .IP "SYSLIBS (inherited)" Additional system libraries to be linked to TARGET .IP LOCALLIBS Local libraries to be linked to TARGET .IP LINTLIBS Libraries to be invoked when executing "lint". .PP \fBShape Specific Macros\fP .PP .IP VERSIONS The default version binding (version selection) rule to be applied for each component. Selection rules are globally defined in the $(SHAPELIBPATH)/stdrules file (see shape_stdrul(7)). It is strongly recommended, to define a project wide version selection policy only in the stdrules file and to renounce version selection rules in local Shapefiles. .IP "BINDDEFAULT (inherited)" Internal name for VERSIONS. Should not be redefined. .IP "BINDINSTALL (inherited)" THe default version binding rule to be applied when installang a system or system part for project wide or global use. .IP "COMPILER (inherited)" The compile environment. This macro represents a shape \fIvariant selection\fP. With each variant, a whole bunch of macro settings may be associated, so that the COMPILER variant not only sets the actual compiler (CC), but also some compilation flags. See \fCstdvar\fP for the default variant raster. The same as version selection rules, the variant raster should be defined project wide. Local variant definitions can very easyly lead to confusion and improper configurations. .IP "QUALITY (inherited)" The desired quality of the produced object code. This is also a variant definition (see \fCstdvar\fP for other options). .IP "RELEASEBASE (inherited)" .IP "PARTIALRELEASEBASE (inherited)" The base of the directory tree, where prereleases and releases of the system are to be constructed. When building a (pre)release, the appropriate versions of all components of the system are copied from the development area to the release area. The release area should only be used for performing final tests and for bundling up a shippable package. .IP RELEASESRCPATH The relative path within the release or partial release area where the suorce files ar to be copied to. Ususally, this is identical to $(NODEPATH). .IP RELEASEMANPATH The relative path within the release or partial release area where all manuals are gathered. .IP "SHAPELIBPATH (inherited)" The directory, where all common parts of the shape_RMS environment reside. Here are all the templates and shape include files located. .IP .BPOOL: This is rather a pseudu\-target, than a Macro. Shape interprets this as directive that causes only the listed files ($(OBJECTS)) to be put into the derived object cache. Defining the pseudo target .NOBPOOL: (without dependents) deactivates the derived object cache. This is necessary, when the development environment requires access to the same derived object cache from machines with different architectures. The reason is, that "dbm" databases (and derived object caches use dbm databases) are not portable between different machine architectures. .SH FILES .ta 3c Shapefile.tmpl \- Template for node specific Shapefiles .br Makefile.tmpl \- Template for node specific Makefiles .br release.c.template .br Release.template .SH SEE ALSO shape_RMS(1) shapetools-1.4pl6.orig/+PATCHLEVEL100644 2013 145 2 5626416642 14512 0ustar dokoswt6 shapetools-1.4pl6.orig/CHANGES-1.4100444 2013 145 35244 5443133014 14460 0ustar dokoswt These are the release notes for shapeTools-1.4pl6 This document describes the changes made since ShapeTools-1.3. We start with a short overview pointing to each part of the toolkit, where changes were made. When you've been a ShapeTools user before, you should in any case read the *Migrating from ShapeTools-1.3 to 1.4* section following the overview. Overview -------- - Major restructuring of the entire system. This results in two new completely documented toolkit libraries AtFStk and Sttk (along with the AtFS base library). - Version binding (version selection) has been factored out into the AtFS toolkit library. This allows uniform rule based version identification in all parts of the system. Earlier versions supported rule based version binding only in the shape program. - More flexible and straightforward version bind rules, providing user customization of global rules, rule evaluation hierarchies, formulation of constraints with respect to other objects, and more. - New version archive organization with subdirectories within the AtFS directory. This is important for people using filesystems with 14 character filenames, as archive names are not any longer built by adding some magic characters to the filename, but rather by taking the filename itself. - New command "mkatfs" for creating AtFS subdirectory structures. - Some minor changes to the AtFS interface. This is only important for people who have own application programs operating directly on the AtFS programming interface. - Better derived object cache handling. - A lock daemon for locking of AtFS archive files during update. - Reimplementation of the vl Program with the capability to show histories (-h option). - Restructuring of all version control commands with introduction of the general version binding functionality in each command. - New version control commands "vbind" (version binding), "cphist" (copy history), "vp" (paginated screen output of version contents), "vgrep/vegrep" (patched GNU grep - see below), "vgdb" (patched gdb - see below), "vattr" (attribute handling) and "vrm" (remove version). - Removal of the commands "pattr" and "vinfo". - New parser for Shapefiles. The syntax of Shapefiles has been slightly straightened (no need for the "#% RULE-SECTION / #% END-RULE-SECTION" junk anymore). - More powerful macro substitution schemes in Shapefiles (e.g. string substitution). - 50% Speedup of the shape program. - A package for GNU Emacs to provide full access to versions including version name completion, checkout (retrv) and checkin (save) from the edit buffer and full version binding capabilities. - A patch to gdb (about 40 lines changed/added), enabling the source context to be read directly from the appropriate versions while debugging. This works only together with find_atfs when running gdb in an emacs window. - A patch to GNU grep (basically a 4 lines patch) adding access to saved versions. This also implants full version binding. - Changes to the release management system (RMS) featuring release documentation (logging) and better release number generation. - New command "lastrelease" indicating the name of the last generated (pre)release. - A new porting strategy with only one central config.h/config.c file pair holding all host system dependent definitions. - Introduction of the environment variable SHAPETOOLS. - ANSI-C/POSIX conformance with documented exceptions (see src/atfs/config.h). - Various bug fixes (and various new bugs =:-). Migrating from 1.3 to 1.4 ------------------------- If you used ShapeTools 1.3 or earlier versions up to now for your development work, you should read this section carefully. As the internal organization of data in the AtFS directory was changed, all version data needs to be converted. This can be done by invoking the program "atfsrepair" on each AtFS directory. Atfsrepair will create the necessary subdirectories in the AtFS directory and will move all archives to the proper places. In order to avoid later permission problems, it is important that all subdirectories in an AtFS directory have the same owner, group and protection as the AtFS directory itself. Hence, -> only the owner of the AtFS directory should perform the conversion. atfsrepair will warn you, if this is not the case. Conversion is done by calling -> atfsrepair [-n] [-q] The -n (non-interactive) option causes atfsrepait to do it's job without user interaction. The -q option is for quiet operation. As the management of derived object caches has changed too, atfsrepair will also remove all objects from the old derived object cache. If you have any own shell scripts, Makefiles or Shapefiles using ShapeTools version control commands, you should check, if these are affected by changes to the version control system. All changes to the version control system are listed in a subsequent section. Version control system ---------------------- - Uniform version binding (version selection) throughout all commands. Version binding is conducted by version bind directives (or just version bindings), which can be one of the following. + version numbers (e.g. "1.2", "1.", ".2") + version alias names (e.g. "ShapeTools-1.4") + date specifications (e.g. "10.2.93", "Feb 10, 1993") + bind rule names (e.g. "mostRecent:", "fromRelease(ShapeTools-1.4)") Version bindings can be given either in brackets, directly following the name to be bound, or as option arguments. The following list names the most important version binding options. + "-bind " option + "-rule " option + "-since " option for defining version ranges + "-before " option " + "-last" and "-lastsaved" option - A new command "vbind", performing version binding. - The "vl" (and "vlog") command was totally reimplemented. It now supports output of histories in an "ls" like manner. This means one entry per known name in a directory -- just try it (option -h). The interface has changed a lot... + vl understands the version binding options (see above). + Some options have been added for "ls" conformance: "-1", "-A", "-c", "-d", "-F", "-g", "-L", "-q", and "-u" + New options are: "-?", "-expand", "-h", "-help", "-noexpand", "-O", and "-U". + The "-A" and "-L" option have now a different meaning as before for sake of "ls conformance. + "-B" and "-b" are now "-cache". + "-H" was renamed to "-log". + "-q" was renamed to "-Q" for sake of "ls" conformance. + The semantics of the "-locker" option was extended. + New optionm "-lll" short for "-l -locker -locked" + The following options are gone: "-#", "-archive", "-author", "-last", "-m", "-noenv", "-owner", "-s", "-ux", "-V", "-v", and "-vnum". + The "-u", "-U", "-uda" and "-Uda" options have been replaced by "-attr" and "-p" - "save" + understands the version binding options (see above). + "-f" now also available as "-force". + "-h" option was renamed to "-?/-help". + "-m" now also available as "-logmsg". + "-q" now also available as "-quiet". + "-n" option was renamed to "-a"/"-alias". + "-newgen" now also available as "-g". + "-setvnum" now also available as "-n". + "-t" option was deleted. Use "-m @filename" instead. - "retrv" + understands the version binding options (see above). + "-d", "-date", "-g", "-last", "-s", and "-V" options are deleted. Use the general version binding options instead. + "-a" option was deleted. + New option "-c/-copy" + "-f" now also available as "-force". + "-h" option was renamed to "-?/-help". + "-i" now also available as "-intent". The semantics of the "-i" option was slightly changed. Filenames have to be preceded by and at-sign ("-f @filename"). + "-q" now also available as "-quiet". - "vadm" + "-b" option was renamed to "-cache". + "-delete" now also available as "-d". + "-f" now also available as "-force". + "-h" option was renamed to "-?/-help". + "-l" now also available as "-lock". + "-q" now also available as "-quiet". + "-setuda" and "-remuda" are replaced by "-attr attribute expressions are e.g. foo=blubber, otto=+berta, hugo=-bar + "-setattrs" is now "-attr @". + "-symbolic" option was renamed to "-alias". + "-unsetuda" is now "-delattr". + "-lock" and "-unlock" now have an optional argument describing the generation to be locked. The argument may be a version number, version alias or a date specification. + new options "-unalias" and "-newgen". - "vfind" + "-h" option was renamed to "-?/-help". + "-bpool" option was renamed to "-cache". - New commands "vp", "vattr", "vrm", "cphist", and "mkatfs". ("vattr" and "vrm" are links to "vadm" - Command "pattr" and "vinfo" deleted. The shape program ----------------- - Completely new parser for shape description files + no need for #% RULE-SECTION / #% END-RULE-SECTION pragmats + version selection rules are recognized by rule header "name :-" + variant defintions are recognized by header "name :+" + include directive takes lists of filenames + include directive takes filenames in macros + all syntactical stuff works robust now + in case of description file syntax errors a standard format error message is issued - version binding has been completely rewritten, extended, and been moved to the AtFStk library. + dynamic chaining of selection rules + more intuitive names for all the predicates, stripping the silly prefix "attr" + parametrization of selection rules - much better diagnostics when shape fails to build a requested target - additive macros can be set from the command line - evaluative macro definitions, defining a macro substitution when it is first referenced by evaluating the definition only once - string substitution in macro evaluations - accessing objects in variant subdirectories is now as fast as accessing objects in the build directory - new special macro in implicit rules, providing the full, version qualified id of processed objects - new build-in macro SHAPEPID - new build-in macro SHAPEVERSION - consistent policy regarding *when* macros are substituted - "-confid " option renamed to "-bct", and changed into a command switch without argument. The bound configuration thread document will be prepared for the requested targets, and be named .bct. bct-files are much more precise in defining a bound configuration than the old "confids". - "-D" option now provides detailed information on version binding and derived object caching - new switch "-h" (short for "-help") - "-t" switch removed - "-novclass" switch is new. It disables checking of incompatible variant combinations - "-expandall" renamed to "-xpon" - "-expandnothing" renamed to "-xpoff" - completely re-written manual page. All described features have been carefully checked. Release management system ------------------------- - New command "lastrelease" - Better support for variations of CFLAGS and LDFLAGS - "lastrelease" attribute is tagged to each invoked version during prerelease or release. - Status of versions is set to "published", when generation a "node release". This has been a bug in 1.3. - Some new variant definitions in stdvar (s-svr4, gnu_posix...) - Start a new generation for each component on "shape release" Patches for gdb and GNU-diff ---------------------------- - A patch to gdb, enabling GNU gdb 4.8 to work on AtFS versions. This patch works on SPARC machines running SunOS 4.1.2 and is not tested with other platforms yet. - A patch to GNU grep 1.6, enabling it to work on AtFS versions. Both patches are new with ShapeTools-1.4. The patch files and two corresponding README files are located in the directory "src/patches". Applying the patches and installing the modified programs is *not* supported by the ShapeTools installation procedure. You must do that manually according to the instructions in the README files. Emacs stuff ----------- This is located in "src/interface" check also the README file there. - New emacs lisp code find-atfs.el and callp-err.el + AtFS versions can be read directly into an Emacs buffer by invoking find-file with the version ID. (with version number or symbolic name). + Filename completion is done on version IDs as well. + If find-file tries to read a non-existent file, and an AtFS history of that file exists, the default version of this history will be read instead. + minor mode atfs-mode (without any features yet, but its name appears in the mode line) + toggle-read-only on a version checks a version out and a busy file in with asking for change intent resp. log message. + toggle-read-only on a file asks if the file shall be checked in as AtFS version. - shapetools.el (ShapeTools-Mode) not available in shapeTools-1.4pl6. Attribute Filesystem (AtFS) ---------------------------- - New functions + "af_establish" - establish version as UNIX file + "af_predsucc" - get physical/logical predecessor/successor of version + "af_cachesize" - get or set maximum size of derived object cache + "af_errmsg" - get AtFS error message + "af_histories" - return a list of known history names - Renamed functions and constants + "af_bpfind" renamed to "af_cachefind" + "af_savebinary" renamed to "af_savecache" + "AF_DERIVED" renamed to "AF_CLASS_DERIVED" - Mode parameter of "af_lock", "af_unlock", and "af_testlock" removed. - Additional storage type parameter to "af_savecache" and "af_saverev". Value is one of AF_STORE_DELTA, AF_STORE_COMPLETE, or AF_STORE_COMPRESSED. - New manual pages + af_cache.3 + af_error.3 + af_history.3 + af_protect.3 (formerly af_perm.3) ShapeTools toolkit library and AtFS toolkit library --------------------------------------------------- The shapetools toolkit library (sttk) and the AtFS toolkit library (AtFStk) are two new libraries containing various basic functions (sttk) and common functions based on AtFS (AtFStk) used throughout the toolkit. They come along with a complete set of manual pages, st...(3) and at...(3). Porting ------- New configuration files src/atfs/config.[ch]. The former configuration files residing in src/atfs/conf//config.[ch] were eliminated. Maintaining 14 files for 7 ports was too clumsy. Check the file "INSTALL" for details on the new porting technique. Patchlevel 1 ------------ ShapeTools-1.4pl1 is mainly a bug-fix release. Other changes are: - Due to numerous problems with the "fcntl" file locking, the old (shapeTools-1.3) archive file locking code was inserted again. It may be activated by defining "-DATFS_OWN_LOCKING" - The gdb patch was updated for gdb 4.9. - mkatfs may now be used for reconfiguring the object cache. shapetools-1.4pl6.orig/README100444 2013 145 37060 5626407627 14064 0ustar dokoswt This is README for shapeTools-1.4pl6. It contains general information on ShapeTools (we also refer to it as "shape toolkit") and an overview of its parts. The file "INSTALL" helps you installing the toolkit on your machine. It also gives hints for solving portability problems and describes the procedure for porting the toolkit to a new operating system platform. If you used ShapeTools-1.3 (or earlier versions) before, you should read "CHANGES-1.4" to check, what has changed since 1.3. *** The file CHANGES-1.4 contains important information *** *** on migrating from ShapeTools-1.3 to ShapeTools-1.4. *** Before installing and using the shape toolkit on your computer, you should also read the file "LICENSE". In the file "SUPPORT", you find important information on how the ShapeTools development will be carried out in the future. You can also find the address of a company offering commercial support for ShapeTools there. If you have any questions, hints or bug reports, you may contact us via: Tech. Univ. Berlin Tel: +49-30-314-73230 "ShapeTools" Fax: +49-30-314-73488 Secr. FR 5-6 E-mail: shape@cs.tu-berlin.de Franklinstr. 28/29 10587 Berlin, Germany We set up a mailing list for announcing new releases and patches and for discussion of ShapeTools specific topics. If you want to be kept informed about the evolution of the toolkit, you should subscribe to the mailing list. The list is managed automatically. You can subscribe by sending a mail to "listserv@tubvm.cs.tu-berlin.de" with the contents "sub shape-l ". Submissions to the mailing list are to be sent to "shape-l@tubvm.cs.tu-berlin.de". General information: ==================== ShapeTools is a collection of programs to support software configuration management in an UNIX environment. It consists of a set of version and attribute control commands, and a configuration interpreter and build tool ("shape"). The toolkit is integrated on top of AtFS (Attributed File System), a storage system supporting multiple versions of files and associating an arbitrary number of application defined attributes of the form "name=value" with each version. AtFS comes as a function library that is meant as an extension to the UNIX file system. It does this without the need for kernel modifications and without imposing any restrictions to existing file system applications. ShapeTools is designed to live meaningfully together with any other UNIX tool operating on regular files. This distribution also contains a prototype for a comprehensive change control and release management system designed to manage the evolution of system releases in multi programmer software development efforts. The ShapeTools version and attribute control system ("shape_VC") ---------------------------------------------------------------- The ShapeTools version and attribute control control system is a set of UNIX(1) commands. Shape_VC offers version control functionality and direct access to user definable attributes associated with each version. In detail, shape_VC comprises - storage and retrieval of multiple revisions of files. - a built in status model for revisions. (States: busy, saved, proposed, published, accessed, frozen) - documentation of change histories. - synchronization of concurrent updates to a history. - symbolic names as version number aliases. - a flexible version selection (version binding) mechanism driven by general version binding rules. - a basic network user concept. - full (read and write) access to user definable attributes. The last point in the list, the attribute control, deserves some more attention. As the underlying storage system (AtFS) supports associating any number of attributes with each version, shape_VC uses this mechanism to allow the user to attach his/her own management information in form of attributes to stored revisions. The attribute mechanism supports - genuine attributes (=) where the attribute value is given statically. - execution attributes (=!) where the attribute value is determined dynamically by executing a given program or shell script and catching its output. - file reference attributes (=^) where the contents of a file is taken as attribute value. The file contents is read on every attribute access. - version reference attributes (=*) where the attribute value points to another version. The toolkit character of the system allows to use it directly by calling the commands from the shell, or to build a customized environment on top of it. As an example, we wrote some code to provide direct access to the system from within GNU-Emacs. The corresponding emacs lisp code is contained in the distribution. The Attributed File System (AtFS) --------------------------------- AtFS is the base abstraction of the whole toolkit. It provides uniform access to immutable revisions of files stored in special archive files (in a directory named "AtFS"), and mutable regular UNIX files. Consequently, the AtFS based toolkit lives peacefully (and meaningfully!) together with standard file system applications (editors, compilers, formatters etc.). Cooperative work within projects is supported by a build-in status model, controlling visibility of version objects, and locking, a primitive form of "long transactions" for synchronizing concurrent updates. The general concept of application defined attributes provides a basis for storing management information with versions and passing this information between individual tools. This mechanism is useful for building integrated environments from a set of unrelated tools. AtFS also supports derived object management, i.e. it maintains a cache of multiple versions of compiled object-files (e.g. compiled c-files with different compile switches). People with sophisticated requirements may also add their own applications on basis of AtFS to the toolkit. There is a fully documented C-language interface to AtFS, on top of which all the toolkit programs are built. Additionally to the AtFS C interface, there is the AtFS toolkit library interface (also in C), providing higher level functions such as the version binding mechanism. The configuration management and build program ("shape_CM") ----------------------------------------------------------- The shape_CM component consists of the program "shape", performing - identification of system components, - component version selection, - variant control, - driving transformations (eg. compilations) and - recording configurations (for later rebuild) for the software system to be built. Shape_CM uses, similar to make, a description file named "Shapefile". In fact shape_CM is upward compatible to Make in that it can properly handle conventional Makefiles. The Shapefile however, uses Makefile-style dependencies as (versionless) abstract system model and employs version selection rules to dynamically bind particular versions to the names listed in the system model. The version selection mechanism exploits AtFS' ability to maintain any number of arbitrary attributes for objects in the object base. On special request, shape records an identified configuration in a configuration identification document (bound configuration thread - BCT) which has the form of a completely bound Shapefile (all object-instances are explicit). One of the most useful features of shape is its support of various variant administration techniques. Shape makes no assumptions about the semantics of the variant notion other than having alternative (conceptually equivalent) instances of the same concept ("module"). Despite the particular semantics of a certain variant-concept, there is a small number of techniques to physically handle variants. These techniques are what shape supports. Most commonly used techniques are: - equally named files in different directories - one source file representing multiple variants that are extracted by a preprocessor using different preprocessor switches (e.g. conditional compilation) - one source file processed by different tools or different tool versions/variants (e.g. cross compilation, different coders) - combinations of the above. Shape includes a variant definition facility that allows very flexible and convenient handling of all of the above variant administration techniques. The ShapeTools release management system (shape_RMS) ---------------------------------------------------- Enclosed in the distribution is a prototype for a configuration management environment to be used for constructing system releases in complex (multi programmer) software development projects. Using this environment does not require any experience in writing Shapefiles (resp. Makefiles). The environment consists of templates for a Shapefile and a Makefiles and of a library of Shapefile fragments for project wide use. The shape_RMS supports: - a fully automatic global release building mechanism with automatic release number generation. - automatic generation of prereleases as systematic preparation of releases. - construction of subsystem releases and prereleases - system building and installation by shape *and* make - standard version selection rules - a project wide unified variant raster - built in standard functions for cleaning up, generating tar or shar files, determine file dependencies etc. Each directory where a part of the managed system is developed, has to be equipped with a Shapefile and a Makefile derived from the given templates. In the normal case, the derivation just requires setting a few macros. Shape- and Makefile are kept redundancy free, the Makefile is inserted in the Shapefile via an "include" mechanism. The management of a Shapefile *and* a Makefile (although the Shapefile alone should be enough) implies, that certain system building functions can also be performed by "make". This is especially important for producing self contained releases (buildable and installable on shape-less computer systems by use of make) from the projects development area (managed by shape). Further reading --------------- You can find additional information on the shape toolkit in the manual pages and the tutorial enclosed in the distribution. The tutorial shall help you to learn to use the toolkit in your development work. If you want to read more about the concepts of shape and its object base, we refer to: Axel Mahler, Andreas Lampen "An Integrated Toolset for Engineering Software Configurations" Proceedings of the ACM SOFSOFT/SIGPLAN Software Engineering Symposium on Practical Software Engineering Environments Boston MA, 28-30 November 1988 pp. 191-200 SIGSOFT SE Notes V13-No5, SIGPLAN NOTICES V24-No2, Andreas Lampen, Axel Mahler "An Object Base for Attributed Software Objects" Proceedings of the EUUG Autumn '88 Conference Cascais (Portugal) 3-7 October 1988 pp. 95-105, European UNIX User Group, London 1988 Ulrich Pralle "Driving the Software Release Process with Shape" Proceedings of the EUUG Autumn '90 Conference Nice (France) October 1990 pp. 27-38, European UNIX User Group, London 1988 This distribution contains the following parts: =============================================== +PATCHLEVEL -- The current patchlevel. CHANGES-1.4 -- Release notes for ShapeTools-1.4 Dependencies -- An automatically generated file containing Makefile dependencies. There are no dependencies on this level. in the ShapeTools root directory. SUPPORT -- Some words about the status of ShapeTools and a company offering support for ShapeTools users. INSTALL -- Information how to build and install the toolkit on your machine. LICENSE -- Important information about copying permissions and warranty issues. This file should *not* be deleted. Makefile -- The top level Makefile for the toolkit. Questionnaire-- A questionnaire asking about your opinion about ShapeTools. Please fill this out after you have used ShapeTools a while. README -- The file you are currently reading. Release -- The current Release Id. Shapefile -- The top level Shapefile. shape_conf.sh-- A configuration script invoked automatically when calling "make" the first time and by "make config". bin/ include/ -- Two local installation directories. These are initially empty. lib/ -- The lib directory for local installation of internal libraries during system build. This is inilially empty, it only only contains the (empty) subdirectories shape/ -- for the common Shapefile parts and the templates for Makefiles and Shapefiles. emacs/lisp -- for the emacs lisp code man/ -- The online manuals for man1/ -- the commands, man3/ -- the AtFS, AtFStk and sttk library interfaces, man5/ -- file formats of AtFS archive files, and man7/ -- templates and version bind rules. src/ -- The sources atfs/ -- the attribute file system (AtFS) atfstk/ -- the AtFS toolkit library (AtFStk) interface/ -- GNU-Emacs lisp code patches/ -- patches for gbd and GNU-grep rms/ -- the release management system shape/ -- the shape program sttk/ -- the ShapeTools toolkit library vc/ -- the version control system tutorial/ -- A tutorial on how to work with the shape toolkit Specialties of the System V version =================================== For sake of a proper release management with shape, it is extremely useful to be able to share AtFS subdirectories (where the archive files are stored) between different directories. On BSD like systems, this can be organized by using symbolic links. Older System V systems do not support symbolic links, so we introduced a mechanism allowing the "AtFS" entry in a directory to be either a subdirectory (the normal case) or a regular file containing a directory name. The latter case is handled like a symbolic link and archive files are searched in the directory named in the "AtFS" entry. Acknowledgement =============== Version 1.0 of the shape toolkit was a result of the UniBase project, a joint research and development project funded by the "Bundesministerium fuer Forschung und Technologie" (BMFT, Federal Ministry for Research and Technology of West Germany) under grant number ITS-8308. The project aimed at the development of a large scale industrial software production environment. The current work on the toolkit (version 1.1 and newer) is mostly part of the STONE project (A STructured and OpeN Environment). STONE is a scientific project aiming at the construction of a generic software development environment kernel. The STONE consortium consists of nine German universities and research institutes, three of them from former East Germany. STONE is also funded by the BMFT under grant ITS-8902E8. Further contributions come from members of the REX project (Reconfigurable and Extensible Parallel and Distributed Systems) funded by the EC as ESPRIT Project 2080, and from faculty members of the TU Berlin. Thanks to the various people who sent bug reports, hints and recommendations. Thank you also to the moderator and reviewers of comp.sources.reviewed, who made very valuable comments on shapeTools-1.2. They definitely had no easy job reviewing shapeTools in it's whole complexity. Special thanks to Steve Emerson (steve@unidata.ucar.edu) who rewrote parts of the shape program. Juergen Nickelsen (re)implemented various parts of the toolkit as member of the STONE project crew. Unfortunately he had to leave the project due to funding problems. We hope to get him back into the ShapeTools family as soon as possible. The ShapeTools people, Andy Lampen and Axel Mahler shapetools-1.4pl6.orig/LICENSE100444 2013 145 5707 5412315613 14156 0ustar dokoswt ShapeTools Public License (Version 4.0, June 1993) ------------------------------------------------- Copyright (c) 1992,1993 by Andreas Lampen and Axel Mahler. You may produce verbatim copies of this license document and distribute them, but you are not allowed to change this document. The "NO WARRANTY" part of this document is taken from the GNU General Public License. 0) This license applies to all parts of the shape toolkit (ShapeTools). Note the special regulations for the tutorial expressed in paragraph 2. 1) Permission is granted to use, copy, modify, or distribute any part of ShapeTools, except the tutorial, as long as this is done without asking for charge, and provided that the copyright notice is retained as part of the source files. Additionally, this license document has to be included in any distributed copy of any part of the system. You may charge a distribution fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2) The tutorial included in the ShapeTools distribution ("tutorial/tutorial.ps") may *not* be modified. It may *only* be distributed as a whole. You are not allowed to take any excerpts from it. When not contradicting to the limitations expressed in this paragraph, all other regulations in this document apply to the tutorial too. -------------------- This part is Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA NO WARRANTY BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -------------------- Direct questions to: Tech. Univ. Berlin "ShapeTools" Secr. FR 5-6 Franklinstr. 28/29 D-10587 Berlin, Germany Tel: +49-30-314-73230 Fax: +49-30-314-73488 E-mail: shape@cs.tu-berlin.de shapetools-1.4pl6.orig/INSTALL100444 2013 145 14514 5465525435 14233 0ustar dokoswt This is INSTALL for shapeTools-1.4pl6. It describes how to build and install the shape toolkit on your computer. Please read the file "LICENSE" before installing and using the shape toolkit on your machine. The build/installation procedure ================================= The first time you call "make" in this directory (the root directory of the ShapeTools source tree), make invokes a configuration script asking you a few questions about the environment where ShapeTools is to be built and installed. You will be asked for: - the operation system of your machine. See the following section for a list of supported operating system platforms. - the compiler and compile flags to be used. - whether the emacs lisp code shall be compiled and installed. This is *very* recommendable if you are an emacs user. - whether the internal C-libraries and header files shall be installed. You will need these, when applying the patches for 'gdb' and 'GNU-grep'. - the locations, where executables, libraries and manuals shall be installed. Below in this file, you will also find some words about installation locations. Subsequent calls of "make" will not run the configuration script again automatically. Type make config to run the script again and change the configuration of the build/install procedure make to build ShapeTools make install to install the commands, libraries and manuals make clean to clean up Important Hints =============== file locking If you are sure, that the system file locking mechanism (fcntl,lockd) is installed correctly and works fine in your network, you should eliminate the -DATFS_OWN_LOCKING from the CFLAGS definition when running the configuring script. System file locking used to be default when installing ShapeTools, but it seems that this is a notorious trouble-maker on most machines (including ours). So we switched back to AtFS's own locking mechanism as default. This, however, is not 100% safe in NFS based environments. In some cases, conflicting updates may cause the loss of a change. AIX If you use AIX 3.2, you should set the environment variable "MALLOCTYPE=3.1". The shape program might run in an infinite loop otherwise. NeXT machines running Mach 3.0 have problems with file locking (fcntl). For this reason, you should not delete the -DATFS_OWN_LOCKING switch from the CFLAGS. BSD On pure BSD systems, /bin/sh is not capable to execute scripts containing shell functions. To use these scripts you have to install another shell (e.g. BASH). Then change the first line of the script from "#!/bin/sh" so that the appropriate shell is called. Currently this applies only to src/vc/vdiff/vdiff. When modifying the Makefile manually, make sure to keep at least one whitespace between equal sign and value in macro definitions. The configuration script expects this. Supported Operating System Platforms ===================================== Our current development platform is Sun4/SunOS 4.1.2. We ported to and tested the toolkit to a certain number of other machines. This is the complete list of supported operating system platforms: AIX (tested on IBM RS6000 with AIX 3.2.0) HP/UX (tested on HP 9000 with HP/UX 9.0) IRIX (tested on Silicon Graphics with IRIX 4.0.5) mach (tested on NextStation with Mach 3.0) SunOS 4 (tested on SUN 4 with SunOS 4.1.3) Solaris 2 (tested on SUN 10 with SunOS 5.1) [*],[**] System V Release 4 (tested on a '386 system with ESIX) [**] Ultrix (tested on DECstation 5000 with Ultrix 4.2) [*] The Solaris port was done with gcc. The Sun C-language package was not yet available. [**] The Solaris 2 and System V Release 4 ports are identical. For installing the toolkit on machines with other operating systems see the section about porting to other system platforms below. Installation Locations ======================= ShapeTools is a pretty big package, consisting if executable commands, manual pages and a bunch of different libraries. We recommend the following installation tree: .../bin commands .../man/man{1,3,5,7} manuals .../include include files (optional) .../lib C-libraries (optional) .../lib/shape shape libraries .../lib/emacs/lisp emacs lisp code (optional) If you agree with this setup, you just have to set the installation base path (...) during the ShapeTools configuration phase. If not, you may set the path for each group individually. Needed Disk Space ================== The following table shows, how much disk space you will approximately need when compiling and installing ShapeTools. The values are determined on a SparcStation 2 and may be different on your machine. Distribution 1.0 Mb (compressed) 2.4 Mb (unpacked) Compilation 5.9 Mb (stripped) 12.4 Mb (with debug info) Installation - base system 2.2 Mb (stripped) 5.5 Mb (with debug info) - libraries 0.6 Mb ( " ) 1.9 Mb ( " ) - emacs stuff 0.1 Mb ( " ) 0.1 Mb ( " ) Porting ShapeTools to other Operating System Platforms ======================================================= When implementing the toolkit, we tried to isolate operating system specific code in two files named "config.c" and "config.h". You find them in 'src/atfs/config.[ch]'. Porting the toolkit to another (UNIX/POSIX) platform should begin with the examination of these files. Try to avoid changes to any source file other than config.[ch] as far as possible. For compiling, configure the top Makefile using 'make config' and choose the default system (sunos_4). After that, edit the Makefile and change the '-DSUN_4' switch in the 'CFLAGS' definition to '-D'. The Makefiles provided with the distribution of ShapeTools are not really suitable for development, since they don't contain include file dependencies. Dependencies are held in separate files, named 'DEPENDENCIES'. Our development environment is based on ShapeTools, where the dependencies files are included in the Shapefiles. For Recompiling ShapeTools (or parts of it) after having changed config.h, you must first perform "make clean" from the root of the source tree or the appropriate subsystem. If you have successfully ported the Shape Toolkit to another system, please let us know. We would like to receive a diff-file documenting your changes. This should help us to enlarge the set of ShapeTools standard system platforms. If you have any problems, drop a mail to: shape@cs.tu-berlin.de shapetools-1.4pl6.orig/SUPPORT100444 2013 145 1732 5517557067 14263 0ustar dokoswt Some words about the status of shapeTools-1.4pl6. This distribution (1.4) will be the last major release of ShapeTools to be distributed freely. Our time at the Technische Universitaet Berlin is over by end of the year ('93) and no further funding is in sight. Nevertheless, support for ShapeTools will go on. We founded a company with the goal to provide consultancy, training, and hotline service for ShapeTools users and for Software Configuration/Quality Management in general.Our market for consultancy and training will primarily be Germany. An electronic mail based hotline service and an update service for ShapeTools-1.4 will be available world-wide. We will start with that in Spring '94. Be prepared to pay money for these services then. We will work out a flyer describing our services and prices. You can receive this from lampen & mahler, software engineering Postfach 100509 10565 Berlin, Germany Tel./FAX: +49-30-2189199 Have fun, Andy Lampen and Axel Mahler shapetools-1.4pl6.orig/shape_conf.sh100555 2013 145 40603 5574604217 15641 0ustar dokoswt#!/bin/sh # # # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # $Header: shape_conf.sh[4.0] Mon Jun 6 13:29:43 1994 andy@cs.tu-berlin.de frozen $ # base=$1 trap "if [ ! -f Makefile ]; then mv $savename Makefile; fi; rm -f Makefile.new; exit 1" 1 2 13 15 # test if echo command interprets -n option xxx=`echo -n` if [ -z "$xxx" ] then echolead=-n echotrail= else echolead= echotrail="""\c""" fi echo echo "Configure the shapeTools-1.4pl6 build/installation procedure ..." # base path (BASE) if [ -z "$base" ] # if path is not given as argument then base=`pwd` # check if the current directory is the ShapeTools distribution root directory if [ ! -f shape_conf.sh ] then echo "Where did you place the shapeTools-1.4pl6 distribution (root directory) ?" echo $echolead "[Default: $base] > " $echotrail read input if [ -n "$input" ] then base=$input fi fi fi grep ShapeTools $base/Makefile > /dev/null 2>&1 retval=$? while [ $retval -ne 0 ] do echo "This seems not to be the right directory." echo "Where did you place the shapeTools-1.4pl6 distribution (root directory) ?" echo $echolead "[Default: $base] > " $echotrail read input base=$input grep ShapeTools $base/Makefile > /dev/null 2>&1 retval=$? done # Operating System type (HOSTSYSTEM) hostsystem=`grep HOSTSYSTEM $base/Makefile | head -1 | \ sed -e 's/HOSTSYSTEM//' -e 's/[= ]//g' -e 's/s_//'` echo echo "Please enter the operating system type. Supported platforms are:" echo " aix -- (IBM/AIX) hpux -- (HP/UX)" echo " irix -- (SGI/IRIX) mach -- (NeXT/Mach)" echo " sunos_4 -- (SunOS 4.x.x) svr_4 -- (SysV R4, Solaris 2)" echo " ultrix -- (DEC/Ultrix) linux -- (Linux 0.99pl14+)" echo " for others see the README file." echo $echolead "[Default: $hostsystem] > " $echotrail read input if [ -n "$input" ] then hostsystem=s_$input else hostsystem=s_$hostsystem fi # machine architecture (HOSTTYPE) hosttype=`(aa=\`arch\`; echo $aa) 2> /dev/null` # Compiler and compile flags (CC, MAKECFLAGS, MAKELDFLAGS) cc=`grep CC $base/Makefile | head -1 | sed -e 's/CC//' -e 's/[= ]//g' -e 's/=//'` makecflags=`grep MAKECFLAGS $base/Makefile | head -1 | sed -e 's/MAKECFLAGS//' -e 's/[ ]*=[ ]*//'` makeldflags=`grep MAKELDFLAGS $base/Makefile | head -1 | sed -e 's/MAKELDFLAGS//' -e 's/[ ]*=[ ]*//'` case $hostsystem in s_aix) makecflags="$makecflags -D_POSIX_SOURCE" ;; s_hpux) makecflags="$makecflags -Aa -D_HPUX_SOURCE" ;; s_mach) makecflags="$makecflags -DATFS_OWN_LOCKING" ;; esac echo echo "Do you want to change any of the following macro definitions ?" echo "(Check the 'Important Hints' section in the INSTALL file for details)" echo " CC = $cc" echo " CFLAGS = $makecflags" echo " LDFLAGS = $makeldflags" echo $echolead "[Default: no] > " $echotrail read input if [ "$input" = "yes" -o "$input" = "y" ] then echo echo $echolead "CC = [Default: $cc] " $echotrail read input if [ -n "$input" ] then cc=$input fi echo $echolead "CFLAGS = [Default: $makecflags] " $echotrail read input if [ -n "$input" ] then makecflags=$input fi echo $echolead "LDFLAGS = [Default: $makeldflags] " $echotrail read input if [ -n "$input" ] then makeldflags=$input fi fi case $hostsystem in s_aix) syslibs="-lPW" ;; s_hpux) syslibs="-lPW" ;; s_irix) syslibs="-lsun" ;; s_svr_4) syslibs="-lnsl -lgen" ;; esac # Determine subsystems to be included (SUBSYTEMS) subsystems=`grep SUBSYSTEMS $base/Makefile | head -1 | \ sed -e 's/SUBSYSTEMS//' -e 's/=//'` subsystems=`echo $subsystems | sed -e 's.src/interface..' \ -e 's.src/patches..' -e 's.tutorial..'` doemacslisp=`grep DOEMACSLISP $base/Makefile | head -1 | \ sed -e 's/DOEMACSLISP//' -e 's/[\= ]//g'` echo echo "Do you use 'GNU-emacs' on your machine ? Do you want the" echo "ShapeTools emacs lisp code to be compiled and installed too ?" echo $echolead "[Default: $doemacslisp] > " $echotrail read input if [ "$input" = "no" -o "$input" = "n" ] then doemacslisp=no fi if [ "$input" = "yes" -o "$input" = "y" ] then doemacslisp=yes fi if [ "$doemacslisp" = "yes" ] then subsystems="$subsystems src/interface" fi # Determine whether libs and include files shall be installed. dolibraries=`grep DOLIBRARIES $base/Makefile | head -1 | \ sed -e 's/DOLIBRARIES//' -e 's/[\= ]//g'` echo echo "Do you want the ShapeTools internal C-libraries and header files" echo "to be installed ? You will need these when applying the patches" echo "for 'gdb' and 'GNU-grep'" echo $echolead "[Default: $dolibraries] > " $echotrail read input if [ "$input" = "no" -o "$input" = "n" ] then dolibraries=no fi if [ "$input" = "yes" -o "$input" = "y" ] then dolibraries=yes fi # Installation base (INSTALLBASE) installbase=`grep INSTALLBASE $base/Makefile | head -1 | \ sed -e 's/INSTALLBASE//' -e 's/[\= ]//g'` echo echo "Where shall shapeTools-1.4pl6 be installed ?" echo "Please specify the installation base directory." echo $echolead "[Default: $installbase] > " $echotrail read input if [ -n "$input" ] then if [ "$input" = "." ] then input=$base fi installbase=$input fi # Installation paths (INSTALL*PATH) installbinpath=`grep INSTALLBINPATH $base/Makefile | head -1 | \ sed -e 's/INSTALLBINPATH//' -e 's/[\= ]//g' -e s,\$\(INSTALLBASE\),$installbase,` installincpath=`grep INSTALLINCPATH $base/Makefile | head -1 | \ sed -e 's/INSTALLINCPATH//' -e 's/[\= ]//g' -e s,\$\(INSTALLBASE\),$installbase,` installlibpath=`grep INSTALLLIBPATH $base/Makefile | head -1 | \ sed -e 's/INSTALLLIBPATH//' -e 's/[\= ]//g' -e s,\$\(INSTALLBASE\),$installbase,` installshapelibpath=`grep INSTALLSHAPELIBPATH $base/Makefile | head -1 | \ sed -e 's/INSTALLSHAPELIBPATH//' -e 's/[\= ]//g' -e s,\$\(INSTALLBASE\),$installbase,` installemacslisppath=`grep INSTALLEMACSLISPPATH $base/Makefile | head -1 | \ sed -e 's/INSTALLEMACSLISPPATH//' -e 's/[\= ]//g' -e s,\$\(INSTALLBASE\),$installbase,` installmanpath=`grep INSTALLMANPATH $base/Makefile | head -1 | \ sed -e 's/INSTALLMANPATH//' -e 's/[\= ]//g' -e s,\$\(INSTALLBASE\),$installbase,` echo echo "Install" if [ -d $installbinpath ] then echo "...executables in $installbinpath" else echo "...executables in $installbinpath (does not exist)" bindirmissing=true fi if [ "$dolibraries" = "yes" ] then if [ -d $installincpath ] then echo "...header files in $installincpath" else echo "...header files in $installincpath (does not exist)" incdirmissing=true fi if [ -d $installlibpath ] then echo "...C-libraries in $installlibpath" else echo "...C-libraries in $installlibpath (does not exist)" libdirmissing=true fi fi if [ -d $installshapelibpath ] then echo "...shape libraries in $installshapelibpath" else echo "...shape libraries in $installshapelibpath (does not exist)" shapelibdirmissing=true fi if [ "$doemacslisp" = "yes" ] then if [ -d $installemacslisppath ] then echo "...emacs lisp code in $installemacslisppath" else echo "...emacs lisp code in $installemacslisppath (does not exist)" emacslispdirmissing=true fi fi if [ ! -d "$installmanpath/man1" ] then man1dirmissing=true fi if [ ! -d "$installmanpath/man7" ] then man7dirmissing=true fi if [ "$dolibraries" = "yes" ] then if [ ! -d "$installmanpath/man3" ] then man3dirmissing=true fi if [ ! -d "$installmanpath/man5" ] then man5dirmissing=true fi if [ "$man1dirmissing" = "true" ] || [ "$man3dirmissing" = "true" ] \ || [ "$man5dirmissing" = "true" ] || [ "$man7dirmissing" = "true" ] then echo "...manuals in $installmanpath/man{1,3,5,7} (at least one directory does not exist)" else echo "...manuals in $installmanpath/man{1,3,5,7}" fi else if [ "$man1dirmissing" = "true" ] || [ "$man7dirmissing" = "true" ] then echo "...manuals in $installmanpath/man{1,7} (at least one directory does not exist)" else echo "...manuals in $installmanpath/man{1,7}" fi fi echo $echolead "Is this correct ? [Default: yes] > " $echotrail read input if [ "$input" = "no" -o "$input" = "n" ] then echo echo "Install executables in..." echo $echolead "[Default: $installbinpath] > " $echotrail read input if [ -n "$input" ] then installbinpath=$input specialbinpath=true fi if [ "$dolibraries" = "yes" ] then echo echo "Install header files in..." echo $echolead "[Default: $installincpath] > " $echotrail read input if [ -n "$input" ] then installincpath=$input specialincpath=true fi echo echo "Install C-libraries in..." echo $echolead "[Default: $installlibpath] > " $echotrail read input if [ -n "$input" ] then installlibpath=$input speciallibpath=true fi fi echo echo "Install shape libraries in..." echo $echolead "[Default: $installshapelibpath] > " $echotrail read input if [ -n "$input" ] then installshapelibpath=$input specialshapelibpath=true fi if [ "$doemacslisp" = "yes" ] then echo echo "Install emacs lisp files in..." echo $echolead "[Default: $installemacslisppath] > " $echotrail read input if [ -n "$input" ] then installemacslisppath=$input specialemacslisppath=true fi fi echo if [ "$dolibraries" = "yes" ] then echo "Install manuals in... (You need man{1,3,5,7} subdirectories there)" else echo "Install manuals in... (You need man{1,7} subdirectories there)" fi echo $echolead "[Default: $installmanpath] > " $echotrail read input if [ -n "$input" ] then installmanpath=$input specialmanpath=true fi fi # Create installation directories if necessary echo if [ "$bindirmissing" = "true" ] || [ "$specialbinpath" = "true" ] && [ ! -d $installbinpath ] then echo $echolead "'$installbinpath' does not exist. Create ? [Default: y] > " $echotrail read input if [ "$input" != "no" -a "$input" != "n" ] then sh src/rms/mkpdir $installbinpath fi fi if [ "$incdirmissing" = "true" ] || [ "$specialincpath" = "true" ] && [ ! -d $installincpath ] then echo $echolead "'$installincpath' does not exist. Create ? [Default: y] > " $echotrail read input if [ "$input" != "no" -a "$input" != "n" ] then sh src/rms/mkpdir $installincpath fi fi if [ "$libdirmissing" = "true" ] || [ "$speciallibpath" = "true" ] && [ ! -d $installlibpath ] then echo $echolead "'$installlibpath' does not exist. Create ? [Default: y] > " $echotrail read input if [ "$input" != "no" -a "$input" != "n" ] then sh src/rms/mkpdir $installlibpath fi fi if [ "$shapelibdirmissing" = "true" ] || [ "$specialshapelibpath" = "true" ] && [ ! -d $installshapelibpath ] then echo $echolead "'$installshapelibpath' does not exist. Create ? [Default: y] > " $echotrail read input if [ "$input" != "no" -a "$input" != "n" ] then sh src/rms/mkpdir $installshapelibpath fi fi if [ "$emacslispdirmissing" = "true" ] || [ "$specialemacslisppath" = "true" ] && [ ! -d $installemacslisppath ] then echo $echolead "'$installemacslisppath' does not exist. Create ? [Default: y] > " $echotrail read input if [ "$input" != "no" -a "$input" != "n" ] then sh src/rms/mkpdir $installemacslisppath fi fi if [ "$man1dirmissing" = "true" ] || [ "$specialmanpath" = "true" ] && [ ! -d $installmanpath/man1 ] then echo $echolead "'$installmanpath/man1' does not exist. Create ? [Default: y] > " $echotrail read input if [ "$input" != "no" -a "$input" != "n" ] then sh src/rms/mkpdir $installmanpath/man1 fi fi if [ "$man3dirmissing" = "true" ] || [ "$specialmanpath" = "true" ] && [ ! -d $installmanpath/man3 ] then echo $echolead "'$installmanpath/man3' does not exist. Create ? [Default: y] > " $echotrail read input if [ "$input" != "no" -a "$input" != "n" ] then sh src/rms/mkpdir $installmanpath/man3 fi fi if [ "$man5dirmissing" = "true" ] || [ "$specialmanpath" = "true" ] && [ ! -d $installmanpath/man5 ] then echo $echolead "'$installmanpath/man5' does not exist. Create ? [Default: y] > " $echotrail read input if [ "$input" != "no" -a "$input" != "n" ] then sh src/rms/mkpdir $installmanpath/man5 fi fi if [ "$man7dirmissing" = "true" ] || [ "$specialmanpath" = "true" ] && [ ! -d $installmanpath/man7 ] then echo $echolead "'$installmanpath/man7' does not exist. Create ? [Default: y] > " $echotrail read input if [ "$input" != "no" -a "$input" != "n" ] then sh src/rms/mkpdir $installmanpath/man7 fi fi awk "{ if ((\$1 == \"BASE\" && \$2 == \"=\") || \$1 == \"BASE=\") print \"BASE = $base\" else if ((\$1 == \"HOSTSYSTEM\" && \$2 == \"=\") || \$1 == \"HOSTSYSTEM=\") print \"HOSTSYSTEM = $hostsystem\" else if ((\$1 == \"HOSTTYPE\" && \$2 == \"=\") || \$1 == \"HOSTTYPE=\") print \"HOSTTYPE = $hosttype\" else if ((\$1 == \"SYSLIBS\" && \$2 == \"=\") || \$1 == \"SYSLIBS=\") print \"SYSLIBS = $syslibs\" else if ((\$1 == \"SUBSYSTEMS\" && \$2 == \"=\") || \$1 == \"SUBSYSTEMS=\") print \"SUBSYSTEMS = $subsystems\" else if ((\$1 == \"CC\" && \$2 == \"=\") || \$1 == \"CC=\") print \"CC = $cc\" else if ((\$1 == \"MAKECFLAGS\" && \$2 == \"=\") || \$1 == \"MAKECFLAGS=\") print \"MAKECFLAGS = $makecflags\" else if ((\$1 == \"MAKELDFLAGS\" && \$2 == \"=\") || \$1 == \"MAKELDFLAGS=\") print \"MAKELDFLAGS = $makeldflags\" else if ((\$1 == \"INSTALLBASE\" && \$2 == \"=\") || \$1 == \"INSTALLBASE=\") print \"INSTALLBASE = $installbase\" else if ((\$1 == \"DOLIBRARIES\" && \$2 == \"=\") || \$1 == \"DOLIBRARIES=\") print \"DOLIBRARIES = $dolibraries\" else if ((\$1 == \"DOEMACSLISP\" && \$2 == \"=\") || \$1 == \"DOEMACSLISP=\") print \"DOEMACSLISP = $doemacslisp\" else print }" Makefile > Makefile.new if [ "$specialbinpath" = "true" ] then awk "{ if ((\$1 == \"INSTALLBINPATH\" && \$2 == \"=\") || \$1 == \"INSTALLBINPATH=\") print \"INSTALLBINPATH = $installbinpath\" else print }" Makefile.new > Makefile.tmp mv Makefile.tmp Makefile.new fi if [ "$specialincpath" = "true" ] then awk "{ if ((\$1 == \"INSTALLINCPATH\" && \$2 == \"=\") || \$1 == \"INSTALLINCPATH=\") print \"INSTALLINCPATH = $installincpath\" else print }" Makefile.new > Makefile.tmp mv Makefile.tmp Makefile.new fi if [ "$speciallibpath" = "true" ] then awk "{ if ((\$1 == \"INSTALLLIBPATH\" && \$2 == \"=\") || \$1 == \"INSTALLLIBPATH=\") print \"INSTALLLIBPATH = $installlibpath\" else print }" Makefile.new > Makefile.tmp mv Makefile.tmp Makefile.new fi if [ "$specialshapelibpath" = "true" ] then awk "{ if ((\$1 == \"INSTALLSHAPELIBPATH\" && \$2 == \"=\") || \$1 == \"INSTALLSHAPELIBPATH=\") print \"INSTALLSHAPELIBPATH = $installshapelibpath\" else print }" Makefile.new > Makefile.tmp mv Makefile.tmp Makefile.new fi if [ "$specialemacslisppath" = "true" ] then awk "{ if ((\$1 == \"INSTALLEMACSLISPPATH\" && \$2 == \"=\") || \$1 == \"INSTALLEMACSLISPPATH=\") print \"INSTALLEMACSLISPPATH = $installemacslisppath\" else print }" Makefile.new > Makefile.tmp mv Makefile.tmp Makefile.new fi if [ "$specialmanpath" = "true" ] then awk "{ if ((\$1 == \"INSTALLMANPATH\" && \$2 == \"=\") || \$1 == \"INSTALLMANPATH=\") print \"INSTALLMANPATH = $installmanpath\" else print }" Makefile.new > Makefile.tmp mv Makefile.tmp Makefile.new fi savename=Makefile.orig echo echo "Saving original Makefile to $savename." mv Makefile $savename mv Makefile.new Makefile touch .configured exit 0 shapetools-1.4pl6.orig/Questionnaire100444 2013 145 20304 5626403553 15740 0ustar dokoswtThis file contains a questionnaire, that shall help us getting an overview of the ShapeTools usership. If you are (or have been) a ShapeTools user, please do us the favor and fill out the questionnaire and return it to "shape@cs.tu-berlin.de". The results will hopefully help us raise (desperately needed) financial support for continuing our work on ShapeTools. If you considered using ShapeTools but decided not to do so, please also fill out the questionnaire. Just skip the questions that don't apply. We appreciate your opinion and critique and want to learn what people like or dislike about ShapeTools. We tried to keep the questionnaire as short as possible (20 questions). It will take you approximately 15 Minutes to answer all the questions. If you cannot spare so much time, please try to answer at least questions 1 thru 8, which should not take longer than 3 minutes. Ok, now it's time to switch to overwrite-mode and type your "x"es. Feel free to enter comments and additional answers to the questions. 1) What is your current status concerning ShapeTools ? - evaluating ShapeTools ___ - using ShapeTools ___ - decided not to use it ___ - abandoned usage ___ 2) How long did you use ShapeTools for your regular work ? - just began using it ___ - less than six months ___ - less than one year ___ - more than one year ___ 3) How big is the project you are using ShapeTools for ? [If you are using ShapeTools in multiple projects, please answer questions 3 thru 6 for your major/biggest project] - it's a one man/woman project ___ - 2 - 5 people ___ - 6 - 20 people ___ - 21 - 100 people ___ - more than 100 people ___ 4) Do other people in the project use ShapeTools too ? - yes, all of them ___ - yes, most of them ___ - yes, some of them ___ - nope, I'm the only one ___ 5) How big is your company/organization ? - up to 10 employees ___ - 10 to 100 employees ___ - 100 to 500 employees ___ - more than 500 ___ 6) Are there other projects in your organization where ShapeTools is used and you are not involved in ? - yes, one other ___ - yes, some ___ - we use ShapeTools for all projects ___ - no ___ 7) How would you describe your position within your company/organization ? - technical staff ___ - senior developer/project leader ___ - management ___ - _____________ 8) May we add your company/project to our list of reference users ? - yes ___ - no ___ 9) What are the programming languages used in your project ? - C ___ - C++ ___ - __________ - __________ 10) What kind of machines/operating systems do you run ShapeTools on ? - Sun/SunOS 4.x.x ___ - Sun/Solaris 2 ___ - IBM/AIX ___ - HP/HP-UX ___ - SGI/IRIX ___ - 80x86/Linux ___ - __________ - __________ 11) What high level network protocols do you use within the project ? - NFS - Andrew File System - __________ - __________ 12) How would you rate ShapeTools in a scale of 1 to 5 ? good bad 1 2 3 4 5 - installation ___ ___ ___ ___ ___ - learning effort ___ ___ ___ ___ ___ - tutorial ___ ___ ___ ___ ___ - documentation ___ ___ ___ ___ ___ - performance (version control) ___ ___ ___ ___ ___ - performance (shape) ___ ___ ___ ___ ___ - reliability ___ ___ ___ ___ ___ - release mgmt. system ___ ___ ___ ___ ___ - attributed files ___ ___ ___ ___ ___ - integration with UNIX envmnt. ___ ___ ___ ___ ___ - overall functionality ___ ___ ___ ___ ___ 13) Which parts of ShapeTools do you use regularly and which other parts did you play around with ? use played never regularly around seen - version control commands ___ ___ ___ - shape program ___ ___ ___ - variant mechanism ___ ___ ___ - different version binding rules ___ ___ ___ - release management system ___ ___ ___ - AtFS programming interface ___ ___ ___ - Emacs interface ___ ___ ___ - vgdb, vgrep ___ ___ ___ 14) Which new features would be important for you ? very would be don't important useful need - graphical user interface ___ ___ ___ - WAN support (distrib. development) ___ ___ ___ - cross platform interoperability ___ ___ ___ - change request tracking ___ ___ ___ - test support ___ ___ ___ - copy-modify-merge mechanism ___ ___ ___ - handling of file groups ___ ___ ___ - full GNU-make compatibility ___ ___ ___ - integration with imake ___ ___ ___ - parallel builds ___ ___ ___ - pre-/post action triggers ___ ___ ___ - ___________________________ ___ ___ ___ - ___________________________ ___ ___ ___ 15) Which new system platforms would you like to be supported ? very would be don't important useful need - DOS ___ ___ ___ - Windows ___ ___ ___ - Windows/NT ___ ___ ___ - OS/2 ___ ___ ___ - NeXTstep ___ ___ ___ - VMS ___ ___ ___ - Macintosh ___ ___ ___ - _________ ___ ___ ___ - _________ ___ ___ ___ 16) What do you like most about ShapeTools ? - _______________________ - _______________________ 17) What do you dislike most about ShapeTools ? - _______________________ - _______________________ 18) What other version control or software configuration management systems did you evaluate beside ShapeTools ? - CVS ___ - SCCS ___ - RCS ___ - _________ - _________ 19) What were the reasons for/against ShapeTools ? - functionality ___ - price ___ - _________________ - _________________ - did not evaluate alternatives ___ - don't know, someone else decided that ___ 20) Where did you learn about ShapeTools ? - Network News ___ - O'Reillys "Managing projects with make" ___ - Prime Time Freeware ___ - A colleague told me ___ - Conference (__________) ___ - __________________ You got it ! Now please return the questionnaire to "shape@cs.tu-berlin.de". Thanks very much ! Andy Lampen, Axel Mahler shapetools-1.4pl6.orig/Release100444 2013 145 106 5420314431 14414 0ustar dokoswtshapeTools-1.4pl6 (Tue Aug 23 18:02:33 1994 by shape@cs.tu-berlin.de) shapetools-1.4pl6.orig/Shapefile100444 2013 145 5464 5405344245 15001 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Shapefile for the shape toolkit # # $Header: Shapefile[4.0] Wed Jun 9 13:25:33 1993 andy@cs.tu-berlin.de frozen $ # # -------------------------------------------------------------------- # version and variant selection # -------------------------------------------------------------------- # The default version selection rule. # See $(SHAPELIBPATH)/stdrules for further options. VERSIONS=most_recent BINDDEFAULT=$(VERSIONS) BINDINSTALL=recent_release # The default variant settings. # The corresponding definitions are in $(SHAPELIBPATH)/stdvar COMPILER=pcc QUALITY=debug # The base directory of the release area # # for global releases of the whole system TOTALRELEASEBASE = /home/stone/shape/release # for collecting the most recent releases of all subsystems PARTIALRELEASEBASE = /home/stone/shape/partial.release # Pathnames for the components within the release areas. RELEASESRCPATH = $(NODEPATH) RELEASEMANPATH = man # Variant activation for normal builds and installation builds _all: all $(TARGET): $(BINDDEFAULT) +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) install: +$(HOSTSYSTEM) +$(COMPILER) +$(QUALITY) # -------------------------------------------------------------------- # includes # -------------------------------------------------------------------- include Makefile SHAPELIBPATH = $(LOCALLIBPATH)/shape include $(SHAPELIBPATH)/stdtargets include $(SHAPELIBPATH)/stdrules include $(SHAPELIBPATH)/stdvar include $(SHAPELIBPATH)/stdconf # -------------------------------------------------------------------- # miscellaneous stuff # -------------------------------------------------------------------- # # List of objects to be stored in the derived object cache. .BPOOL: $(OBJECTS) # .NOBPOOL: # deactivates the derived object cache. # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- MAKE=shape #% VARIANT-SECTION all: MAINTARGET=all ALLTARGETS=subsystems targets install: MAINTARGET=install ALLTARGETS=subsystems installtargets BINDDEFAULT=$(BINDINSTALL) clean: MAINTARGET=clean ALLTARGETS=subsystems doclean #% END-VARIANT-SECTION shapetools-1.4pl6.orig/Makefile100444 2013 145 32307 5626413424 14633 0ustar dokoswt# # Copyright (C) 1993,1994 by the author(s). # # This software is published in the hope that it will be useful, but # WITHOUT ANY WARRANTY for any part of this software to work correctly # or as described in the manuals. See the ShapeTools Public License # for details. # # Permission is granted to use, copy, modify, or distribute any part of # this software but only under the conditions described in the ShapeTools # Public License. A copy of this license is supposed to have been given # to you along with ShapeTools in a file named LICENSE. Among other # things, this copyright notice and the Public License must be # preserved on all copies. # # Makefile for the ShapeTools # # $Header: Makefile[5.1] Tue Aug 23 17:34:52 1994 andy@cs.tu-berlin.de frozen $ # # The base directory of the shape source tree. BASE = /home/stone/shape/development # The operating system. Supported platforms are: # s_aix -- AIX (tested on IBM RS6000 with AIX 3.2.0) # s_hpux -- HP/UX (tested on HP 9000 with HP/UX 9.0) # s_irix -- IRIX (tested on Silicon Graphics with IRIX 4.0.5) # s_mach -- mach (tested on NextStation with Mach 3.0) # s_sunos_4 -- SunOS 4 (tested on SUN 4 with SunOS 4.1.3) # s_svr_4 -- Solaris 2 (tested on SUN 10 with SunOS 5.1) # s_svr_4 -- Sys V Rel.4 (tested on a '386 machine with ESIX) # s_ultrix_4 -- Ultrix (tested on DECStation 5000 with Ultrix 4.2) # For installing the toolkit on other operating systems see the # README file in this directory. HOSTSYSTEM = s_sunos_4 # The processor type (may be empty). HOSTTYPE = sun4 # Preprocessor switches. # Set "-DSYSLOG" if you want to have internal diagnostic messages # handled by the syslog package. SWITCHES = # Needed system libraries. # As the shape toolkit uses "re_comp" (regular expressions), # System V machines require an additional library to be linked. # This is usally "SYSLIBS = -lPW". SYSLIBS = # Path of a subsystem relative to the root of the system hierarchy # (e.g. vc/save) NODEPATH = # A short name for the (sub)system (used for building the release ID) NODENAME = shapeTools # The installation base directory. # Make sure, that the subdirectories "bin", "include", and "lib" # exist in installation directory. INSTALLBASE = /usr/local # Locations and modes for the installation of executables, header # files, libraries and manuals. INSTALLBINPATH = $(INSTALLBASE)/bin INSTALLBINMODE = 755 INSTALLINCPATH = $(INSTALLBASE)/include INSTALLINCMODE = 444 INSTALLLIBPATH = $(INSTALLBASE)/lib INSTALLSHAPELIBPATH = $(INSTALLBASE)/lib/shape INSTALLEMACSLISPPATH = $(INSTALLBASE)/lib/emacs/lisp INSTALLLIBMODE = 644 INSTALLMANPATH = $(INSTALLBASE)/man INSTALLMANMODE = 444 # Directories, where local libraries and header files are to be # installed for project wide use. LOCALLIBPATH = $(BASE)/lib LOCALINCLUDEPATH = $(BASE)/include # -------------------------------------------------------------------- # the system's components # -------------------------------------------------------------------- # # The system (program, library, etc.) to be built. If you want to # manage multiple programs, you should introduce multiple targets # (like TARGET1 TARGET2 or any better names). In this case you # have to adjust the system building actions accordingly. TARGET = # The release number generator. The version number of this file will # be used as release identifier for the whole system. VERSIONFILE = Release # source # The names of the subdirectories containing subsystems which are also # to be built. SUBSYSTEMS = src/atfs src/sttk src/atfstk src/shape src/vc src/rms src/interface src/patches #SUBSYSTEMS = src/atfs src/sttk src/atfstk src/shape src/vc src/interface src/rms src/patches tutorial # The regular source and header files. SOURCES = CHANGES-1.4 README LICENSE INSTALL SUPPORT shape_conf.sh Questionnaire HEADERS = # All source components of the system (should not be changed) COMPONENTS = $(SOURCES) $(HEADERS) $(MANUALS) Shapefile Makefile Dependencies # -------------------------------------------------------------------- # tools, flags, libraries etc. # -------------------------------------------------------------------- SHELL=/bin/sh INCLUDES = -I$(LOCALINCLUDEPATH) MAKECFLAGS = -O -DATFS_OWN_LOCKING MAKELDFLAGS = -s CC = cc CFLAGS = $(INCLUDES) $(MAKECFLAGS) -D$(HOSTSYSTEM) $(SWITCHES) LDFLAGS = $(MAKELDFLAGS) RANLIB = ranlib CONFIGSCRIPT = ./shape_conf.sh # System libraries, local libraries and lint libraries. LOCALLIBS = LINTLIBS = # -------------------------------------------------------------------- # the targets # -------------------------------------------------------------------- # The default action (do not change) all: +all $(ALLTARGETS) config: configure configure: @$(CONFIGSCRIPT) `pwd` # The final system building action. targets: $(TARGET) DOLIBRARIES = yes DOEMACSLISP = yes installtargets: installmanuals installmanuals: $(MANUALS) @-echo "installing manuals in $(INSTALLMANPATH)"; \ if [ "$(INSTALLMANPATH)" = "$(BASE)/man" ]; \ then \ exit 0; \ fi; \ _manuals=`ls man/man1`; \ for i in $$_manuals; \ do \ if [ -f $(INSTALLMANPATH)/man1/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man1/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man1/$$i; \ fi; \ cp man/man1/$$i $(INSTALLMANPATH)/man1/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man1/$$i; \ done; \ if [ "$(DOLIBRARIES)" = yes ]; \ then \ _manuals=`ls man/man3`; \ for i in $$_manuals; \ do \ if [ -f $(INSTALLMANPATH)/man3/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man3/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man3/$$i; \ fi; \ cp man/man3/$$i $(INSTALLMANPATH)/man3/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man3/$$i; \ done; \ _manuals=`ls man/man5`; \ for i in $$_manuals; \ do \ if [ -f $(INSTALLMANPATH)/man5/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man5/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man5/$$i; \ fi; \ cp man/man5/$$i $(INSTALLMANPATH)/man5/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man5/$$i; \ done; \ fi; \ _manuals=`ls man/man7`; \ for i in $$_manuals; \ do \ if [ -f $(INSTALLMANPATH)/man7/$$i ] && \ [ ! -w $(INSTALLMANPATH)/man7/$$i ]; \ then \ chmod u+w $(INSTALLMANPATH)/man7/$$i; \ fi; \ cp man/man7/$$i $(INSTALLMANPATH)/man7/$$i; \ chmod $(INSTALLMANMODE) $(INSTALLMANPATH)/man7/$$i; \ done # The cleanup action. Removes all automatically rederivable files. doclean: rm -f $(TARGET) $(ALIASES) $(OBJECTS) \ lib/libAtFS.a.old lib/libAtFS.a lib/libsttk.old.a \ lib/libsttk.a lib/libAtFStk.old.a lib/libAtFStk.a \ include/atfs.h include/afsys.h include/config.h \ include/sttk.h include/atfstk.h # Recursive builds. Performed *before* building $(TARGET) subsystems: @-_subsystems="$(SUBSYSTEMS)"; \ for i in $$_subsystems; \ do \ maketarget=$(MAINTARGET); \ installlibpath=$(INSTALLLIBPATH); \ installincpath=$(INSTALLINCPATH); \ libpath=$(LOCALLIBPATH); \ includepath=$(LOCALINCLUDEPATH); \ if [ $$i = src/atfs -o $$i = src/sttk -o $$i = src/atfstk ]; \ then \ if [ "$(MAINTARGET)" = all ]; \ then \ maketarget=localinstall; \ if [ "$(INSTALLLIBPATH)" = "$(LOCALLIBPATH)" ]; \ then \ installlibpath=/tmp; \ fi; \ if [ "$(INSTALLINCPATH)" = "$(LOCALINCLUDEPATH)" ]; \ then \ installincpath=/tmp; \ fi; \ elif [ "$(MAINTARGET)" = install ]; \ then \ if [ "$(DOLIBRARIES)" = no ]; \ then \ maketarget="noinstall localinstall"; \ else \ maketarget="install localinstall"; \ fi; \ if [ "$(INSTALLLIBPATH)" = "$(LOCALLIBPATH)" ]; \ then \ libpath=/tmp; \ maketarget=`echo $$maketarget | sed -e s/localinstall//`; \ fi; \ if [ "$(INSTALLINCPATH)" = "$(LOCALINCLUDEPATH)" ]; \ then \ includepath=/tmp; \ maketarget=`echo $$maketarget | sed -e s/localinstall//`; \ fi; \ else \ if [ "$(INSTALLLIBPATH)" = "$(LOCALLIBPATH)" ]; \ then \ installlibpath=/tmp; \ fi; \ if [ "$(INSTALLINCPATH)" = "$(LOCALINCLUDEPATH)" ]; \ then \ installincpath=/tmp; \ fi; \ fi; \ fi; \ echo cd $$i; \ (cd $$i; $(MAKE) \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$$installincpath \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$$installlibpath \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLEMACSLISPPATH=$(INSTALLEMACSLISPPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$$libpath \ LOCALINCLUDEPATH=$$includepath \ MAKE="$(MAKE)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ ALLTARGETS= \ MAINTARGET= \ SHAPELIBPATH=$(SHAPELIBPATH) $$maketarget ); \ done # -------------------------------------------------------------------- # internals (do not modify) # -------------------------------------------------------------------- install: +install $(ALLTARGETS) clean: +clean $(ALLTARGETS) +all: @-if [ ! -f .configured ]; \ then \ echo; echo "Initial build of shapeTools on this machine."; \ ./shape_conf.sh `pwd`; \ echo; echo "Got it ! Now call 'make' again to start system build."; \ exit 0; \ fi; \ if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems targets" MAINTARGET=all \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLEMACSLISPPATH=$(INSTALLEMACSLISPPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) all; \ fi +install: @-if [ ! -f .configured ]; \ then \ echo; echo "Initial build of shapeTools on this machine."; \ ./shape_conf.sh `pwd`; \ echo; echo "Got it ! Now call 'make install' again to start system build and installation."; \ exit 0; \ fi; \ if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems installtargets" \ MAINTARGET=install \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLEMACSLISPPATH=$(INSTALLEMACSLISPPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) install; \ fi +clean: @-if [ -n "$(ALLTARGETS)" ]; \ then : ; \ else \ $(MAKE) ALLTARGETS="subsystems doclean" MAINTARGET=clean \ BASE=$(BASE) \ HOSTSYSTEM=$(HOSTSYSTEM) \ HOSTTYPE=$(HOSTTYPE) \ SWITCHES="$(SWITCHES)" \ INSTALLBASE=$(INSTALLBASE) \ INSTALLBINPATH=$(INSTALLBINPATH) \ INSTALLBINMODE=$(INSTALLBINMODE) \ INSTALLINCPATH=$(INSTALLINCPATH) \ INSTALLINCMODE=$(INSTALLINCMODE) \ INSTALLLIBPATH=$(INSTALLLIBPATH) \ INSTALLSHAPELIBPATH=$(INSTALLSHAPELIBPATH) \ INSTALLEMACSLISPPATH=$(INSTALLEMACSLISPPATH) \ INSTALLLIBMODE=$(INSTALLLIBMODE) \ INSTALLMANPATH=$(INSTALLMANPATH) \ INSTALLMANMODE=$(INSTALLMANMODE) \ LOCALLIBPATH=$(LOCALLIBPATH) \ LOCALINCLUDEPATH=$(LOCALINCLUDEPATH) \ MAKE="$(MAKE)" \ CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LDFLAGS="$(LDFLAGS)" \ RANLIB="$(RANLIB)" \ SYSLIBS="$(SYSLIBS)" \ BINDDEFAULT=$(BINDDEFAULT) \ BINDINSTALL=$(BINDINSTALL) \ COMPILER=$(COMPILER) \ QUALITY=$(QUALITY) \ TOTALRELEASEBASE=$(TOTALRELEASEBASE) \ PARTIALRELEASEBASE=$(PARTIALRELEASEBASE) \ SHAPELIBPATH=$(SHAPELIBPATH) clean; \ fi shapetools-1.4pl6.orig/Dependencies100444 2013 145 22 5405356011 15402 0ustar dokoswt# no dependencies shapetools-1.4pl6.orig/bin/ 40755 2013 145 0 5626416642 13630 5ustar dokoswtshapetools-1.4pl6.orig/lib/ 40755 2013 145 0 5626416643 13627 5ustar dokoswtshapetools-1.4pl6.orig/lib/shape/ 40755 2013 145 0 5626416642 14726 5ustar dokoswtshapetools-1.4pl6.orig/lib/emacs/ 40755 2013 145 0 5626416643 14717 5ustar dokoswtshapetools-1.4pl6.orig/lib/emacs/lisp/ 40755 2013 145 0 5626416643 15666 5ustar dokoswtshapetools-1.4pl6.orig/include/ 40755 2013 145 0 5626416643 14504 5ustar dokoswtshapetools-1.4pl6.orig/vgrep-2.0/ 40755 2013 145 0 5402236620 14464 5ustar dokoswtshapetools-1.4pl6.orig/vgrep-2.0/tests/ 40755 2013 145 0 5402236620 15626 5ustar dokoswtshapetools-1.4pl6.orig/vgrep-2.0/tests/check.sh100644 2013 145 1022 5371016522 17331 0ustar dokoswt#! /bin/sh # Regression test for GNU grep. # Usage: regress.sh [testdir] testdir=${1-tests} failures=0 # The Khadafy test is brought to you by Scott Anderson . . . ./grep -E -f $testdir/khadafy.regexp $testdir/khadafy.lines > khadafy.out if cmp $testdir/khadafy.lines khadafy.out then : else echo Khadafy test failed -- output left on khadafy.out failures=1 fi # . . . and the following by Henry Spencer. ${AWK-awk} -F: -f $testdir/scriptgen.awk $testdir/spencer.tests > tmp.script sh tmp.script && exit $failures exit 1 shapetools-1.4pl6.orig/vgrep-2.0/tests/khadafy.lines100644 2013 145 1330 5246514613 20372 0ustar dokoswt1) Muammar Qaddafi 2) Mo'ammar Gadhafi 3) Muammar Kaddafi 4) Muammar Qadhafi 5) Moammar El Kadhafi 6) Muammar Gadafi 7) Mu'ammar al-Qadafi 8) Moamer El Kazzafi 9) Moamar al-Gaddafi 10) Mu'ammar Al Qathafi 11) Muammar Al Qathafi 12) Mo'ammar el-Gadhafi 13) Moamar El Kadhafi 14) Muammar al-Qadhafi 15) Mu'ammar al-Qadhdhafi 16) Mu'ammar Qadafi 17) Moamar Gaddafi 18) Mu'ammar Qadhdhafi 19) Muammar Khaddafi 20) Muammar al-Khaddafi 21) Mu'amar al-Kadafi 22) Muammar Ghaddafy 23) Muammar Ghadafi 24) Muammar Ghaddafi 25) Muamar Kaddafi 26) Muammar Quathafi 27) Muammar Gheddafi 28) Muamar Al-Kaddafi 29) Moammar Khadafy 30) Moammar Qudhafi 31) Mu'ammar al-Qaddafi 32) Mulazim Awwal Mu'ammar Muhammad Abu Minyar al-Qadhafi shapetools-1.4pl6.orig/vgrep-2.0/tests/khadafy.regexp100644 2013 145 102 5246514613 20526 0ustar dokoswtM[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] shapetools-1.4pl6.orig/vgrep-2.0/tests/scriptgen.awk100644 2013 145 430 5357421242 20407 0ustar dokoswtBEGIN { print "failures=0"; } $0 !~ /^#/ && NF == 3 { print "echo '" $3 "' | ./grep -E -e '" $2 "' > /dev/null 2>&1"; print "if [ $? != " $1 " ]" print "then" printf "\techo Spencer test \\#%d failed\n", ++n print "\tfailures=1" print "fi" } END { print "exit $failures"; } shapetools-1.4pl6.orig/vgrep-2.0/tests/spencer.tests100644 2013 145 3324 5251234047 20453 0ustar dokoswt0:abc:abc 1:abc:xbc 1:abc:axc 1:abc:abx 0:abc:xabcy 0:abc:ababc 0:ab*c:abc 0:ab*bc:abc 0:ab*bc:abbc 0:ab*bc:abbbbc 0:ab+bc:abbc 1:ab+bc:abc 1:ab+bc:abq 0:ab+bc:abbbbc 0:ab?bc:abbc 0:ab?bc:abc 1:ab?bc:abbbbc 0:ab?c:abc 0:^abc$:abc 1:^abc$:abcc 0:^abc:abcc 1:^abc$:aabc 0:abc$:aabc 0:^:abc 0:$:abc 0:a.c:abc 0:a.c:axc 0:a.*c:axyzc 1:a.*c:axyzd 1:a[bc]d:abc 0:a[bc]d:abd 1:a[b-d]e:abd 0:a[b-d]e:ace 0:a[b-d]:aac 0:a[-b]:a- 0:a[b-]:a- 1:a[b-a]:- 2:a[]b:- 2:a[:- 0:a]:a] 0:a[]]b:a]b 0:a[^bc]d:aed 1:a[^bc]d:abd 0:a[^-b]c:adc 1:a[^-b]c:a-c 1:a[^]b]c:a]c 0:a[^]b]c:adc 0:ab|cd:abc 0:ab|cd:abcd 0:()ef:def 0:()*:- 1:*a:- 0:^*:- 0:$*:- 1:(*)b:- 1:$b:b 2:a\:- 0:a\(b:a(b 0:a\(*b:ab 0:a\(*b:a((b 1:a\x:a\x 2:abc):- 2:(abc:- 0:((a)):abc 0:(a)b(c):abc 0:a+b+c:aabbabc 0:a**:- 0:a*?:- 0:(a*)*:- 0:(a*)+:- 0:(a|)*:- 0:(a*|b)*:- 0:(a+|b)*:ab 0:(a+|b)+:ab 0:(a+|b)?:ab 0:[^ab]*:cde 0:(^)*:- 0:(ab|)*:- 2:)(:- 1:abc: 1:abc: 0:a*: 0:([abc])*d:abbbcd 0:([abc])*bcd:abcd 0:a|b|c|d|e:e 0:(a|b|c|d|e)f:ef 0:((a*|b))*:- 0:abcd*efg:abcdefg 0:ab*:xabyabbbz 0:ab*:xayabbbz 0:(ab|cd)e:abcde 0:[abhgefdc]ij:hij 1:^(ab|cd)e:abcde 0:(abc|)ef:abcdef 0:(a|b)c*d:abcd 0:(ab|ab*)bc:abc 0:a([bc]*)c*:abc 0:a([bc]*)(c*d):abcd 0:a([bc]+)(c*d):abcd 0:a([bc]*)(c+d):abcd 0:a[bcd]*dcdcde:adcdcde 1:a[bcd]+dcdcde:adcdcde 0:(ab|a)b*c:abc 0:((a)(b)c)(d):abcd 0:[A-Za-z_][A-Za-z0-9_]*:alpha 0:^a(bc+|b[eh])g|.h$:abh 0:(bc+d$|ef*g.|h?i(j|k)):effgz 0:(bc+d$|ef*g.|h?i(j|k)):ij 1:(bc+d$|ef*g.|h?i(j|k)):effg 1:(bc+d$|ef*g.|h?i(j|k)):bcdd 0:(bc+d$|ef*g.|h?i(j|k)):reffgz 1:((((((((((a)))))))))):- 0:(((((((((a))))))))):a 1:multiple words of text:uh-uh 0:multiple words:multiple words, yeah 0:(.*)c(.*):abcde 1:\((.*),:(.*)\) 1:[k]:ab 0:abcd:abcd 0:a(bc)d:abcd 0:a[-]?c:ac 0:(....).*\1:beriberi shapetools-1.4pl6.orig/vgrep-2.0/AUTHORS100644 2013 145 2320 5261470130 15625 0ustar dokoswtMike Haertel wrote the main program and the dfa and kwset matchers. Arthur David Olson contributed the heuristics for finding fixed substrings at the end of dfa.c. Richard Stallman and Karl Berry wrote the regex backtracking matcher. Henry Spencer wrote the original test suite from which grep's was derived. Scott Anderson invented the Khadafy test. David MacKenzie wrote the automatic configuration software use to produce the configure script. Authors of the replacements for standard library routines are identified in the corresponding source files. The idea of using Boyer-Moore type algorithms to quickly filter out non-matching text before calling the regexp matcher was originally due to James Woods. He also contributed some code to early versions of GNU grep. Finally, I would like to thank Andrew Hume for many fascinating discussions of string searching issues over the years. Hume & Sunday's excellent paper on fast string searching (AT&T Bell Laboratories CSTR #156) describes some of the history of the subject, as well as providing exhaustive performance analysis of various implementation alternatives. The inner loop of GNU grep is similar to Hume & Sunday's recommended "Tuned Boyer Moore" inner loop. shapetools-1.4pl6.orig/vgrep-2.0/ChangeLog100644 2013 145 130 5377611503 16315 0ustar dokoswtSat May 22 22:59:48 1993 Mike Haertel (mike@cs.uoregon.edu) * Version 2.0 released. shapetools-1.4pl6.orig/vgrep-2.0/COPYING100644 2013 145 43076 5375616414 15662 0ustar dokoswt GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. shapetools-1.4pl6.orig/vgrep-2.0/INSTALL100644 2013 145 12460 5261472131 15637 0ustar dokoswtThis is a generic INSTALL file for utilities distributions. If this package does not come with, e.g., installable documentation or data files, please ignore the references to them below. To compile this package: 1. Configure the package for your system. In the directory that this file is in, type `./configure'. If you're using `csh' on an old version of System V, you might need to type `sh configure' instead to prevent `csh' from trying to execute `configure' itself. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation, and creates the Makefile(s) (one in each subdirectory of the source directory). In some packages it creates a C header file containing system-dependent definitions. It also creates a file `config.status' that you can run in the future to recreate the current configuration. Running `configure' takes a minute or two. While it is running, it prints some messages that tell what it is doing. If you don't want to see the messages, run `configure' with its standard output redirected to `/dev/null'; for example, `./configure >/dev/null'. To compile the package in a different directory from the one containing the source code, you must use a version of make that supports the VPATH variable, such as GNU make. `cd' to the directory where you want the object files and executables to go and run `configure' with the option `--srcdir=DIR', where DIR is the directory that contains the source code. Using this option is actually unnecessary if the source code is in the parent directory of the one in which you are compiling; `configure' automatically checks for the source code in `..' if it does not find it in the current directory. By default, `make install' will install the package's files in /usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify an installation prefix other than /usr/local by giving `configure' the option `--prefix=PATH'. Alternately, you can do so by changing the `prefix' variable in the Makefile that `configure' creates (the Makefile in the top-level directory, if the package contains subdirectories). You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec_prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Data files and documentation will still use the regular prefix. Normally, all files are installed using the regular prefix. You can tell `configure' to figure out the configuration for your system, and record it in `config.status', without actually configuring the package (creating `Makefile's and perhaps a configuration header file). To do this, give `configure' the `--no-create' option. Later, you can run `./config.status' to actually configure the package. This option is useful mainly in `Makefile' rules for updating `config.status' and `Makefile'. You can also give `config.status' the `--recheck' option, which makes it re-run `configure' with the same arguments you used before. This is useful if you change `configure'. `configure' ignores any other arguments that you give it. If your system requires unusual options for compilation or linking that `configure' doesn't know about, you can give `configure' initial values for some variables by setting them in the environment. In Bourne-compatible shells, you can do that on the command line like this: CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure The `make' variables that you might want to override with environment variables when running `configure' are: (For these variables, any value given in the environment overrides the value that `configure' would choose:) CC C compiler program. Default is `cc', or `gcc' if `gcc' is in your PATH. INSTALL Program to use to install files. Default is `install' if you have it, `cp' otherwise. (For these variables, any value given in the environment is added to the value that `configure' chooses:) DEFS Configuration options, in the form `-Dfoo -Dbar ...' LIBS Libraries to link with, in the form `-lfoo -lbar ...' If you need to do unusual things to compile the package, we encourage you to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the README so we can include them in the next release. 2. Type `make' to compile the package. If you want, you can override the `make' variables CFLAGS and LDFLAGS like this: make CFLAGS=-O2 LDFLAGS=-s 3. If the package comes with self-tests and you want to run them, type `make check'. If you're not sure whether there are any, try it; if `make' responds with something like make: *** No way to make target `check'. Stop. then the package does not come with self-tests. 4. Type `make install' to install programs, data files, and documentation. 5. You can remove the program binaries and object files from the source directory by typing `make clean'. To also remove the Makefile(s), the header file containing system-dependent definitions (if the package uses one), and `config.status' (all the files that `configure' created), type `make distclean'. The file `configure.in' is used as a template to create `configure' by a program called `autoconf'. You will only need it if you want to regenerate `configure' using a newer version of `autoconf'. shapetools-1.4pl6.orig/vgrep-2.0/INSTALL.VMS100644 2013 145 235 5377611006 16244 0ustar dokoswtVMS users should try running the enclosed command file "make.com". It may be necessary to add #ifdef vms #include #endif at line 72 of grep.c. shapetools-1.4pl6.orig/vgrep-2.0/MANIFEST100644 2013 145 2702 5377611050 15720 0ustar dokoswtAUTHORS List of authors and other contributors. ChangeLog Revision history of this program. COPYING Terms for redistribution. INSTALL Compilation and installation instructions. INSTALL.VMS VMS instructions. MANIFEST This file. Makefile.in Source for the Makefile produced by 'configure'. NEWS History of major changes since the last release. PROJECTS Useful things to do. README Overview. alloca.c Doug Gwyn's C alloca() emulation. configure Configuration script used in installation. configure.in Input to autoconf to produce configure. dfa.c Deterministic regexp matcher. dfa.h Interface to dfa.c. getopt.c Argument parser. getopt.h Declarations for getopt.c. getpagesize.h Portability hack for getpagesize(). grep.c Main program. grep.h Interface to grep.c for searching subroutines. grep.man Manual page (nroff -man). kwset.c Fixed string keyword set matcher. kwset.h Interface to kwset.c. make.com VMS command script to build grep. obstack.c Stack-oriented allocation subroutines. obstack.h Stack-oriented allocation macros. regex.c Backtracking regexp matcher. regex.h Interface to regex.c and syntax flags shared by dfa.c. search.c Interface from grep to all the matchers. tests/check.sh Driver shell script for the tests. tests/khadafy.lines How many ways can you spell Khaddafy? tests/khadafy.regexp Moby regexp matching the all of them. tests/scriptgen.awk Test script generator. tests/spencer.tests Input for scriptgen. shapetools-1.4pl6.orig/vgrep-2.0/Makefile.in100644 2013 145 6530 5371032400 16625 0ustar dokoswt# Makefile for GNU grep # Copyright (C) 1992 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. SHELL = /bin/sh #### Start of system configuration section. #### srcdir=@srcdir@ VPATH=@srcdir@ AWK=@AWK@ INSTALL=@INSTALL@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ INSTALL_DATA=@INSTALL_DATA@ CC=@CC@ LINT=lint # Things you might add to DEFS: # -DSTDC_HEADERS If you have ANSI C headers and libraries. # -DHAVE_UNISTD_H If you have unistd.h. # -DUSG If you have System V/ANSI C string # and memory functions and headers. # -D__CHAR_UNSIGNED__ If type `char' is unsigned. # gcc defines this automatically. DEFS=-DGREP @DEFS@ # Extra libraries. LIBS=@LIBS@ ALLOCA=@ALLOCA@ CFLAGS=-O LDFLAGS=$(CFLAGS) prefix=/usr/local exec_prefix=$(prefix) # Prefix for installed program, normally empty or `g'. binprefix= # Prefix for installed man page, normally empty or `g'. manprefix= # Where to install executables. bindir=$(exec_prefix)/bin # Where to install man pages. mandir=$(prefix)/man/man1 # Extension for man pages. manext=1 # How to make a hard link. LN=ln #### End of system configuration section. #### SRCS=grep.c getopt.c regex.c dfa.c kwset.c obstack.c search.c OBJS=grep.o getopt.o regex.o dfa.o kwset.o obstack.o search.o .c.o: $(CC) $(CFLAGS) $(DEFS) -I$(srcdir) -c $< all: grep check.done # For Saber C. grep.load: $(SRCS) #load $(CFLAGS) $(DEFS) -I$(srcdir) (SRCS) # For Lint. grep.lint: $(SRCS) $(LINT) $(CFLAGS) $(DEFS) -I$(srcdir) $(SRCS) install: all $(INSTALL_PROGRAM) grep $(bindir)/$(binprefix)grep rm -f $(bindir)/$(binprefix)egrep $(LN) $(bindir)/$(binprefix)grep $(bindir)/$(binprefix)egrep rm -f $(bindir)/$(binprefix)fgrep $(LN) $(bindir)/$(binprefix)grep $(bindir)/$(binprefix)fgrep $(INSTALL_DATA) $(srcdir)/grep.man $(mandir)/grep.$(manext) check: AWK=$(AWK) sh $(srcdir)/tests/check.sh $(srcdir)/tests touch check.done check.done: grep AWK=$(AWK) sh $(srcdir)/tests/check.sh $(srcdir)/tests touch check.done grep: $(OBJS) $(LIBOBJS) $(ALLOCA) $(CC) $(LDFLAGS) -o grep $(OBJS) $(LIBOBJS) $(LIBS) $(ALLOCA) clean: rm -f core grep *.o check.done tmp.script khadafy.out mostlyclean: clean distclean: clean rm -f Makefile config.status realclean: distclean rm -f TAGS Makefile: $(srcdir)/Makefile.in config.status $(SHELL) config.status dist: V=`sed -n '/version\\[/s/.*\\([0-9][0-9]*\\.[0-9]*\\).*/\\1/p' \ grep.c`; \ mkdir grep-$$V; mkdir grep-$$V/tests; \ for f in `awk '{print $$1}' MANIFEST`; do ln $$f grep-$$V/$$f; done; \ tar cvhf - grep-$$V | gzip > grep-$$V.tar.z; \ rm -fr grep-$$V # Some header file dependencies that really ought to be automatically deduced. dfa.o search.o: dfa.h grep.o search.o: grep.h kwset.o search.o: kwset.h kwset.o obstack.o: obstack.h regex.o search.o: regex.h shapetools-1.4pl6.orig/vgrep-2.0/NEWS100644 2013 145 3350 5371047326 15271 0ustar dokoswtVersion 2.0: The most important user visible change is that egrep and fgrep have disappeared as separate programs into the single grep program mandated by POSIX 1003.2. New options -G, -E, and -F have been added, selecting grep, egrep, and fgrep behavior respectively. For compatibility with historical practice, hard links named egrep and fgrep are also provided. See the manual page for details. In addition, the regular expression facilities described in Posix draft 11.2 are now supported, except for internationalization features related to locale-dependent collating sequence information. There is a new option, -L, which is like -l except it lists files which don't contain matches. The reason this option was added is because '-l -v' doesn't do what you expect. Performance has been improved; the amount of improvement is platform dependent, but (for example) grep 2.0 typically runs at least 30% faster than grep 1.6 on a DECstation using the MIPS compiler. Where possible, grep now uses mmap() for file input; on a Sun 4 running SunOS 4.1 this may cut system time by as much as half, for a total reduction in running time by nearly 50%. On machines that don't use mmap(), the buffering code has been rewritten to choose more favorable alignments and buffer sizes for read(). Portability has been substantially cleaned up, and an automatic configure script is now provided. The internals have changed in ways too numerous to mention. People brave enough to reuse the DFA matcher in other programs will now have their bravery amply "rewarded", for the interface to that file has been completely changed. Some changes were necessary to track the evolution of the regex package, and since I was changing it anyway I decided to do a general cleanup. shapetools-1.4pl6.orig/vgrep-2.0/PROJECTS100644 2013 145 1254 5261471105 15741 0ustar dokoswtWrite Texinfo documentation for grep. The manual page would be a good place to start, but Info documents are also supposed to contain a tutorial and examples. Fix the DFA matcher to never use exponential space. (Fortunately, these cases are rare.) Improve the performance of the regex backtracking matcher. This matcher is agonizingly slow, and is responsible for grep sometimes being slower than Unix grep when backreferences are used. Provide support for the Posix [= =] and [. .] constructs. This is difficult because it requires locale-dependent details of the character set and collating sequence, but Posix does not standardize any method for accessing this information! shapetools-1.4pl6.orig/vgrep-2.0/README100644 2013 145 2420 5261473556 15455 0ustar dokoswtThis is GNU grep 2.0, the "fastest grep in the west" (we hope). All bugs reported in previous releases have been fixed. Many exciting new bugs have probably been introduced in this major revision. GNU grep is provided "as is" with no warranty. The exact terms under which you may use and (re)distribute this program are detailed in the GNU General Public License, in the file COPYING. GNU grep is based on a fast lazy-state deterministic matcher (about twice as fast as stock Unix egrep) hybridized with a Boyer-Moore-Gosper search for a fixed string that eliminates impossible text from being considered by the full regexp matcher without necessarily having to look at every character. The result is typically many times faster than Unix grep or egrep. (Regular expressions containing backreferencing will run more slowly, however.) See the file AUTHORS for a list of authors and other contributors. See the file INSTALL for compilation and installation instructions. See the file MANIFEST for a list of files in this distribution. See the file NEWS for a description of major changes in this release. See the file PROJECTS if you want to be mentioned in AUTHORS. Send bug reports to bug-gnu-utils@prep.ai.mit.edu. Be sure to include the word "grep" in your Subject: header field. shapetools-1.4pl6.orig/vgrep-2.0/alloca.c100644 2013 145 31723 5377062163 16220 0ustar dokoswt/* alloca.c -- allocate automatically reclaimed memory (Mostly) portable public-domain implementation -- D A Gwyn This implementation of the PWB library alloca function, which is used to allocate space off the run-time stack so that it is automatically reclaimed upon procedure exit, was inspired by discussions with J. Q. Johnson of Cornell. J.Otto Tennant contributed the Cray support. There are some preprocessor constants that can be defined when compiling for your specific system, for improved efficiency; however, the defaults should be okay. The general concept of this implementation is to keep track of all alloca-allocated blocks, and reclaim any that are found to be deeper in the stack than the current invocation. This heuristic does not reclaim storage as soon as it becomes invalid, but it will do so eventually. As a special case, alloca(0) reclaims storage without allocating any. It is a good idea to use alloca(0) in your main control loop, etc. to force garbage collection. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* If compiling with GCC, this file's not needed. */ #ifndef alloca #ifdef emacs #ifdef static /* actually, only want this if static is defined as "" -- this is for usg, in which emacs must undefine static in order to make unexec workable */ #ifndef STACK_DIRECTION you lose -- must know STACK_DIRECTION at compile-time #endif /* STACK_DIRECTION undefined */ #endif /* static */ #endif /* emacs */ #ifdef emacs #define free xfree #endif /* If your stack is a linked list of frames, you have to provide an "address metric" ADDRESS_FUNCTION macro. */ #ifdef CRAY long i00afunc (); #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) #else #define ADDRESS_FUNCTION(arg) &(arg) #endif #if __STDC__ typedef void *pointer; #else typedef char *pointer; #endif #define NULL 0 extern pointer xmalloc (); /* Define STACK_DIRECTION if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #ifndef STACK_DIRECTION #define STACK_DIRECTION 0 /* Direction unknown. */ #endif #if STACK_DIRECTION != 0 #define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ #else /* STACK_DIRECTION == 0; need run-time code. */ static int stack_dir; /* 1 or -1 once known. */ #define STACK_DIR stack_dir static void find_stack_direction () { static char *addr = NULL; /* Address of first `dummy', once known. */ auto char dummy; /* To get stack address. */ if (addr == NULL) { /* Initial entry. */ addr = ADDRESS_FUNCTION (dummy); find_stack_direction (); /* Recurse once. */ } else { /* Second entry. */ if (ADDRESS_FUNCTION (dummy) > addr) stack_dir = 1; /* Stack grew upward. */ else stack_dir = -1; /* Stack grew downward. */ } } #endif /* STACK_DIRECTION == 0 */ /* An "alloca header" is used to: (a) chain together all alloca'ed blocks; (b) keep track of stack depth. It is very important that sizeof(header) agree with malloc alignment chunk size. The following default should work okay. */ #ifndef ALIGN_SIZE #define ALIGN_SIZE sizeof(double) #endif typedef union hdr { char align[ALIGN_SIZE]; /* To force sizeof(header). */ struct { union hdr *next; /* For chaining headers. */ char *deep; /* For stack depth measure. */ } h; } header; static header *last_alloca_header = NULL; /* -> last alloca header. */ /* Return a pointer to at least SIZE bytes of storage, which will be automatically reclaimed upon exit from the procedure that called alloca. Originally, this space was supposed to be taken from the current stack frame of the caller, but that method cannot be made to work for some implementations of C, for example under Gould's UTX/32. */ pointer alloca (size) unsigned size; { auto char probe; /* Probes stack depth: */ register char *depth = ADDRESS_FUNCTION (probe); #if STACK_DIRECTION == 0 if (STACK_DIR == 0) /* Unknown growth direction. */ find_stack_direction (); #endif /* Reclaim garbage, defined as all alloca'd storage that was allocated from deeper in the stack than currently. */ { register header *hp; /* Traverses linked list. */ for (hp = last_alloca_header; hp != NULL;) if ((STACK_DIR > 0 && hp->h.deep > depth) || (STACK_DIR < 0 && hp->h.deep < depth)) { register header *np = hp->h.next; free ((pointer) hp); /* Collect garbage. */ hp = np; /* -> next header. */ } else break; /* Rest are not deeper. */ last_alloca_header = hp; /* -> last valid storage. */ } if (size == 0) return NULL; /* No allocation required. */ /* Allocate combined header + user data storage. */ { register pointer new = xmalloc (sizeof (header) + size); /* Address of header. */ ((header *) new)->h.next = last_alloca_header; ((header *) new)->h.deep = depth; last_alloca_header = (header *) new; /* User storage begins just after header. */ return (pointer) ((char *) new + sizeof (header)); } } #ifdef CRAY #ifdef DEBUG_I00AFUNC #include #endif #ifndef CRAY_STACK #define CRAY_STACK #ifndef CRAY2 /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ struct stack_control_header { long shgrow:32; /* Number of times stack has grown. */ long shaseg:32; /* Size of increments to stack. */ long shhwm:32; /* High water mark of stack. */ long shsize:32; /* Current size of stack (all segments). */ }; /* The stack segment linkage control information occurs at the high-address end of a stack segment. (The stack grows from low addresses to high addresses.) The initial part of the stack segment linkage control information is 0200 (octal) words. This provides for register storage for the routine which overflows the stack. */ struct stack_segment_linkage { long ss[0200]; /* 0200 overflow words. */ long sssize:32; /* Number of words in this segment. */ long ssbase:32; /* Offset to stack base. */ long:32; long sspseg:32; /* Offset to linkage control of previous segment of stack. */ long:32; long sstcpt:32; /* Pointer to task common address block. */ long sscsnm; /* Private control structure number for microtasking. */ long ssusr1; /* Reserved for user. */ long ssusr2; /* Reserved for user. */ long sstpid; /* Process ID for pid based multi-tasking. */ long ssgvup; /* Pointer to multitasking thread giveup. */ long sscray[7]; /* Reserved for Cray Research. */ long ssa0; long ssa1; long ssa2; long ssa3; long ssa4; long ssa5; long ssa6; long ssa7; long sss0; long sss1; long sss2; long sss3; long sss4; long sss5; long sss6; long sss7; }; #else /* CRAY2 */ /* The following structure defines the vector of words returned by the STKSTAT library routine. */ struct stk_stat { long now; /* Current total stack size. */ long maxc; /* Amount of contiguous space which would be required to satisfy the maximum stack demand to date. */ long high_water; /* Stack high-water mark. */ long overflows; /* Number of stack overflow ($STKOFEN) calls. */ long hits; /* Number of internal buffer hits. */ long extends; /* Number of block extensions. */ long stko_mallocs; /* Block allocations by $STKOFEN. */ long underflows; /* Number of stack underflow calls ($STKRETN). */ long stko_free; /* Number of deallocations by $STKRETN. */ long stkm_free; /* Number of deallocations by $STKMRET. */ long segments; /* Current number of stack segments. */ long maxs; /* Maximum number of stack segments so far. */ long pad_size; /* Stack pad size. */ long current_address; /* Current stack segment address. */ long current_size; /* Current stack segment size. This number is actually corrupted by STKSTAT to include the fifteen word trailer area. */ long initial_address; /* Address of initial segment. */ long initial_size; /* Size of initial segment. */ }; /* The following structure describes the data structure which trails any stack segment. I think that the description in 'asdef' is out of date. I only describe the parts that I am sure about. */ struct stk_trailer { long this_address; /* Address of this block. */ long this_size; /* Size of this block (does not include this trailer). */ long unknown2; long unknown3; long link; /* Address of trailer block of previous segment. */ long unknown5; long unknown6; long unknown7; long unknown8; long unknown9; long unknown10; long unknown11; long unknown12; long unknown13; long unknown14; }; #endif /* CRAY2 */ #endif /* not CRAY_STACK */ #ifdef CRAY2 /* Determine a "stack measure" for an arbitrary ADDRESS. I doubt that "lint" will like this much. */ static long i00afunc (long *address) { struct stk_stat status; struct stk_trailer *trailer; long *block, size; long result = 0; /* We want to iterate through all of the segments. The first step is to get the stack status structure. We could do this more quickly and more directly, perhaps, by referencing the $LM00 common block, but I know that this works. */ STKSTAT (&status); /* Set up the iteration. */ trailer = (struct stk_trailer *) (status.current_address + status.current_size - 15); /* There must be at least one stack segment. Therefore it is a fatal error if "trailer" is null. */ if (trailer == 0) abort (); /* Discard segments that do not contain our argument address. */ while (trailer != 0) { block = (long *) trailer->this_address; size = trailer->this_size; if (block == 0 || size == 0) abort (); trailer = (struct stk_trailer *) trailer->link; if ((block <= address) && (address < (block + size))) break; } /* Set the result to the offset in this segment and add the sizes of all predecessor segments. */ result = address - block; if (trailer == 0) { return result; } do { if (trailer->this_size <= 0) abort (); result += trailer->this_size; trailer = (struct stk_trailer *) trailer->link; } while (trailer != 0); /* We are done. Note that if you present a bogus address (one not in any segment), you will get a different number back, formed from subtracting the address of the first block. This is probably not what you want. */ return (result); } #else /* not CRAY2 */ /* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. Determine the number of the cell within the stack, given the address of the cell. The purpose of this routine is to linearize, in some sense, stack addresses for alloca. */ static long i00afunc (long address) { long stkl = 0; long size, pseg, this_segment, stack; long result = 0; struct stack_segment_linkage *ssptr; /* Register B67 contains the address of the end of the current stack segment. If you (as a subprogram) store your registers on the stack and find that you are past the contents of B67, you have overflowed the segment. B67 also points to the stack segment linkage control area, which is what we are really interested in. */ stkl = CRAY_STACKSEG_END (); ssptr = (struct stack_segment_linkage *) stkl; /* If one subtracts 'size' from the end of the segment, one has the address of the first word of the segment. If this is not the first segment, 'pseg' will be nonzero. */ pseg = ssptr->sspseg; size = ssptr->sssize; this_segment = stkl - size; /* It is possible that calling this routine itself caused a stack overflow. Discard stack segments which do not contain the target address. */ while (!(this_segment <= address && address <= stkl)) { #ifdef DEBUG_I00AFUNC fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); #endif if (pseg == 0) break; stkl = stkl - pseg; ssptr = (struct stack_segment_linkage *) stkl; size = ssptr->sssize; pseg = ssptr->sspseg; this_segment = stkl - size; } result = address - this_segment; /* If you subtract pseg from the current end of the stack, you get the address of the previous stack segment's end. This seems a little convoluted to me, but I'll bet you save a cycle somewhere. */ while (pseg != 0) { #ifdef DEBUG_I00AFUNC fprintf (stderr, "%011o %011o\n", pseg, size); #endif stkl = stkl - pseg; ssptr = (struct stack_segment_linkage *) stkl; size = ssptr->sssize; pseg = ssptr->sspseg; result += size; } return (result); } #endif /* not CRAY2 */ #endif /* CRAY */ #endif /* no alloca */ shapetools-1.4pl6.orig/vgrep-2.0/configure100755 2013 145 47335 5377325007 16535 0ustar dokoswt#!/bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf. # Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create] # [--prefix=PREFIX] [--exec-prefix=PREFIX] [--with-PACKAGE] [TARGET] # Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and # --with-PACKAGE unless this script has special code to handle it. for arg do # Handle --exec-prefix with a space before the argument. if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix= # Handle --host with a space before the argument. elif test x$next_host = xyes; then next_host= # Handle --prefix with a space before the argument. elif test x$next_prefix = xyes; then prefix=$arg; next_prefix= # Handle --srcdir with a space before the argument. elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir= else case $arg in # For backward compatibility, also recognize exact --exec_prefix. -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* | --exe=* | --ex=* | --e=*) exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e) next_exec_prefix=yes ;; -gas | --gas | --ga | --g) ;; -host=* | --host=* | --hos=* | --ho=* | --h=*) ;; -host | --host | --hos | --ho | --h) next_host=yes ;; -nfp | --nfp | --nf) ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no) no_create=1 ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) next_prefix=yes ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*) srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s) next_srcdir=yes ;; -with-* | --with-*) package=`echo $arg|sed 's/-*with-//'` # Delete all the valid chars; see if any are left. if test -n "`echo $package|sed 's/[-a-zA-Z0-9_]*//g'`"; then echo "configure: $package: invalid package name" >&2; exit 1 fi eval "with_`echo $package|sed s/-/_/g`=1" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb | --ver | --ve | --v) verbose=yes ;; *) ;; esac fi done trap 'rm -f conftest* core; exit 1' 1 3 15 # Needed for some versions of `tr' so that character classes in `[]' work. if test "${LANG+set}" = "set" ; then LANG=C fi rm -f conftest* compile='${CC-cc} $CFLAGS $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1' # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. unique_file=grep.c # Find the source files, if location was not specified. if test -z "$srcdir"; then srcdirdefaulted=yes # Try the directory containing this script, then `..'. prog=$0 confdir=`echo $prog|sed 's%/[^/][^/]*$%%'` test "X$confdir" = "X$prog" && confdir=. srcdir=$confdir if test ! -r $srcdir/$unique_file; then srcdir=.. fi fi if test ! -r $srcdir/$unique_file; then if test x$srcdirdefaulted = xyes; then echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2 else echo "configure: Can not find sources in \`${srcdir}'." 1>&2 fi exit 1 fi # Preserve a srcdir of `.' to avoid automounter screwups with pwd. # But we can't avoid them for `..', to make subdirectories work. case $srcdir in .|/*|~*) ;; *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute. esac for p in mawk gawk nawk awk do if test -z "$AWK"; then # Extract the first word of `$p', so it can be a program name with args. set dummy $p; word=$2 echo checking for $word IFS="${IFS= }"; saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/$word; then AWK="$p" break fi done IFS="$saveifs" fi test -n "$AWK" -a -n "$verbose" && echo " setting AWK to $AWK" test -n "$AWK" && break done if test -z "$CC"; then # Extract the first word of `gcc', so it can be a program name with args. set dummy gcc; word=$2 echo checking for $word IFS="${IFS= }"; saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/$word; then CC="gcc" break fi done IFS="$saveifs" fi test -z "$CC" && CC="cc" test -n "$CC" -a -n "$verbose" && echo " setting CC to $CC" # Find out if we are using GNU C, under whatever name. cat > conftest.c < conftest.out 2>&1 if egrep yes conftest.out >/dev/null 2>&1; then GCC=1 # For later tests. fi rm -f conftest* echo checking for POSIXized ISC if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then ISC=1 # If later tests want to check for ISC. { test -n "$verbose" && \ echo ' defining' _POSIX_SOURCE DEFS="$DEFS -D_POSIX_SOURCE=1" } if test -n "$GCC"; then CC="$CC -posix" else CC="$CC -Xp" fi fi echo checking how to run the C preprocessor if test -z "$CPP"; then CPP='${CC-cc} -E' cat > conftest.c < EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then : else CPP=/lib/cpp fi rm -f conftest* fi # Make sure to not get the incompatible SysV /etc/install and # /usr/sbin/install, which might be in PATH before a BSD-like install, # or the SunOS /usr/etc/install directory, or the AIX /bin/install, # or the AFS install, which mishandles nonexistent args, or # /usr/ucb/install on SVR4, which tries to use the nonexistent group # `staff'. On most BSDish systems install is in /usr/bin, not /usr/ucb # anyway. Sigh. if test "z${INSTALL}" = "z" ; then echo checking for install IFS="${IFS= }"; saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. case $dir in /etc|/usr/sbin|/usr/etc|/usr/afsws/bin|/usr/ucb) ;; *) if test -f $dir/installbsd; then INSTALL="$dir/installbsd -c" # OSF1 INSTALL_PROGRAM='$(INSTALL)' INSTALL_DATA='$(INSTALL) -m 644' break fi if test -f $dir/install; then if grep dspmsg $dir/install >/dev/null 2>&1; then : # AIX else INSTALL="$dir/install -c" INSTALL_PROGRAM='$(INSTALL)' INSTALL_DATA='$(INSTALL) -m 644' break fi fi ;; esac done IFS="$saveifs" fi INSTALL=${INSTALL-cp} INSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'} INSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'} echo checking for ANSI C header files cat > conftest.c < #include #include #include EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. echo '#include ' > conftest.c eval "$CPP \$DEFS conftest.c > conftest.out 2>&1" if egrep "memchr" conftest.out >/dev/null 2>&1; then # SGI's /bin/cc from Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. cat > conftest.c < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e,f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF eval $compile if test -s conftest && (./conftest; exit) 2>/dev/null; then { test -n "$verbose" && \ echo ' defining' STDC_HEADERS DEFS="$DEFS -DSTDC_HEADERS=1" } fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* for hdr in string.h sys/param.h do trhdr=HAVE_`echo $hdr | tr '[a-z]./' '[A-Z]__'` echo checking for ${hdr} cat > conftest.c < EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then { test -n "$verbose" && \ echo ' defining' ${trhdr} DEFS="$DEFS -D${trhdr}=1" } fi rm -f conftest* done echo checking whether string.h declares mem functions echo '#include ' > conftest.c eval "$CPP \$DEFS conftest.c > conftest.out 2>&1" if egrep "memchr" conftest.out >/dev/null 2>&1; then : else echo checking for memory.h cat > conftest.c < EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then { test -n "$verbose" && \ echo ' defining' NEED_MEMORY_H DEFS="$DEFS -DNEED_MEMORY_H=1" } fi rm -f conftest* fi rm -f conftest* echo checking for unistd.h cat > conftest.c < EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then { test -n "$verbose" && \ echo ' defining' HAVE_UNISTD_H DEFS="$DEFS -DHAVE_UNISTD_H=1" } fi rm -f conftest* echo checking for size_t in sys/types.h echo '#include ' > conftest.c eval "$CPP \$DEFS conftest.c > conftest.out 2>&1" if egrep "size_t" conftest.out >/dev/null 2>&1; then : else { test -n "$verbose" && \ echo ' defining' size_t to be 'unsigned' DEFS="$DEFS -Dsize_t=unsigned" } fi rm -f conftest* # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo checking for working alloca.h cat > conftest.c < int main() { exit(0); } int t() { char *p = alloca(2 * sizeof(int)); } EOF if eval $compile; then { test -n "$verbose" && \ echo ' defining' HAVE_ALLOCA_H DEFS="$DEFS -DHAVE_ALLOCA_H=1" } fi rm -f conftest* decl="#ifdef __GNUC__ #define alloca __builtin_alloca #else #if HAVE_ALLOCA_H #include #else #ifdef _AIX #pragma alloca #else char *alloca (); #endif #endif #endif " echo checking for alloca cat > conftest.c < conftest.c < conftest.out 2>&1" if egrep "winnitude" conftest.out >/dev/null 2>&1; then echo checking for _getb67 cat > conftest.c < int main() { exit(0); } int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub__getb67) || defined (__stub____getb67) choke me #else /* Override any gcc2 internal prototype to avoid an error. */ extern char _getb67(); _getb67(); #endif } EOF if eval $compile; then { test -n "$verbose" && \ echo ' defining' CRAY_STACKSEG_END to be '_getb67' DEFS="$DEFS -DCRAY_STACKSEG_END=_getb67" } else echo checking for GETB67 cat > conftest.c < int main() { exit(0); } int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_GETB67) || defined (__stub___GETB67) choke me #else /* Override any gcc2 internal prototype to avoid an error. */ extern char GETB67(); GETB67(); #endif } EOF if eval $compile; then { test -n "$verbose" && \ echo ' defining' CRAY_STACKSEG_END to be 'GETB67' DEFS="$DEFS -DCRAY_STACKSEG_END=GETB67" } else echo checking for getb67 cat > conftest.c < int main() { exit(0); } int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getb67) || defined (__stub___getb67) choke me #else /* Override any gcc2 internal prototype to avoid an error. */ extern char getb67(); getb67(); #endif } EOF if eval $compile; then { test -n "$verbose" && \ echo ' defining' CRAY_STACKSEG_END to be 'getb67' DEFS="$DEFS -DCRAY_STACKSEG_END=getb67" } fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* if test -n "$alloca_missing"; then # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=alloca.o echo 'checking stack direction for C alloca' echo checking whether cross-compiling # If we cannot run a trivial program, we must be cross compiling. cat > conftest.c </dev/null; then : else cross_compiling=1 fi rm -f conftest* if test -n "$cross_compiling" then { test -n "$verbose" && \ echo ' defining' STACK_DIRECTION to be '0' DEFS="$DEFS -DSTACK_DIRECTION=0" } else cat > conftest.c < addr) ? 1 : -1; } main () { exit (find_stack_direction() < 0); } EOF eval $compile if test -s conftest && (./conftest; exit) 2>/dev/null; then { test -n "$verbose" && \ echo ' defining' STACK_DIRECTION to be '1' DEFS="$DEFS -DSTACK_DIRECTION=1" } else { test -n "$verbose" && \ echo ' defining' STACK_DIRECTION to be '-1' DEFS="$DEFS -DSTACK_DIRECTION=-1" } fi fi rm -f conftest* fi for func in getpagesize memchr strerror valloc do trfunc=HAVE_`echo $func | tr '[a-z]' '[A-Z]'` echo checking for ${func} cat > conftest.c < int main() { exit(0); } int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_${func}) || defined (__stub___${func}) choke me #else /* Override any gcc2 internal prototype to avoid an error. */ extern char ${func}(); ${func}(); #endif } EOF if eval $compile; then { test -n "$verbose" && \ echo ' defining' ${trfunc} DEFS="$DEFS -D${trfunc}=1" } fi rm -f conftest* done echo checking for unsigned characters cat > conftest.c </dev/null; then { test -n "$verbose" && \ echo ' defining' __CHAR_UNSIGNED__ DEFS="$DEFS -D__CHAR_UNSIGNED__=1" } fi rm -f conftest* prog='/* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset x; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; p = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++ccp; p = (char**) ccp; ccp = (char const *const *) p; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25,17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; }' echo checking for working const cat > conftest.c < conftest.c < #include #include #ifdef BSD #ifndef BSD4_1 #define HAVE_GETPAGESIZE #endif #endif #ifndef HAVE_GETPAGESIZE #include #ifdef EXEC_PAGESIZE #define getpagesize() EXEC_PAGESIZE #else #ifdef NBPG #define getpagesize() NBPG * CLSIZE #ifndef CLSIZE #define CLSIZE 1 #endif /* no CLSIZE */ #else /* no NBPG */ #define getpagesize() NBPC #endif /* no NBPG */ #endif /* no EXEC_PAGESIZE */ #endif /* not HAVE_GETPAGESIZE */ #ifdef __osf__ #define valloc malloc #endif extern char *valloc(); int main() { char *buf1, *buf2; int i = getpagesize(), j; int fd; buf1 = valloc(i); buf2 = valloc(i); for (j = 0; j < i; ++j) *(buf1 + j) = rand(); fd = open("conftestmmap", O_CREAT | O_RDWR, 0666); write(fd, buf1, i); mmap(buf2, i, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fd, 0); for (j = 0; j < i; ++j) if (*(buf1 + j) != *(buf2 + j)) exit(1); exit(0); } EOF eval $compile if test -s conftest && (./conftest; exit) 2>/dev/null; then { test -n "$verbose" && \ echo ' defining' HAVE_WORKING_MMAP DEFS="$DEFS -DHAVE_WORKING_MMAP=1" } fi rm -f conftest* if test -n "$prefix"; then test -z "$exec_prefix" && exec_prefix='${prefix}' prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%" fi if test -n "$exec_prefix"; then prsub="$prsub s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%\ exec_prefix\\1=\\2$exec_prefix%" fi DEFS="`echo \"$DEFS\" | sed 's%[&\\\]%\\\&%g'`" trap 'rm -f config.status; exit 1' 1 3 15 echo creating config.status rm -f config.status cat > config.status </dev/null | sed 1q`: # # $0 $* for arg do case "\$arg" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) exec /bin/sh $0 $* ;; *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; esac done trap 'rm -f Makefile; exit 1' 1 3 15 AWK='$AWK' CC='$CC' CPP='$CPP' INSTALL='$INSTALL' INSTALL_PROGRAM='$INSTALL_PROGRAM' INSTALL_DATA='$INSTALL_DATA' ALLOCA='$ALLOCA' LIBS='$LIBS' srcdir='$srcdir' DEFS='$DEFS' prefix='$prefix' exec_prefix='$exec_prefix' prsub='$prsub' EOF cat >> config.status <<\EOF top_srcdir=$srcdir # Allow make-time overrides of the generated file list. test -n "$gen_files" || gen_files="Makefile" for file in .. $gen_files; do if [ "x$file" != "x.." ]; then srcdir=$top_srcdir # Remove last slash and all that follows it. Not all systems have dirname. dir=`echo $file|sed 's%/[^/][^/]*$%%'` if test "$dir" != "$file"; then test "$top_srcdir" != . && srcdir=$top_srcdir/$dir test ! -d $dir && mkdir $dir fi echo creating $file rm -f $file echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file sed -e " $prsub s%@AWK@%$AWK%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@INSTALL@%$INSTALL%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@ALLOCA@%$ALLOCA%g s%@LIBS@%$LIBS%g s%@srcdir@%$srcdir%g s%@DEFS@%$DEFS% " $top_srcdir/${file}.in >> $file fi; done exit 0 EOF chmod +x config.status test -n "$no_create" || ./config.status shapetools-1.4pl6.orig/vgrep-2.0/configure.in100644 2013 145 2533 5377325000 17077 0ustar dokoswtdnl Process this file with autoconf to produce a configure script AC_INIT(grep.c) AC_PROG_AWK AC_PROG_CC AC_ISC_POSIX AC_PROG_CPP AC_PROG_INSTALL AC_STDC_HEADERS AC_HAVE_HEADERS(string.h sys/param.h) AC_MEMORY_H AC_UNISTD_H AC_SIZE_T AC_ALLOCA AC_HAVE_FUNCS(getpagesize memchr strerror valloc) AC_CHAR_UNSIGNED AC_CONST echo checking for working mmap AC_TEST_PROGRAM([ #include #include #include #ifdef BSD #ifndef BSD4_1 #define HAVE_GETPAGESIZE #endif #endif #ifndef HAVE_GETPAGESIZE #include #ifdef EXEC_PAGESIZE #define getpagesize() EXEC_PAGESIZE #else #ifdef NBPG #define getpagesize() NBPG * CLSIZE #ifndef CLSIZE #define CLSIZE 1 #endif /* no CLSIZE */ #else /* no NBPG */ #define getpagesize() NBPC #endif /* no NBPG */ #endif /* no EXEC_PAGESIZE */ #endif /* not HAVE_GETPAGESIZE */ #ifdef __osf__ #define valloc malloc #endif extern char *valloc(); int main() { char *buf1, *buf2; int i = getpagesize(), j; int fd; buf1 = valloc(i); buf2 = valloc(i); for (j = 0; j < i; ++j) *(buf1 + j) = rand(); fd = open("conftestmmap", O_CREAT | O_RDWR, 0666); write(fd, buf1, i); mmap(buf2, i, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fd, 0); for (j = 0; j < i; ++j) if (*(buf1 + j) != *(buf2 + j)) exit(1); exit(0); } ], AC_DEFINE(HAVE_WORKING_MMAP)) AC_OUTPUT(Makefile) shapetools-1.4pl6.orig/vgrep-2.0/dfa.c100644 2013 145 174451 5402236374 15541 0ustar dokoswt/* dfa.c - deterministic extended regexp routines for GNU Copyright (C) 1988 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Written June, 1988 by Mike Haertel Modified July, 1988 by Arthur David Olson to assist BMG speedups */ #include #include #include #ifdef STDC_HEADERS #include #else #include extern char *calloc(), *malloc(), *realloc(); extern void free(); #endif #if defined(HAVE_STRING_H) || defined(STDC_HEADERS) #include #undef index #define index strchr #else #include #endif #ifndef isgraph #define isgraph(C) (isprint(C) && !isspace(C)) #endif #ifdef isascii #define ISALPHA(C) (isascii(C) && isalpha(C)) #define ISUPPER(C) (isascii(C) && isupper(C)) #define ISLOWER(C) (isascii(C) && islower(C)) #define ISDIGIT(C) (isascii(C) && isdigit(C)) #define ISXDIGIT(C) (isascii(C) && isxdigit(C)) #define ISSPACE(C) (isascii(C) && isspace(C)) #define ISPUNCT(C) (isascii(C) && ispunct(C)) #define ISALNUM(C) (isascii(C) && isalnum(C)) #define ISPRINT(C) (isascii(C) && isprint(C)) #define ISGRAPH(C) (isascii(C) && isgraph(C)) #define ISCNTRL(C) (isascii(C) && iscntrl(C)) #else #define ISALPHA(C) isalpha(C) #define ISUPPER(C) isupper(C) #define ISLOWER(C) islower(C) #define ISDIGIT(C) isdigit(C) #define ISXDIGIT(C) isxdigit(C) #define ISSPACE(C) isspace(C) #define ISPUNCT(C) ispunct(C) #define ISALNUM(C) isalnum(C) #define ISPRINT(C) isprint(C) #define ISGRAPH(C) isgraph(C) #define ISCNTRL(C) iscntrl(C) #endif #include "dfa.h" #include "regex.h" #if __STDC__ typedef void *ptr_t; #else typedef char *ptr_t; #endif static void dfamust(); static ptr_t xcalloc(n, s) int n; size_t s; { ptr_t r = calloc(n, s); if (!r) dfaerror("Memory exhausted"); return r; } static ptr_t xmalloc(n) size_t n; { ptr_t r = malloc(n); assert(n != 0); if (!r) dfaerror("Memory exhausted"); return r; } static ptr_t xrealloc(p, n) ptr_t p; size_t n; { ptr_t r = realloc(p, n); assert(n != 0); if (!r) dfaerror("Memory exhausted"); return r; } #define CALLOC(p, t, n) ((p) = (t *) xcalloc((n), sizeof (t))) #define MALLOC(p, t, n) ((p) = (t *) xmalloc((n) * sizeof (t))) #define REALLOC(p, t, n) ((p) = (t *) xrealloc((ptr_t) (p), (n) * sizeof (t))) /* Reallocate an array of type t if nalloc is too small for index. */ #define REALLOC_IF_NECESSARY(p, t, nalloc, index) \ if ((index) >= (nalloc)) \ { \ while ((index) >= (nalloc)) \ (nalloc) *= 2; \ REALLOC(p, t, nalloc); \ } #ifdef DEBUG static void prtok(t) token t; { char *s; if (t < 0) fprintf(stderr, "END"); else if (t < NOTCHAR) fprintf(stderr, "%c", t); else { switch (t) { case EMPTY: s = "EMPTY"; break; case BACKREF: s = "BACKREF"; break; case BEGLINE: s = "BEGLINE"; break; case ENDLINE: s = "ENDLINE"; break; case BEGWORD: s = "BEGWORD"; break; case ENDWORD: s = "ENDWORD"; break; case LIMWORD: s = "LIMWORD"; break; case NOTLIMWORD: s = "NOTLIMWORD"; break; case QMARK: s = "QMARK"; break; case STAR: s = "STAR"; break; case PLUS: s = "PLUS"; break; case CAT: s = "CAT"; break; case OR: s = "OR"; break; case ORTOP: s = "ORTOP"; break; case LPAREN: s = "LPAREN"; break; case RPAREN: s = "RPAREN"; break; default: s = "CSET"; break; } fprintf(stderr, "%s", s); } } #endif /* DEBUG */ /* Stuff pertaining to charclasses. */ static int tstbit(b, c) int b; charclass c; { return c[b / INTBITS] & 1 << b % INTBITS; } static void setbit(b, c) int b; charclass c; { c[b / INTBITS] |= 1 << b % INTBITS; } static void clrbit(b, c) int b; charclass c; { c[b / INTBITS] &= ~(1 << b % INTBITS); } static void copyset(src, dst) charclass src; charclass dst; { int i; for (i = 0; i < CHARCLASS_INTS; ++i) dst[i] = src[i]; } static void zeroset(s) charclass s; { int i; for (i = 0; i < CHARCLASS_INTS; ++i) s[i] = 0; } static void notset(s) charclass s; { int i; for (i = 0; i < CHARCLASS_INTS; ++i) s[i] = ~s[i]; } static int equal(s1, s2) charclass s1; charclass s2; { int i; for (i = 0; i < CHARCLASS_INTS; ++i) if (s1[i] != s2[i]) return 0; return 1; } /* A pointer to the current dfa is kept here during parsing. */ static struct dfa *dfa; /* Find the index of charclass s in dfa->charclasses, or allocate a new charclass. */ static int charclass_index(s) charclass s; { int i; for (i = 0; i < dfa->cindex; ++i) if (equal(s, dfa->charclasses[i])) return i; REALLOC_IF_NECESSARY(dfa->charclasses, charclass, dfa->calloc, dfa->cindex); ++dfa->cindex; copyset(s, dfa->charclasses[i]); return i; } /* Syntax bits controlling the behavior of the lexical analyzer. */ static int syntax_bits, syntax_bits_set; /* Flag for case-folding letters into sets. */ static int case_fold; /* Entry point to set syntax options. */ void dfasyntax(bits, fold) int bits; int fold; { syntax_bits_set = 1; syntax_bits = bits; case_fold = fold; } /* Lexical analyzer. All the dross that deals with the obnoxious GNU Regex syntax bits is located here. The poor, suffering reader is referred to the GNU Regex documentation for the meaning of the @#%!@#%^!@ syntax bits. */ static char *lexstart; /* Pointer to beginning of input string. */ static char *lexptr; /* Pointer to next input character. */ static lexleft; /* Number of characters remaining. */ static token lasttok; /* Previous token returned; initially END. */ static int laststart; /* True if we're separated from beginning or (, | only by zero-width characters. */ static int parens; /* Count of outstanding left parens. */ static int minrep, maxrep; /* Repeat counts for {m,n}. */ /* Note that characters become unsigned here. */ #define FETCH(c, eoferr) \ { \ if (! lexleft) \ if (eoferr != 0) \ dfaerror(eoferr); \ else \ return END; \ (c) = (unsigned char) *lexptr++; \ --lexleft; \ } #define FUNC(F, P) static int F(c) int c; { return P(c); } FUNC(is_alpha, ISALPHA) FUNC(is_upper, ISUPPER) FUNC(is_lower, ISLOWER) FUNC(is_digit, ISDIGIT) FUNC(is_xdigit, ISXDIGIT) FUNC(is_space, ISSPACE) FUNC(is_punct, ISPUNCT) FUNC(is_alnum, ISALNUM) FUNC(is_print, ISPRINT) FUNC(is_graph, ISGRAPH) FUNC(is_cntrl, ISCNTRL) /* The following list maps the names of the Posix named character classes to predicate functions that determine whether a given character is in the class. The leading [ has already been eaten by the lexical analyzer. */ static struct { char *name; int (*pred)(); } prednames[] = { ":alpha:]", is_alpha, ":upper:]", is_upper, ":lower:]", is_lower, ":digit:]", is_digit, ":xdigit:]", is_xdigit, ":space:]", is_space, ":punct:]", is_punct, ":alnum:]", is_alnum, ":print:]", is_print, ":graph:]", is_graph, ":cntrl:]", is_cntrl, 0 }; static int looking_at(s) char *s; { int len; len = strlen(s); if (lexleft < len) return 0; return strncmp(s, lexptr, len) == 0; } static token lex() { token c, c1, c2; int backslash = 0, invert; charclass ccl; int i; /* Basic plan: We fetch a character. If it's a backslash, we set the backslash flag and go through the loop again. On the plus side, this avoids having a duplicate of the main switch inside the backslash case. On the minus side, it means that just about every case begins with "if (backslash) ...". */ for (i = 0; i < 2; ++i) { FETCH(c, 0); switch (c) { case '\\': if (backslash) goto normal_char; if (lexleft == 0) dfaerror("Unfinished \\ escape"); backslash = 1; break; case '^': if (backslash) goto normal_char; if (syntax_bits & RE_CONTEXT_INDEP_ANCHORS || lasttok == END || lasttok == LPAREN || lasttok == OR) return lasttok = BEGLINE; goto normal_char; case '$': if (backslash) goto normal_char; if (syntax_bits & RE_CONTEXT_INDEP_ANCHORS || lexleft == 0 || (syntax_bits & RE_NO_BK_PARENS ? lexleft > 0 && *lexptr == ')' : lexleft > 1 && lexptr[0] == '\\' && lexptr[1] == ')') || (syntax_bits & RE_NO_BK_VBAR ? lexleft > 0 && *lexptr == '|' : lexleft > 1 && lexptr[0] == '\\' && lexptr[1] == '|') || ((syntax_bits & RE_NEWLINE_ALT) && lexleft > 0 && *lexptr == '\n')) return lasttok = ENDLINE; goto normal_char; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (backslash && !(syntax_bits & RE_NO_BK_REFS)) { laststart = 0; return lasttok = BACKREF; } goto normal_char; case '<': if (backslash) return lasttok = BEGWORD; goto normal_char; case '>': if (backslash) return lasttok = ENDWORD; goto normal_char; case 'b': if (backslash) return lasttok = LIMWORD; goto normal_char; case 'B': if (backslash) return lasttok = NOTLIMWORD; goto normal_char; case '?': if (syntax_bits & RE_LIMITED_OPS) goto normal_char; if (backslash != ((syntax_bits & RE_BK_PLUS_QM) != 0)) goto normal_char; if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart) goto normal_char; return lasttok = QMARK; case '*': if (backslash) goto normal_char; if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart) goto normal_char; return lasttok = STAR; case '+': if (syntax_bits & RE_LIMITED_OPS) goto normal_char; if (backslash != ((syntax_bits & RE_BK_PLUS_QM) != 0)) goto normal_char; if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart) goto normal_char; return lasttok = PLUS; case '{': if (!(syntax_bits & RE_INTERVALS)) goto normal_char; if (backslash != ((syntax_bits & RE_NO_BK_BRACES) == 0)) goto normal_char; minrep = maxrep = 0; /* Cases: {M} - exact count {M,} - minimum count, maximum is infinity {,M} - 0 through M {M,N} - M through N */ FETCH(c, "unfinished repeat count"); if (ISDIGIT(c)) { minrep = c - '0'; for (;;) { FETCH(c, "unfinished repeat count"); if (!ISDIGIT(c)) break; minrep = 10 * minrep + c - '0'; } } else if (c != ',') dfaerror("malformed repeat count"); if (c == ',') for (;;) { FETCH(c, "unfinished repeat count"); if (!ISDIGIT(c)) break; maxrep = 10 * maxrep + c - '0'; } else maxrep = minrep; if (!(syntax_bits & RE_NO_BK_BRACES)) { if (c != '\\') dfaerror("malformed repeat count"); FETCH(c, "unfinished repeat count"); } if (c != '}') dfaerror("malformed repeat count"); laststart = 0; return lasttok = REPMN; case '|': if (syntax_bits & RE_LIMITED_OPS) goto normal_char; if (backslash != ((syntax_bits & RE_NO_BK_VBAR) == 0)) goto normal_char; laststart = 1; return lasttok = OR; case '\n': if (syntax_bits & RE_LIMITED_OPS || backslash || !(syntax_bits & RE_NEWLINE_ALT)) goto normal_char; laststart = 1; return lasttok = OR; case '(': if (backslash != ((syntax_bits & RE_NO_BK_PARENS) == 0)) goto normal_char; ++parens; laststart = 1; return lasttok = LPAREN; case ')': if (backslash != ((syntax_bits & RE_NO_BK_PARENS) == 0)) goto normal_char; if (parens == 0 && syntax_bits & RE_UNMATCHED_RIGHT_PAREN_ORD) goto normal_char; --parens; laststart = 0; return lasttok = RPAREN; case '.': if (backslash) goto normal_char; zeroset(ccl); notset(ccl); if (!(syntax_bits & RE_DOT_NEWLINE)) clrbit('\n', ccl); if (syntax_bits & RE_DOT_NOT_NULL) clrbit('\0', ccl); laststart = 0; return lasttok = CSET + charclass_index(ccl); case 'w': case 'W': if (!backslash) goto normal_char; zeroset(ccl); for (c2 = 0; c2 < NOTCHAR; ++c2) if (ISALNUM(c2)) setbit(c2, ccl); if (c == 'W') notset(ccl); laststart = 0; return lasttok = CSET + charclass_index(ccl); case '[': if (backslash) goto normal_char; zeroset(ccl); FETCH(c, "Unbalanced ["); if (c == '^') { FETCH(c, "Unbalanced ["); invert = 1; } else invert = 0; do { /* Nobody ever said this had to be fast. :-) Note that if we're looking at some other [:...:] construct, we just treat it as a bunch of ordinary characters. We can do this because we assume regex has checked for syntax errors before dfa is ever called. */ if (c == '[' && (syntax_bits & RE_CHAR_CLASSES)) for (c1 = 0; prednames[c1].name; ++c1) if (looking_at(prednames[c1].name)) { for (c2 = 0; c2 < NOTCHAR; ++c2) if ((*prednames[c1].pred)(c2)) setbit(c2, ccl); lexptr += strlen(prednames[c1].name); lexleft -= strlen(prednames[c1].name); FETCH(c1, "Unbalanced ["); goto skip; } if (c == '\\' && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS)) FETCH(c, "Unbalanced ["); FETCH(c1, "Unbalanced ["); if (c1 == '-') { FETCH(c2, "Unbalanced ["); if (c2 == ']') { /* In the case [x-], the - is an ordinary hyphen, which is left in c1, the lookahead character. */ --lexptr; ++lexleft; c2 = c; } else { if (c2 == '\\' && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS)) FETCH(c2, "Unbalanced ["); FETCH(c1, "Unbalanced ["); } } else c2 = c; while (c <= c2) { setbit(c, ccl); if (case_fold) if (ISUPPER(c)) setbit(tolower(c), ccl); else if (ISLOWER(c)) setbit(toupper(c), ccl); ++c; } skip: ; } while ((c = c1) != ']'); if (invert) { notset(ccl); if (syntax_bits & RE_HAT_LISTS_NOT_NEWLINE) clrbit('\n', ccl); } laststart = 0; return lasttok = CSET + charclass_index(ccl); default: normal_char: laststart = 0; if (case_fold && ISALPHA(c)) { zeroset(ccl); setbit(c, ccl); if (isupper(c)) setbit(tolower(c), ccl); else setbit(toupper(c), ccl); return lasttok = CSET + charclass_index(ccl); } return c; } } /* The above loop should consume at most a backslash and some other character. */ abort(); } /* Recursive descent parser for regular expressions. */ static token tok; /* Lookahead token. */ static depth; /* Current depth of a hypothetical stack holding deferred productions. This is used to determine the depth that will be required of the real stack later on in dfaanalyze(). */ /* Add the given token to the parse tree, maintaining the depth count and updating the maximum depth if necessary. */ static void addtok(t) token t; { REALLOC_IF_NECESSARY(dfa->tokens, token, dfa->talloc, dfa->tindex); dfa->tokens[dfa->tindex++] = t; switch (t) { case QMARK: case STAR: case PLUS: break; case CAT: case OR: case ORTOP: --depth; break; default: ++dfa->nleaves; case EMPTY: ++depth; break; } if (depth > dfa->depth) dfa->depth = depth; } /* The grammar understood by the parser is as follows. regexp: regexp OR branch branch branch: branch closure closure closure: closure QMARK closure STAR closure PLUS atom atom: CSET BACKREF BEGLINE ENDLINE BEGWORD ENDWORD LIMWORD NOTLIMWORD The parser builds a parse tree in postfix form in an array of tokens. */ #if __STDC__ static void regexp(int); #else static void regexp(); #endif static void atom() { if ((tok >= 0 && tok < NOTCHAR) || tok >= CSET || tok == BACKREF || tok == BEGLINE || tok == ENDLINE || tok == BEGWORD || tok == ENDWORD || tok == LIMWORD || tok == NOTLIMWORD) { addtok(tok); tok = lex(); } else if (tok == LPAREN) { tok = lex(); regexp(0); if (tok != RPAREN) dfaerror("Unbalanced ("); tok = lex(); } else addtok(EMPTY); } /* Return the number of tokens in the given subexpression. */ static int nsubtoks(tindex) { int ntoks1; switch (dfa->tokens[tindex - 1]) { default: return 1; case QMARK: case STAR: case PLUS: return 1 + nsubtoks(tindex - 1); case CAT: case OR: case ORTOP: ntoks1 = nsubtoks(tindex - 1); return 1 + ntoks1 + nsubtoks(tindex - 1 - ntoks1); } } /* Copy the given subexpression to the top of the tree. */ static void copytoks(tindex, ntokens) int tindex, ntokens; { int i; for (i = 0; i < ntokens; ++i) addtok(dfa->tokens[tindex + i]); } static void closure() { int tindex, ntokens, i; atom(); while (tok == QMARK || tok == STAR || tok == PLUS || tok == REPMN) if (tok == REPMN) { ntokens = nsubtoks(dfa->tindex); tindex = dfa->tindex - ntokens; if (maxrep == 0) addtok(PLUS); if (minrep == 0) addtok(QMARK); for (i = 1; i < minrep; ++i) { copytoks(tindex, ntokens); addtok(CAT); } for (; i < maxrep; ++i) { copytoks(tindex, ntokens); addtok(QMARK); addtok(CAT); } tok = lex(); } else { addtok(tok); tok = lex(); } } static void branch() { closure(); while (tok != RPAREN && tok != OR && tok >= 0) { closure(); addtok(CAT); } } static void regexp(toplevel) int toplevel; { branch(); while (tok == OR) { tok = lex(); branch(); if (toplevel) addtok(ORTOP); else addtok(OR); } } /* Main entry point for the parser. S is a string to be parsed, len is the length of the string, so s can include NUL characters. D is a pointer to the struct dfa to parse into. */ void dfaparse(s, len, d) char *s; size_t len; struct dfa *d; { dfa = d; lexstart = lexptr = s; lexleft = len; lasttok = END; laststart = 1; parens = 0; if (! syntax_bits_set) dfaerror("No syntax specified"); tok = lex(); depth = d->depth; regexp(1); if (tok != END) dfaerror("Unbalanced )"); addtok(END - d->nregexps); addtok(CAT); if (d->nregexps) addtok(ORTOP); ++d->nregexps; } /* Some primitives for operating on sets of positions. */ /* Copy one set to another; the destination must be large enough. */ static void copy(src, dst) position_set *src; position_set *dst; { int i; for (i = 0; i < src->nelem; ++i) dst->elems[i] = src->elems[i]; dst->nelem = src->nelem; } /* Insert a position in a set. Position sets are maintained in sorted order according to index. If position already exists in the set with the same index then their constraints are logically or'd together. S->elems must point to an array large enough to hold the resulting set. */ static void insert(p, s) position p; position_set *s; { int i; position t1, t2; for (i = 0; i < s->nelem && p.index < s->elems[i].index; ++i) ; if (i < s->nelem && p.index == s->elems[i].index) s->elems[i].constraint |= p.constraint; else { t1 = p; ++s->nelem; while (i < s->nelem) { t2 = s->elems[i]; s->elems[i++] = t1; t1 = t2; } } } /* Merge two sets of positions into a third. The result is exactly as if the positions of both sets were inserted into an initially empty set. */ static void merge(s1, s2, m) position_set *s1; position_set *s2; position_set *m; { int i = 0, j = 0; m->nelem = 0; while (i < s1->nelem && j < s2->nelem) if (s1->elems[i].index > s2->elems[j].index) m->elems[m->nelem++] = s1->elems[i++]; else if (s1->elems[i].index < s2->elems[j].index) m->elems[m->nelem++] = s2->elems[j++]; else { m->elems[m->nelem] = s1->elems[i++]; m->elems[m->nelem++].constraint |= s2->elems[j++].constraint; } while (i < s1->nelem) m->elems[m->nelem++] = s1->elems[i++]; while (j < s2->nelem) m->elems[m->nelem++] = s2->elems[j++]; } /* Delete a position from a set. */ static void delete(p, s) position p; position_set *s; { int i; for (i = 0; i < s->nelem; ++i) if (p.index == s->elems[i].index) break; if (i < s->nelem) for (--s->nelem; i < s->nelem; ++i) s->elems[i] = s->elems[i + 1]; } /* Find the index of the state corresponding to the given position set with the given preceding context, or create a new state if there is no such state. Newline and letter tell whether we got here on a newline or letter, respectively. */ static int state_index(d, s, newline, letter) struct dfa *d; position_set *s; int newline; int letter; { int hash = 0; int constraint; int i, j; newline = newline ? 1 : 0; letter = letter ? 1 : 0; for (i = 0; i < s->nelem; ++i) hash ^= s->elems[i].index + s->elems[i].constraint; /* Try to find a state that exactly matches the proposed one. */ for (i = 0; i < d->sindex; ++i) { if (hash != d->states[i].hash || s->nelem != d->states[i].elems.nelem || newline != d->states[i].newline || letter != d->states[i].letter) continue; for (j = 0; j < s->nelem; ++j) if (s->elems[j].constraint != d->states[i].elems.elems[j].constraint || s->elems[j].index != d->states[i].elems.elems[j].index) break; if (j == s->nelem) return i; } /* We'll have to create a new state. */ REALLOC_IF_NECESSARY(d->states, dfa_state, d->salloc, d->sindex); d->states[i].hash = hash; MALLOC(d->states[i].elems.elems, position, s->nelem); copy(s, &d->states[i].elems); d->states[i].newline = newline; d->states[i].letter = letter; d->states[i].backref = 0; d->states[i].constraint = 0; d->states[i].first_end = 0; for (j = 0; j < s->nelem; ++j) if (d->tokens[s->elems[j].index] < 0) { constraint = s->elems[j].constraint; if (SUCCEEDS_IN_CONTEXT(constraint, newline, 0, letter, 0) || SUCCEEDS_IN_CONTEXT(constraint, newline, 0, letter, 1) || SUCCEEDS_IN_CONTEXT(constraint, newline, 1, letter, 0) || SUCCEEDS_IN_CONTEXT(constraint, newline, 1, letter, 1)) d->states[i].constraint |= constraint; if (! d->states[i].first_end) d->states[i].first_end = d->tokens[s->elems[j].index]; } else if (d->tokens[s->elems[j].index] == BACKREF) { d->states[i].constraint = NO_CONSTRAINT; d->states[i].backref = 1; } ++d->sindex; return i; } /* Find the epsilon closure of a set of positions. If any position of the set contains a symbol that matches the empty string in some context, replace that position with the elements of its follow labeled with an appropriate constraint. Repeat exhaustively until no funny positions are left. S->elems must be large enough to hold the result. */ void epsclosure(s, d) position_set *s; struct dfa *d; { int i, j; int *visited; position p, old; MALLOC(visited, int, d->tindex); for (i = 0; i < d->tindex; ++i) visited[i] = 0; for (i = 0; i < s->nelem; ++i) if (d->tokens[s->elems[i].index] >= NOTCHAR && d->tokens[s->elems[i].index] != BACKREF && d->tokens[s->elems[i].index] < CSET) { old = s->elems[i]; p.constraint = old.constraint; delete(s->elems[i], s); if (visited[old.index]) { --i; continue; } visited[old.index] = 1; switch (d->tokens[old.index]) { case BEGLINE: p.constraint &= BEGLINE_CONSTRAINT; break; case ENDLINE: p.constraint &= ENDLINE_CONSTRAINT; break; case BEGWORD: p.constraint &= BEGWORD_CONSTRAINT; break; case ENDWORD: p.constraint &= ENDWORD_CONSTRAINT; break; case LIMWORD: p.constraint &= LIMWORD_CONSTRAINT; break; case NOTLIMWORD: p.constraint &= NOTLIMWORD_CONSTRAINT; break; default: break; } for (j = 0; j < d->follows[old.index].nelem; ++j) { p.index = d->follows[old.index].elems[j].index; insert(p, s); } /* Force rescan to start at the beginning. */ i = -1; } free(visited); } /* Perform bottom-up analysis on the parse tree, computing various functions. Note that at this point, we're pretending constructs like \< are real characters rather than constraints on what can follow them. Nullable: A node is nullable if it is at the root of a regexp that can match the empty string. * EMPTY leaves are nullable. * No other leaf is nullable. * A QMARK or STAR node is nullable. * A PLUS node is nullable if its argument is nullable. * A CAT node is nullable if both its arguments are nullable. * An OR node is nullable if either argument is nullable. Firstpos: The firstpos of a node is the set of positions (nonempty leaves) that could correspond to the first character of a string matching the regexp rooted at the given node. * EMPTY leaves have empty firstpos. * The firstpos of a nonempty leaf is that leaf itself. * The firstpos of a QMARK, STAR, or PLUS node is the firstpos of its argument. * The firstpos of a CAT node is the firstpos of the left argument, union the firstpos of the right if the left argument is nullable. * The firstpos of an OR node is the union of firstpos of each argument. Lastpos: The lastpos of a node is the set of positions that could correspond to the last character of a string matching the regexp at the given node. * EMPTY leaves have empty lastpos. * The lastpos of a nonempty leaf is that leaf itself. * The lastpos of a QMARK, STAR, or PLUS node is the lastpos of its argument. * The lastpos of a CAT node is the lastpos of its right argument, union the lastpos of the left if the right argument is nullable. * The lastpos of an OR node is the union of the lastpos of each argument. Follow: The follow of a position is the set of positions that could correspond to the character following a character matching the node in a string matching the regexp. At this point we consider special symbols that match the empty string in some context to be just normal characters. Later, if we find that a special symbol is in a follow set, we will replace it with the elements of its follow, labeled with an appropriate constraint. * Every node in the firstpos of the argument of a STAR or PLUS node is in the follow of every node in the lastpos. * Every node in the firstpos of the second argument of a CAT node is in the follow of every node in the lastpos of the first argument. Because of the postfix representation of the parse tree, the depth-first analysis is conveniently done by a linear scan with the aid of a stack. Sets are stored as arrays of the elements, obeying a stack-like allocation scheme; the number of elements in each set deeper in the stack can be used to determine the address of a particular set's array. */ void dfaanalyze(d, searchflag) struct dfa *d; int searchflag; { int *nullable; /* Nullable stack. */ int *nfirstpos; /* Element count stack for firstpos sets. */ position *firstpos; /* Array where firstpos elements are stored. */ int *nlastpos; /* Element count stack for lastpos sets. */ position *lastpos; /* Array where lastpos elements are stored. */ int *nalloc; /* Sizes of arrays allocated to follow sets. */ position_set tmp; /* Temporary set for merging sets. */ position_set merged; /* Result of merging sets. */ int wants_newline; /* True if some position wants newline info. */ int *o_nullable; int *o_nfirst, *o_nlast; position *o_firstpos, *o_lastpos; int i, j; position *pos; #ifdef DEBUG fprintf(stderr, "dfaanalyze:\n"); for (i = 0; i < d->tindex; ++i) { fprintf(stderr, " %d:", i); prtok(d->tokens[i]); } putc('\n', stderr); #endif d->searchflag = searchflag; MALLOC(nullable, int, d->depth); o_nullable = nullable; MALLOC(nfirstpos, int, d->depth); o_nfirst = nfirstpos; MALLOC(firstpos, position, d->nleaves); o_firstpos = firstpos, firstpos += d->nleaves; MALLOC(nlastpos, int, d->depth); o_nlast = nlastpos; MALLOC(lastpos, position, d->nleaves); o_lastpos = lastpos, lastpos += d->nleaves; MALLOC(nalloc, int, d->tindex); for (i = 0; i < d->tindex; ++i) nalloc[i] = 0; MALLOC(merged.elems, position, d->nleaves); CALLOC(d->follows, position_set, d->tindex); for (i = 0; i < d->tindex; ++i) #ifdef DEBUG { /* Nonsyntactic #ifdef goo... */ #endif switch (d->tokens[i]) { case EMPTY: /* The empty set is nullable. */ *nullable++ = 1; /* The firstpos and lastpos of the empty leaf are both empty. */ *nfirstpos++ = *nlastpos++ = 0; break; case STAR: case PLUS: /* Every element in the firstpos of the argument is in the follow of every element in the lastpos. */ tmp.nelem = nfirstpos[-1]; tmp.elems = firstpos; pos = lastpos; for (j = 0; j < nlastpos[-1]; ++j) { merge(&tmp, &d->follows[pos[j].index], &merged); REALLOC_IF_NECESSARY(d->follows[pos[j].index].elems, position, nalloc[pos[j].index], merged.nelem - 1); copy(&merged, &d->follows[pos[j].index]); } case QMARK: /* A QMARK or STAR node is automatically nullable. */ if (d->tokens[i] != PLUS) nullable[-1] = 1; break; case CAT: /* Every element in the firstpos of the second argument is in the follow of every element in the lastpos of the first argument. */ tmp.nelem = nfirstpos[-1]; tmp.elems = firstpos; pos = lastpos + nlastpos[-1]; for (j = 0; j < nlastpos[-2]; ++j) { merge(&tmp, &d->follows[pos[j].index], &merged); REALLOC_IF_NECESSARY(d->follows[pos[j].index].elems, position, nalloc[pos[j].index], merged.nelem - 1); copy(&merged, &d->follows[pos[j].index]); } /* The firstpos of a CAT node is the firstpos of the first argument, union that of the second argument if the first is nullable. */ if (nullable[-2]) nfirstpos[-2] += nfirstpos[-1]; else firstpos += nfirstpos[-1]; --nfirstpos; /* The lastpos of a CAT node is the lastpos of the second argument, union that of the first argument if the second is nullable. */ if (nullable[-1]) nlastpos[-2] += nlastpos[-1]; else { pos = lastpos + nlastpos[-2]; for (j = nlastpos[-1] - 1; j >= 0; --j) pos[j] = lastpos[j]; lastpos += nlastpos[-2]; nlastpos[-2] = nlastpos[-1]; } --nlastpos; /* A CAT node is nullable if both arguments are nullable. */ nullable[-2] = nullable[-1] && nullable[-2]; --nullable; break; case OR: case ORTOP: /* The firstpos is the union of the firstpos of each argument. */ nfirstpos[-2] += nfirstpos[-1]; --nfirstpos; /* The lastpos is the union of the lastpos of each argument. */ nlastpos[-2] += nlastpos[-1]; --nlastpos; /* An OR node is nullable if either argument is nullable. */ nullable[-2] = nullable[-1] || nullable[-2]; --nullable; break; default: /* Anything else is a nonempty position. (Note that special constructs like \< are treated as nonempty strings here; an "epsilon closure" effectively makes them nullable later. Backreferences have to get a real position so we can detect transitions on them later. But they are nullable. */ *nullable++ = d->tokens[i] == BACKREF; /* This position is in its own firstpos and lastpos. */ *nfirstpos++ = *nlastpos++ = 1; --firstpos, --lastpos; firstpos->index = lastpos->index = i; firstpos->constraint = lastpos->constraint = NO_CONSTRAINT; /* Allocate the follow set for this position. */ nalloc[i] = 1; MALLOC(d->follows[i].elems, position, nalloc[i]); break; } #ifdef DEBUG /* ... balance the above nonsyntactic #ifdef goo... */ fprintf(stderr, "node %d:", i); prtok(d->tokens[i]); putc('\n', stderr); fprintf(stderr, nullable[-1] ? " nullable: yes\n" : " nullable: no\n"); fprintf(stderr, " firstpos:"); for (j = nfirstpos[-1] - 1; j >= 0; --j) { fprintf(stderr, " %d:", firstpos[j].index); prtok(d->tokens[firstpos[j].index]); } fprintf(stderr, "\n lastpos:"); for (j = nlastpos[-1] - 1; j >= 0; --j) { fprintf(stderr, " %d:", lastpos[j].index); prtok(d->tokens[lastpos[j].index]); } putc('\n', stderr); } #endif /* For each follow set that is the follow set of a real position, replace it with its epsilon closure. */ for (i = 0; i < d->tindex; ++i) if (d->tokens[i] < NOTCHAR || d->tokens[i] == BACKREF || d->tokens[i] >= CSET) { #ifdef DEBUG fprintf(stderr, "follows(%d:", i); prtok(d->tokens[i]); fprintf(stderr, "):"); for (j = d->follows[i].nelem - 1; j >= 0; --j) { fprintf(stderr, " %d:", d->follows[i].elems[j].index); prtok(d->tokens[d->follows[i].elems[j].index]); } putc('\n', stderr); #endif copy(&d->follows[i], &merged); epsclosure(&merged, d); if (d->follows[i].nelem < merged.nelem) REALLOC(d->follows[i].elems, position, merged.nelem); copy(&merged, &d->follows[i]); } /* Get the epsilon closure of the firstpos of the regexp. The result will be the set of positions of state 0. */ merged.nelem = 0; for (i = 0; i < nfirstpos[-1]; ++i) insert(firstpos[i], &merged); epsclosure(&merged, d); /* Check if any of the positions of state 0 will want newline context. */ wants_newline = 0; for (i = 0; i < merged.nelem; ++i) if (PREV_NEWLINE_DEPENDENT(merged.elems[i].constraint)) wants_newline = 1; /* Build the initial state. */ d->salloc = 1; d->sindex = 0; MALLOC(d->states, dfa_state, d->salloc); state_index(d, &merged, wants_newline, 0); free(o_nullable); free(o_nfirst); free(o_firstpos); free(o_nlast); free(o_lastpos); free(nalloc); free(merged.elems); } /* Find, for each character, the transition out of state s of d, and store it in the appropriate slot of trans. We divide the positions of s into groups (positions can appear in more than one group). Each group is labeled with a set of characters that every position in the group matches (taking into account, if necessary, preceding context information of s). For each group, find the union of the its elements' follows. This set is the set of positions of the new state. For each character in the group's label, set the transition on this character to be to a state corresponding to the set's positions, and its associated backward context information, if necessary. If we are building a searching matcher, we include the positions of state 0 in every state. The collection of groups is constructed by building an equivalence-class partition of the positions of s. For each position, find the set of characters C that it matches. Eliminate any characters from C that fail on grounds of backward context. Search through the groups, looking for a group whose label L has nonempty intersection with C. If L - C is nonempty, create a new group labeled L - C and having the same positions as the current group, and set L to the intersection of L and C. Insert the position in this group, set C = C - L, and resume scanning. If after comparing with every group there are characters remaining in C, create a new group labeled with the characters of C and insert this position in that group. */ void dfastate(s, d, trans) int s; struct dfa *d; int trans[]; { position_set grps[NOTCHAR]; /* As many as will ever be needed. */ charclass labels[NOTCHAR]; /* Labels corresponding to the groups. */ int ngrps = 0; /* Number of groups actually used. */ position pos; /* Current position being considered. */ charclass matches; /* Set of matching characters. */ int matchesf; /* True if matches is nonempty. */ charclass intersect; /* Intersection with some label set. */ int intersectf; /* True if intersect is nonempty. */ charclass leftovers; /* Stuff in the label that didn't match. */ int leftoversf; /* True if leftovers is nonempty. */ static charclass letters; /* Set of characters considered letters. */ static charclass newline; /* Set of characters that aren't newline. */ position_set follows; /* Union of the follows of some group. */ position_set tmp; /* Temporary space for merging sets. */ int state; /* New state. */ int wants_newline; /* New state wants to know newline context. */ int state_newline; /* New state on a newline transition. */ int wants_letter; /* New state wants to know letter context. */ int state_letter; /* New state on a letter transition. */ static initialized; /* Flag for static initialization. */ int i, j, k; /* Initialize the set of letters, if necessary. */ if (! initialized) { initialized = 1; for (i = 0; i < NOTCHAR; ++i) if (ISALNUM(i)) setbit(i, letters); setbit('\n', newline); } zeroset(matches); for (i = 0; i < d->states[s].elems.nelem; ++i) { pos = d->states[s].elems.elems[i]; if (d->tokens[pos.index] >= 0 && d->tokens[pos.index] < NOTCHAR) setbit(d->tokens[pos.index], matches); else if (d->tokens[pos.index] >= CSET) copyset(d->charclasses[d->tokens[pos.index] - CSET], matches); else continue; /* Some characters may need to be eliminated from matches because they fail in the current context. */ if (pos.constraint != 0xFF) { if (! MATCHES_NEWLINE_CONTEXT(pos.constraint, d->states[s].newline, 1)) clrbit('\n', matches); if (! MATCHES_NEWLINE_CONTEXT(pos.constraint, d->states[s].newline, 0)) for (j = 0; j < CHARCLASS_INTS; ++j) matches[j] &= newline[j]; if (! MATCHES_LETTER_CONTEXT(pos.constraint, d->states[s].letter, 1)) for (j = 0; j < CHARCLASS_INTS; ++j) matches[j] &= ~letters[j]; if (! MATCHES_LETTER_CONTEXT(pos.constraint, d->states[s].letter, 0)) for (j = 0; j < CHARCLASS_INTS; ++j) matches[j] &= letters[j]; /* If there are no characters left, there's no point in going on. */ for (j = 0; j < CHARCLASS_INTS && !matches[j]; ++j) ; if (j == CHARCLASS_INTS) continue; } for (j = 0; j < ngrps; ++j) { /* If matches contains a single character only, and the current group's label doesn't contain that character, go on to the next group. */ if (d->tokens[pos.index] >= 0 && d->tokens[pos.index] < NOTCHAR && !tstbit(d->tokens[pos.index], labels[j])) continue; /* Check if this group's label has a nonempty intersection with matches. */ intersectf = 0; for (k = 0; k < CHARCLASS_INTS; ++k) (intersect[k] = matches[k] & labels[j][k]) ? intersectf = 1 : 0; if (! intersectf) continue; /* It does; now find the set differences both ways. */ leftoversf = matchesf = 0; for (k = 0; k < CHARCLASS_INTS; ++k) { /* Even an optimizing compiler can't know this for sure. */ int match = matches[k], label = labels[j][k]; (leftovers[k] = ~match & label) ? leftoversf = 1 : 0; (matches[k] = match & ~label) ? matchesf = 1 : 0; } /* If there were leftovers, create a new group labeled with them. */ if (leftoversf) { copyset(leftovers, labels[ngrps]); copyset(intersect, labels[j]); MALLOC(grps[ngrps].elems, position, d->nleaves); copy(&grps[j], &grps[ngrps]); ++ngrps; } /* Put the position in the current group. Note that there is no reason to call insert() here. */ grps[j].elems[grps[j].nelem++] = pos; /* If every character matching the current position has been accounted for, we're done. */ if (! matchesf) break; } /* If we've passed the last group, and there are still characters unaccounted for, then we'll have to create a new group. */ if (j == ngrps) { copyset(matches, labels[ngrps]); zeroset(matches); MALLOC(grps[ngrps].elems, position, d->nleaves); grps[ngrps].nelem = 1; grps[ngrps].elems[0] = pos; ++ngrps; } } MALLOC(follows.elems, position, d->nleaves); MALLOC(tmp.elems, position, d->nleaves); /* If we are a searching matcher, the default transition is to a state containing the positions of state 0, otherwise the default transition is to fail miserably. */ if (d->searchflag) { wants_newline = 0; wants_letter = 0; for (i = 0; i < d->states[0].elems.nelem; ++i) { if (PREV_NEWLINE_DEPENDENT(d->states[0].elems.elems[i].constraint)) wants_newline = 1; if (PREV_LETTER_DEPENDENT(d->states[0].elems.elems[i].constraint)) wants_letter = 1; } copy(&d->states[0].elems, &follows); state = state_index(d, &follows, 0, 0); if (wants_newline) state_newline = state_index(d, &follows, 1, 0); else state_newline = state; if (wants_letter) state_letter = state_index(d, &follows, 0, 1); else state_letter = state; for (i = 0; i < NOTCHAR; ++i) if (i == '\n') trans[i] = state_newline; else if (ISALNUM(i)) trans[i] = state_letter; else trans[i] = state; } else for (i = 0; i < NOTCHAR; ++i) trans[i] = -1; for (i = 0; i < ngrps; ++i) { follows.nelem = 0; /* Find the union of the follows of the positions of the group. This is a hideously inefficient loop. Fix it someday. */ for (j = 0; j < grps[i].nelem; ++j) for (k = 0; k < d->follows[grps[i].elems[j].index].nelem; ++k) insert(d->follows[grps[i].elems[j].index].elems[k], &follows); /* If we are building a searching matcher, throw in the positions of state 0 as well. */ if (d->searchflag) for (j = 0; j < d->states[0].elems.nelem; ++j) insert(d->states[0].elems.elems[j], &follows); /* Find out if the new state will want any context information. */ wants_newline = 0; if (tstbit('\n', labels[i])) for (j = 0; j < follows.nelem; ++j) if (PREV_NEWLINE_DEPENDENT(follows.elems[j].constraint)) wants_newline = 1; wants_letter = 0; for (j = 0; j < CHARCLASS_INTS; ++j) if (labels[i][j] & letters[j]) break; if (j < CHARCLASS_INTS) for (j = 0; j < follows.nelem; ++j) if (PREV_LETTER_DEPENDENT(follows.elems[j].constraint)) wants_letter = 1; /* Find the state(s) corresponding to the union of the follows. */ state = state_index(d, &follows, 0, 0); if (wants_newline) state_newline = state_index(d, &follows, 1, 0); else state_newline = state; if (wants_letter) state_letter = state_index(d, &follows, 0, 1); else state_letter = state; /* Set the transitions for each character in the current label. */ for (j = 0; j < CHARCLASS_INTS; ++j) for (k = 0; k < INTBITS; ++k) if (labels[i][j] & 1 << k) { int c = j * INTBITS + k; if (c == '\n') trans[c] = state_newline; else if (ISALNUM(c)) trans[c] = state_letter; else if (c < NOTCHAR) trans[c] = state; } } for (i = 0; i < ngrps; ++i) free(grps[i].elems); free(follows.elems); free(tmp.elems); } /* Some routines for manipulating a compiled dfa's transition tables. Each state may or may not have a transition table; if it does, and it is a non-accepting state, then d->trans[state] points to its table. If it is an accepting state then d->fails[state] points to its table. If it has no table at all, then d->trans[state] is NULL. TODO: Improve this comment, get rid of the unnecessary redundancy. */ static void build_state(s, d) int s; struct dfa *d; { int *trans; /* The new transition table. */ int i; /* Set an upper limit on the number of transition tables that will ever exist at once. 1024 is arbitrary. The idea is that the frequently used transition tables will be quickly rebuilt, whereas the ones that were only needed once or twice will be cleared away. */ if (d->trcount >= 1024) { for (i = 0; i < d->tralloc; ++i) if (d->trans[i]) { free((ptr_t) d->trans[i]); d->trans[i] = NULL; } else if (d->fails[i]) { free((ptr_t) d->fails[i]); d->fails[i] = NULL; } d->trcount = 0; } ++d->trcount; /* Set up the success bits for this state. */ d->success[s] = 0; if (ACCEPTS_IN_CONTEXT(d->states[s].newline, 1, d->states[s].letter, 0, s, *d)) d->success[s] |= 4; if (ACCEPTS_IN_CONTEXT(d->states[s].newline, 0, d->states[s].letter, 1, s, *d)) d->success[s] |= 2; if (ACCEPTS_IN_CONTEXT(d->states[s].newline, 0, d->states[s].letter, 0, s, *d)) d->success[s] |= 1; MALLOC(trans, int, NOTCHAR); dfastate(s, d, trans); /* Now go through the new transition table, and make sure that the trans and fail arrays are allocated large enough to hold a pointer for the largest state mentioned in the table. */ for (i = 0; i < NOTCHAR; ++i) if (trans[i] >= d->tralloc) { int oldalloc = d->tralloc; while (trans[i] >= d->tralloc) d->tralloc *= 2; REALLOC(d->realtrans, int *, d->tralloc + 1); d->trans = d->realtrans + 1; REALLOC(d->fails, int *, d->tralloc); REALLOC(d->success, int, d->tralloc); REALLOC(d->newlines, int, d->tralloc); while (oldalloc < d->tralloc) { d->trans[oldalloc] = NULL; d->fails[oldalloc++] = NULL; } } /* Keep the newline transition in a special place so we can use it as a sentinel. */ d->newlines[s] = trans['\n']; trans['\n'] = -1; if (ACCEPTING(s, *d)) d->fails[s] = trans; else d->trans[s] = trans; } static void build_state_zero(d) struct dfa *d; { d->tralloc = 1; d->trcount = 0; CALLOC(d->realtrans, int *, d->tralloc + 1); d->trans = d->realtrans + 1; CALLOC(d->fails, int *, d->tralloc); MALLOC(d->success, int, d->tralloc); MALLOC(d->newlines, int, d->tralloc); build_state(0, d); } /* Search through a buffer looking for a match to the given struct dfa. Find the first occurrence of a string matching the regexp in the buffer, and the shortest possible version thereof. Return a pointer to the first character after the match, or NULL if none is found. Begin points to the beginning of the buffer, and end points to the first character after its end. We store a newline in *end to act as a sentinel, so end had better point somewhere valid. Newline is a flag indicating whether to allow newlines to be in the matching string. If count is non- NULL it points to a place we're supposed to increment every time we see a newline. Finally, if backref is non-NULL it points to a place where we're supposed to store a 1 if backreferencing happened and the match needs to be verified by a backtracking matcher. Otherwise we store a 0 in *backref. */ char * dfaexec(d, begin, end, newline, count, backref) struct dfa *d; char *begin; char *end; int newline; int *count; int *backref; { register s, s1, tmp; /* Current state. */ register unsigned char *p; /* Current input character. */ register **trans, *t; /* Copy of d->trans so it can be optimized into a register. */ static sbit[NOTCHAR]; /* Table for anding with d->success. */ static sbit_init; if (! sbit_init) { int i; sbit_init = 1; for (i = 0; i < NOTCHAR; ++i) if (i == '\n') sbit[i] = 4; else if (ISALNUM(i)) sbit[i] = 2; else sbit[i] = 1; } if (! d->tralloc) build_state_zero(d); s = s1 = 0; p = (unsigned char *) begin; trans = d->trans; *end = '\n'; for (;;) { /* The dreaded inner loop. */ if ((t = trans[s]) != 0) do { s1 = t[*p++]; if (! (t = trans[s1])) goto last_was_s; s = t[*p++]; } while ((t = trans[s]) != 0); goto last_was_s1; last_was_s: tmp = s, s = s1, s1 = tmp; last_was_s1: if (s >= 0 && p <= (unsigned char *) end && d->fails[s]) { if (d->success[s] & sbit[*p]) { if (backref) if (d->states[s].backref) *backref = 1; else *backref = 0; return (char *) p; } s1 = s; s = d->fails[s][*p++]; continue; } /* If the previous character was a newline, count it. */ if (count && (char *) p <= end && p[-1] == '\n') ++*count; /* Check if we've run off the end of the buffer. */ if ((char *) p > end) return NULL; if (s >= 0) { build_state(s, d); trans = d->trans; continue; } if (p[-1] == '\n' && newline) { s = d->newlines[s1]; continue; } s = 0; } } /* Initialize the components of a dfa that the other routines don't initialize for themselves. */ void dfainit(d) struct dfa *d; { d->calloc = 1; MALLOC(d->charclasses, charclass, d->calloc); d->cindex = 0; d->talloc = 1; MALLOC(d->tokens, token, d->talloc); d->tindex = d->depth = d->nleaves = d->nregexps = 0; d->searchflag = 0; d->tralloc = 0; d->musts = 0; } /* Parse and analyze a single string of the given length. */ void dfacomp(s, len, d, searchflag) char *s; size_t len; struct dfa *d; int searchflag; { if (case_fold) /* dummy folding in service of dfamust() */ { char *copy; int i; copy = malloc(len); if (!copy) dfaerror("out of memory"); /* This is a kludge. */ case_fold = 0; for (i = 0; i < len; ++i) if (ISUPPER(s[i])) copy[i] = tolower(s[i]); else copy[i] = s[i]; dfainit(d); dfaparse(copy, len, d); free(copy); dfamust(d); d->cindex = d->tindex = d->depth = d->nleaves = d->nregexps = 0; case_fold = 1; dfaparse(s, len, d); dfaanalyze(d, searchflag); } else { dfainit(d); dfaparse(s, len, d); dfamust(d); dfaanalyze(d, searchflag); } } /* Free the storage held by the components of a dfa. */ void dfafree(d) struct dfa *d; { int i; struct dfamust *dm, *ndm; free((ptr_t) d->charclasses); free((ptr_t) d->tokens); for (i = 0; i < d->sindex; ++i) free((ptr_t) d->states[i].elems.elems); free((ptr_t) d->states); for (i = 0; i < d->tindex; ++i) if (d->follows[i].elems) free((ptr_t) d->follows[i].elems); free((ptr_t) d->follows); for (i = 0; i < d->tralloc; ++i) if (d->trans[i]) free((ptr_t) d->trans[i]); else if (d->fails[i]) free((ptr_t) d->fails[i]); free((ptr_t) d->realtrans); free((ptr_t) d->fails); free((ptr_t) d->newlines); for (dm = d->musts; dm; dm = ndm) { ndm = dm->next; free(dm->must); free((ptr_t) dm); } } /* Having found the postfix representation of the regular expression, try to find a long sequence of characters that must appear in any line containing the r.e. Finding a "longest" sequence is beyond the scope here; we take an easy way out and hope for the best. (Take "(ab|a)b"--please.) We do a bottom-up calculation of sequences of characters that must appear in matches of r.e.'s represented by trees rooted at the nodes of the postfix representation: sequences that must appear at the left of the match ("left") sequences that must appear at the right of the match ("right") lists of sequences that must appear somewhere in the match ("in") sequences that must constitute the match ("is") When we get to the root of the tree, we use one of the longest of its calculated "in" sequences as our answer. The sequence we find is returned in d->must (where "d" is the single argument passed to "dfamust"); the length of the sequence is returned in d->mustn. The sequences calculated for the various types of node (in pseudo ANSI c) are shown below. "p" is the operand of unary operators (and the left-hand operand of binary operators); "q" is the right-hand operand of binary operators. "ZERO" means "a zero-length sequence" below. Type left right is in ---- ---- ----- -- -- char c # c # c # c # c CSET ZERO ZERO ZERO ZERO STAR ZERO ZERO ZERO ZERO QMARK ZERO ZERO ZERO ZERO PLUS p->left p->right ZERO p->in CAT (p->is==ZERO)? (q->is==ZERO)? (p->is!=ZERO && p->in plus p->left : q->right : q->is!=ZERO) ? q->in plus p->is##q->left p->right##q->is p->is##q->is : p->right##q->left ZERO OR longest common longest common (do p->is and substrings common to leading trailing q->is have same p->in and q->in (sub)sequence (sub)sequence length and of p->left of p->right content) ? and q->left and q->right p->is : NULL If there's anything else we recognize in the tree, all four sequences get set to zero-length sequences. If there's something we don't recognize in the tree, we just return a zero-length sequence. Break ties in favor of infrequent letters (choosing 'zzz' in preference to 'aaa')? And. . .is it here or someplace that we might ponder "optimizations" such as egrep 'psi|epsilon' -> egrep 'psi' egrep 'pepsi|epsilon' -> egrep 'epsi' (Yes, we now find "epsi" as a "string that must occur", but we might also simplify the *entire* r.e. being sought) grep '[c]' -> grep 'c' grep '(ab|a)b' -> grep 'ab' grep 'ab*' -> grep 'a' grep 'a*b' -> grep 'b' There are several issues: Is optimization easy (enough)? Does optimization actually accomplish anything, or is the automaton you get from "psi|epsilon" (for example) the same as the one you get from "psi" (for example)? Are optimizable r.e.'s likely to be used in real-life situations (something like 'ab*' is probably unlikely; something like is 'psi|epsilon' is likelier)? */ static char * icatalloc(old, new) char *old; char *new; { char *result; int oldsize, newsize; newsize = (new == NULL) ? 0 : strlen(new); if (old == NULL) oldsize = 0; else if (newsize == 0) return old; else oldsize = strlen(old); if (old == NULL) result = (char *) malloc(newsize + 1); else result = (char *) realloc((void *) old, oldsize + newsize + 1); if (result != NULL && new != NULL) (void) strcpy(result + oldsize, new); return result; } static char * icpyalloc(string) char *string; { return icatalloc((char *) NULL, string); } static char * istrstr(lookin, lookfor) char *lookin; char *lookfor; { char *cp; int len; len = strlen(lookfor); for (cp = lookin; *cp != '\0'; ++cp) if (strncmp(cp, lookfor, len) == 0) return cp; return NULL; } static void ifree(cp) char *cp; { if (cp != NULL) free(cp); } static void freelist(cpp) char **cpp; { int i; if (cpp == NULL) return; for (i = 0; cpp[i] != NULL; ++i) { free(cpp[i]); cpp[i] = NULL; } } static char ** enlist(cpp, new, len) char **cpp; char *new; int len; { int i, j; if (cpp == NULL) return NULL; if ((new = icpyalloc(new)) == NULL) { freelist(cpp); return NULL; } new[len] = '\0'; /* Is there already something in the list that's new (or longer)? */ for (i = 0; cpp[i] != NULL; ++i) if (istrstr(cpp[i], new) != NULL) { free(new); return cpp; } /* Eliminate any obsoleted strings. */ j = 0; while (cpp[j] != NULL) if (istrstr(new, cpp[j]) == NULL) ++j; else { free(cpp[j]); if (--i == j) break; cpp[j] = cpp[i]; cpp[i] = NULL; } /* Add the new string. */ cpp = (char **) realloc((char *) cpp, (i + 2) * sizeof *cpp); if (cpp == NULL) return NULL; cpp[i] = new; cpp[i + 1] = NULL; return cpp; } /* Given pointers to two strings, return a pointer to an allocated list of their distinct common substrings. Return NULL if something seems wild. */ static char ** comsubs(left, right) char *left; char *right; { char **cpp; char *lcp; char *rcp; int i, len; if (left == NULL || right == NULL) return NULL; cpp = (char **) malloc(sizeof *cpp); if (cpp == NULL) return NULL; cpp[0] = NULL; for (lcp = left; *lcp != '\0'; ++lcp) { len = 0; rcp = index(right, *lcp); while (rcp != NULL) { for (i = 1; lcp[i] != '\0' && lcp[i] == rcp[i]; ++i) ; if (i > len) len = i; rcp = index(rcp + 1, *lcp); } if (len == 0) continue; if ((cpp = enlist(cpp, lcp, len)) == NULL) break; } return cpp; } static char ** addlists(old, new) char **old; char **new; { int i; if (old == NULL || new == NULL) return NULL; for (i = 0; new[i] != NULL; ++i) { old = enlist(old, new[i], strlen(new[i])); if (old == NULL) break; } return old; } /* Given two lists of substrings, return a new list giving substrings common to both. */ static char ** inboth(left, right) char **left; char **right; { char **both; char **temp; int lnum, rnum; if (left == NULL || right == NULL) return NULL; both = (char **) malloc(sizeof *both); if (both == NULL) return NULL; both[0] = NULL; for (lnum = 0; left[lnum] != NULL; ++lnum) { for (rnum = 0; right[rnum] != NULL; ++rnum) { temp = comsubs(left[lnum], right[rnum]); if (temp == NULL) { freelist(both); return NULL; } both = addlists(both, temp); freelist(temp); if (both == NULL) return NULL; } } return both; } typedef struct { char **in; char *left; char *right; char *is; } must; static void resetmust(mp) must *mp; { mp->left[0] = mp->right[0] = mp->is[0] = '\0'; freelist(mp->in); } static void dfamust(dfa) struct dfa *dfa; { must *musts; must *mp; char *result; int ri; int i; int exact; token t; static must must0; struct dfamust *dm; result = ""; exact = 0; musts = (must *) malloc((dfa->tindex + 1) * sizeof *musts); if (musts == NULL) return; mp = musts; for (i = 0; i <= dfa->tindex; ++i) mp[i] = must0; for (i = 0; i <= dfa->tindex; ++i) { mp[i].in = (char **) malloc(sizeof *mp[i].in); mp[i].left = malloc(2); mp[i].right = malloc(2); mp[i].is = malloc(2); if (mp[i].in == NULL || mp[i].left == NULL || mp[i].right == NULL || mp[i].is == NULL) goto done; mp[i].left[0] = mp[i].right[0] = mp[i].is[0] = '\0'; mp[i].in[0] = NULL; } #ifdef DEBUG fprintf(stderr, "dfamust:\n"); for (i = 0; i < dfa->tindex; ++i) { fprintf(stderr, " %d:", i); prtok(dfa->tokens[i]); } putc('\n', stderr); #endif for (ri = 0; ri < dfa->tindex; ++ri) { switch (t = dfa->tokens[ri]) { case LPAREN: case RPAREN: goto done; /* "cannot happen" */ case EMPTY: case BEGLINE: case ENDLINE: case BEGWORD: case ENDWORD: case LIMWORD: case NOTLIMWORD: case BACKREF: resetmust(mp); break; case STAR: case QMARK: if (mp <= musts) goto done; /* "cannot happen" */ --mp; resetmust(mp); break; case OR: case ORTOP: if (mp < &musts[2]) goto done; /* "cannot happen" */ { char **new; must *lmp; must *rmp; int j, ln, rn, n; rmp = --mp; lmp = --mp; /* Guaranteed to be. Unlikely, but. . . */ if (strcmp(lmp->is, rmp->is) != 0) lmp->is[0] = '\0'; /* Left side--easy */ i = 0; while (lmp->left[i] != '\0' && lmp->left[i] == rmp->left[i]) ++i; lmp->left[i] = '\0'; /* Right side */ ln = strlen(lmp->right); rn = strlen(rmp->right); n = ln; if (n > rn) n = rn; for (i = 0; i < n; ++i) if (lmp->right[ln - i - 1] != rmp->right[rn - i - 1]) break; for (j = 0; j < i; ++j) lmp->right[j] = lmp->right[(ln - i) + j]; lmp->right[j] = '\0'; new = inboth(lmp->in, rmp->in); if (new == NULL) goto done; freelist(lmp->in); free((char *) lmp->in); lmp->in = new; } break; case PLUS: if (mp <= musts) goto done; /* "cannot happen" */ --mp; mp->is[0] = '\0'; break; case END: if (mp != &musts[1]) goto done; /* "cannot happen" */ for (i = 0; musts[0].in[i] != NULL; ++i) if (strlen(musts[0].in[i]) > strlen(result)) result = musts[0].in[i]; if (strcmp(result, musts[0].is) == 0) exact = 1; goto done; case CAT: if (mp < &musts[2]) goto done; /* "cannot happen" */ { must *lmp; must *rmp; rmp = --mp; lmp = --mp; /* In. Everything in left, plus everything in right, plus catenation of left's right and right's left. */ lmp->in = addlists(lmp->in, rmp->in); if (lmp->in == NULL) goto done; if (lmp->right[0] != '\0' && rmp->left[0] != '\0') { char *tp; tp = icpyalloc(lmp->right); if (tp == NULL) goto done; tp = icatalloc(tp, rmp->left); if (tp == NULL) goto done; lmp->in = enlist(lmp->in, tp, strlen(tp)); free(tp); if (lmp->in == NULL) goto done; } /* Left-hand */ if (lmp->is[0] != '\0') { lmp->left = icatalloc(lmp->left, rmp->left); if (lmp->left == NULL) goto done; } /* Right-hand */ if (rmp->is[0] == '\0') lmp->right[0] = '\0'; lmp->right = icatalloc(lmp->right, rmp->right); if (lmp->right == NULL) goto done; /* Guaranteed to be */ if (lmp->is[0] != '\0' && rmp->is[0] != '\0') { lmp->is = icatalloc(lmp->is, rmp->is); if (lmp->is == NULL) goto done; } else lmp->is[0] = '\0'; } break; default: if (t < END) { /* "cannot happen" */ goto done; } else if (t == '\0') { /* not on *my* shift */ goto done; } else if (t >= CSET) { /* easy enough */ resetmust(mp); } else { /* plain character */ resetmust(mp); mp->is[0] = mp->left[0] = mp->right[0] = t; mp->is[1] = mp->left[1] = mp->right[1] = '\0'; mp->in = enlist(mp->in, mp->is, 1); if (mp->in == NULL) goto done; } break; } #ifdef DEBUG fprintf(stderr, " node: %d:", ri); prtok(dfa->tokens[ri]); fprintf(stderr, "\n in:"); for (i = 0; mp->in[i]; ++i) fprintf(stderr, " \"%s\"", mp->in[i]); fprintf(stderr, "\n is: \"%s\"\n", mp->is); fprintf(stderr, " left: \"%s\"\n", mp->left); fprintf(stderr, " right: \"%s\"\n", mp->right); #endif ++mp; } done: if (strlen(result)) { dm = (struct dfamust *) malloc(sizeof (struct dfamust)); dm->exact = exact; dm->must = malloc(strlen(result) + 1); strcpy(dm->must, result); dm->next = dfa->musts; dfa->musts = dm; } mp = musts; for (i = 0; i <= dfa->tindex; ++i) { freelist(mp[i].in); ifree((char *) mp[i].in); ifree(mp[i].left); ifree(mp[i].right); ifree(mp[i].is); } free((char *) mp); } shapetools-1.4pl6.orig/vgrep-2.0/dfa.h100644 2013 145 34504 5362105342 15513 0ustar dokoswt/* dfa.h - declarations for GNU deterministic regexp compiler Copyright (C) 1988 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Written June, 1988 by Mike Haertel */ /* FIXME: 2. We should not export so much of the DFA internals. In addition to clobbering modularity, we eat up valuable name space. */ /* Number of bits in an unsigned char. */ #define CHARBITS 8 /* First integer value that is greater than any character code. */ #define NOTCHAR (1 << CHARBITS) /* INTBITS need not be exact, just a lower bound. */ #define INTBITS (CHARBITS * sizeof (int)) /* Number of ints required to hold a bit for every character. */ #define CHARCLASS_INTS ((NOTCHAR + INTBITS - 1) / INTBITS) /* Sets of unsigned characters are stored as bit vectors in arrays of ints. */ typedef int charclass[CHARCLASS_INTS]; /* The regexp is parsed into an array of tokens in postfix form. Some tokens are operators and others are terminal symbols. Most (but not all) of these codes are returned by the lexical analyzer. */ typedef enum { END = -1, /* END is a terminal symbol that matches the end of input; any value of END or less in the parse tree is such a symbol. Accepting states of the DFA are those that would have a transition on END. */ /* Ordinary character values are terminal symbols that match themselves. */ EMPTY = NOTCHAR, /* EMPTY is a terminal symbol that matches the empty string. */ BACKREF, /* BACKREF is generated by \; it it not completely handled. If the scanner detects a transition on backref, it returns a kind of "semi-success" indicating that the match will have to be verified with a backtracking matcher. */ BEGLINE, /* BEGLINE is a terminal symbol that matches the empty string if it is at the beginning of a line. */ ENDLINE, /* ENDLINE is a terminal symbol that matches the empty string if it is at the end of a line. */ BEGWORD, /* BEGWORD is a terminal symbol that matches the empty string if it is at the beginning of a word. */ ENDWORD, /* ENDWORD is a terminal symbol that matches the empty string if it is at the end of a word. */ LIMWORD, /* LIMWORD is a terminal symbol that matches the empty string if it is at the beginning or the end of a word. */ NOTLIMWORD, /* NOTLIMWORD is a terminal symbol that matches the empty string if it is not at the beginning or end of a word. */ QMARK, /* QMARK is an operator of one argument that matches zero or one occurences of its argument. */ STAR, /* STAR is an operator of one argument that matches the Kleene closure (zero or more occurrences) of its argument. */ PLUS, /* PLUS is an operator of one argument that matches the positive closure (one or more occurrences) of its argument. */ REPMN, /* REPMN is a lexical token corresponding to the {m,n} construct. REPMN never appears in the compiled token vector. */ CAT, /* CAT is an operator of two arguments that matches the concatenation of its arguments. CAT is never returned by the lexical analyzer. */ OR, /* OR is an operator of two arguments that matches either of its arguments. */ ORTOP, /* OR at the toplevel in the parse tree. This is used for a boyer-moore heuristic. */ LPAREN, /* LPAREN never appears in the parse tree, it is only a lexeme. */ RPAREN, /* RPAREN never appears in the parse tree. */ CSET /* CSET and (and any value greater) is a terminal symbol that matches any of a class of characters. */ } token; /* Sets are stored in an array in the compiled dfa; the index of the array corresponding to a given set token is given by SET_INDEX(t). */ #define SET_INDEX(t) ((t) - CSET) /* Sometimes characters can only be matched depending on the surrounding context. Such context decisions depend on what the previous character was, and the value of the current (lookahead) character. Context dependent constraints are encoded as 8 bit integers. Each bit that is set indicates that the constraint succeeds in the corresponding context. bit 7 - previous and current are newlines bit 6 - previous was newline, current isn't bit 5 - previous wasn't newline, current is bit 4 - neither previous nor current is a newline bit 3 - previous and current are word-constituents bit 2 - previous was word-constituent, current isn't bit 1 - previous wasn't word-constituent, current is bit 0 - neither previous nor current is word-constituent Word-constituent characters are those that satisfy isalnum(). The macro SUCCEEDS_IN_CONTEXT determines whether a a given constraint succeeds in a particular context. Prevn is true if the previous character was a newline, currn is true if the lookahead character is a newline. Prevl and currl similarly depend upon whether the previous and current characters are word-constituent letters. */ #define MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn) \ ((constraint) & 1 << (((prevn) ? 2 : 0) + ((currn) ? 1 : 0) + 4)) #define MATCHES_LETTER_CONTEXT(constraint, prevl, currl) \ ((constraint) & 1 << (((prevl) ? 2 : 0) + ((currl) ? 1 : 0))) #define SUCCEEDS_IN_CONTEXT(constraint, prevn, currn, prevl, currl) \ (MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn) \ && MATCHES_LETTER_CONTEXT(constraint, prevl, currl)) /* The following macros give information about what a constraint depends on. */ #define PREV_NEWLINE_DEPENDENT(constraint) \ (((constraint) & 0xc0) >> 2 != ((constraint) & 0x30)) #define PREV_LETTER_DEPENDENT(constraint) \ (((constraint) & 0x0c) >> 2 != ((constraint) & 0x03)) /* Tokens that match the empty string subject to some constraint actually work by applying that constraint to determine what may follow them, taking into account what has gone before. The following values are the constraints corresponding to the special tokens previously defined. */ #define NO_CONSTRAINT 0xff #define BEGLINE_CONSTRAINT 0xcf #define ENDLINE_CONSTRAINT 0xaf #define BEGWORD_CONSTRAINT 0xf2 #define ENDWORD_CONSTRAINT 0xf4 #define LIMWORD_CONSTRAINT 0xf6 #define NOTLIMWORD_CONSTRAINT 0xf9 /* States of the recognizer correspond to sets of positions in the parse tree, together with the constraints under which they may be matched. So a position is encoded as an index into the parse tree together with a constraint. */ typedef struct { unsigned index; /* Index into the parse array. */ unsigned constraint; /* Constraint for matching this position. */ } position; /* Sets of positions are stored as arrays. */ typedef struct { position *elems; /* Elements of this position set. */ int nelem; /* Number of elements in this set. */ } position_set; /* A state of the dfa consists of a set of positions, some flags, and the token value of the lowest-numbered position of the state that contains an END token. */ typedef struct { int hash; /* Hash of the positions of this state. */ position_set elems; /* Positions this state could match. */ char newline; /* True if previous state matched newline. */ char letter; /* True if previous state matched a letter. */ char backref; /* True if this state matches a \. */ unsigned char constraint; /* Constraint for this state to accept. */ int first_end; /* Token value of the first END in elems. */ } dfa_state; /* Element of a list of strings, at least one of which is known to appear in any R.E. matching the DFA. */ struct dfamust { int exact; char *must; struct dfamust *next; }; /* A compiled regular expression. */ struct dfa { /* Stuff built by the scanner. */ charclass *charclasses; /* Array of character sets for CSET tokens. */ int cindex; /* Index for adding new charclasses. */ int calloc; /* Number of charclasses currently allocated. */ /* Stuff built by the parser. */ token *tokens; /* Postfix parse array. */ int tindex; /* Index for adding new tokens. */ int talloc; /* Number of tokens currently allocated. */ int depth; /* Depth required of an evaluation stack used for depth-first traversal of the parse tree. */ int nleaves; /* Number of leaves on the parse tree. */ int nregexps; /* Count of parallel regexps being built with dfaparse(). */ /* Stuff owned by the state builder. */ dfa_state *states; /* States of the dfa. */ int sindex; /* Index for adding new states. */ int salloc; /* Number of states currently allocated. */ /* Stuff built by the structure analyzer. */ position_set *follows; /* Array of follow sets, indexed by position index. The follow of a position is the set of positions containing characters that could conceivably follow a character matching the given position in a string matching the regexp. Allocated to the maximum possible position index. */ int searchflag; /* True if we are supposed to build a searching as opposed to an exact matcher. A searching matcher finds the first and shortest string matching a regexp anywhere in the buffer, whereas an exact matcher finds the longest string matching, but anchored to the beginning of the buffer. */ /* Stuff owned by the executor. */ int tralloc; /* Number of transition tables that have slots so far. */ int trcount; /* Number of transition tables that have actually been built. */ int **trans; /* Transition tables for states that can never accept. If the transitions for a state have not yet been computed, or the state could possibly accept, its entry in this table is NULL. */ int **realtrans; /* Trans always points to realtrans + 1; this is so trans[-1] can contain NULL. */ int **fails; /* Transition tables after failing to accept on a state that potentially could do so. */ int *success; /* Table of acceptance conditions used in dfaexec and computed in build_state. */ int *newlines; /* Transitions on newlines. The entry for a newline in any transition table is always -1 so we can count lines without wasting too many cycles. The transition for a newline is stored separately and handled as a special case. Newline is also used as a sentinel at the end of the buffer. */ struct dfamust *musts; /* List of strings, at least one of which is known to appear in any r.e. matching the dfa. */ }; /* Some macros for user access to dfa internals. */ /* ACCEPTING returns true if s could possibly be an accepting state of r. */ #define ACCEPTING(s, r) ((r).states[s].constraint) /* ACCEPTS_IN_CONTEXT returns true if the given state accepts in the specified context. */ #define ACCEPTS_IN_CONTEXT(prevn, currn, prevl, currl, state, dfa) \ SUCCEEDS_IN_CONTEXT((dfa).states[state].constraint, \ prevn, currn, prevl, currl) /* FIRST_MATCHING_REGEXP returns the index number of the first of parallel regexps that a given state could accept. Parallel regexps are numbered starting at 1. */ #define FIRST_MATCHING_REGEXP(state, dfa) (-(dfa).states[state].first_end) /* Entry points. */ #if __STDC__ /* dfasyntax() takes two arguments; the first sets the syntax bits described earlier in this file, and the second sets the case-folding flag. */ extern void dfasyntax(int, int); /* Compile the given string of the given length into the given struct dfa. Final argument is a flag specifying whether to build a searching or an exact matcher. */ extern void dfacomp(char *, size_t, struct dfa *, int); /* Execute the given struct dfa on the buffer of characters. The first char * points to the beginning, and the second points to the first character after the end of the buffer, which must be a writable place so a sentinel end-of-buffer marker can be stored there. The second-to-last argument is a flag telling whether to allow newlines to be part of a string matching the regexp. The next-to-last argument, if non-NULL, points to a place to increment every time we see a newline. The final argument, if non-NULL, points to a flag that will be set if further examination by a backtracking matcher is needed in order to verify backreferencing; otherwise the flag will be cleared. Returns NULL if no match is found, or a pointer to the first character after the first & shortest matching string in the buffer. */ extern char *dfaexec(struct dfa *, char *, char *, int, int *, int *); /* Free the storage held by the components of a struct dfa. */ extern void dfafree(struct dfa *); /* Entry points for people who know what they're doing. */ /* Initialize the components of a struct dfa. */ extern void dfainit(struct dfa *); /* Incrementally parse a string of given length into a struct dfa. */ extern void dfaparse(char *, size_t, struct dfa *); /* Analyze a parsed regexp; second argument tells whether to build a searching or an exact matcher. */ extern void dfaanalyze(struct dfa *, int); /* Compute, for each possible character, the transitions out of a given state, storing them in an array of integers. */ extern void dfastate(int, struct dfa *, int []); /* Error handling. */ /* dfaerror() is called by the regexp routines whenever an error occurs. It takes a single argument, a NUL-terminated string describing the error. The default dfaerror() prints the error message to stderr and exits. The user can provide a different dfafree() if so desired. */ extern void dfaerror(char *); #else /* ! __STDC__ */ extern void dfasyntax(), dfacomp(), dfafree(), dfainit(), dfaparse(); extern void dfaanalyze(), dfastate(), dfaerror(); extern char *dfaexec(); #endif /* ! __STDC__ */ shapetools-1.4pl6.orig/vgrep-2.0/getopt.c100644 2013 145 50614 5377062167 16273 0ustar dokoswt/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* NOTE!!! AIX requires this to be the first thing in the file. Do not put ANYTHING before it! */ #if !defined (__GNUC__) && defined (_AIX) #pragma alloca #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__)))) #include #else #ifndef _AIX char *alloca (); #endif #endif /* alloca.h */ #endif /* not __GNUC__ */ #if !__STDC__ && !defined(const) && IN_GCC #define const #endif /* This tells Alpha OSF/1 not to define a getopt prototype in . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #undef alloca /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #else /* Not GNU C library. */ #define __alloca alloca #endif /* GNU C library. */ /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a long-named option. Because this is not POSIX.2 compliant, it is being phased out. */ /* #define GETOPT_COMPAT */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = 0; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } static void my_bcopy (from, to, size) const char *from; char *to; int size; { int i; for (i = 0; i < size; i++) to[i] = from[i]; } #endif /* GNU C library. */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange (argv) char **argv; { int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); char **temp = (char **) __alloca (nonopts_size); /* Interchange the two blocks of data in ARGV. */ my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size); my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt], (optind - last_nonopt) * sizeof (char *)); my_bcopy ((char *) temp, (char *) &argv[first_nonopt + optind - last_nonopt], nonopts_size); /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { int option_index; optarg = 0; /* Initialize the internal data when the first call is made. Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ if (optind == 0) { first_nonopt = last_nonopt = optind = 1; nextchar = NULL; /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (getenv ("POSIXLY_CORRECT") != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; } if (nextchar == NULL || *nextchar == '\0') { if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Now skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) optind++; last_nonopt = optind; } /* Special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Start decoding its characters. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } if (longopts != NULL && ((argv[optind][0] == '-' && (argv[optind][1] == '-' || long_only)) #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ )) { const struct option *p; char *s = nextchar; int exact = 0; int ambig = 0; const struct option *pfound = NULL; int indfound; while (*s && *s != '=') s++; /* Test all options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, s - nextchar)) { if (s - nextchar == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*s) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = s + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { #if 0 if (c < 040 || c >= 0177) fprintf (stderr, "%s: unrecognized option, character code 0%o\n", argv[0], c); else fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); #endif } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = 0; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { #if 0 fprintf (stderr, "%s: option `-%c' requires an argument\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); #endif } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ shapetools-1.4pl6.orig/vgrep-2.0/getopt.h100644 2013 145 10474 5377062173 16275 0ustar dokoswt/* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if __STDC__ #if defined(__GNU_LIBRARY__) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* not __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ shapetools-1.4pl6.orig/vgrep-2.0/getpagesize.h100644 2013 145 1345 5377063102 17250 0ustar dokoswt#ifdef BSD #ifndef BSD4_1 #define HAVE_GETPAGESIZE #endif #endif #ifndef HAVE_GETPAGESIZE #ifdef VMS #define getpagesize() 512 #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef _SC_PAGESIZE #define getpagesize() sysconf(_SC_PAGESIZE) #else #ifdef HAVE_SYS_PARAM_H #include #ifdef EXEC_PAGESIZE #define getpagesize() EXEC_PAGESIZE #else #ifdef NBPG #define getpagesize() NBPG * CLSIZE #ifndef CLSIZE #define CLSIZE 1 #endif /* no CLSIZE */ #else /* no NBPG */ #define getpagesize() NBPC #endif /* no NBPG */ #endif /* no EXEC_PAGESIZE */ #else /* !HAVE_SYS_PARAM_H */ #define getpagesize() 8192 /* punt totally */ #endif /* !HAVE_SYS_PARAM_H */ #endif /* no _SC_PAGESIZE */ #endif /* not HAVE_GETPAGESIZE */ shapetools-1.4pl6.orig/vgrep-2.0/grep.c100644 2013 145 42075 5377610464 15727 0ustar dokoswt/* grep.c - main driver file for grep. Copyright (C) 1992 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Written July 1992 by Mike Haertel. */ #include #include #ifndef errno extern int errno; #endif #ifdef STDC_HEADERS #include #else #include extern char *malloc(), *realloc(); extern void free(); #endif #if defined(STDC_HEADERS) || defined(HAVE_STRING_H) #include #ifdef NEED_MEMORY_H #include #endif #else #include #ifdef __STDC__ extern void *memchr(); #else extern char *memchr(); #endif #define strrchr rindex #endif #ifdef HAVE_UNISTD_H #include #include #include #else #define O_RDONLY 0 extern int open(), read(), close(); #endif #include "getpagesize.h" #include "grep.h" #undef MAX #define MAX(A,B) ((A) > (B) ? (A) : (B)) /* Provide missing ANSI features if necessary. */ #ifndef HAVE_STRERROR extern int sys_nerr; extern char *sys_errlist[]; #define strerror(E) ((E) < sys_nerr ? sys_errlist[(E)] : "bogus error number") #endif #ifndef HAVE_MEMCHR #ifdef __STDC__ #define VOID void #else #define VOID char #endif VOID * memchr(vp, c, n) VOID *vp; int c; size_t n; { unsigned char *p; for (p = (unsigned char *) vp; n--; ++p) if (*p == c) return (VOID *) p; return 0; } #endif /* Define flags declared in grep.h. */ char *matcher; int match_icase; int match_words; int match_lines; /* Functions we'll use to search. */ static void (*compile)(); static char *(*execute)(); /* For error messages. */ static char *prog; static char *filename; static int errseen; /* Print a message and possibly an error string. Remember that something awful happened. */ static void error(mesg, errnum) #ifdef __STDC__ const #endif char *mesg; int errnum; { if (errnum) fprintf(stderr, "%s: %s: %s\n", prog, mesg, strerror(errnum)); else fprintf(stderr, "%s: %s\n", prog, mesg); errseen = 1; } /* Like error(), but die horribly after printing. */ void fatal(mesg, errnum) #ifdef __STDC__ const #endif char *mesg; int errnum; { error(mesg, errnum); exit(2); } /* Interface to handle errors and fix library lossage. */ char * xmalloc(size) size_t size; { char *result; result = malloc(size); if (size && !result) fatal("memory exhausted", 0); return result; } /* Interface to handle errors and fix some library lossage. */ char * xrealloc(ptr, size) char *ptr; size_t size; { char *result; if (ptr) result = realloc(ptr, size); else result = malloc(size); if (size && !result) fatal("memory exhausted", 0); return result; } #if !defined(HAVE_VALLOC) #define valloc malloc #else #ifdef __STDC__ extern void *valloc(size_t); #else extern char *valloc(); #endif #endif /* Hairy buffering mechanism for grep. The intent is to keep all reads aligned on a page boundary and multiples of the page size. */ static char *buffer; /* Base of buffer. */ static size_t bufsalloc; /* Allocated size of buffer save region. */ static size_t bufalloc; /* Total buffer size. */ static int bufdesc; /* File descriptor. */ static char *bufbeg; /* Beginning of user-visible stuff. */ static char *buflim; /* Limit of user-visible stuff. */ #if defined(HAVE_WORKING_MMAP) #include #include #include static int bufmapped; /* True for ordinary files. */ static struct stat bufstat; /* From fstat(). */ static off_t bufoffset; /* What read() normally remembers. */ #endif /* Reset the buffer for a new file. Initialize on the first time through. */ void reset(fd) int fd; { static int initialized; if (!initialized) { initialized = 1; #ifndef BUFSALLOC bufsalloc = MAX(8192, getpagesize()); #else bufsalloc = BUFSALLOC; #endif bufalloc = 5 * bufsalloc; /* The 1 byte of overflow is a kludge for dfaexec(), which inserts a sentinel newline at the end of the buffer being searched. There's gotta be a better way... */ buffer = valloc(bufalloc + 1); if (!buffer) fatal("memory exhausted", 0); bufbeg = buffer; buflim = buffer; } bufdesc = fd; #if defined(HAVE_WORKING_MMAP) if (fstat(fd, &bufstat) < 0 || !S_ISREG(bufstat.st_mode)) bufmapped = 0; else { bufmapped = 1; bufoffset = lseek(fd, 0, 1); } #endif } /* Read new stuff into the buffer, saving the specified amount of old stuff. When we're done, 'bufbeg' points to the beginning of the buffer contents, and 'buflim' points just after the end. Return count of new stuff. */ static int fillbuf(save) size_t save; { char *nbuffer, *dp, *sp; int cc; #if defined(HAVE_WORKING_MMAP) caddr_t maddr; #endif static int pagesize; if (pagesize == 0 && (pagesize = getpagesize()) == 0) abort(); if (save > bufsalloc) { while (save > bufsalloc) bufsalloc *= 2; bufalloc = 5 * bufsalloc; nbuffer = valloc(bufalloc + 1); if (!nbuffer) fatal("memory exhausted", 0); } else nbuffer = buffer; sp = buflim - save; dp = nbuffer + bufsalloc - save; bufbeg = dp; while (save--) *dp++ = *sp++; /* We may have allocated a new, larger buffer. Since there is no portable vfree(), we just have to forget about the old one. Sorry. */ buffer = nbuffer; #if defined(HAVE_WORKING_MMAP) if (bufmapped && bufoffset % pagesize == 0 && bufstat.st_size - bufoffset >= bufalloc - bufsalloc) { maddr = buffer + bufsalloc; maddr = mmap(maddr, bufalloc - bufsalloc, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, bufdesc, bufoffset); if (maddr == (caddr_t) -1) { fprintf(stderr, "%s: warning: %s: %s\n", filename, strerror(errno)); goto tryread; } #if 0 /* You might thing this (or MADV_WILLNEED) would help, but it doesn't, at least not on a Sun running 4.1. In fact, it actually slows us down about 30%! */ madvise(maddr, bufalloc - bufsalloc, MADV_SEQUENTIAL); #endif cc = bufalloc - bufsalloc; bufoffset += cc; } else { tryread: /* We come here when we're not going to use mmap() any more. Note that we need to synchronize the file offset the first time through. */ if (bufmapped) { bufmapped = 0; lseek(bufdesc, bufoffset, 0); } cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc); } #else cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc); #endif if (cc > 0) buflim = buffer + bufsalloc + cc; else buflim = buffer + bufsalloc; return cc; } /* Flags controlling the style of output. */ static int out_quiet; /* Suppress all normal output. */ static int out_invert; /* Print nonmatching stuff. */ static int out_file; /* Print filenames. */ static int out_line; /* Print line numbers. */ static int out_byte; /* Print byte offsets. */ static int out_before; /* Lines of leading context. */ static int out_after; /* Lines of trailing context. */ /* Internal variables to keep track of byte count, context, etc. */ static size_t totalcc; /* Total character count before bufbeg. */ static char *lastnl; /* Pointer after last newline counted. */ static char *lastout; /* Pointer after last character output; NULL if no character has been output or if it's conceptually before bufbeg. */ static size_t totalnl; /* Total newline count before lastnl. */ static int pending; /* Pending lines of output. */ static void nlscan(lim) char *lim; { char *beg; for (beg = lastnl; beg < lim; ++beg) if (*beg == '\n') ++totalnl; lastnl = beg; } static void prline(beg, lim, sep) char *beg; char *lim; char sep; { if (out_file) printf("%s%c", filename, sep); if (out_line) { nlscan(beg); printf("%d%c", ++totalnl, sep); lastnl = lim; } if (out_byte) printf("%lu%c", totalcc + (beg - bufbeg), sep); fwrite(beg, 1, lim - beg, stdout); if (ferror(stdout)) error("writing output", errno); lastout = lim; } /* Print pending lines of trailing context prior to LIM. */ static void prpending(lim) char *lim; { char *nl; if (!lastout) lastout = bufbeg; while (pending > 0 && lastout < lim) { --pending; if ((nl = memchr(lastout, '\n', lim - lastout)) != 0) ++nl; else nl = lim; prline(lastout, nl, '-'); } } /* Print the lines between BEG and LIM. Deal with context crap. If NLINESP is non-null, store a count of lines between BEG and LIM. */ static void prtext(beg, lim, nlinesp) char *beg; char *lim; int *nlinesp; { static int used; /* avoid printing "--" before any output */ char *bp, *p, *nl; int i, n; if (!out_quiet && pending > 0) prpending(beg); p = beg; if (!out_quiet) { /* Deal with leading context crap. */ bp = lastout ? lastout : bufbeg; for (i = 0; i < out_before; ++i) if (p > bp) do --p; while (p > bp && p[-1] != '\n'); /* We only print the "--" separator if our output is discontiguous from the last output in the file. */ if ((out_before || out_after) && used && p != lastout) puts("--"); while (p < beg) { nl = memchr(p, '\n', beg - p); prline(p, nl + 1, '-'); p = nl + 1; } } if (nlinesp) { /* Caller wants a line count. */ for (n = 0; p < lim; ++n) { if ((nl = memchr(p, '\n', lim - p)) != 0) ++nl; else nl = lim; if (!out_quiet) prline(p, nl, ':'); p = nl; } *nlinesp = n; } else if (!out_quiet) prline(beg, lim, ':'); pending = out_after; used = 1; } /* Scan the specified portion of the buffer, matching lines (or between matching lines if OUT_INVERT is true). Return a count of lines printed. */ static int grepbuf(beg, lim) char *beg; char *lim; { int nlines, n; register char *p, *b; char *endp; nlines = 0; p = beg; while ((b = (*execute)(p, lim - p, &endp)) != 0) { /* Avoid matching the empty line at the end of the buffer. */ if (b == lim && ((b > beg && b[-1] == '\n') || b == beg)) break; if (!out_invert) { prtext(b, endp, (int *) 0); nlines += 1; } else if (p < b) { prtext(p, b, &n); nlines += n; } p = endp; } if (out_invert && p < lim) { prtext(p, lim, &n); nlines += n; } return nlines; } /* Search a given file. Return a count of lines printed. */ static int grep(fd) int fd; { int nlines, i; size_t residue, save; char *beg, *lim; reset(fd); totalcc = 0; lastout = 0; totalnl = 0; pending = 0; nlines = 0; residue = 0; save = 0; for (;;) { if (fillbuf(save) < 0) { error(filename, errno); return nlines; } lastnl = bufbeg; if (lastout) lastout = bufbeg; if (buflim - bufbeg == save) break; beg = bufbeg + save - residue; for (lim = buflim; lim > beg && lim[-1] != '\n'; --lim) ; residue = buflim - lim; if (beg < lim) { nlines += grepbuf(beg, lim); if (pending) prpending(lim); } i = 0; beg = lim; while (i < out_before && beg > bufbeg && beg != lastout) { ++i; do --beg; while (beg > bufbeg && beg[-1] != '\n'); } if (beg != lastout) lastout = 0; save = residue + lim - beg; totalcc += buflim - bufbeg - save; if (out_line) nlscan(beg); } if (residue) { nlines += grepbuf(bufbeg + save - residue, buflim); if (pending) prpending(buflim); } return nlines; } static char version[] = "GNU grep version 2.0"; #define USAGE \ "usage: %s [-[[AB] ]] [-[CEFGVchilnqsvwx]] [-[ef]] []\n" static void usage() { fprintf(stderr, USAGE, prog); exit(2); } /* Go through the matchers vector and look for the specified matcher. If we find it, install it in compile and execute, and return 1. */ int setmatcher(name) char *name; { int i; for (i = 0; matchers[i].name; ++i) if (strcmp(name, matchers[i].name) == 0) { compile = matchers[i].compile; execute = matchers[i].execute; return 1; } return 0; } int main(argc, argv) int argc; char *argv[]; { char *keys; size_t keycc, oldcc, keyalloc; int keyfound, count_matches, no_filenames, list_files, suppress_errors; int opt, cc, desc, count, status; FILE *fp; extern char *optarg; extern int optind; prog = argv[0]; if (prog && strrchr(prog, '/')) prog = strrchr(prog, '/') + 1; keys = NULL; keycc = 0; keyfound = 0; count_matches = 0; no_filenames = 0; list_files = 0; suppress_errors = 0; matcher = NULL; while ((opt = getopt(argc, argv, "0123456789A:B:CEFGVX:bce:f:hiLlnqsvwxy")) != EOF) switch (opt) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': out_before = 10 * out_before + opt - '0'; out_after = 10 * out_after + opt - '0'; break; case 'A': out_after = atoi(optarg); if (out_after < 0) usage(); break; case 'B': out_before = atoi(optarg); if (out_before < 0) usage(); break; case 'C': out_before = out_after = 2; break; case 'E': if (matcher && strcmp(matcher, "egrep") != 0) fatal("you may specify only one of -E, -F, or -G", 0); matcher = "posix-egrep"; break; case 'F': if (matcher && strcmp(matcher, "fgrep") != 0) fatal("you may specify only one of -E, -F, or -G", 0);; matcher = "fgrep"; break; case 'G': if (matcher && strcmp(matcher, "grep") != 0) fatal("you may specify only one of -E, -F, or -G", 0); matcher = "grep"; break; case 'V': fprintf(stderr, "%s\n", version); break; case 'X': if (matcher) fatal("matcher already specified", 0); matcher = optarg; break; case 'b': out_byte = 1; break; case 'c': out_quiet = 1; count_matches = 1; break; case 'e': cc = strlen(optarg); keys = xrealloc(keys, keycc + cc + 1); if (keyfound) keys[keycc++] = '\n'; strcpy(&keys[keycc], optarg); keycc += cc; keyfound = 1; break; case 'f': fp = strcmp(optarg, "-") != 0 ? fopen(optarg, "r") : stdin; if (!fp) fatal(optarg, errno); for (keyalloc = 1; keyalloc <= keycc; keyalloc *= 2) ; keys = xrealloc(keys, keyalloc); oldcc = keycc; if (keyfound) keys[keycc++] = '\n'; while (!feof(fp) && (cc = fread(keys + keycc, 1, keyalloc - keycc, fp)) > 0) { keycc += cc; if (keycc == keyalloc) keys = xrealloc(keys, keyalloc *= 2); } if (fp != stdin) fclose(fp); /* Nuke the final newline to avoid matching a null string. */ if (keycc - oldcc > 0 && keys[keycc - 1] == '\n') --keycc; keyfound = 1; break; case 'h': no_filenames = 1; break; case 'i': case 'y': /* For old-timers . . . */ match_icase = 1; break; case 'L': /* Like -l, except list files that don't contain matches. Inspired by the same option in Hume's gre. */ out_quiet = 1; list_files = -1; break; case 'l': out_quiet = 1; list_files = 1; break; case 'n': out_line = 1; break; case 'q': out_quiet = 1; break; case 's': suppress_errors = 1; break; case 'v': out_invert = 1; break; case 'w': match_words = 1; break; case 'x': match_lines = 1; break; default: usage(); break; } if (!keyfound) if (optind < argc) { keys = argv[optind++]; keycc = strlen(keys); } else usage(); if (!matcher) matcher = prog; if (!setmatcher(matcher) && !setmatcher("default")) abort(); (*compile)(keys, keycc); if (argc - optind > 1 && !no_filenames) out_file = 1; status = 1; if (optind < argc) while (optind < argc) { desc = strcmp(argv[optind], "-") ? open(argv[optind], O_RDONLY) : 0; if (desc < 0) { if (!suppress_errors) error(argv[optind], errno); } else { filename = desc == 0 ? "(standard input)" : argv[optind]; count = grep(desc); if (count_matches) { if (out_file) printf("%s:", filename); printf("%d\n", count); } if (count) { status = 0; if (list_files == 1) printf("%s\n", filename); } else if (list_files == -1) printf("%s\n", filename); } if (desc != 0) close(desc); ++optind; } else { filename = "(standard input)"; count = grep(0); if (count_matches) printf("%d\n", count); if (count) { status = 0; if (list_files == 1) printf("(standard input)\n"); } else if (list_files == -1) printf("(standard input)\n"); } exit(errseen ? 2 : status); } shapetools-1.4pl6.orig/vgrep-2.0/grep.h100644 2013 145 2732 5261455261 15702 0ustar dokoswt/* grep.h - interface to grep driver for searching subroutines. Copyright (C) 1992 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #if __STDC__ extern void fatal(const char *, int); /* Grep.c expects the matchers vector to be terminated by an entry with a NULL name, and to contain at least an entry named "default". */ extern struct matcher { char *name; void (*compile)(char *, size_t); char *(*execute)(char *, size_t, char **); } matchers[]; #else extern void fatal(); extern struct matcher { char *name; void (*compile)(); char *(*execute)(); } matchers[]; #endif /* Exported from grep.c. */ extern char *matcher; /* The following flags are exported from grep for the matchers to look at. */ extern int match_icase; /* -i */ extern int match_words; /* -w */ extern int match_lines; /* -x */ shapetools-1.4pl6.orig/vgrep-2.0/grep.man100644 2013 145 20127 5267672620 16252 0ustar dokoswt.TH GREP 1 "1992 September 10" "GNU Project" .SH NAME grep, egrep, fgrep \- print lines matching a pattern .SH SYNOPOSIS .B grep [ .BR \- [[ AB "] ]\c" .I "num" ] [ .BR \- [ CEFGVBchilnsvwx ] ] [ .B \-e ] .I pattern | .BI \-f file ] [ .I files... ] .SH DESCRIPTION .PP .B Grep searches the named input .I files (or standard input if no files are named, or the file name .B \- is given) for lines containing a match to the given .IR pattern . By default, .B grep prints the matching lines. .PP There are three major variants of .BR grep , controlled by the following options. .PD 0 .TP .B \-G Interpret .I pattern as a basic regular expression (see below). This is the default. .TP .B \-E Interpret .I pattern as an extended regular expression (see below). .TP .B \-F Interpret .I pattern as a list of fixed strings, separated by newlines, any of which is to be matched. .LP In addition, two variant programs .B egrep and .B fgrep are available. .B Egrep is similiar (but not identical) to .BR "grep\ \-E" , and is compatible with the historical Unix .BR egrep . .B Fgrep is the same as .BR "grep\ \-F" . .PD .LP All variants of .B grep understand the following options: .PD 0 .TP .BI \- num Matches will be printed with .I num lines of leading and trailing context. However, .B grep will never print any given line more than once. .TP .BI \-A " num" Print .I num lines of trailing context after matching lines. .TP .BI \-B " num" Print .I num lines of leading context before matching lines. .TP .B \-C Equivalent to .BR \-2 . .TP .B \-V Print the version number of .B grep to standard error. This version number should be included in all bug reports (see below). .TP .B \-b Print the byte offset within the input file before each line of output. .TP .B \-c Suppress normal output; instead print a count of matching lines for each input file. With the .B \-v option (see below), count non-matching lines. .TP .BI \-e " pattern" Use .I pattern as the pattern; useful to protect patterns beginning with .BR \- . .TP .BI \-f " file" Obtain the pattern from .IR file . .TP .B \-h Suppress the prefixing of filenames on output when multiple files are searched. .TP .B \-i Ignore case distinctions in both the .I pattern and the input files. .TP .B \-L Suppress normal output; instead print the name of each input file from which no output would normally have been printed. .TP .B \-l Suppress normal output; instead print the name of each input file from which output would normally have been printed. .TP .B \-n Prefix each line of output with the line number within its input file. .TP .B \-q Quiet; suppress normal output. .TP .B \-s Suppress error messages about nonexistent or unreadable files. .TP .B \-v Invert the sense of matching, to select non-matching lines. .TP .B \-w Select only those lines containing matches that form whole words. The test is that the matching substring must either be at the beginning of the line, or preceded by a non-word constituent character. Similarly, it must be either at the end of the line or followed by a non-word constituent character. Word-constituent characters are letters, digits, and the underscore. .TP .B \-x Select only those matches that exactly match the whole line. .PD .SH "REGULAR EXPRESSIONS" .PP A regular expression is a pattern that describes a set of strings. Regular expressions are constructed analagously to arithmetic expressions, by using various operators to combine smaller expressions. .PP .B Grep understands two different versions of regular expression syntax: ``basic'' and ``extended.'' In .RB "GNU\ " grep , there is no difference in available functionality using either syntax. In other implementations, basic regular expressions are less powerful. The following description applies to extended regular expressions; differences for basic regular expressions are summarized afterwards. .PP The fundamental building blocks are the regular expressions that match a single character. Most characters, including all letters and digits, are regular expressions that match themselves. Any metacharacter with special meaning may be quoted by preceding it with a backslash. .PP A list of characters enclosed by .B [ and .B ] matches any single character in that list; if the first character of the list is the caret .B ^ then it matches any character .I not in the list. For example, the regular expression .B [0123456789] matches any single digit. A range of ASCII characters may be specified by giving the first and last characters, separated by a hyphen. Finally, certain named classes of characters are predefined. Their names are self explanatory, and they are .BR [:alnum:] , .BR [:alpha:] , .BR [:cntrl:] , .BR [:digit:] , .BR [:graph:] , .BR [:lower:] , .BR [:print:] , .BR [:punct:] , .BR [:space:] , .BR [:upper:] , and .BR [:xdigit:]. For example, .B [[:alnum:]] means .BR [0-9A-Za-z] , except the latter form is dependent upon the ASCII character encoding, whereas the former is portable. (Note that the brackets in these class names are part of the symbolic names, and must be included in addition to the brackets delimiting the bracket list.) Most metacharacters lose their special meaning inside lists. To include a literal .B ] place it first in the list. Similarly, to include a literal .B ^ place it anywhere but first. Finally, to include a literal .B \- place it last. .PP The period .B . matches any single character. The symbol .B \ew is a synonym for .B [[:alnum:]] and .B \eW is a synonym for .BR [^[:alnum]] . .PP The caret .B ^ and the dollar sign .B $ are metacharacters that respectively match the empty string at the beginning and end of a line. The symbols .B \e< and .B \e> respectively match the empty string at the beginning and end of a word. The symbol .B \eb matches the empty string at the edge of a word, and .B \eB matches the empty string provided it's .I not at the edge of a word. .PP A regular expression matching a single character may be followed by one of several repetition operators: .PD 0 .TP .B ? The preceding item is optional and matched at most once. .TP .B * The preceding item will be matched zero or more times. .TP .B + The preceding item will be matched one or more times. .TP .BI { n } The preceding item is matched exactly .I n times. .TP .BI { n ,} The preceding item is matched .I n or more times. .TP .BI {, m } The preceding item is optional and is matched at most .I m times. .TP .BI { n , m } The preceding item is matched at least .I n times, but not more than .I m times. .PD .PP Two regular expressions may be concatenated; the resulting regular expression matches any string formed by concatenating two substrings that respectively match the concatenated subexpressions. .PP Two regular expressions may be joined by the infix operator .BR | ; the resulting regular expression matches any string matching either subexpression. .PP Repetition takes precedence over concatenation, which in turn takes precedence over alternation. A whole subexpression may be enclosed in parentheses to override these precedence rules. .PP The backreference .BI \e n\c \&, where .I n is a single digit, matches the substring previously matched by the .IR n th parenthesized subexpression of the regular expression. .PP In basic regular expressions the metacharacters .BR ? , .BR + , .BR { , .BR | , .BR ( , and .BR ) lose their special meaning; instead use the backslashed versions .BR \e? , .BR \e+ , .BR \e{ , .BR \e| , .BR \e( , and .BR \e) . .PP In .B egrep the metacharacter .B { loses its special meaning; instead use .BR \e{ . .SH DIAGNOSTICS .PP Normally, exit status is 0 if matches were found, and 1 if no matches were found. (The .B \-v option inverts the sense of the exit status.) Exit status is 2 if there were syntax errors in the pattern, inaccessible input files, or other system errors. .SH BUGS .PP Email bug reports to .BR bug-gnu-utils@prep.ai.mit.edu . Be sure to include the word ``grep'' somewhere in the ``Subject:'' field. .PP Large repetition counts in the .BI { m , n } construct may cause grep to use lots of memory. In addition, certain other obscure regular expressions require exponential time and space, and may cause .B grep to run out of memory. .PP Backreferences are very slow, and may require exponential time. shapetools-1.4pl6.orig/vgrep-2.0/kwset.c100644 2013 145 50735 5371020134 16110 0ustar dokoswt/* kwset.c - search for any of a set of keywords. Copyright 1989 Free Software Foundation Written August 1989 by Mike Haertel. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author may be reached (Email) at the address mike@ai.mit.edu, or (US mail) as Mike Haertel c/o Free Software Foundation. */ /* The algorithm implemented by these routines bears a startling resemblence to one discovered by Beate Commentz-Walter, although it is not identical. See "A String Matching Algorithm Fast on the Average," Technical Report, IBM-Germany, Scientific Center Heidelberg, Tiergartenstrasse 15, D-6900 Heidelberg, Germany. See also Aho, A.V., and M. Corasick, "Efficient String Matching: An Aid to Bibliographic Search," CACM June 1975, Vol. 18, No. 6, which describes the failure function used below. */ #ifdef STDC_HEADERS #include #include #else #define INT_MAX 2147483647 #define UCHAR_MAX 255 #ifdef __STDC__ #include #else #include #endif extern char *malloc(); extern void free(); #endif #ifdef HAVE_MEMCHR #include #ifdef NEED_MEMORY_H #include #endif #else #ifdef __STDC__ extern void *memchr(); #else extern char *memchr(); #endif #endif #ifdef GREP extern char *xmalloc(); #define malloc xmalloc #endif #include "kwset.h" #include "obstack.h" #define NCHAR (UCHAR_MAX + 1) #define obstack_chunk_alloc malloc #define obstack_chunk_free free /* Balanced tree of edges and labels leaving a given trie node. */ struct tree { struct tree *llink; /* Left link; MUST be first field. */ struct tree *rlink; /* Right link (to larger labels). */ struct trie *trie; /* Trie node pointed to by this edge. */ unsigned char label; /* Label on this edge. */ char balance; /* Difference in depths of subtrees. */ }; /* Node of a trie representing a set of reversed keywords. */ struct trie { unsigned int accepting; /* Word index of accepted word, or zero. */ struct tree *links; /* Tree of edges leaving this node. */ struct trie *parent; /* Parent of this node. */ struct trie *next; /* List of all trie nodes in level order. */ struct trie *fail; /* Aho-Corasick failure function. */ int depth; /* Depth of this node from the root. */ int shift; /* Shift function for search failures. */ int maxshift; /* Max shift of self and descendents. */ }; /* Structure returned opaquely to the caller, containing everything. */ struct kwset { struct obstack obstack; /* Obstack for node allocation. */ int words; /* Number of words in the trie. */ struct trie *trie; /* The trie itself. */ int mind; /* Minimum depth of an accepting node. */ int maxd; /* Maximum depth of any node. */ unsigned char delta[NCHAR]; /* Delta table for rapid search. */ struct trie *next[NCHAR]; /* Table of children of the root. */ char *target; /* Target string if there's only one. */ int mind2; /* Used in Boyer-Moore search for one string. */ char *trans; /* Character translation table. */ }; /* Allocate and initialize a keyword set object, returning an opaque pointer to it. Return NULL if memory is not available. */ kwset_t kwsalloc(trans) char *trans; { struct kwset *kwset; kwset = (struct kwset *) malloc(sizeof (struct kwset)); if (!kwset) return 0; obstack_init(&kwset->obstack); kwset->words = 0; kwset->trie = (struct trie *) obstack_alloc(&kwset->obstack, sizeof (struct trie)); if (!kwset->trie) { kwsfree((kwset_t) kwset); return 0; } kwset->trie->accepting = 0; kwset->trie->links = 0; kwset->trie->parent = 0; kwset->trie->next = 0; kwset->trie->fail = 0; kwset->trie->depth = 0; kwset->trie->shift = 0; kwset->mind = INT_MAX; kwset->maxd = -1; kwset->target = 0; kwset->trans = trans; return (kwset_t) kwset; } /* Add the given string to the contents of the keyword set. Return NULL for success, an error message otherwise. */ char * kwsincr(kws, text, len) kwset_t kws; char *text; size_t len; { struct kwset *kwset; register struct trie *trie; register unsigned char label; register struct tree *link; register int depth; struct tree *links[12]; enum { L, R } dirs[12]; struct tree *t, *r, *l, *rl, *lr; kwset = (struct kwset *) kws; trie = kwset->trie; text += len; /* Descend the trie (built of reversed keywords) character-by-character, installing new nodes when necessary. */ while (len--) { label = kwset->trans ? kwset->trans[(unsigned char) *--text] : *--text; /* Descend the tree of outgoing links for this trie node, looking for the current character and keeping track of the path followed. */ link = trie->links; links[0] = (struct tree *) &trie->links; dirs[0] = L; depth = 1; while (link && label != link->label) { links[depth] = link; if (label < link->label) dirs[depth++] = L, link = link->llink; else dirs[depth++] = R, link = link->rlink; } /* The current character doesn't have an outgoing link at this trie node, so build a new trie node and install a link in the current trie node's tree. */ if (!link) { link = (struct tree *) obstack_alloc(&kwset->obstack, sizeof (struct tree)); if (!link) return "memory exhausted"; link->llink = 0; link->rlink = 0; link->trie = (struct trie *) obstack_alloc(&kwset->obstack, sizeof (struct trie)); if (!link->trie) return "memory exhausted"; link->trie->accepting = 0; link->trie->links = 0; link->trie->parent = trie; link->trie->next = 0; link->trie->fail = 0; link->trie->depth = trie->depth + 1; link->trie->shift = 0; link->label = label; link->balance = 0; /* Install the new tree node in its parent. */ if (dirs[--depth] == L) links[depth]->llink = link; else links[depth]->rlink = link; /* Back up the tree fixing the balance flags. */ while (depth && !links[depth]->balance) { if (dirs[depth] == L) --links[depth]->balance; else ++links[depth]->balance; --depth; } /* Rebalance the tree by pointer rotations if necessary. */ if (depth && ((dirs[depth] == L && --links[depth]->balance) || (dirs[depth] == R && ++links[depth]->balance))) { switch (links[depth]->balance) { case (char) -2: switch (dirs[depth + 1]) { case L: r = links[depth], t = r->llink, rl = t->rlink; t->rlink = r, r->llink = rl; t->balance = r->balance = 0; break; case R: r = links[depth], l = r->llink, t = l->rlink; rl = t->rlink, lr = t->llink; t->llink = l, l->rlink = lr, t->rlink = r, r->llink = rl; l->balance = t->balance != 1 ? 0 : -1; r->balance = t->balance != (char) -1 ? 0 : 1; t->balance = 0; break; } break; case 2: switch (dirs[depth + 1]) { case R: l = links[depth], t = l->rlink, lr = t->llink; t->llink = l, l->rlink = lr; t->balance = l->balance = 0; break; case L: l = links[depth], r = l->rlink, t = r->llink; lr = t->llink, rl = t->rlink; t->llink = l, l->rlink = lr, t->rlink = r, r->llink = rl; l->balance = t->balance != 1 ? 0 : -1; r->balance = t->balance != (char) -1 ? 0 : 1; t->balance = 0; break; } break; } if (dirs[depth - 1] == L) links[depth - 1]->llink = t; else links[depth - 1]->rlink = t; } } trie = link->trie; } /* Mark the node we finally reached as accepting, encoding the index number of this word in the keyword set so far. */ if (!trie->accepting) trie->accepting = 1 + 2 * kwset->words; ++kwset->words; /* Keep track of the longest and shortest string of the keyword set. */ if (trie->depth < kwset->mind) kwset->mind = trie->depth; if (trie->depth > kwset->maxd) kwset->maxd = trie->depth; return 0; } /* Enqueue the trie nodes referenced from the given tree in the given queue. */ static void enqueue(tree, last) struct tree *tree; struct trie **last; { if (!tree) return; enqueue(tree->llink, last); enqueue(tree->rlink, last); (*last) = (*last)->next = tree->trie; } /* Compute the Aho-Corasick failure function for the trie nodes referenced from the given tree, given the failure function for their parent as well as a last resort failure node. */ static void treefails(tree, fail, recourse) register struct tree *tree; struct trie *fail; struct trie *recourse; { register struct tree *link; if (!tree) return; treefails(tree->llink, fail, recourse); treefails(tree->rlink, fail, recourse); /* Find, in the chain of fails going back to the root, the first node that has a descendent on the current label. */ while (fail) { link = fail->links; while (link && tree->label != link->label) if (tree->label < link->label) link = link->llink; else link = link->rlink; if (link) { tree->trie->fail = link->trie; return; } fail = fail->fail; } tree->trie->fail = recourse; } /* Set delta entries for the links of the given tree such that the preexisting delta value is larger than the current depth. */ static void treedelta(tree, depth, delta) register struct tree *tree; register unsigned int depth; unsigned char delta[]; { if (!tree) return; treedelta(tree->llink, depth, delta); treedelta(tree->rlink, depth, delta); if (depth < delta[tree->label]) delta[tree->label] = depth; } /* Return true if A has every label in B. */ static int hasevery(a, b) register struct tree *a; register struct tree *b; { if (!b) return 1; if (!hasevery(a, b->llink)) return 0; if (!hasevery(a, b->rlink)) return 0; while (a && b->label != a->label) if (b->label < a->label) a = a->llink; else a = a->rlink; return !!a; } /* Compute a vector, indexed by character code, of the trie nodes referenced from the given tree. */ static void treenext(tree, next) struct tree *tree; struct trie *next[]; { if (!tree) return; treenext(tree->llink, next); treenext(tree->rlink, next); next[tree->label] = tree->trie; } /* Compute the shift for each trie node, as well as the delta table and next cache for the given keyword set. */ char * kwsprep(kws) kwset_t kws; { register struct kwset *kwset; register int i; register struct trie *curr, *fail; register char *trans; unsigned char delta[NCHAR]; struct trie *last, *next[NCHAR]; kwset = (struct kwset *) kws; /* Initial values for the delta table; will be changed later. The delta entry for a given character is the smallest depth of any node at which an outgoing edge is labeled by that character. */ if (kwset->mind < 256) for (i = 0; i < NCHAR; ++i) delta[i] = kwset->mind; else for (i = 0; i < NCHAR; ++i) delta[i] = 255; /* Check if we can use the simple boyer-moore algorithm, instead of the hairy commentz-walter algorithm. */ if (kwset->words == 1 && kwset->trans == 0) { /* Looking for just one string. Extract it from the trie. */ kwset->target = obstack_alloc(&kwset->obstack, kwset->mind); for (i = kwset->mind - 1, curr = kwset->trie; i >= 0; --i) { kwset->target[i] = curr->links->label; curr = curr->links->trie; } /* Build the Boyer Moore delta. Boy that's easy compared to CW. */ for (i = 0; i < kwset->mind; ++i) delta[(unsigned char) kwset->target[i]] = kwset->mind - (i + 1); kwset->mind2 = kwset->mind; /* Find the minimal delta2 shift that we might make after a backwards match has failed. */ for (i = 0; i < kwset->mind - 1; ++i) if (kwset->target[i] == kwset->target[kwset->mind - 1]) kwset->mind2 = kwset->mind - (i + 1); } else { /* Traverse the nodes of the trie in level order, simultaneously computing the delta table, failure function, and shift function. */ for (curr = last = kwset->trie; curr; curr = curr->next) { /* Enqueue the immediate descendents in the level order queue. */ enqueue(curr->links, &last); curr->shift = kwset->mind; curr->maxshift = kwset->mind; /* Update the delta table for the descendents of this node. */ treedelta(curr->links, curr->depth, delta); /* Compute the failure function for the decendents of this node. */ treefails(curr->links, curr->fail, kwset->trie); /* Update the shifts at each node in the current node's chain of fails back to the root. */ for (fail = curr->fail; fail; fail = fail->fail) { /* If the current node has some outgoing edge that the fail doesn't, then the shift at the fail should be no larger than the difference of their depths. */ if (!hasevery(fail->links, curr->links)) if (curr->depth - fail->depth < fail->shift) fail->shift = curr->depth - fail->depth; /* If the current node is accepting then the shift at the fail and its descendents should be no larger than the difference of their depths. */ if (curr->accepting && fail->maxshift > curr->depth - fail->depth) fail->maxshift = curr->depth - fail->depth; } } /* Traverse the trie in level order again, fixing up all nodes whose shift exceeds their inherited maxshift. */ for (curr = kwset->trie->next; curr; curr = curr->next) { if (curr->maxshift > curr->parent->maxshift) curr->maxshift = curr->parent->maxshift; if (curr->shift > curr->maxshift) curr->shift = curr->maxshift; } /* Create a vector, indexed by character code, of the outgoing links from the root node. */ for (i = 0; i < NCHAR; ++i) next[i] = 0; treenext(kwset->trie->links, next); if ((trans = kwset->trans) != 0) for (i = 0; i < NCHAR; ++i) kwset->next[i] = next[(unsigned char) trans[i]]; else for (i = 0; i < NCHAR; ++i) kwset->next[i] = next[i]; } /* Fix things up for any translation table. */ if ((trans = kwset->trans) != 0) for (i = 0; i < NCHAR; ++i) kwset->delta[i] = delta[(unsigned char) trans[i]]; else for (i = 0; i < NCHAR; ++i) kwset->delta[i] = delta[i]; return 0; } #define U(C) ((unsigned char) (C)) /* Fast boyer-moore search. */ static char * bmexec(kws, text, size) kwset_t kws; char *text; size_t size; { struct kwset *kwset; register unsigned char *d1; register char *ep, *sp, *tp; register int d, gc, i, len, md2; kwset = (struct kwset *) kws; len = kwset->mind; if (len == 0) return text; if (len > size) return 0; if (len == 1) return memchr(text, kwset->target[0], size); d1 = kwset->delta; sp = kwset->target + len; gc = U(sp[-2]); md2 = kwset->mind2; tp = text + len; /* Significance of 12: 1 (initial offset) + 10 (skip loop) + 1 (md2). */ if (size > 12 * len) /* 11 is not a bug, the initial offset happens only once. */ for (ep = text + size - 11 * len;;) { while (tp <= ep) { d = d1[U(tp[-1])], tp += d; d = d1[U(tp[-1])], tp += d; if (d == 0) goto found; d = d1[U(tp[-1])], tp += d; d = d1[U(tp[-1])], tp += d; d = d1[U(tp[-1])], tp += d; if (d == 0) goto found; d = d1[U(tp[-1])], tp += d; d = d1[U(tp[-1])], tp += d; d = d1[U(tp[-1])], tp += d; if (d == 0) goto found; d = d1[U(tp[-1])], tp += d; d = d1[U(tp[-1])], tp += d; } break; found: if (U(tp[-2]) == gc) { for (i = 3; i <= len && U(tp[-i]) == U(sp[-i]); ++i) ; if (i > len) return tp - len; } tp += md2; } /* Now we have only a few characters left to search. We carefully avoid ever producing an out-of-bounds pointer. */ ep = text + size; d = d1[U(tp[-1])]; while (d <= ep - tp) { d = d1[U((tp += d)[-1])]; if (d != 0) continue; if (tp[-2] == gc) { for (i = 3; i <= len && U(tp[-i]) == U(sp[-i]); ++i) ; if (i > len) return tp - len; } d = md2; } return 0; } /* Hairy multiple string search. */ static char * cwexec(kws, text, len, kwsmatch) kwset_t kws; char *text; size_t len; struct kwsmatch *kwsmatch; { struct kwset *kwset; struct trie **next, *trie, *accept; char *beg, *lim, *mch, *lmch; register unsigned char c, *delta; register int d; register char *end, *qlim; register struct tree *tree; register char *trans; /* Initialize register copies and look for easy ways out. */ kwset = (struct kwset *) kws; if (len < kwset->mind) return 0; next = kwset->next; delta = kwset->delta; trans = kwset->trans; lim = text + len; end = text; if ((d = kwset->mind) != 0) mch = 0; else { mch = text, accept = kwset->trie; goto match; } if (len >= 4 * kwset->mind) qlim = lim - 4 * kwset->mind; else qlim = 0; while (lim - end >= d) { if (qlim && end <= qlim) { end += d - 1; while ((d = delta[c = *end]) && end < qlim) { end += d; end += delta[(unsigned char) *end]; end += delta[(unsigned char) *end]; } ++end; } else d = delta[c = (end += d)[-1]]; if (d) continue; beg = end - 1; trie = next[c]; if (trie->accepting) { mch = beg; accept = trie; } d = trie->shift; while (beg > text) { c = trans ? trans[(unsigned char) *--beg] : *--beg; tree = trie->links; while (tree && c != tree->label) if (c < tree->label) tree = tree->llink; else tree = tree->rlink; if (tree) { trie = tree->trie; if (trie->accepting) { mch = beg; accept = trie; } } else break; d = trie->shift; } if (mch) goto match; } return 0; match: /* Given a known match, find the longest possible match anchored at or before its starting point. This is nearly a verbatim copy of the preceding main search loops. */ if (lim - mch > kwset->maxd) lim = mch + kwset->maxd; lmch = 0; d = 1; while (lim - end >= d) { if ((d = delta[c = (end += d)[-1]]) != 0) continue; beg = end - 1; if (!(trie = next[c])) { d = 1; continue; } if (trie->accepting && beg <= mch) { lmch = beg; accept = trie; } d = trie->shift; while (beg > text) { c = trans ? trans[(unsigned char) *--beg] : *--beg; tree = trie->links; while (tree && c != tree->label) if (c < tree->label) tree = tree->llink; else tree = tree->rlink; if (tree) { trie = tree->trie; if (trie->accepting && beg <= mch) { lmch = beg; accept = trie; } } else break; d = trie->shift; } if (lmch) { mch = lmch; goto match; } if (!d) d = 1; } if (kwsmatch) { kwsmatch->index = accept->accepting / 2; kwsmatch->beg[0] = mch; kwsmatch->size[0] = accept->depth; } return mch; } /* Search through the given text for a match of any member of the given keyword set. Return a pointer to the first character of the matching substring, or NULL if no match is found. If FOUNDLEN is non-NULL store in the referenced location the length of the matching substring. Similarly, if FOUNDIDX is non-NULL, store in the referenced location the index number of the particular keyword matched. */ char * kwsexec(kws, text, size, kwsmatch) kwset_t kws; char *text; size_t size; struct kwsmatch *kwsmatch; { struct kwset *kwset; char *ret; kwset = (struct kwset *) kws; if (kwset->words == 1 && kwset->trans == 0) { ret = bmexec(kws, text, size); if (kwsmatch != 0 && ret != 0) { kwsmatch->index = 0; kwsmatch->beg[0] = ret; kwsmatch->size[0] = kwset->mind; } return ret; } else return cwexec(kws, text, size, kwsmatch); } /* Free the components of the given keyword set. */ void kwsfree(kws) kwset_t kws; { struct kwset *kwset; kwset = (struct kwset *) kws; obstack_free(&kwset->obstack, 0); free(kws); } shapetools-1.4pl6.orig/vgrep-2.0/kwset.h100644 2013 145 4743 5222746130 16101 0ustar dokoswt/* kwset.h - header declaring the keyword set library. Copyright 1989 Free Software Foundation Written August 1989 by Mike Haertel. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author may be reached (Email) at the address mike@ai.mit.edu, or (US mail) as Mike Haertel c/o Free Software Foundation. */ struct kwsmatch { int index; /* Index number of matching keyword. */ char *beg[1]; /* Begin pointer for each submatch. */ size_t size[1]; /* Length of each submatch. */ }; #if __STDC__ typedef void *kwset_t; /* Return an opaque pointer to a newly allocated keyword set, or NULL if enough memory cannot be obtained. The argument if non-NULL specifies a table of character translations to be applied to all pattern and search text. */ extern kwset_t kwsalloc(char *); /* Incrementally extend the keyword set to include the given string. Return NULL for success, or an error message. Remember an index number for each keyword included in the set. */ extern char *kwsincr(kwset_t, char *, size_t); /* When the keyword set has been completely built, prepare it for use. Return NULL for success, or an error message. */ extern char *kwsprep(kwset_t); /* Search through the given buffer for a member of the keyword set. Return a pointer to the leftmost longest match found, or NULL if no match is found. If foundlen is non-NULL, store the length of the matching substring in the integer it points to. Similarly, if foundindex is non-NULL, store the index of the particular keyword found therein. */ extern char *kwsexec(kwset_t, char *, size_t, struct kwsmatch *); /* Deallocate the given keyword set and all its associated storage. */ extern void kwsfree(kwset_t); #else typedef char *kwset_t; extern kwset_t kwsalloc(); extern char *kwsincr(); extern char *kwsprep(); extern char *kwsexec(); extern void kwsfree(); #endif shapetools-1.4pl6.orig/vgrep-2.0/make.com100644 2013 145 1662 5377610446 16220 0ustar dokoswt$ WRITE SYS$OUTPUT "Compiling ALLOCA..." $ CC ALLOCA.C /DEFINE=(HAVE_STRING_H,HAVE_MEMCHR,HAVE_STRERROR) $ WRITE SYS$OUTPUT "Compiling DFA..." $ CC DFA.C /DEFINE=(HAVE_STRING_H,HAVE_MEMCHR,HAVE_STRERROR) $ WRITE SYS$OUTPUT "Compiling GETOPT..." $ CC GETOPT.C /DEFINE=(HAVE_STRING_H,HAVE_MEMCHR,HAVE_STRERROR) $ WRITE SYS$OUTPUT "Compiling GREP..." $ CC GREP.C /DEFINE=(HAVE_STRING_H,HAVE_MEMCHR,HAVE_STRERROR) $ WRITE SYS$OUTPUT "Compiling KWSET..." $ CC KWSET.C /DEFINE=(HAVE_STRING_H,HAVE_MEMCHR,HAVE_STRERROR) $ WRITE SYS$OUTPUT "Compiling OBSTACK..." $ CC OBSTACK.C /DEFINE=(HAVE_STRING_H,HAVE_MEMCHR,HAVE_STRERROR) $ WRITE SYS$OUTPUT "Compiling REGEX..." $ CC REGEX.C /DEFINE=(HAVE_STRING_H,HAVE_MEMCHR,HAVE_STRERROR) $ WRITE SYS$OUTPUT "Compiling SEARCH..." $ CC SEARCH.C /DEFINE=(HAVE_STRING_H,HAVE_MEMCHR,HAVE_STRERROR) $ WRITE SYS$OUTPUT "Linking..." $ LINK GREP,ALLOCA,DFA,GETOPT,KWSET,OBSTACK,REGEX,SEARCH $ EXIT shapetools-1.4pl6.orig/vgrep-2.0/obstack.c100644 2013 145 33173 5377062175 16417 0ustar dokoswt/* obstack.c - subroutines used implicitly by object stack macros Copyright (C) 1988, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "obstack.h" /* This is just to get __GNU_LIBRARY__ defined. */ #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) #ifdef __STDC__ #define POINTER void * #else #define POINTER char * #endif /* Determine default alignment. */ struct fooalign {char x; double d;}; #define DEFAULT_ALIGNMENT \ ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0)) /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. But in fact it might be less smart and round addresses to as much as DEFAULT_ROUNDING. So we prepare for it to do that. */ union fooround {long x; double d;}; #define DEFAULT_ROUNDING (sizeof (union fooround)) /* When we copy a long block of data, this is the unit to do it with. On some machines, copying successive ints does not work; in such a case, redefine COPYING_UNIT to `long' (if that works) or `char' as a last resort. */ #ifndef COPYING_UNIT #define COPYING_UNIT int #endif /* The non-GNU-C macros copy the obstack into this global variable to avoid multiple evaluation. */ struct obstack *_obstack; /* Define a macro that either calls functions with the traditional malloc/free calling interface, or calls functions with the mmalloc/mfree interface (that adds an extra first argument), based on the state of use_extra_arg. For free, do not use ?:, since some compilers, like the MIPS compilers, do not allow (expr) ? void : void. */ #define CALL_CHUNKFUN(h, size) \ (((h) -> use_extra_arg) \ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ : (*(h)->chunkfun) ((size))) #define CALL_FREEFUN(h, old_chunk) \ do { \ if ((h) -> use_extra_arg) \ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ else \ (*(h)->freefun) ((old_chunk)); \ } while (0) /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). Objects start on multiples of ALIGNMENT (0 means use default). CHUNKFUN is the function to use to allocate chunks, and FREEFUN the function to free them. */ void _obstack_begin (h, size, alignment, chunkfun, freefun) struct obstack *h; int size; int alignment; POINTER (*chunkfun) (); void (*freefun) (); { register struct _obstack_chunk* chunk; /* points to new chunk */ if (alignment == 0) alignment = DEFAULT_ALIGNMENT; if (size == 0) /* Default size is what GNU malloc can fit in a 4096-byte block. */ { /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. Use the values for range checking, because if range checking is off, the extra bytes won't be missed terribly, but if range checking is on and we used a larger request, a whole extra 4096 bytes would be allocated. These number are irrelevant to the new GNU malloc. I suspect it is less sensitive to the size of the request. */ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) + 4 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)); size = 4096 - extra; } h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; h->freefun = freefun; h->chunk_size = size; h->alignment_mask = alignment - 1; h->use_extra_arg = 0; chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); h->next_free = h->object_base = chunk->contents; h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size; chunk->prev = 0; /* The initial chunk now contains no empty object. */ h->maybe_empty_object = 0; } void _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) struct obstack *h; int size; int alignment; POINTER (*chunkfun) (); void (*freefun) (); POINTER arg; { register struct _obstack_chunk* chunk; /* points to new chunk */ if (alignment == 0) alignment = DEFAULT_ALIGNMENT; if (size == 0) /* Default size is what GNU malloc can fit in a 4096-byte block. */ { /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. Use the values for range checking, because if range checking is off, the extra bytes won't be missed terribly, but if range checking is on and we used a larger request, a whole extra 4096 bytes would be allocated. These number are irrelevant to the new GNU malloc. I suspect it is less sensitive to the size of the request. */ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) + 4 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)); size = 4096 - extra; } h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; h->freefun = freefun; h->chunk_size = size; h->alignment_mask = alignment - 1; h->extra_arg = arg; h->use_extra_arg = 1; chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); h->next_free = h->object_base = chunk->contents; h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size; chunk->prev = 0; /* The initial chunk now contains no empty object. */ h->maybe_empty_object = 0; } /* Allocate a new current chunk for the obstack *H on the assumption that LENGTH bytes need to be added to the current object, or a new object of length LENGTH allocated. Copies any partial object from the end of the old chunk to the beginning of the new one. */ void _obstack_newchunk (h, length) struct obstack *h; int length; { register struct _obstack_chunk* old_chunk = h->chunk; register struct _obstack_chunk* new_chunk; register long new_size; register int obj_size = h->next_free - h->object_base; register int i; int already; /* Compute size for new chunk. */ new_size = (obj_size + length) + (obj_size >> 3) + 100; if (new_size < h->chunk_size) new_size = h->chunk_size; /* Allocate and initialize the new chunk. */ new_chunk = h->chunk = CALL_CHUNKFUN (h, new_size); new_chunk->prev = old_chunk; new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; /* Move the existing object to the new chunk. Word at a time is fast and is safe if the object is sufficiently aligned. */ if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) { for (i = obj_size / sizeof (COPYING_UNIT) - 1; i >= 0; i--) ((COPYING_UNIT *)new_chunk->contents)[i] = ((COPYING_UNIT *)h->object_base)[i]; /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, but that can cross a page boundary on a machine which does not do strict alignment for COPYING_UNITS. */ already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT); } else already = 0; /* Copy remaining bytes one by one. */ for (i = already; i < obj_size; i++) new_chunk->contents[i] = h->object_base[i]; /* If the object just copied was the only data in OLD_CHUNK, free that chunk and remove it from the chain. But not if that chunk might contain an empty object. */ if (h->object_base == old_chunk->contents && ! h->maybe_empty_object) { new_chunk->prev = old_chunk->prev; CALL_FREEFUN (h, old_chunk); } h->object_base = new_chunk->contents; h->next_free = h->object_base + obj_size; /* The new chunk certainly contains no empty object yet. */ h->maybe_empty_object = 0; } /* Return nonzero if object OBJ has been allocated from obstack H. This is here for debugging. If you use it in a program, you are probably losing. */ int _obstack_allocated_p (h, obj) struct obstack *h; POINTER obj; { register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ register struct _obstack_chunk* plp; /* point to previous chunk if any */ lp = (h)->chunk; /* We use >= rather than > since the object cannot be exactly at the beginning of the chunk but might be an empty object exactly at the end of an adjacent chunk. */ while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) { plp = lp->prev; lp = plp; } return lp != 0; } /* Free objects in obstack H, including OBJ and everything allocate more recently than OBJ. If OBJ is zero, free everything in H. */ #undef obstack_free /* This function has two names with identical definitions. This is the first one, called from non-ANSI code. */ void _obstack_free (h, obj) struct obstack *h; POINTER obj; { register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ register struct _obstack_chunk* plp; /* point to previous chunk if any */ lp = h->chunk; /* We use >= because there cannot be an object at the beginning of a chunk. But there can be an empty object at that address at the end of another chunk. */ while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) { plp = lp->prev; CALL_FREEFUN (h, lp); lp = plp; /* If we switch chunks, we can't tell whether the new current chunk contains an empty object, so assume that it may. */ h->maybe_empty_object = 1; } if (lp) { h->object_base = h->next_free = (char *)(obj); h->chunk_limit = lp->limit; h->chunk = lp; } else if (obj != 0) /* obj is not in any of the chunks! */ abort (); } /* This function is used from ANSI code. */ void obstack_free (h, obj) struct obstack *h; POINTER obj; { register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ register struct _obstack_chunk* plp; /* point to previous chunk if any */ lp = h->chunk; /* We use >= because there cannot be an object at the beginning of a chunk. But there can be an empty object at that address at the end of another chunk. */ while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj)) { plp = lp->prev; CALL_FREEFUN (h, lp); lp = plp; /* If we switch chunks, we can't tell whether the new current chunk contains an empty object, so assume that it may. */ h->maybe_empty_object = 1; } if (lp) { h->object_base = h->next_free = (char *)(obj); h->chunk_limit = lp->limit; h->chunk = lp; } else if (obj != 0) /* obj is not in any of the chunks! */ abort (); } #if 0 /* These are now turned off because the applications do not use it and it uses bcopy via obstack_grow, which causes trouble on sysV. */ /* Now define the functional versions of the obstack macros. Define them to simply use the corresponding macros to do the job. */ #ifdef __STDC__ /* These function definitions do not work with non-ANSI preprocessors; they won't pass through the macro names in parentheses. */ /* The function names appear in parentheses in order to prevent the macro-definitions of the names from being expanded there. */ POINTER (obstack_base) (obstack) struct obstack *obstack; { return obstack_base (obstack); } POINTER (obstack_next_free) (obstack) struct obstack *obstack; { return obstack_next_free (obstack); } int (obstack_object_size) (obstack) struct obstack *obstack; { return obstack_object_size (obstack); } int (obstack_room) (obstack) struct obstack *obstack; { return obstack_room (obstack); } void (obstack_grow) (obstack, pointer, length) struct obstack *obstack; POINTER pointer; int length; { obstack_grow (obstack, pointer, length); } void (obstack_grow0) (obstack, pointer, length) struct obstack *obstack; POINTER pointer; int length; { obstack_grow0 (obstack, pointer, length); } void (obstack_1grow) (obstack, character) struct obstack *obstack; int character; { obstack_1grow (obstack, character); } void (obstack_blank) (obstack, length) struct obstack *obstack; int length; { obstack_blank (obstack, length); } void (obstack_1grow_fast) (obstack, character) struct obstack *obstack; int character; { obstack_1grow_fast (obstack, character); } void (obstack_blank_fast) (obstack, length) struct obstack *obstack; int length; { obstack_blank_fast (obstack, length); } POINTER (obstack_finish) (obstack) struct obstack *obstack; { return obstack_finish (obstack); } POINTER (obstack_alloc) (obstack, length) struct obstack *obstack; int length; { return obstack_alloc (obstack, length); } POINTER (obstack_copy) (obstack, pointer, length) struct obstack *obstack; POINTER pointer; int length; { return obstack_copy (obstack, pointer, length); } POINTER (obstack_copy0) (obstack, pointer, length) struct obstack *obstack; POINTER pointer; int length; { return obstack_copy0 (obstack, pointer, length); } #endif /* __STDC__ */ #endif /* 0 */ #endif /* _LIBC or not __GNU_LIBRARY__. */ shapetools-1.4pl6.orig/vgrep-2.0/obstack.h100644 2013 145 44250 5377313033 16412 0ustar dokoswt/* obstack.h - object stack macros Copyright (C) 1988, 1992 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Summary: All the apparent functions defined here are macros. The idea is that you would use these pre-tested macros to solve a very specific set of problems, and they would run fast. Caution: no side-effects in arguments please!! They may be evaluated MANY times!! These macros operate a stack of objects. Each object starts life small, and may grow to maturity. (Consider building a word syllable by syllable.) An object can move while it is growing. Once it has been "finished" it never changes address again. So the "top of the stack" is typically an immature growing object, while the rest of the stack is of mature, fixed size and fixed address objects. These routines grab large chunks of memory, using a function you supply, called `obstack_chunk_alloc'. On occasion, they free chunks, by calling `obstack_chunk_free'. You must define them and declare them before using any obstack macros. Each independent stack is represented by a `struct obstack'. Each of the obstack macros expects a pointer to such a structure as the first argument. One motivation for this package is the problem of growing char strings in symbol tables. Unless you are "fascist pig with a read-only mind" --Gosper's immortal quote from HAKMEM item 154, out of context--you would not like to put any arbitrary upper limit on the length of your symbols. In practice this often means you will build many short symbols and a few long symbols. At the time you are reading a symbol you don't know how long it is. One traditional method is to read a symbol into a buffer, realloc()ating the buffer every time you try to read a symbol that is longer than the buffer. This is beaut, but you still will want to copy the symbol from the buffer to a more permanent symbol-table entry say about half the time. With obstacks, you can work differently. Use one obstack for all symbol names. As you read a symbol, grow the name in the obstack gradually. When the name is complete, finalize it. Then, if the symbol exists already, free the newly read name. The way we do this is to take a large chunk, allocating memory from low addresses. When you want to build a symbol in the chunk you just add chars above the current "high water mark" in the chunk. When you have finished adding chars, because you got to the end of the symbol, you know how long the chars are, and you can create a new object. Mostly the chars will not burst over the highest address of the chunk, because you would typically expect a chunk to be (say) 100 times as long as an average object. In case that isn't clear, when we have enough chars to make up the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) so we just point to it where it lies. No moving of chars is needed and this is the second win: potentially long strings need never be explicitly shuffled. Once an object is formed, it does not change its address during its lifetime. When the chars burst over a chunk boundary, we allocate a larger chunk, and then copy the partly formed object from the end of the old chunk to the beginning of the new larger chunk. We then carry on accreting characters to the end of the object as we normally would. A special macro is provided to add a single char at a time to a growing object. This allows the use of register variables, which break the ordinary 'growth' macro. Summary: We allocate large chunks. We carve out one object at a time from the current chunk. Once carved, an object never moves. We are free to append data of any size to the currently growing object. Exactly one object is growing in an obstack at any one time. You can run one obstack per control block. You may have as many control blocks as you dare. Because of the way we do it, you can `unwind' an obstack back to a previous state. (You may remove objects much as you would with a stack.) */ /* Don't do the contents of this file more than once. */ #ifndef __OBSTACKS__ #define __OBSTACKS__ /* We use subtraction of (char *)0 instead of casting to int because on word-addressable machines a simple cast to int may ignore the byte-within-word field of the pointer. */ #ifndef __PTR_TO_INT #define __PTR_TO_INT(P) ((P) - (char *)0) #endif #ifndef __INT_TO_PTR #define __INT_TO_PTR(P) ((P) + (char *)0) #endif /* We need the type of the resulting object. In ANSI C it is ptrdiff_t but in traditional C it is usually long. If we are in ANSI C and don't already have ptrdiff_t get it. */ #if defined (__STDC__) && ! defined (offsetof) #if defined (__GNUC__) && defined (IN_GCC) /* On Next machine, the system's stddef.h screws up if included after we have defined just ptrdiff_t, so include all of gstddef.h. Otherwise, define just ptrdiff_t, which is all we need. */ #ifndef __NeXT__ #define __need_ptrdiff_t #endif /* While building GCC, the stddef.h that goes with GCC has this name. */ #include "gstddef.h" #else #include #endif #endif #ifdef __STDC__ #define PTR_INT_TYPE ptrdiff_t #else #define PTR_INT_TYPE long #endif struct _obstack_chunk /* Lives at front of each chunk. */ { char *limit; /* 1 past end of this chunk */ struct _obstack_chunk *prev; /* address of prior chunk or NULL */ char contents[4]; /* objects begin here */ }; struct obstack /* control current object in current chunk */ { long chunk_size; /* preferred size to allocate chunks in */ struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */ char *object_base; /* address of object we are building */ char *next_free; /* where to add next char to current object */ char *chunk_limit; /* address of char after current chunk */ PTR_INT_TYPE temp; /* Temporary for some macros. */ int alignment_mask; /* Mask of alignment for each object. */ struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ void (*freefun) (); /* User's function to free a chunk. */ char *extra_arg; /* first arg for chunk alloc/dealloc funcs */ unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ unsigned maybe_empty_object:1;/* There is a possibility that the current chunk contains a zero-length object. This prevents freeing the chunk if we allocate a bigger chunk to replace it. */ }; /* Declare the external functions we use; they are in obstack.c. */ #ifdef __STDC__ extern void _obstack_newchunk (struct obstack *, int); extern void _obstack_free (struct obstack *, void *); extern void _obstack_begin (struct obstack *, int, int, void *(*) (), void (*) ()); extern void _obstack_begin_1 (struct obstack *, int, int, void *(*) (), void (*) (), void *); #else extern void _obstack_newchunk (); extern void _obstack_free (); extern void _obstack_begin (); extern void _obstack_begin_1 (); #endif #ifdef __STDC__ /* Do the function-declarations after the structs but before defining the macros. */ void obstack_init (struct obstack *obstack); void * obstack_alloc (struct obstack *obstack, int size); void * obstack_copy (struct obstack *obstack, void *address, int size); void * obstack_copy0 (struct obstack *obstack, void *address, int size); void obstack_free (struct obstack *obstack, void *block); void obstack_blank (struct obstack *obstack, int size); void obstack_grow (struct obstack *obstack, void *data, int size); void obstack_grow0 (struct obstack *obstack, void *data, int size); void obstack_1grow (struct obstack *obstack, int data_char); void obstack_ptr_grow (struct obstack *obstack, void *data); void obstack_int_grow (struct obstack *obstack, int data); void * obstack_finish (struct obstack *obstack); int obstack_object_size (struct obstack *obstack); int obstack_room (struct obstack *obstack); void obstack_1grow_fast (struct obstack *obstack, int data_char); void obstack_ptr_grow_fast (struct obstack *obstack, void *data); void obstack_int_grow_fast (struct obstack *obstack, int data); void obstack_blank_fast (struct obstack *obstack, int size); void * obstack_base (struct obstack *obstack); void * obstack_next_free (struct obstack *obstack); int obstack_alignment_mask (struct obstack *obstack); int obstack_chunk_size (struct obstack *obstack); #endif /* __STDC__ */ /* Non-ANSI C cannot really support alternative functions for these macros, so we do not declare them. */ /* Pointer to beginning of object being allocated or to be allocated next. Note that this might not be the final address of the object because a new chunk might be needed to hold the final size. */ #define obstack_base(h) ((h)->object_base) /* Size for allocating ordinary chunks. */ #define obstack_chunk_size(h) ((h)->chunk_size) /* Pointer to next byte not yet allocated in current chunk. */ #define obstack_next_free(h) ((h)->next_free) /* Mask specifying low bits that should be clear in address of an object. */ #define obstack_alignment_mask(h) ((h)->alignment_mask) #define obstack_init(h) \ _obstack_begin ((h), 0, 0, \ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) #define obstack_begin(h, size) \ _obstack_begin ((h), (size), 0, \ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ _obstack_begin ((h), (size), (alignment), \ (void *(*) ()) (chunkfun), (void (*) ()) (freefun)) #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ _obstack_begin_1 ((h), (size), (alignment), \ (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg)) #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar) #define obstack_blank_fast(h,n) ((h)->next_free += (n)) #if defined (__GNUC__) && defined (__STDC__) #if __GNUC__ < 2 || defined(NeXT) #define __extension__ #endif /* For GNU C, if not -traditional, we can define these macros to compute all args only once without using a global variable. Also, we can avoid using the `temp' slot, to make faster code. */ #define obstack_object_size(OBSTACK) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ (unsigned) (__o->next_free - __o->object_base); }) #define obstack_room(OBSTACK) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ (unsigned) (__o->chunk_limit - __o->next_free); }) /* Note that the call to _obstack_newchunk is enclosed in (..., 0) so that we can avoid having void expressions in the arms of the conditional expression. Casting the third operand to void was tried before, but some compilers won't accept it. */ #define obstack_grow(OBSTACK,where,length) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ int __len = (length); \ ((__o->next_free + __len > __o->chunk_limit) \ ? (_obstack_newchunk (__o, __len), 0) : 0); \ bcopy (where, __o->next_free, __len); \ __o->next_free += __len; \ (void) 0; }) #define obstack_grow0(OBSTACK,where,length) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ int __len = (length); \ ((__o->next_free + __len + 1 > __o->chunk_limit) \ ? (_obstack_newchunk (__o, __len + 1), 0) : 0), \ bcopy (where, __o->next_free, __len), \ __o->next_free += __len, \ *(__o->next_free)++ = 0; \ (void) 0; }) #define obstack_1grow(OBSTACK,datum) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ ((__o->next_free + 1 > __o->chunk_limit) \ ? (_obstack_newchunk (__o, 1), 0) : 0), \ *(__o->next_free)++ = (datum); \ (void) 0; }) /* These assume that the obstack alignment is good enough for pointers or ints, and that the data added so far to the current object shares that much alignment. */ #define obstack_ptr_grow(OBSTACK,datum) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ ((__o->next_free + sizeof (void *) > __o->chunk_limit) \ ? (_obstack_newchunk (__o, sizeof (void *)), 0) : 0), \ *((void **)__o->next_free)++ = ((void *)datum); \ (void) 0; }) #define obstack_int_grow(OBSTACK,datum) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ ((__o->next_free + sizeof (int) > __o->chunk_limit) \ ? (_obstack_newchunk (__o, sizeof (int)), 0) : 0), \ *((int *)__o->next_free)++ = ((int)datum); \ (void) 0; }) #define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr) #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) #define obstack_blank(OBSTACK,length) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ int __len = (length); \ ((__o->chunk_limit - __o->next_free < __len) \ ? (_obstack_newchunk (__o, __len), 0) : 0); \ __o->next_free += __len; \ (void) 0; }) #define obstack_alloc(OBSTACK,length) \ __extension__ \ ({ struct obstack *__h = (OBSTACK); \ obstack_blank (__h, (length)); \ obstack_finish (__h); }) #define obstack_copy(OBSTACK,where,length) \ __extension__ \ ({ struct obstack *__h = (OBSTACK); \ obstack_grow (__h, (where), (length)); \ obstack_finish (__h); }) #define obstack_copy0(OBSTACK,where,length) \ __extension__ \ ({ struct obstack *__h = (OBSTACK); \ obstack_grow0 (__h, (where), (length)); \ obstack_finish (__h); }) /* The local variable is named __o1 to avoid a name conflict when obstack_blank is called. */ #define obstack_finish(OBSTACK) \ __extension__ \ ({ struct obstack *__o1 = (OBSTACK); \ void *value = (void *) __o1->object_base; \ if (__o1->next_free == value) \ __o1->maybe_empty_object = 1; \ __o1->next_free \ = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ & ~ (__o1->alignment_mask)); \ ((__o1->next_free - (char *)__o1->chunk \ > __o1->chunk_limit - (char *)__o1->chunk) \ ? (__o1->next_free = __o1->chunk_limit) : 0); \ __o1->object_base = __o1->next_free; \ value; }) #define obstack_free(OBSTACK, OBJ) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ void *__obj = (OBJ); \ if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ __o->next_free = __o->object_base = __obj; \ else (obstack_free) (__o, __obj); }) #else /* not __GNUC__ or not __STDC__ */ #define obstack_object_size(h) \ (unsigned) ((h)->next_free - (h)->object_base) #define obstack_room(h) \ (unsigned) ((h)->chunk_limit - (h)->next_free) #define obstack_grow(h,where,length) \ ( (h)->temp = (length), \ (((h)->next_free + (h)->temp > (h)->chunk_limit) \ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ bcopy (where, (h)->next_free, (h)->temp), \ (h)->next_free += (h)->temp) #define obstack_grow0(h,where,length) \ ( (h)->temp = (length), \ (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ bcopy (where, (h)->next_free, (h)->temp), \ (h)->next_free += (h)->temp, \ *((h)->next_free)++ = 0) #define obstack_1grow(h,datum) \ ( (((h)->next_free + 1 > (h)->chunk_limit) \ ? (_obstack_newchunk ((h), 1), 0) : 0), \ *((h)->next_free)++ = (datum)) #define obstack_ptr_grow(h,datum) \ ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ *((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum)) #define obstack_int_grow(h,datum) \ ( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ *((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum)) #define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr) #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) #define obstack_blank(h,length) \ ( (h)->temp = (length), \ (((h)->chunk_limit - (h)->next_free < (h)->temp) \ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ (h)->next_free += (h)->temp) #define obstack_alloc(h,length) \ (obstack_blank ((h), (length)), obstack_finish ((h))) #define obstack_copy(h,where,length) \ (obstack_grow ((h), (where), (length)), obstack_finish ((h))) #define obstack_copy0(h,where,length) \ (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) #define obstack_finish(h) \ ( ((h)->next_free == (h)->object_base \ ? (((h)->maybe_empty_object = 1), 0) \ : 0), \ (h)->temp = __PTR_TO_INT ((h)->object_base), \ (h)->next_free \ = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ & ~ ((h)->alignment_mask)), \ (((h)->next_free - (char *)(h)->chunk \ > (h)->chunk_limit - (char *)(h)->chunk) \ ? ((h)->next_free = (h)->chunk_limit) : 0), \ (h)->object_base = (h)->next_free, \ __INT_TO_PTR ((h)->temp)) #ifdef __STDC__ #define obstack_free(h,obj) \ ( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ ? (int) ((h)->next_free = (h)->object_base \ = (h)->temp + (char *) (h)->chunk) \ : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) #else #define obstack_free(h,obj) \ ( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ ? (int) ((h)->next_free = (h)->object_base \ = (h)->temp + (char *) (h)->chunk) \ : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0))) #endif #endif /* not __GNUC__ or not __STDC__ */ #endif /* not __OBSTACKS__ */ shapetools-1.4pl6.orig/vgrep-2.0/regex.c100644 2013 145 476167 5377062214 16133 0ustar dokoswt/* Extended regular expression matching and search library, version 0.12. (Implements POSIX draft P10003.2/D11.2, except for internationalization features.) Copyright (C) 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* AIX requires this to be the first thing in the file. */ #if defined (_AIX) && !defined (REGEX_MALLOC) #pragma alloca #endif #define _GNU_SOURCE /* We need this for `regex.h', and perhaps for the Emacs include files. */ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif /* The `emacs' switch turns on certain matching commands that make sense only in Emacs. */ #ifdef emacs #include "lisp.h" #include "buffer.h" #include "syntax.h" /* Emacs uses `NULL' as a predicate. */ #undef NULL #else /* not emacs */ /* We used to test for `BSTRING' here, but only GCC and Emacs define `BSTRING', as far as I know, and neither of them use this code. */ #if HAVE_STRING_H || STDC_HEADERS #include #ifndef bcmp #define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) #endif #ifndef bcopy #define bcopy(s, d, n) memcpy ((d), (s), (n)) #endif #ifndef bzero #define bzero(s, n) memset ((s), 0, (n)) #endif #else #include #endif #ifdef STDC_HEADERS #include #else char *malloc (); char *realloc (); #endif /* Define the syntax stuff for \<, \>, etc. */ /* This must be nonzero for the wordchar and notwordchar pattern commands in re_match_2. */ #ifndef Sword #define Sword 1 #endif #ifdef SYNTAX_TABLE extern char *re_syntax_table; #else /* not SYNTAX_TABLE */ /* How many characters in the character set. */ #define CHAR_SET_SIZE 256 static char re_syntax_table[CHAR_SET_SIZE]; static void init_syntax_once () { register int c; static int done = 0; if (done) return; bzero (re_syntax_table, sizeof re_syntax_table); for (c = 'a'; c <= 'z'; c++) re_syntax_table[c] = Sword; for (c = 'A'; c <= 'Z'; c++) re_syntax_table[c] = Sword; for (c = '0'; c <= '9'; c++) re_syntax_table[c] = Sword; re_syntax_table['_'] = Sword; done = 1; } #endif /* not SYNTAX_TABLE */ #define SYNTAX(c) re_syntax_table[c] #endif /* not emacs */ /* Get the interface, including the syntax bits. */ #include "regex.h" /* isalpha etc. are used for the character classes. */ #include /* Jim Meyering writes: "... Some ctype macros are valid only for character codes that isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when using /bin/cc or gcc but without giving an ansi option). So, all ctype uses should be through macros like ISPRINT... If STDC_HEADERS is defined, then autoconf has verified that the ctype macros don't need to be guarded with references to isascii. ... Defining isascii to 1 should let any compiler worth its salt eliminate the && through constant folding." */ #if ! defined (isascii) || defined (STDC_HEADERS) #undef isascii #define isascii(c) 1 #endif #ifdef isblank #define ISBLANK(c) (isascii (c) && isblank (c)) #else #define ISBLANK(c) ((c) == ' ' || (c) == '\t') #endif #ifdef isgraph #define ISGRAPH(c) (isascii (c) && isgraph (c)) #else #define ISGRAPH(c) (isascii (c) && isprint (c) && !isspace (c)) #endif #define ISPRINT(c) (isascii (c) && isprint (c)) #define ISDIGIT(c) (isascii (c) && isdigit (c)) #define ISALNUM(c) (isascii (c) && isalnum (c)) #define ISALPHA(c) (isascii (c) && isalpha (c)) #define ISCNTRL(c) (isascii (c) && iscntrl (c)) #define ISLOWER(c) (isascii (c) && islower (c)) #define ISPUNCT(c) (isascii (c) && ispunct (c)) #define ISSPACE(c) (isascii (c) && isspace (c)) #define ISUPPER(c) (isascii (c) && isupper (c)) #define ISXDIGIT(c) (isascii (c) && isxdigit (c)) #ifndef NULL #define NULL 0 #endif /* We remove any previous definition of `SIGN_EXTEND_CHAR', since ours (we hope) works properly with all combinations of machines, compilers, `char' and `unsigned char' argument types. (Per Bothner suggested the basic approach.) */ #undef SIGN_EXTEND_CHAR #if __STDC__ #define SIGN_EXTEND_CHAR(c) ((signed char) (c)) #else /* not __STDC__ */ /* As in Harbison and Steele. */ #define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) #endif /* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we use `alloca' instead of `malloc'. This is because using malloc in re_search* or re_match* could cause memory leaks when C-g is used in Emacs; also, malloc is slower and causes storage fragmentation. On the other hand, malloc is more portable, and easier to debug. Because we sometimes use alloca, some routines have to be macros, not functions -- `alloca'-allocated space disappears at the end of the function it is called in. */ #ifdef REGEX_MALLOC #define REGEX_ALLOCATE malloc #define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) #else /* not REGEX_MALLOC */ /* Emacs already defines alloca, sometimes. */ #ifndef alloca /* Make alloca work the best possible way. */ #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #if HAVE_ALLOCA_H #include #else /* not __GNUC__ or HAVE_ALLOCA_H */ #ifndef _AIX /* Already did AIX, up at the top. */ char *alloca (); #endif /* not _AIX */ #endif /* not HAVE_ALLOCA_H */ #endif /* not __GNUC__ */ #endif /* not alloca */ #define REGEX_ALLOCATE alloca /* Assumes a `char *destination' variable. */ #define REGEX_REALLOCATE(source, osize, nsize) \ (destination = (char *) alloca (nsize), \ bcopy (source, destination, osize), \ destination) #endif /* not REGEX_MALLOC */ /* True if `size1' is non-NULL and PTR is pointing anywhere inside `string1' or just past its end. This works if PTR is NULL, which is a good thing. */ #define FIRST_STRING_P(ptr) \ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) /* (Re)Allocate N items of type T using malloc, or fail. */ #define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) #define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) #define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) #define BYTEWIDTH 8 /* In bits. */ #define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) typedef char boolean; #define false 0 #define true 1 /* These are the command codes that appear in compiled regular expressions. Some opcodes are followed by argument bytes. A command code can specify any interpretation whatsoever for its arguments. Zero bytes may appear in the compiled regular expression. The value of `exactn' is needed in search.c (search_buffer) in Emacs. So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of `exactn' we use here must also be 1. */ typedef enum { no_op = 0, /* Followed by one byte giving n, then by n literal bytes. */ exactn = 1, /* Matches any (more or less) character. */ anychar, /* Matches any one char belonging to specified set. First following byte is number of bitmap bytes. Then come bytes for a bitmap saying which chars are in. Bits in each byte are ordered low-bit-first. A character is in the set if its bit is 1. A character too large to have a bit in the map is automatically not in the set. */ charset, /* Same parameters as charset, but match any character that is not one of those specified. */ charset_not, /* Start remembering the text that is matched, for storing in a register. Followed by one byte with the register number, in the range 0 to one less than the pattern buffer's re_nsub field. Then followed by one byte with the number of groups inner to this one. (This last has to be part of the start_memory only because we need it in the on_failure_jump of re_match_2.) */ start_memory, /* Stop remembering the text that is matched and store it in a memory register. Followed by one byte with the register number, in the range 0 to one less than `re_nsub' in the pattern buffer, and one byte with the number of inner groups, just like `start_memory'. (We need the number of inner groups here because we don't have any easy way of finding the corresponding start_memory when we're at a stop_memory.) */ stop_memory, /* Match a duplicate of something remembered. Followed by one byte containing the register number. */ duplicate, /* Fail unless at beginning of line. */ begline, /* Fail unless at end of line. */ endline, /* Succeeds if at beginning of buffer (if emacs) or at beginning of string to be matched (if not). */ begbuf, /* Analogously, for end of buffer/string. */ endbuf, /* Followed by two byte relative address to which to jump. */ jump, /* Same as jump, but marks the end of an alternative. */ jump_past_alt, /* Followed by two-byte relative address of place to resume at in case of failure. */ on_failure_jump, /* Like on_failure_jump, but pushes a placeholder instead of the current string position when executed. */ on_failure_keep_string_jump, /* Throw away latest failure point and then jump to following two-byte relative address. */ pop_failure_jump, /* Change to pop_failure_jump if know won't have to backtrack to match; otherwise change to jump. This is used to jump back to the beginning of a repeat. If what follows this jump clearly won't match what the repeat does, such that we can be sure that there is no use backtracking out of repetitions already matched, then we change it to a pop_failure_jump. Followed by two-byte address. */ maybe_pop_jump, /* Jump to following two-byte address, and push a dummy failure point. This failure point will be thrown away if an attempt is made to use it for a failure. A `+' construct makes this before the first repeat. Also used as an intermediary kind of jump when compiling an alternative. */ dummy_failure_jump, /* Push a dummy failure point and continue. Used at the end of alternatives. */ push_dummy_failure, /* Followed by two-byte relative address and two-byte number n. After matching N times, jump to the address upon failure. */ succeed_n, /* Followed by two-byte relative address, and two-byte number n. Jump to the address N times, then fail. */ jump_n, /* Set the following two-byte relative address to the subsequent two-byte number. The address *includes* the two bytes of number. */ set_number_at, wordchar, /* Matches any word-constituent character. */ notwordchar, /* Matches any char that is not a word-constituent. */ wordbeg, /* Succeeds if at word beginning. */ wordend, /* Succeeds if at word end. */ wordbound, /* Succeeds if at a word boundary. */ notwordbound /* Succeeds if not at a word boundary. */ #ifdef emacs ,before_dot, /* Succeeds if before point. */ at_dot, /* Succeeds if at point. */ after_dot, /* Succeeds if after point. */ /* Matches any character whose syntax is specified. Followed by a byte which contains a syntax code, e.g., Sword. */ syntaxspec, /* Matches any character whose syntax is not that specified. */ notsyntaxspec #endif /* emacs */ } re_opcode_t; /* Common operations on the compiled pattern. */ /* Store NUMBER in two contiguous bytes starting at DESTINATION. */ #define STORE_NUMBER(destination, number) \ do { \ (destination)[0] = (number) & 0377; \ (destination)[1] = (number) >> 8; \ } while (0) /* Same as STORE_NUMBER, except increment DESTINATION to the byte after where the number is stored. Therefore, DESTINATION must be an lvalue. */ #define STORE_NUMBER_AND_INCR(destination, number) \ do { \ STORE_NUMBER (destination, number); \ (destination) += 2; \ } while (0) /* Put into DESTINATION a number stored in two contiguous bytes starting at SOURCE. */ #define EXTRACT_NUMBER(destination, source) \ do { \ (destination) = *(source) & 0377; \ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ } while (0) #ifdef DEBUG static void extract_number (dest, source) int *dest; unsigned char *source; { int temp = SIGN_EXTEND_CHAR (*(source + 1)); *dest = *source & 0377; *dest += temp << 8; } #ifndef EXTRACT_MACROS /* To debug the macros. */ #undef EXTRACT_NUMBER #define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) #endif /* not EXTRACT_MACROS */ #endif /* DEBUG */ /* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. SOURCE must be an lvalue. */ #define EXTRACT_NUMBER_AND_INCR(destination, source) \ do { \ EXTRACT_NUMBER (destination, source); \ (source) += 2; \ } while (0) #ifdef DEBUG static void extract_number_and_incr (destination, source) int *destination; unsigned char **source; { extract_number (destination, *source); *source += 2; } #ifndef EXTRACT_MACROS #undef EXTRACT_NUMBER_AND_INCR #define EXTRACT_NUMBER_AND_INCR(dest, src) \ extract_number_and_incr (&dest, &src) #endif /* not EXTRACT_MACROS */ #endif /* DEBUG */ /* If DEBUG is defined, Regex prints many voluminous messages about what it is doing (if the variable `debug' is nonzero). If linked with the main program in `iregex.c', you can enter patterns and strings interactively. And if linked with the main program in `main.c' and the other test files, you can run the already-written tests. */ #ifdef DEBUG /* We use standard I/O for debugging. */ #include /* It is useful to test things that ``must'' be true when debugging. */ #include static int debug = 0; #define DEBUG_STATEMENT(e) e #define DEBUG_PRINT1(x) if (debug) printf (x) #define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) #define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) #define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) #define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ if (debug) print_partial_compiled_pattern (s, e) #define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ if (debug) print_double_string (w, s1, sz1, s2, sz2) extern void printchar (); /* Print the fastmap in human-readable form. */ void print_fastmap (fastmap) char *fastmap; { unsigned was_a_range = 0; unsigned i = 0; while (i < (1 << BYTEWIDTH)) { if (fastmap[i++]) { was_a_range = 0; printchar (i - 1); while (i < (1 << BYTEWIDTH) && fastmap[i]) { was_a_range = 1; i++; } if (was_a_range) { printf ("-"); printchar (i - 1); } } } putchar ('\n'); } /* Print a compiled pattern string in human-readable form, starting at the START pointer into it and ending just before the pointer END. */ void print_partial_compiled_pattern (start, end) unsigned char *start; unsigned char *end; { int mcnt, mcnt2; unsigned char *p = start; unsigned char *pend = end; if (start == NULL) { printf ("(null)\n"); return; } /* Loop over pattern commands. */ while (p < pend) { printf ("%d:\t", p - start); switch ((re_opcode_t) *p++) { case no_op: printf ("/no_op"); break; case exactn: mcnt = *p++; printf ("/exactn/%d", mcnt); do { putchar ('/'); printchar (*p++); } while (--mcnt); break; case start_memory: mcnt = *p++; printf ("/start_memory/%d/%d", mcnt, *p++); break; case stop_memory: mcnt = *p++; printf ("/stop_memory/%d/%d", mcnt, *p++); break; case duplicate: printf ("/duplicate/%d", *p++); break; case anychar: printf ("/anychar"); break; case charset: case charset_not: { register int c, last = -100; register int in_range = 0; printf ("/charset [%s", (re_opcode_t) *(p - 1) == charset_not ? "^" : ""); assert (p + *p < pend); for (c = 0; c < 256; c++) if (c / 8 < *p && (p[1 + (c/8)] & (1 << (c % 8)))) { /* Are we starting a range? */ if (last + 1 == c && ! in_range) { putchar ('-'); in_range = 1; } /* Have we broken a range? */ else if (last + 1 != c && in_range) { printchar (last); in_range = 0; } if (! in_range) printchar (c); last = c; } if (in_range) printchar (last); putchar (']'); p += 1 + *p; } break; case begline: printf ("/begline"); break; case endline: printf ("/endline"); break; case on_failure_jump: extract_number_and_incr (&mcnt, &p); printf ("/on_failure_jump to %d", p + mcnt - start); break; case on_failure_keep_string_jump: extract_number_and_incr (&mcnt, &p); printf ("/on_failure_keep_string_jump to %d", p + mcnt - start); break; case dummy_failure_jump: extract_number_and_incr (&mcnt, &p); printf ("/dummy_failure_jump to %d", p + mcnt - start); break; case push_dummy_failure: printf ("/push_dummy_failure"); break; case maybe_pop_jump: extract_number_and_incr (&mcnt, &p); printf ("/maybe_pop_jump to %d", p + mcnt - start); break; case pop_failure_jump: extract_number_and_incr (&mcnt, &p); printf ("/pop_failure_jump to %d", p + mcnt - start); break; case jump_past_alt: extract_number_and_incr (&mcnt, &p); printf ("/jump_past_alt to %d", p + mcnt - start); break; case jump: extract_number_and_incr (&mcnt, &p); printf ("/jump to %d", p + mcnt - start); break; case succeed_n: extract_number_and_incr (&mcnt, &p); extract_number_and_incr (&mcnt2, &p); printf ("/succeed_n to %d, %d times", p + mcnt - start, mcnt2); break; case jump_n: extract_number_and_incr (&mcnt, &p); extract_number_and_incr (&mcnt2, &p); printf ("/jump_n to %d, %d times", p + mcnt - start, mcnt2); break; case set_number_at: extract_number_and_incr (&mcnt, &p); extract_number_and_incr (&mcnt2, &p); printf ("/set_number_at location %d to %d", p + mcnt - start, mcnt2); break; case wordbound: printf ("/wordbound"); break; case notwordbound: printf ("/notwordbound"); break; case wordbeg: printf ("/wordbeg"); break; case wordend: printf ("/wordend"); #ifdef emacs case before_dot: printf ("/before_dot"); break; case at_dot: printf ("/at_dot"); break; case after_dot: printf ("/after_dot"); break; case syntaxspec: printf ("/syntaxspec"); mcnt = *p++; printf ("/%d", mcnt); break; case notsyntaxspec: printf ("/notsyntaxspec"); mcnt = *p++; printf ("/%d", mcnt); break; #endif /* emacs */ case wordchar: printf ("/wordchar"); break; case notwordchar: printf ("/notwordchar"); break; case begbuf: printf ("/begbuf"); break; case endbuf: printf ("/endbuf"); break; default: printf ("?%d", *(p-1)); } putchar ('\n'); } printf ("%d:\tend of pattern.\n", p - start); } void print_compiled_pattern (bufp) struct re_pattern_buffer *bufp; { unsigned char *buffer = bufp->buffer; print_partial_compiled_pattern (buffer, buffer + bufp->used); printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated); if (bufp->fastmap_accurate && bufp->fastmap) { printf ("fastmap: "); print_fastmap (bufp->fastmap); } printf ("re_nsub: %d\t", bufp->re_nsub); printf ("regs_alloc: %d\t", bufp->regs_allocated); printf ("can_be_null: %d\t", bufp->can_be_null); printf ("newline_anchor: %d\n", bufp->newline_anchor); printf ("no_sub: %d\t", bufp->no_sub); printf ("not_bol: %d\t", bufp->not_bol); printf ("not_eol: %d\t", bufp->not_eol); printf ("syntax: %d\n", bufp->syntax); /* Perhaps we should print the translate table? */ } void print_double_string (where, string1, size1, string2, size2) const char *where; const char *string1; const char *string2; int size1; int size2; { unsigned this_char; if (where == NULL) printf ("(null)"); else { if (FIRST_STRING_P (where)) { for (this_char = where - string1; this_char < size1; this_char++) printchar (string1[this_char]); where = string2; } for (this_char = where - string2; this_char < size2; this_char++) printchar (string2[this_char]); } } #else /* not DEBUG */ #undef assert #define assert(e) #define DEBUG_STATEMENT(e) #define DEBUG_PRINT1(x) #define DEBUG_PRINT2(x1, x2) #define DEBUG_PRINT3(x1, x2, x3) #define DEBUG_PRINT4(x1, x2, x3, x4) #define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) #define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) #endif /* not DEBUG */ /* Set by `re_set_syntax' to the current regexp syntax to recognize. Can also be assigned to arbitrarily: each pattern buffer stores its own syntax, so it can be changed between regex compilations. */ reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS; /* Specify the precise syntax of regexps for compilation. This provides for compatibility for various utilities which historically have different, incompatible syntaxes. The argument SYNTAX is a bit mask comprised of the various bits defined in regex.h. We return the old syntax. */ reg_syntax_t re_set_syntax (syntax) reg_syntax_t syntax; { reg_syntax_t ret = re_syntax_options; re_syntax_options = syntax; return ret; } /* This table gives an error message for each of the error codes listed in regex.h. Obviously the order here has to be same as there. */ static const char *re_error_msg[] = { NULL, /* REG_NOERROR */ "No match", /* REG_NOMATCH */ "Invalid regular expression", /* REG_BADPAT */ "Invalid collation character", /* REG_ECOLLATE */ "Invalid character class name", /* REG_ECTYPE */ "Trailing backslash", /* REG_EESCAPE */ "Invalid back reference", /* REG_ESUBREG */ "Unmatched [ or [^", /* REG_EBRACK */ "Unmatched ( or \\(", /* REG_EPAREN */ "Unmatched \\{", /* REG_EBRACE */ "Invalid content of \\{\\}", /* REG_BADBR */ "Invalid range end", /* REG_ERANGE */ "Memory exhausted", /* REG_ESPACE */ "Invalid preceding regular expression", /* REG_BADRPT */ "Premature end of regular expression", /* REG_EEND */ "Regular expression too big", /* REG_ESIZE */ "Unmatched ) or \\)", /* REG_ERPAREN */ }; /* Subroutine declarations and macros for regex_compile. */ static void store_op1 (), store_op2 (); static void insert_op1 (), insert_op2 (); static boolean at_begline_loc_p (), at_endline_loc_p (); static boolean group_in_compile_stack (); static reg_errcode_t compile_range (); /* Fetch the next character in the uncompiled pattern---translating it if necessary. Also cast from a signed character in the constant string passed to us by the user to an unsigned char that we can use as an array index (in, e.g., `translate'). */ #define PATFETCH(c) \ do {if (p == pend) return REG_EEND; \ c = (unsigned char) *p++; \ if (translate) c = translate[c]; \ } while (0) /* Fetch the next character in the uncompiled pattern, with no translation. */ #define PATFETCH_RAW(c) \ do {if (p == pend) return REG_EEND; \ c = (unsigned char) *p++; \ } while (0) /* Go backwards one character in the pattern. */ #define PATUNFETCH p-- /* If `translate' is non-null, return translate[D], else just D. We cast the subscript to translate because some data is declared as `char *', to avoid warnings when a string constant is passed. But when we use a character as a subscript we must make it unsigned. */ #define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d)) /* Macros for outputting the compiled pattern into `buffer'. */ /* If the buffer isn't allocated when it comes in, use this. */ #define INIT_BUF_SIZE 32 /* Make sure we have at least N more bytes of space in buffer. */ #define GET_BUFFER_SPACE(n) \ while (b - bufp->buffer + (n) > bufp->allocated) \ EXTEND_BUFFER () /* Make sure we have one more byte of buffer space and then add C to it. */ #define BUF_PUSH(c) \ do { \ GET_BUFFER_SPACE (1); \ *b++ = (unsigned char) (c); \ } while (0) /* Ensure we have two more bytes of buffer space and then append C1 and C2. */ #define BUF_PUSH_2(c1, c2) \ do { \ GET_BUFFER_SPACE (2); \ *b++ = (unsigned char) (c1); \ *b++ = (unsigned char) (c2); \ } while (0) /* As with BUF_PUSH_2, except for three bytes. */ #define BUF_PUSH_3(c1, c2, c3) \ do { \ GET_BUFFER_SPACE (3); \ *b++ = (unsigned char) (c1); \ *b++ = (unsigned char) (c2); \ *b++ = (unsigned char) (c3); \ } while (0) /* Store a jump with opcode OP at LOC to location TO. We store a relative address offset by the three bytes the jump itself occupies. */ #define STORE_JUMP(op, loc, to) \ store_op1 (op, loc, (to) - (loc) - 3) /* Likewise, for a two-argument jump. */ #define STORE_JUMP2(op, loc, to, arg) \ store_op2 (op, loc, (to) - (loc) - 3, arg) /* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ #define INSERT_JUMP(op, loc, to) \ insert_op1 (op, loc, (to) - (loc) - 3, b) /* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ #define INSERT_JUMP2(op, loc, to, arg) \ insert_op2 (op, loc, (to) - (loc) - 3, arg, b) /* This is not an arbitrary limit: the arguments which represent offsets into the pattern are two bytes long. So if 2^16 bytes turns out to be too small, many things would have to change. */ #define MAX_BUF_SIZE (1L << 16) /* Extend the buffer by twice its current size via realloc and reset the pointers that pointed into the old block to point to the correct places in the new one. If extending the buffer results in it being larger than MAX_BUF_SIZE, then flag memory exhausted. */ #define EXTEND_BUFFER() \ do { \ unsigned char *old_buffer = bufp->buffer; \ if (bufp->allocated == MAX_BUF_SIZE) \ return REG_ESIZE; \ bufp->allocated <<= 1; \ if (bufp->allocated > MAX_BUF_SIZE) \ bufp->allocated = MAX_BUF_SIZE; \ bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\ if (bufp->buffer == NULL) \ return REG_ESPACE; \ /* If the buffer moved, move all the pointers into it. */ \ if (old_buffer != bufp->buffer) \ { \ b = (b - old_buffer) + bufp->buffer; \ begalt = (begalt - old_buffer) + bufp->buffer; \ if (fixup_alt_jump) \ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\ if (laststart) \ laststart = (laststart - old_buffer) + bufp->buffer; \ if (pending_exact) \ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ } \ } while (0) /* Since we have one byte reserved for the register number argument to {start,stop}_memory, the maximum number of groups we can report things about is what fits in that byte. */ #define MAX_REGNUM 255 /* But patterns can have more than `MAX_REGNUM' registers. We just ignore the excess. */ typedef unsigned regnum_t; /* Macros for the compile stack. */ /* Since offsets can go either forwards or backwards, this type needs to be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ typedef int pattern_offset_t; typedef struct { pattern_offset_t begalt_offset; pattern_offset_t fixup_alt_jump; pattern_offset_t inner_group_offset; pattern_offset_t laststart_offset; regnum_t regnum; } compile_stack_elt_t; typedef struct { compile_stack_elt_t *stack; unsigned size; unsigned avail; /* Offset of next open position. */ } compile_stack_type; #define INIT_COMPILE_STACK_SIZE 32 #define COMPILE_STACK_EMPTY (compile_stack.avail == 0) #define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) /* The next available element. */ #define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) /* Set the bit for character C in a list. */ #define SET_LIST_BIT(c) \ (b[((unsigned char) (c)) / BYTEWIDTH] \ |= 1 << (((unsigned char) c) % BYTEWIDTH)) /* Get the next unsigned number in the uncompiled pattern. */ #define GET_UNSIGNED_NUMBER(num) \ { if (p != pend) \ { \ PATFETCH (c); \ while (ISDIGIT (c)) \ { \ if (num < 0) \ num = 0; \ num = num * 10 + c - '0'; \ if (p == pend) \ break; \ PATFETCH (c); \ } \ } \ } #define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ #define IS_CHAR_CLASS(string) \ (STREQ (string, "alpha") || STREQ (string, "upper") \ || STREQ (string, "lower") || STREQ (string, "digit") \ || STREQ (string, "alnum") || STREQ (string, "xdigit") \ || STREQ (string, "space") || STREQ (string, "print") \ || STREQ (string, "punct") || STREQ (string, "graph") \ || STREQ (string, "cntrl") || STREQ (string, "blank")) /* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. Returns one of error codes defined in `regex.h', or zero for success. Assumes the `allocated' (and perhaps `buffer') and `translate' fields are set in BUFP on entry. If it succeeds, results are put in BUFP (if it returns an error, the contents of BUFP are undefined): `buffer' is the compiled pattern; `syntax' is set to SYNTAX; `used' is set to the length of the compiled pattern; `fastmap_accurate' is zero; `re_nsub' is the number of subexpressions in PATTERN; `not_bol' and `not_eol' are zero; The `fastmap' and `newline_anchor' fields are neither examined nor set. */ static reg_errcode_t regex_compile (pattern, size, syntax, bufp) const char *pattern; int size; reg_syntax_t syntax; struct re_pattern_buffer *bufp; { /* We fetch characters from PATTERN here. Even though PATTERN is `char *' (i.e., signed), we declare these variables as unsigned, so they can be reliably used as array indices. */ register unsigned char c, c1; /* A random tempory spot in PATTERN. */ const char *p1; /* Points to the end of the buffer, where we should append. */ register unsigned char *b; /* Keeps track of unclosed groups. */ compile_stack_type compile_stack; /* Points to the current (ending) position in the pattern. */ const char *p = pattern; const char *pend = pattern + size; /* How to translate the characters in the pattern. */ char *translate = bufp->translate; /* Address of the count-byte of the most recently inserted `exactn' command. This makes it possible to tell if a new exact-match character can be added to that command or if the character requires a new `exactn' command. */ unsigned char *pending_exact = 0; /* Address of start of the most recently finished expression. This tells, e.g., postfix * where to find the start of its operand. Reset at the beginning of groups and alternatives. */ unsigned char *laststart = 0; /* Address of beginning of regexp, or inside of last group. */ unsigned char *begalt; /* Place in the uncompiled pattern (i.e., the {) to which to go back if the interval is invalid. */ const char *beg_interval; /* Address of the place where a forward jump should go to the end of the containing expression. Each alternative of an `or' -- except the last -- ends with a forward jump of this sort. */ unsigned char *fixup_alt_jump = 0; /* Counts open-groups as they are encountered. Remembered for the matching close-group on the compile stack, so the same register number is put in the stop_memory as the start_memory. */ regnum_t regnum = 0; #ifdef DEBUG DEBUG_PRINT1 ("\nCompiling pattern: "); if (debug) { unsigned debug_count; for (debug_count = 0; debug_count < size; debug_count++) printchar (pattern[debug_count]); putchar ('\n'); } #endif /* DEBUG */ /* Initialize the compile stack. */ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); if (compile_stack.stack == NULL) return REG_ESPACE; compile_stack.size = INIT_COMPILE_STACK_SIZE; compile_stack.avail = 0; /* Initialize the pattern buffer. */ bufp->syntax = syntax; bufp->fastmap_accurate = 0; bufp->not_bol = bufp->not_eol = 0; /* Set `used' to zero, so that if we return an error, the pattern printer (for debugging) will think there's no pattern. We reset it at the end. */ bufp->used = 0; /* Always count groups, whether or not bufp->no_sub is set. */ bufp->re_nsub = 0; #if !defined (emacs) && !defined (SYNTAX_TABLE) /* Initialize the syntax table. */ init_syntax_once (); #endif if (bufp->allocated == 0) { if (bufp->buffer) { /* If zero allocated, but buffer is non-null, try to realloc enough space. This loses if buffer's address is bogus, but that is the user's responsibility. */ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); } else { /* Caller did not allocate a buffer. Do it for them. */ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char); } if (!bufp->buffer) return REG_ESPACE; bufp->allocated = INIT_BUF_SIZE; } begalt = b = bufp->buffer; /* Loop through the uncompiled pattern until we're at the end. */ while (p != pend) { PATFETCH (c); switch (c) { case '^': { if ( /* If at start of pattern, it's an operator. */ p == pattern + 1 /* If context independent, it's an operator. */ || syntax & RE_CONTEXT_INDEP_ANCHORS /* Otherwise, depends on what's come before. */ || at_begline_loc_p (pattern, p, syntax)) BUF_PUSH (begline); else goto normal_char; } break; case '$': { if ( /* If at end of pattern, it's an operator. */ p == pend /* If context independent, it's an operator. */ || syntax & RE_CONTEXT_INDEP_ANCHORS /* Otherwise, depends on what's next. */ || at_endline_loc_p (p, pend, syntax)) BUF_PUSH (endline); else goto normal_char; } break; case '+': case '?': if ((syntax & RE_BK_PLUS_QM) || (syntax & RE_LIMITED_OPS)) goto normal_char; handle_plus: case '*': /* If there is no previous pattern... */ if (!laststart) { if (syntax & RE_CONTEXT_INVALID_OPS) return REG_BADRPT; else if (!(syntax & RE_CONTEXT_INDEP_OPS)) goto normal_char; } { /* Are we optimizing this jump? */ boolean keep_string_p = false; /* 1 means zero (many) matches is allowed. */ char zero_times_ok = 0, many_times_ok = 0; /* If there is a sequence of repetition chars, collapse it down to just one (the right one). We can't combine interval operators with these because of, e.g., `a{2}*', which should only match an even number of `a's. */ for (;;) { zero_times_ok |= c != '+'; many_times_ok |= c != '?'; if (p == pend) break; PATFETCH (c); if (c == '*' || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) ; else if (syntax & RE_BK_PLUS_QM && c == '\\') { if (p == pend) return REG_EESCAPE; PATFETCH (c1); if (!(c1 == '+' || c1 == '?')) { PATUNFETCH; PATUNFETCH; break; } c = c1; } else { PATUNFETCH; break; } /* If we get here, we found another repeat character. */ } /* Star, etc. applied to an empty pattern is equivalent to an empty pattern. */ if (!laststart) break; /* Now we know whether or not zero matches is allowed and also whether or not two or more matches is allowed. */ if (many_times_ok) { /* More than one repetition is allowed, so put in at the end a backward relative jump from `b' to before the next jump we're going to put in below (which jumps from laststart to after this jump). But if we are at the `*' in the exact sequence `.*\n', insert an unconditional jump backwards to the ., instead of the beginning of the loop. This way we only push a failure point once, instead of every time through the loop. */ assert (p - 1 > pattern); /* Allocate the space for the jump. */ GET_BUFFER_SPACE (3); /* We know we are not at the first character of the pattern, because laststart was nonzero. And we've already incremented `p', by the way, to be the character after the `*'. Do we have to do something analogous here for null bytes, because of RE_DOT_NOT_NULL? */ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.') && zero_times_ok && p < pend && TRANSLATE (*p) == TRANSLATE ('\n') && !(syntax & RE_DOT_NEWLINE)) { /* We have .*\n. */ STORE_JUMP (jump, b, laststart); keep_string_p = true; } else /* Anything else. */ STORE_JUMP (maybe_pop_jump, b, laststart - 3); /* We've added more stuff to the buffer. */ b += 3; } /* On failure, jump from laststart to b + 3, which will be the end of the buffer after this jump is inserted. */ GET_BUFFER_SPACE (3); INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump : on_failure_jump, laststart, b + 3); pending_exact = 0; b += 3; if (!zero_times_ok) { /* At least one repetition is required, so insert a `dummy_failure_jump' before the initial `on_failure_jump' instruction of the loop. This effects a skip over that instruction the first time we hit that loop. */ GET_BUFFER_SPACE (3); INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); b += 3; } } break; case '.': laststart = b; BUF_PUSH (anychar); break; case '[': { boolean had_char_class = false; if (p == pend) return REG_EBRACK; /* Ensure that we have enough space to push a charset: the opcode, the length count, and the bitset; 34 bytes in all. */ GET_BUFFER_SPACE (34); laststart = b; /* We test `*p == '^' twice, instead of using an if statement, so we only need one BUF_PUSH. */ BUF_PUSH (*p == '^' ? charset_not : charset); if (*p == '^') p++; /* Remember the first position in the bracket expression. */ p1 = p; /* Push the number of bytes in the bitmap. */ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); /* Clear the whole map. */ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); /* charset_not matches newline according to a syntax bit. */ if ((re_opcode_t) b[-2] == charset_not && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) SET_LIST_BIT ('\n'); /* Read in characters and ranges, setting map bits. */ for (;;) { if (p == pend) return REG_EBRACK; PATFETCH (c); /* \ might escape characters inside [...] and [^...]. */ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') { if (p == pend) return REG_EESCAPE; PATFETCH (c1); SET_LIST_BIT (c1); continue; } /* Could be the end of the bracket expression. If it's not (i.e., when the bracket expression is `[]' so far), the ']' character bit gets set way below. */ if (c == ']' && p != p1 + 1) break; /* Look ahead to see if it's a range when the last thing was a character class. */ if (had_char_class && c == '-' && *p != ']') return REG_ERANGE; /* Look ahead to see if it's a range when the last thing was a character: if this is a hyphen not at the beginning or the end of a list, then it's the range operator. */ if (c == '-' && !(p - 2 >= pattern && p[-2] == '[') && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') && *p != ']') { reg_errcode_t ret = compile_range (&p, pend, translate, syntax, b); if (ret != REG_NOERROR) return ret; } else if (p[0] == '-' && p[1] != ']') { /* This handles ranges made up of characters only. */ reg_errcode_t ret; /* Move past the `-'. */ PATFETCH (c1); ret = compile_range (&p, pend, translate, syntax, b); if (ret != REG_NOERROR) return ret; } /* See if we're at the beginning of a possible character class. */ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') { /* Leave room for the null. */ char str[CHAR_CLASS_MAX_LENGTH + 1]; PATFETCH (c); c1 = 0; /* If pattern is `[[:'. */ if (p == pend) return REG_EBRACK; for (;;) { PATFETCH (c); if (c == ':' || c == ']' || p == pend || c1 == CHAR_CLASS_MAX_LENGTH) break; str[c1++] = c; } str[c1] = '\0'; /* If isn't a word bracketed by `[:' and:`]': undo the ending character, the letters, and leave the leading `:' and `[' (but set bits for them). */ if (c == ':' && *p == ']') { int ch; boolean is_alnum = STREQ (str, "alnum"); boolean is_alpha = STREQ (str, "alpha"); boolean is_blank = STREQ (str, "blank"); boolean is_cntrl = STREQ (str, "cntrl"); boolean is_digit = STREQ (str, "digit"); boolean is_graph = STREQ (str, "graph"); boolean is_lower = STREQ (str, "lower"); boolean is_print = STREQ (str, "print"); boolean is_punct = STREQ (str, "punct"); boolean is_space = STREQ (str, "space"); boolean is_upper = STREQ (str, "upper"); boolean is_xdigit = STREQ (str, "xdigit"); if (!IS_CHAR_CLASS (str)) return REG_ECTYPE; /* Throw away the ] at the end of the character class. */ PATFETCH (c); if (p == pend) return REG_EBRACK; for (ch = 0; ch < 1 << BYTEWIDTH; ch++) { if ( (is_alnum && ISALNUM (ch)) || (is_alpha && ISALPHA (ch)) || (is_blank && ISBLANK (ch)) || (is_cntrl && ISCNTRL (ch)) || (is_digit && ISDIGIT (ch)) || (is_graph && ISGRAPH (ch)) || (is_lower && ISLOWER (ch)) || (is_print && ISPRINT (ch)) || (is_punct && ISPUNCT (ch)) || (is_space && ISSPACE (ch)) || (is_upper && ISUPPER (ch)) || (is_xdigit && ISXDIGIT (ch))) SET_LIST_BIT (ch); } had_char_class = true; } else { c1++; while (c1--) PATUNFETCH; SET_LIST_BIT ('['); SET_LIST_BIT (':'); had_char_class = false; } } else { had_char_class = false; SET_LIST_BIT (c); } } /* Discard any (non)matching list bytes that are all 0 at the end of the map. Decrease the map-length byte too. */ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) b[-1]--; b += b[-1]; } break; case '(': if (syntax & RE_NO_BK_PARENS) goto handle_open; else goto normal_char; case ')': if (syntax & RE_NO_BK_PARENS) goto handle_close; else goto normal_char; case '\n': if (syntax & RE_NEWLINE_ALT) goto handle_alt; else goto normal_char; case '|': if (syntax & RE_NO_BK_VBAR) goto handle_alt; else goto normal_char; case '{': if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) goto handle_interval; else goto normal_char; case '\\': if (p == pend) return REG_EESCAPE; /* Do not translate the character after the \, so that we can distinguish, e.g., \B from \b, even if we normally would translate, e.g., B to b. */ PATFETCH_RAW (c); switch (c) { case '(': if (syntax & RE_NO_BK_PARENS) goto normal_backslash; handle_open: bufp->re_nsub++; regnum++; if (COMPILE_STACK_FULL) { RETALLOC (compile_stack.stack, compile_stack.size << 1, compile_stack_elt_t); if (compile_stack.stack == NULL) return REG_ESPACE; compile_stack.size <<= 1; } /* These are the values to restore when we hit end of this group. They are all relative offsets, so that if the whole pattern moves because of realloc, they will still be valid. */ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer; COMPILE_STACK_TOP.fixup_alt_jump = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer; COMPILE_STACK_TOP.regnum = regnum; /* We will eventually replace the 0 with the number of groups inner to this one. But do not push a start_memory for groups beyond the last one we can represent in the compiled pattern. */ if (regnum <= MAX_REGNUM) { COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; BUF_PUSH_3 (start_memory, regnum, 0); } compile_stack.avail++; fixup_alt_jump = 0; laststart = 0; begalt = b; /* If we've reached MAX_REGNUM groups, then this open won't actually generate any code, so we'll have to clear pending_exact explicitly. */ pending_exact = 0; break; case ')': if (syntax & RE_NO_BK_PARENS) goto normal_backslash; if (COMPILE_STACK_EMPTY) if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) goto normal_backslash; else return REG_ERPAREN; handle_close: if (fixup_alt_jump) { /* Push a dummy failure point at the end of the alternative for a possible future `pop_failure_jump' to pop. See comments at `push_dummy_failure' in `re_match_2'. */ BUF_PUSH (push_dummy_failure); /* We allocated space for this jump when we assigned to `fixup_alt_jump', in the `handle_alt' case below. */ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); } /* See similar code for backslashed left paren above. */ if (COMPILE_STACK_EMPTY) if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) goto normal_char; else return REG_ERPAREN; /* Since we just checked for an empty stack above, this ``can't happen''. */ assert (compile_stack.avail != 0); { /* We don't just want to restore into `regnum', because later groups should continue to be numbered higher, as in `(ab)c(de)' -- the second group is #2. */ regnum_t this_group_regnum; compile_stack.avail--; begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset; fixup_alt_jump = COMPILE_STACK_TOP.fixup_alt_jump ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 : 0; laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset; this_group_regnum = COMPILE_STACK_TOP.regnum; /* If we've reached MAX_REGNUM groups, then this open won't actually generate any code, so we'll have to clear pending_exact explicitly. */ pending_exact = 0; /* We're at the end of the group, so now we know how many groups were inside this one. */ if (this_group_regnum <= MAX_REGNUM) { unsigned char *inner_group_loc = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset; *inner_group_loc = regnum - this_group_regnum; BUF_PUSH_3 (stop_memory, this_group_regnum, regnum - this_group_regnum); } } break; case '|': /* `\|'. */ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) goto normal_backslash; handle_alt: if (syntax & RE_LIMITED_OPS) goto normal_char; /* Insert before the previous alternative a jump which jumps to this alternative if the former fails. */ GET_BUFFER_SPACE (3); INSERT_JUMP (on_failure_jump, begalt, b + 6); pending_exact = 0; b += 3; /* The alternative before this one has a jump after it which gets executed if it gets matched. Adjust that jump so it will jump to this alternative's analogous jump (put in below, which in turn will jump to the next (if any) alternative's such jump, etc.). The last such jump jumps to the correct final destination. A picture: _____ _____ | | | | | v | v a | b | c If we are at `b', then fixup_alt_jump right now points to a three-byte space after `a'. We'll put in the jump, set fixup_alt_jump to right after `b', and leave behind three bytes which we'll fill in when we get to after `c'. */ if (fixup_alt_jump) STORE_JUMP (jump_past_alt, fixup_alt_jump, b); /* Mark and leave space for a jump after this alternative, to be filled in later either by next alternative or when know we're at the end of a series of alternatives. */ fixup_alt_jump = b; GET_BUFFER_SPACE (3); b += 3; laststart = 0; begalt = b; break; case '{': /* If \{ is a literal. */ if (!(syntax & RE_INTERVALS) /* If we're at `\{' and it's not the open-interval operator. */ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) || (p - 2 == pattern && p == pend)) goto normal_backslash; handle_interval: { /* If got here, then the syntax allows intervals. */ /* At least (most) this many matches must be made. */ int lower_bound = -1, upper_bound = -1; beg_interval = p - 1; if (p == pend) { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else return REG_EBRACE; } GET_UNSIGNED_NUMBER (lower_bound); if (c == ',') { GET_UNSIGNED_NUMBER (upper_bound); if (upper_bound < 0) upper_bound = RE_DUP_MAX; } else /* Interval such as `{1}' => match exactly once. */ upper_bound = lower_bound; if (lower_bound < 0 || upper_bound > RE_DUP_MAX || lower_bound > upper_bound) { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else return REG_BADBR; } if (!(syntax & RE_NO_BK_BRACES)) { if (c != '\\') return REG_EBRACE; PATFETCH (c); } if (c != '}') { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else return REG_BADBR; } /* We just parsed a valid interval. */ /* If it's invalid to have no preceding re. */ if (!laststart) { if (syntax & RE_CONTEXT_INVALID_OPS) return REG_BADRPT; else if (syntax & RE_CONTEXT_INDEP_OPS) laststart = b; else goto unfetch_interval; } /* If the upper bound is zero, don't want to succeed at all; jump from `laststart' to `b + 3', which will be the end of the buffer after we insert the jump. */ if (upper_bound == 0) { GET_BUFFER_SPACE (3); INSERT_JUMP (jump, laststart, b + 3); b += 3; } /* Otherwise, we have a nontrivial interval. When we're all done, the pattern will look like: set_number_at set_number_at succeed_n jump_n (The upper bound and `jump_n' are omitted if `upper_bound' is 1, though.) */ else { /* If the upper bound is > 1, we need to insert more at the end of the loop. */ unsigned nbytes = 10 + (upper_bound > 1) * 10; GET_BUFFER_SPACE (nbytes); /* Initialize lower bound of the `succeed_n', even though it will be set during matching by its attendant `set_number_at' (inserted next), because `re_compile_fastmap' needs to know. Jump to the `jump_n' we might insert below. */ INSERT_JUMP2 (succeed_n, laststart, b + 5 + (upper_bound > 1) * 5, lower_bound); b += 5; /* Code to initialize the lower bound. Insert before the `succeed_n'. The `5' is the last two bytes of this `set_number_at', plus 3 bytes of the following `succeed_n'. */ insert_op2 (set_number_at, laststart, 5, lower_bound, b); b += 5; if (upper_bound > 1) { /* More than one repetition is allowed, so append a backward jump to the `succeed_n' that starts this interval. When we've reached this during matching, we'll have matched the interval once, so jump back only `upper_bound - 1' times. */ STORE_JUMP2 (jump_n, b, laststart + 5, upper_bound - 1); b += 5; /* The location we want to set is the second parameter of the `jump_n'; that is `b-2' as an absolute address. `laststart' will be the `set_number_at' we're about to insert; `laststart+3' the number to set, the source for the relative address. But we are inserting into the middle of the pattern -- so everything is getting moved up by 5. Conclusion: (b - 2) - (laststart + 3) + 5, i.e., b - laststart. We insert this at the beginning of the loop so that if we fail during matching, we'll reinitialize the bounds. */ insert_op2 (set_number_at, laststart, b - laststart, upper_bound - 1, b); b += 5; } } pending_exact = 0; beg_interval = NULL; } break; unfetch_interval: /* If an invalid interval, match the characters as literals. */ assert (beg_interval); p = beg_interval; beg_interval = NULL; /* normal_char and normal_backslash need `c'. */ PATFETCH (c); if (!(syntax & RE_NO_BK_BRACES)) { if (p > pattern && p[-1] == '\\') goto normal_backslash; } goto normal_char; #ifdef emacs /* There is no way to specify the before_dot and after_dot operators. rms says this is ok. --karl */ case '=': BUF_PUSH (at_dot); break; case 's': laststart = b; PATFETCH (c); BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); break; case 'S': laststart = b; PATFETCH (c); BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); break; #endif /* emacs */ case 'w': laststart = b; BUF_PUSH (wordchar); break; case 'W': laststart = b; BUF_PUSH (notwordchar); break; case '<': BUF_PUSH (wordbeg); break; case '>': BUF_PUSH (wordend); break; case 'b': BUF_PUSH (wordbound); break; case 'B': BUF_PUSH (notwordbound); break; case '`': BUF_PUSH (begbuf); break; case '\'': BUF_PUSH (endbuf); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (syntax & RE_NO_BK_REFS) goto normal_char; c1 = c - '0'; if (c1 > regnum) return REG_ESUBREG; /* Can't back reference to a subexpression if inside of it. */ if (group_in_compile_stack (compile_stack, c1)) goto normal_char; laststart = b; BUF_PUSH_2 (duplicate, c1); break; case '+': case '?': if (syntax & RE_BK_PLUS_QM) goto handle_plus; else goto normal_backslash; default: normal_backslash: /* You might think it would be useful for \ to mean not to translate; but if we don't translate it it will never match anything. */ c = TRANSLATE (c); goto normal_char; } break; default: /* Expects the character in `c'. */ normal_char: /* If no exactn currently being built. */ if (!pending_exact /* If last exactn not at current position. */ || pending_exact + *pending_exact + 1 != b /* We have only one byte following the exactn for the count. */ || *pending_exact == (1 << BYTEWIDTH) - 1 /* If followed by a repetition operator. */ || *p == '*' || *p == '^' || ((syntax & RE_BK_PLUS_QM) ? *p == '\\' && (p[1] == '+' || p[1] == '?') : (*p == '+' || *p == '?')) || ((syntax & RE_INTERVALS) && ((syntax & RE_NO_BK_BRACES) ? *p == '{' : (p[0] == '\\' && p[1] == '{')))) { /* Start building a new exactn. */ laststart = b; BUF_PUSH_2 (exactn, 0); pending_exact = b - 1; } BUF_PUSH (c); (*pending_exact)++; break; } /* switch (c) */ } /* while p != pend */ /* Through the pattern now. */ if (fixup_alt_jump) STORE_JUMP (jump_past_alt, fixup_alt_jump, b); if (!COMPILE_STACK_EMPTY) return REG_EPAREN; free (compile_stack.stack); /* We have succeeded; set the length of the buffer. */ bufp->used = b - bufp->buffer; #ifdef DEBUG if (debug) { DEBUG_PRINT1 ("\nCompiled pattern: \n"); print_compiled_pattern (bufp); } #endif /* DEBUG */ return REG_NOERROR; } /* regex_compile */ /* Subroutines for `regex_compile'. */ /* Store OP at LOC followed by two-byte integer parameter ARG. */ static void store_op1 (op, loc, arg) re_opcode_t op; unsigned char *loc; int arg; { *loc = (unsigned char) op; STORE_NUMBER (loc + 1, arg); } /* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ static void store_op2 (op, loc, arg1, arg2) re_opcode_t op; unsigned char *loc; int arg1, arg2; { *loc = (unsigned char) op; STORE_NUMBER (loc + 1, arg1); STORE_NUMBER (loc + 3, arg2); } /* Copy the bytes from LOC to END to open up three bytes of space at LOC for OP followed by two-byte integer parameter ARG. */ static void insert_op1 (op, loc, arg, end) re_opcode_t op; unsigned char *loc; int arg; unsigned char *end; { register unsigned char *pfrom = end; register unsigned char *pto = end + 3; while (pfrom != loc) *--pto = *--pfrom; store_op1 (op, loc, arg); } /* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ static void insert_op2 (op, loc, arg1, arg2, end) re_opcode_t op; unsigned char *loc; int arg1, arg2; unsigned char *end; { register unsigned char *pfrom = end; register unsigned char *pto = end + 5; while (pfrom != loc) *--pto = *--pfrom; store_op2 (op, loc, arg1, arg2); } /* P points to just after a ^ in PATTERN. Return true if that ^ comes after an alternative or a begin-subexpression. We assume there is at least one character before the ^. */ static boolean at_begline_loc_p (pattern, p, syntax) const char *pattern, *p; reg_syntax_t syntax; { const char *prev = p - 2; boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; return /* After a subexpression? */ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) /* After an alternative? */ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); } /* The dual of at_begline_loc_p. This one is for $. We assume there is at least one character after the $, i.e., `P < PEND'. */ static boolean at_endline_loc_p (p, pend, syntax) const char *p, *pend; int syntax; { const char *next = p; boolean next_backslash = *next == '\\'; const char *next_next = p + 1 < pend ? p + 1 : NULL; return /* Before a subexpression? */ (syntax & RE_NO_BK_PARENS ? *next == ')' : next_backslash && next_next && *next_next == ')') /* Before an alternative? */ || (syntax & RE_NO_BK_VBAR ? *next == '|' : next_backslash && next_next && *next_next == '|'); } /* Returns true if REGNUM is in one of COMPILE_STACK's elements and false if it's not. */ static boolean group_in_compile_stack (compile_stack, regnum) compile_stack_type compile_stack; regnum_t regnum; { int this_element; for (this_element = compile_stack.avail - 1; this_element >= 0; this_element--) if (compile_stack.stack[this_element].regnum == regnum) return true; return false; } /* Read the ending character of a range (in a bracket expression) from the uncompiled pattern *P_PTR (which ends at PEND). We assume the starting character is in `P[-2]'. (`P[-1]' is the character `-'.) Then we set the translation of all bits between the starting and ending characters (inclusive) in the compiled pattern B. Return an error code. We use these short variable names so we can use the same macros as `regex_compile' itself. */ static reg_errcode_t compile_range (p_ptr, pend, translate, syntax, b) const char **p_ptr, *pend; char *translate; reg_syntax_t syntax; unsigned char *b; { unsigned this_char; const char *p = *p_ptr; int range_start, range_end; if (p == pend) return REG_ERANGE; /* Even though the pattern is a signed `char *', we need to fetch with unsigned char *'s; if the high bit of the pattern character is set, the range endpoints will be negative if we fetch using a signed char *. We also want to fetch the endpoints without translating them; the appropriate translation is done in the bit-setting loop below. */ range_start = ((unsigned char *) p)[-2]; range_end = ((unsigned char *) p)[0]; /* Have to increment the pointer into the pattern string, so the caller isn't still at the ending character. */ (*p_ptr)++; /* If the start is after the end, the range is empty. */ if (range_start > range_end) return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; /* Here we see why `this_char' has to be larger than an `unsigned char' -- the range is inclusive, so if `range_end' == 0xff (assuming 8-bit characters), we would otherwise go into an infinite loop, since all characters <= 0xff. */ for (this_char = range_start; this_char <= range_end; this_char++) { SET_LIST_BIT (TRANSLATE (this_char)); } return REG_NOERROR; } /* Failure stack declarations and macros; both re_compile_fastmap and re_match_2 use a failure stack. These have to be macros because of REGEX_ALLOCATE. */ /* Number of failure points for which to initially allocate space when matching. If this number is exceeded, we allocate more space, so it is not a hard limit. */ #ifndef INIT_FAILURE_ALLOC #define INIT_FAILURE_ALLOC 5 #endif /* Roughly the maximum number of failure points on the stack. Would be exactly that if always used MAX_FAILURE_SPACE each time we failed. This is a variable only so users of regex can assign to it; we never change it ourselves. */ int re_max_failures = 2000; typedef const unsigned char *fail_stack_elt_t; typedef struct { fail_stack_elt_t *stack; unsigned size; unsigned avail; /* Offset of next open position. */ } fail_stack_type; #define FAIL_STACK_EMPTY() (fail_stack.avail == 0) #define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) #define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) #define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail]) /* Initialize `fail_stack'. Do `return -2' if the alloc fails. */ #define INIT_FAIL_STACK() \ do { \ fail_stack.stack = (fail_stack_elt_t *) \ REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ \ if (fail_stack.stack == NULL) \ return -2; \ \ fail_stack.size = INIT_FAILURE_ALLOC; \ fail_stack.avail = 0; \ } while (0) /* Double the size of FAIL_STACK, up to approximately `re_max_failures' items. Return 1 if succeeds, and 0 if either ran out of memory allocating space for it or it was already too large. REGEX_REALLOCATE requires `destination' be declared. */ #define DOUBLE_FAIL_STACK(fail_stack) \ ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \ ? 0 \ : ((fail_stack).stack = (fail_stack_elt_t *) \ REGEX_REALLOCATE ((fail_stack).stack, \ (fail_stack).size * sizeof (fail_stack_elt_t), \ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \ \ (fail_stack).stack == NULL \ ? 0 \ : ((fail_stack).size <<= 1, \ 1))) /* Push PATTERN_OP on FAIL_STACK. Return 1 if was able to do so and 0 if ran out of memory allocating space to do so. */ #define PUSH_PATTERN_OP(pattern_op, fail_stack) \ ((FAIL_STACK_FULL () \ && !DOUBLE_FAIL_STACK (fail_stack)) \ ? 0 \ : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \ 1)) /* This pushes an item onto the failure stack. Must be a four-byte value. Assumes the variable `fail_stack'. Probably should only be called from within `PUSH_FAILURE_POINT'. */ #define PUSH_FAILURE_ITEM(item) \ fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item /* The complement operation. Assumes `fail_stack' is nonempty. */ #define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail] /* Used to omit pushing failure point id's when we're not debugging. */ #ifdef DEBUG #define DEBUG_PUSH PUSH_FAILURE_ITEM #define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM () #else #define DEBUG_PUSH(item) #define DEBUG_POP(item_addr) #endif /* Push the information about the state we will need if we ever fail back to it. Requires variables fail_stack, regstart, regend, reg_info, and num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be declared. Does `return FAILURE_CODE' if runs out of memory. */ #define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ do { \ char *destination; \ /* Must be int, so when we don't save any registers, the arithmetic \ of 0 + -1 isn't done as unsigned. */ \ int this_reg; \ \ DEBUG_STATEMENT (failure_id++); \ DEBUG_STATEMENT (nfailure_points_pushed++); \ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ \ DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ \ /* Ensure we have enough space allocated for what we will push. */ \ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ { \ if (!DOUBLE_FAIL_STACK (fail_stack)) \ return failure_code; \ \ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ (fail_stack).size); \ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ } \ \ /* Push the info, starting with the registers. */ \ DEBUG_PRINT1 ("\n"); \ \ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ this_reg++) \ { \ DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \ DEBUG_STATEMENT (num_regs_pushed++); \ \ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \ PUSH_FAILURE_ITEM (regstart[this_reg]); \ \ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ PUSH_FAILURE_ITEM (regend[this_reg]); \ \ DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \ DEBUG_PRINT2 (" match_null=%d", \ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ DEBUG_PRINT2 (" matched_something=%d", \ MATCHED_SOMETHING (reg_info[this_reg])); \ DEBUG_PRINT2 (" ever_matched=%d", \ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ DEBUG_PRINT1 ("\n"); \ PUSH_FAILURE_ITEM (reg_info[this_reg].word); \ } \ \ DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\ PUSH_FAILURE_ITEM (lowest_active_reg); \ \ DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\ PUSH_FAILURE_ITEM (highest_active_reg); \ \ DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ PUSH_FAILURE_ITEM (pattern_place); \ \ DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ size2); \ DEBUG_PRINT1 ("'\n"); \ PUSH_FAILURE_ITEM (string_place); \ \ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ DEBUG_PUSH (failure_id); \ } while (0) /* This is the number of items that are pushed and popped on the stack for each register. */ #define NUM_REG_ITEMS 3 /* Individual items aside from the registers. */ #ifdef DEBUG #define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ #else #define NUM_NONREG_ITEMS 4 #endif /* We push at most this many items on the stack. */ #define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS) /* We actually push this many items. */ #define NUM_FAILURE_ITEMS \ ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \ + NUM_NONREG_ITEMS) /* How many items can still be added to the stack without overflowing it. */ #define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) /* Pops what PUSH_FAIL_STACK pushes. We restore into the parameters, all of which should be lvalues: STR -- the saved data position. PAT -- the saved pattern position. LOW_REG, HIGH_REG -- the highest and lowest active registers. REGSTART, REGEND -- arrays of string positions. REG_INFO -- array of information about each subexpression. Also assumes the variables `fail_stack' and (if debugging), `bufp', `pend', `string1', `size1', `string2', and `size2'. */ #define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ { \ DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \ int this_reg; \ const unsigned char *string_temp; \ \ assert (!FAIL_STACK_EMPTY ()); \ \ /* Remove failure points and point to how many regs pushed. */ \ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ \ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ \ DEBUG_POP (&failure_id); \ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ \ /* If the saved string location is NULL, it came from an \ on_failure_keep_string_jump opcode, and we want to throw away the \ saved NULL, thus retaining our current position in the string. */ \ string_temp = POP_FAILURE_ITEM (); \ if (string_temp != NULL) \ str = (const char *) string_temp; \ \ DEBUG_PRINT2 (" Popping string 0x%x: `", str); \ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ DEBUG_PRINT1 ("'\n"); \ \ pat = (unsigned char *) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ \ /* Restore register info. */ \ high_reg = (unsigned) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \ \ low_reg = (unsigned) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \ \ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ { \ DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \ \ reg_info[this_reg].word = POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \ \ regend[this_reg] = (const char *) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ \ regstart[this_reg] = (const char *) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \ } \ \ DEBUG_STATEMENT (nfailure_points_popped++); \ } /* POP_FAILURE_POINT */ /* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible characters can start a string that matches the pattern. This fastmap is used by re_search to skip quickly over impossible starting points. The caller must supply the address of a (1 << BYTEWIDTH)-byte data area as BUFP->fastmap. We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in the pattern buffer. Returns 0 if we succeed, -2 if an internal error. */ int re_compile_fastmap (bufp) struct re_pattern_buffer *bufp; { int j, k; fail_stack_type fail_stack; #ifndef REGEX_MALLOC char *destination; #endif /* We don't push any register information onto the failure stack. */ unsigned num_regs = 0; register char *fastmap = bufp->fastmap; unsigned char *pattern = bufp->buffer; unsigned long size = bufp->used; const unsigned char *p = pattern; register unsigned char *pend = pattern + size; /* Assume that each path through the pattern can be null until proven otherwise. We set this false at the bottom of switch statement, to which we get only if a particular path doesn't match the empty string. */ boolean path_can_be_null = true; /* We aren't doing a `succeed_n' to begin with. */ boolean succeed_n_p = false; assert (fastmap != NULL && p != NULL); INIT_FAIL_STACK (); bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ bufp->fastmap_accurate = 1; /* It will be when we're done. */ bufp->can_be_null = 0; while (p != pend || !FAIL_STACK_EMPTY ()) { if (p == pend) { bufp->can_be_null |= path_can_be_null; /* Reset for next path. */ path_can_be_null = true; p = fail_stack.stack[--fail_stack.avail]; } /* We should never be about to go beyond the end of the pattern. */ assert (p < pend); #ifdef SWITCH_ENUM_BUG switch ((int) ((re_opcode_t) *p++)) #else switch ((re_opcode_t) *p++) #endif { /* I guess the idea here is to simply not bother with a fastmap if a backreference is used, since it's too hard to figure out the fastmap for the corresponding group. Setting `can_be_null' stops `re_search_2' from using the fastmap, so that is all we do. */ case duplicate: bufp->can_be_null = 1; return 0; /* Following are the cases which match a character. These end with `break'. */ case exactn: fastmap[p[1]] = 1; break; case charset: for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) fastmap[j] = 1; break; case charset_not: /* Chars beyond end of map must be allowed. */ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) fastmap[j] = 1; for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) fastmap[j] = 1; break; case wordchar: for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) == Sword) fastmap[j] = 1; break; case notwordchar: for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) != Sword) fastmap[j] = 1; break; case anychar: /* `.' matches anything ... */ for (j = 0; j < (1 << BYTEWIDTH); j++) fastmap[j] = 1; /* ... except perhaps newline. */ if (!(bufp->syntax & RE_DOT_NEWLINE)) fastmap['\n'] = 0; /* Return if we have already set `can_be_null'; if we have, then the fastmap is irrelevant. Something's wrong here. */ else if (bufp->can_be_null) return 0; /* Otherwise, have to check alternative paths. */ break; #ifdef emacs case syntaxspec: k = *p++; for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) == (enum syntaxcode) k) fastmap[j] = 1; break; case notsyntaxspec: k = *p++; for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) != (enum syntaxcode) k) fastmap[j] = 1; break; /* All cases after this match the empty string. These end with `continue'. */ case before_dot: case at_dot: case after_dot: continue; #endif /* not emacs */ case no_op: case begline: case endline: case begbuf: case endbuf: case wordbound: case notwordbound: case wordbeg: case wordend: case push_dummy_failure: continue; case jump_n: case pop_failure_jump: case maybe_pop_jump: case jump: case jump_past_alt: case dummy_failure_jump: EXTRACT_NUMBER_AND_INCR (j, p); p += j; if (j > 0) continue; /* Jump backward implies we just went through the body of a loop and matched nothing. Opcode jumped to should be `on_failure_jump' or `succeed_n'. Just treat it like an ordinary jump. For a * loop, it has pushed its failure point already; if so, discard that as redundant. */ if ((re_opcode_t) *p != on_failure_jump && (re_opcode_t) *p != succeed_n) continue; p++; EXTRACT_NUMBER_AND_INCR (j, p); p += j; /* If what's on the stack is where we are now, pop it. */ if (!FAIL_STACK_EMPTY () && fail_stack.stack[fail_stack.avail - 1] == p) fail_stack.avail--; continue; case on_failure_jump: case on_failure_keep_string_jump: handle_on_failure_jump: EXTRACT_NUMBER_AND_INCR (j, p); /* For some patterns, e.g., `(a?)?', `p+j' here points to the end of the pattern. We don't want to push such a point, since when we restore it above, entering the switch will increment `p' past the end of the pattern. We don't need to push such a point since we obviously won't find any more fastmap entries beyond `pend'. Such a pattern can match the null string, though. */ if (p + j < pend) { if (!PUSH_PATTERN_OP (p + j, fail_stack)) return -2; } else bufp->can_be_null = 1; if (succeed_n_p) { EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ succeed_n_p = false; } continue; case succeed_n: /* Get to the number of times to succeed. */ p += 2; /* Increment p past the n for when k != 0. */ EXTRACT_NUMBER_AND_INCR (k, p); if (k == 0) { p -= 4; succeed_n_p = true; /* Spaghetti code alert. */ goto handle_on_failure_jump; } continue; case set_number_at: p += 4; continue; case start_memory: case stop_memory: p += 2; continue; default: abort (); /* We have listed all the cases. */ } /* switch *p++ */ /* Getting here means we have found the possible starting characters for one path of the pattern -- and that the empty string does not match. We need not follow this path further. Instead, look at the next alternative (remembered on the stack), or quit if no more. The test at the top of the loop does these things. */ path_can_be_null = false; p = pend; } /* while p */ /* Set `can_be_null' for the last path (also the first path, if the pattern is empty). */ bufp->can_be_null |= path_can_be_null; return 0; } /* re_compile_fastmap */ /* Set REGS to hold NUM_REGS registers, storing them in STARTS and ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use this memory for recording register information. STARTS and ENDS must be allocated using the malloc library routine, and must each be at least NUM_REGS * sizeof (regoff_t) bytes long. If NUM_REGS == 0, then subsequent matches should allocate their own register data. Unless this function is called, the first search or match using PATTERN_BUFFER will allocate its own register data, without freeing the old data. */ void re_set_registers (bufp, regs, num_regs, starts, ends) struct re_pattern_buffer *bufp; struct re_registers *regs; unsigned num_regs; regoff_t *starts, *ends; { if (num_regs) { bufp->regs_allocated = REGS_REALLOCATE; regs->num_regs = num_regs; regs->start = starts; regs->end = ends; } else { bufp->regs_allocated = REGS_UNALLOCATED; regs->num_regs = 0; regs->start = regs->end = (regoff_t) 0; } } /* Searching routines. */ /* Like re_search_2, below, but only one string is specified, and doesn't let you say where to stop matching. */ int re_search (bufp, string, size, startpos, range, regs) struct re_pattern_buffer *bufp; const char *string; int size, startpos, range; struct re_registers *regs; { return re_search_2 (bufp, NULL, 0, string, size, startpos, range, regs, size); } /* Using the compiled pattern in BUFP->buffer, first tries to match the virtual concatenation of STRING1 and STRING2, starting first at index STARTPOS, then at STARTPOS + 1, and so on. STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. RANGE is how far to scan while trying to match. RANGE = 0 means try only at STARTPOS; in general, the last start tried is STARTPOS + RANGE. In REGS, return the indices of the virtual concatenation of STRING1 and STRING2 that matched the entire BUFP->buffer and its contained subexpressions. Do not consider matching one past the index STOP in the virtual concatenation of STRING1 and STRING2. We return either the position in the strings at which the match was found, -1 if no match, or -2 if error (such as failure stack overflow). */ int re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) struct re_pattern_buffer *bufp; const char *string1, *string2; int size1, size2; int startpos; int range; struct re_registers *regs; int stop; { int val; register char *fastmap = bufp->fastmap; register char *translate = bufp->translate; int total_size = size1 + size2; int endpos = startpos + range; /* Check for out-of-range STARTPOS. */ if (startpos < 0 || startpos > total_size) return -1; /* Fix up RANGE if it might eventually take us outside the virtual concatenation of STRING1 and STRING2. */ if (endpos < -1) range = -1 - startpos; else if (endpos > total_size) range = total_size - startpos; /* If the search isn't to be a backwards one, don't waste time in a search for a pattern that must be anchored. */ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0) { if (startpos > 0) return -1; else range = 1; } /* Update the fastmap now if not correct already. */ if (fastmap && !bufp->fastmap_accurate) if (re_compile_fastmap (bufp) == -2) return -2; /* Loop through the string, looking for a place to start matching. */ for (;;) { /* If a fastmap is supplied, skip quickly over characters that cannot be the start of a match. If the pattern can match the null string, however, we don't need to skip characters; we want the first null string. */ if (fastmap && startpos < total_size && !bufp->can_be_null) { if (range > 0) /* Searching forwards. */ { register const char *d; register int lim = 0; int irange = range; if (startpos < size1 && startpos + range >= size1) lim = range - (size1 - startpos); d = (startpos >= size1 ? string2 - size1 : string1) + startpos; /* Written out as an if-else to avoid testing `translate' inside the loop. */ if (translate) while (range > lim && !fastmap[(unsigned char) translate[(unsigned char) *d++]]) range--; else while (range > lim && !fastmap[(unsigned char) *d++]) range--; startpos += irange - range; } else /* Searching backwards. */ { register char c = (size1 == 0 || startpos >= size1 ? string2[startpos - size1] : string1[startpos]); if (!fastmap[(unsigned char) TRANSLATE (c)]) goto advance; } } /* If can't match the null string, and that's all we have left, fail. */ if (range >= 0 && startpos == total_size && fastmap && !bufp->can_be_null) return -1; val = re_match_2 (bufp, string1, size1, string2, size2, startpos, regs, stop); if (val >= 0) return startpos; if (val == -2) return -2; advance: if (!range) break; else if (range > 0) { range--; startpos++; } else { range++; startpos--; } } return -1; } /* re_search_2 */ /* Declarations and macros for re_match_2. */ static int bcmp_translate (); static boolean alt_match_null_string_p (), common_op_match_null_string_p (), group_match_null_string_p (); /* Structure for per-register (a.k.a. per-group) information. This must not be longer than one word, because we push this value onto the failure stack. Other register information, such as the starting and ending positions (which are addresses), and the list of inner groups (which is a bits list) are maintained in separate variables. We are making a (strictly speaking) nonportable assumption here: that the compiler will pack our bit fields into something that fits into the type of `word', i.e., is something that fits into one item on the failure stack. */ typedef union { fail_stack_elt_t word; struct { /* This field is one if this group can match the empty string, zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ #define MATCH_NULL_UNSET_VALUE 3 unsigned match_null_string_p : 2; unsigned is_active : 1; unsigned matched_something : 1; unsigned ever_matched_something : 1; } bits; } register_info_type; #define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) #define IS_ACTIVE(R) ((R).bits.is_active) #define MATCHED_SOMETHING(R) ((R).bits.matched_something) #define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) /* Call this when have matched a real character; it sets `matched' flags for the subexpressions which we are currently inside. Also records that those subexprs have matched. */ #define SET_REGS_MATCHED() \ do \ { \ unsigned r; \ for (r = lowest_active_reg; r <= highest_active_reg; r++) \ { \ MATCHED_SOMETHING (reg_info[r]) \ = EVER_MATCHED_SOMETHING (reg_info[r]) \ = 1; \ } \ } \ while (0) /* This converts PTR, a pointer into one of the search strings `string1' and `string2' into an offset from the beginning of that string. */ #define POINTER_TO_OFFSET(ptr) \ (FIRST_STRING_P (ptr) ? (ptr) - string1 : (ptr) - string2 + size1) /* Registers are set to a sentinel when they haven't yet matched. */ #define REG_UNSET_VALUE ((char *) -1) #define REG_UNSET(e) ((e) == REG_UNSET_VALUE) /* Macros for dealing with the split strings in re_match_2. */ #define MATCHING_IN_FIRST_STRING (dend == end_match_1) /* Call before fetching a character with *d. This switches over to string2 if necessary. */ #define PREFETCH() \ while (d == dend) \ { \ /* End of string2 => fail. */ \ if (dend == end_match_2) \ goto fail; \ /* End of string1 => advance to string2. */ \ d = string2; \ dend = end_match_2; \ } /* Test if at very beginning or at very end of the virtual concatenation of `string1' and `string2'. If only one string, it's `string2'. */ #define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) #define AT_STRINGS_END(d) ((d) == end2) /* Test if D points to a character which is word-constituent. We have two special cases to check for: if past the end of string1, look at the first character in string2; and if before the beginning of string2, look at the last character in string1. */ #define WORDCHAR_P(d) \ (SYNTAX ((d) == end1 ? *string2 \ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ == Sword) /* Test if the character before D and the one at D differ with respect to being word-constituent. */ #define AT_WORD_BOUNDARY(d) \ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) /* Free everything we malloc. */ #ifdef REGEX_MALLOC #define FREE_VAR(var) if (var) free (var); var = NULL #define FREE_VARIABLES() \ do { \ FREE_VAR (fail_stack.stack); \ FREE_VAR (regstart); \ FREE_VAR (regend); \ FREE_VAR (old_regstart); \ FREE_VAR (old_regend); \ FREE_VAR (best_regstart); \ FREE_VAR (best_regend); \ FREE_VAR (reg_info); \ FREE_VAR (reg_dummy); \ FREE_VAR (reg_info_dummy); \ } while (0) #else /* not REGEX_MALLOC */ /* Some MIPS systems (at least) want this to free alloca'd storage. */ #define FREE_VARIABLES() alloca (0) #endif /* not REGEX_MALLOC */ /* These values must meet several constraints. They must not be valid register values; since we have a limit of 255 registers (because we use only one byte in the pattern for the register number), we can use numbers larger than 255. They must differ by 1, because of NUM_FAILURE_ITEMS above. And the value for the lowest register must be larger than the value for the highest register, so we do not try to actually save any registers when none are active. */ #define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) #define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) /* Matching routines. */ #ifndef emacs /* Emacs never uses this. */ /* re_match is like re_match_2 except it takes only a single string. */ int re_match (bufp, string, size, pos, regs) struct re_pattern_buffer *bufp; const char *string; int size, pos; struct re_registers *regs; { return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size); } #endif /* not emacs */ /* re_match_2 matches the compiled pattern in BUFP against the the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 and SIZE2, respectively). We start matching at POS, and stop matching at STOP. If REGS is non-null and the `no_sub' field of BUFP is nonzero, we store offsets for the substring each group matched in REGS. See the documentation for exactly how many groups we fill. We return -1 if no match, -2 if an internal error (such as the failure stack overflowing). Otherwise, we return the length of the matched substring. */ int re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) struct re_pattern_buffer *bufp; const char *string1, *string2; int size1, size2; int pos; struct re_registers *regs; int stop; { /* General temporaries. */ int mcnt; unsigned char *p1; /* Just past the end of the corresponding string. */ const char *end1, *end2; /* Pointers into string1 and string2, just past the last characters in each to consider matching. */ const char *end_match_1, *end_match_2; /* Where we are in the data, and the end of the current string. */ const char *d, *dend; /* Where we are in the pattern, and the end of the pattern. */ unsigned char *p = bufp->buffer; register unsigned char *pend = p + bufp->used; /* We use this to map every character in the string. */ char *translate = bufp->translate; /* Failure point stack. Each place that can handle a failure further down the line pushes a failure point on this stack. It consists of restart, regend, and reg_info for all registers corresponding to the subexpressions we're currently inside, plus the number of such registers, and, finally, two char *'s. The first char * is where to resume scanning the pattern; the second one is where to resume scanning the strings. If the latter is zero, the failure point is a ``dummy''; if a failure happens and the failure point is a dummy, it gets discarded and the next next one is tried. */ fail_stack_type fail_stack; #ifdef DEBUG static unsigned failure_id = 0; unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; #endif /* We fill all the registers internally, independent of what we return, for use in backreferences. The number here includes an element for register zero. */ unsigned num_regs = bufp->re_nsub + 1; /* The currently active registers. */ unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG; unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG; /* Information on the contents of registers. These are pointers into the input strings; they record just what was matched (on this attempt) by a subexpression part of the pattern, that is, the regnum-th regstart pointer points to where in the pattern we began matching and the regnum-th regend points to right after where we stopped matching the regnum-th subexpression. (The zeroth register keeps track of what the whole pattern matches.) */ const char **regstart, **regend; /* If a group that's operated upon by a repetition operator fails to match anything, then the register for its start will need to be restored because it will have been set to wherever in the string we are when we last see its open-group operator. Similarly for a register's end. */ const char **old_regstart, **old_regend; /* The is_active field of reg_info helps us keep track of which (possibly nested) subexpressions we are currently in. The matched_something field of reg_info[reg_num] helps us tell whether or not we have matched any of the pattern so far this time through the reg_num-th subexpression. These two fields get reset each time through any loop their register is in. */ register_info_type *reg_info; /* The following record the register info as found in the above variables when we find a match better than any we've seen before. This happens as we backtrack through the failure points, which in turn happens only if we have not yet matched the entire string. */ unsigned best_regs_set = false; const char **best_regstart, **best_regend; /* Logically, this is `best_regend[0]'. But we don't want to have to allocate space for that if we're not allocating space for anything else (see below). Also, we never need info about register 0 for any of the other register vectors, and it seems rather a kludge to treat `best_regend' differently than the rest. So we keep track of the end of the best match so far in a separate variable. We initialize this to NULL so that when we backtrack the first time and need to test it, it's not garbage. */ const char *match_end = NULL; /* Used when we pop values we don't care about. */ const char **reg_dummy; register_info_type *reg_info_dummy; #ifdef DEBUG /* Counts the total number of registers pushed. */ unsigned num_regs_pushed = 0; #endif DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); INIT_FAIL_STACK (); /* Do not bother to initialize all the register variables if there are no groups in the pattern, as it takes a fair amount of time. If there are groups, we include space for register 0 (the whole pattern), even though we never use it, since it simplifies the array indexing. We should fix this. */ if (bufp->re_nsub) { regstart = REGEX_TALLOC (num_regs, const char *); regend = REGEX_TALLOC (num_regs, const char *); old_regstart = REGEX_TALLOC (num_regs, const char *); old_regend = REGEX_TALLOC (num_regs, const char *); best_regstart = REGEX_TALLOC (num_regs, const char *); best_regend = REGEX_TALLOC (num_regs, const char *); reg_info = REGEX_TALLOC (num_regs, register_info_type); reg_dummy = REGEX_TALLOC (num_regs, const char *); reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); if (!(regstart && regend && old_regstart && old_regend && reg_info && best_regstart && best_regend && reg_dummy && reg_info_dummy)) { FREE_VARIABLES (); return -2; } } #ifdef REGEX_MALLOC else { /* We must initialize all our variables to NULL, so that `FREE_VARIABLES' doesn't try to free them. */ regstart = regend = old_regstart = old_regend = best_regstart = best_regend = reg_dummy = NULL; reg_info = reg_info_dummy = (register_info_type *) NULL; } #endif /* REGEX_MALLOC */ /* The starting position is bogus. */ if (pos < 0 || pos > size1 + size2) { FREE_VARIABLES (); return -1; } /* Initialize subexpression text positions to -1 to mark ones that no start_memory/stop_memory has been seen for. Also initialize the register information struct. */ for (mcnt = 1; mcnt < num_regs; mcnt++) { regstart[mcnt] = regend[mcnt] = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; IS_ACTIVE (reg_info[mcnt]) = 0; MATCHED_SOMETHING (reg_info[mcnt]) = 0; EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; } /* We move `string1' into `string2' if the latter's empty -- but not if `string1' is null. */ if (size2 == 0 && string1 != NULL) { string2 = string1; size2 = size1; string1 = 0; size1 = 0; } end1 = string1 + size1; end2 = string2 + size2; /* Compute where to stop matching, within the two strings. */ if (stop <= size1) { end_match_1 = string1 + stop; end_match_2 = string2; } else { end_match_1 = end1; end_match_2 = string2 + stop - size1; } /* `p' scans through the pattern as `d' scans through the data. `dend' is the end of the input string that `d' points within. `d' is advanced into the following input string whenever necessary, but this happens before fetching; therefore, at the beginning of the loop, `d' can be pointing at the end of a string, but it cannot equal `string2'. */ if (size1 > 0 && pos <= size1) { d = string1 + pos; dend = end_match_1; } else { d = string2 + pos - size1; dend = end_match_2; } DEBUG_PRINT1 ("The compiled pattern is: "); DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); DEBUG_PRINT1 ("The string to match is: `"); DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); DEBUG_PRINT1 ("'\n"); /* This loops over pattern commands. It exits by returning from the function if the match is complete, or it drops through if the match fails at this starting point in the input data. */ for (;;) { DEBUG_PRINT2 ("\n0x%x: ", p); if (p == pend) { /* End of pattern means we might have succeeded. */ DEBUG_PRINT1 ("end of pattern ... "); /* If we haven't matched the entire string, and we want the longest match, try backtracking. */ if (d != end_match_2) { DEBUG_PRINT1 ("backtracking.\n"); if (!FAIL_STACK_EMPTY ()) { /* More failure points to try. */ boolean same_str_p = (FIRST_STRING_P (match_end) == MATCHING_IN_FIRST_STRING); /* If exceeds best match so far, save it. */ if (!best_regs_set || (same_str_p && d > match_end) || (!same_str_p && !MATCHING_IN_FIRST_STRING)) { best_regs_set = true; match_end = d; DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); for (mcnt = 1; mcnt < num_regs; mcnt++) { best_regstart[mcnt] = regstart[mcnt]; best_regend[mcnt] = regend[mcnt]; } } goto fail; } /* If no failure points, don't restore garbage. */ else if (best_regs_set) { restore_best_regs: /* Restore best match. It may happen that `dend == end_match_1' while the restored d is in string2. For example, the pattern `x.*y.*z' against the strings `x-' and `y-z-', if the two strings are not consecutive in memory. */ DEBUG_PRINT1 ("Restoring best registers.\n"); d = match_end; dend = ((d >= string1 && d <= end1) ? end_match_1 : end_match_2); for (mcnt = 1; mcnt < num_regs; mcnt++) { regstart[mcnt] = best_regstart[mcnt]; regend[mcnt] = best_regend[mcnt]; } } } /* d != end_match_2 */ DEBUG_PRINT1 ("Accepting match.\n"); /* If caller wants register contents data back, do it. */ if (regs && !bufp->no_sub) { /* Have the register data arrays been allocated? */ if (bufp->regs_allocated == REGS_UNALLOCATED) { /* No. So allocate them with malloc. We need one extra element beyond `num_regs' for the `-1' marker GNU code uses. */ regs->num_regs = MAX (RE_NREGS, num_regs + 1); regs->start = TALLOC (regs->num_regs, regoff_t); regs->end = TALLOC (regs->num_regs, regoff_t); if (regs->start == NULL || regs->end == NULL) return -2; bufp->regs_allocated = REGS_REALLOCATE; } else if (bufp->regs_allocated == REGS_REALLOCATE) { /* Yes. If we need more elements than were already allocated, reallocate them. If we need fewer, just leave it alone. */ if (regs->num_regs < num_regs + 1) { regs->num_regs = num_regs + 1; RETALLOC (regs->start, regs->num_regs, regoff_t); RETALLOC (regs->end, regs->num_regs, regoff_t); if (regs->start == NULL || regs->end == NULL) return -2; } } else { /* These braces fend off a "empty body in an else-statement" warning under GCC when assert expands to nothing. */ assert (bufp->regs_allocated == REGS_FIXED); } /* Convert the pointer data in `regstart' and `regend' to indices. Register zero has to be set differently, since we haven't kept track of any info for it. */ if (regs->num_regs > 0) { regs->start[0] = pos; regs->end[0] = (MATCHING_IN_FIRST_STRING ? d - string1 : d - string2 + size1); } /* Go through the first `min (num_regs, regs->num_regs)' registers, since that is all we initialized. */ for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++) { if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) regs->start[mcnt] = regs->end[mcnt] = -1; else { regs->start[mcnt] = POINTER_TO_OFFSET (regstart[mcnt]); regs->end[mcnt] = POINTER_TO_OFFSET (regend[mcnt]); } } /* If the regs structure we return has more elements than were in the pattern, set the extra elements to -1. If we (re)allocated the registers, this is the case, because we always allocate enough to have at least one -1 at the end. */ for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++) regs->start[mcnt] = regs->end[mcnt] = -1; } /* regs && !bufp->no_sub */ FREE_VARIABLES (); DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", nfailure_points_pushed, nfailure_points_popped, nfailure_points_pushed - nfailure_points_popped); DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); mcnt = d - pos - (MATCHING_IN_FIRST_STRING ? string1 : string2 - size1); DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); return mcnt; } /* Otherwise match next pattern command. */ #ifdef SWITCH_ENUM_BUG switch ((int) ((re_opcode_t) *p++)) #else switch ((re_opcode_t) *p++) #endif { /* Ignore these. Used to ignore the n of succeed_n's which currently have n == 0. */ case no_op: DEBUG_PRINT1 ("EXECUTING no_op.\n"); break; /* Match the next n pattern characters exactly. The following byte in the pattern defines n, and the n bytes after that are the characters to match. */ case exactn: mcnt = *p++; DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); /* This is written out as an if-else so we don't waste time testing `translate' inside the loop. */ if (translate) { do { PREFETCH (); if (translate[(unsigned char) *d++] != (char) *p++) goto fail; } while (--mcnt); } else { do { PREFETCH (); if (*d++ != (char) *p++) goto fail; } while (--mcnt); } SET_REGS_MATCHED (); break; /* Match any character except possibly a newline or a null. */ case anychar: DEBUG_PRINT1 ("EXECUTING anychar.\n"); PREFETCH (); if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) goto fail; SET_REGS_MATCHED (); DEBUG_PRINT2 (" Matched `%d'.\n", *d); d++; break; case charset: case charset_not: { register unsigned char c; boolean not = (re_opcode_t) *(p - 1) == charset_not; DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); PREFETCH (); c = TRANSLATE (*d); /* The character to match. */ /* Cast to `unsigned' instead of `unsigned char' in case the bit list is a full 32 bytes long. */ if (c < (unsigned) (*p * BYTEWIDTH) && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) not = !not; p += 1 + *p; if (!not) goto fail; SET_REGS_MATCHED (); d++; break; } /* The beginning of a group is represented by start_memory. The arguments are the register number in the next byte, and the number of groups inner to this one in the next. The text matched within the group is recorded (in the internal registers data structure) under the register number. */ case start_memory: DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); /* Find out if this group can match the empty string. */ p1 = p; /* To send to group_match_null_string_p. */ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) REG_MATCH_NULL_STRING_P (reg_info[*p]) = group_match_null_string_p (&p1, pend, reg_info); /* Save the position in the string where we were the last time we were at this open-group operator in case the group is operated upon by a repetition operator, e.g., with `(a*)*b' against `ab'; then we want to ignore where we are now in the string in case this attempt to match fails. */ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) ? REG_UNSET (regstart[*p]) ? d : regstart[*p] : regstart[*p]; DEBUG_PRINT2 (" old_regstart: %d\n", POINTER_TO_OFFSET (old_regstart[*p])); regstart[*p] = d; DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); IS_ACTIVE (reg_info[*p]) = 1; MATCHED_SOMETHING (reg_info[*p]) = 0; /* This is the new highest active register. */ highest_active_reg = *p; /* If nothing was active before, this is the new lowest active register. */ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) lowest_active_reg = *p; /* Move past the register number and inner group count. */ p += 2; break; /* The stop_memory opcode represents the end of a group. Its arguments are the same as start_memory's: the register number, and the number of inner groups. */ case stop_memory: DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]); /* We need to save the string position the last time we were at this close-group operator in case the group is operated upon by a repetition operator, e.g., with `((a*)*(b*)*)*' against `aba'; then we want to ignore where we are now in the string in case this attempt to match fails. */ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) ? REG_UNSET (regend[*p]) ? d : regend[*p] : regend[*p]; DEBUG_PRINT2 (" old_regend: %d\n", POINTER_TO_OFFSET (old_regend[*p])); regend[*p] = d; DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); /* This register isn't active anymore. */ IS_ACTIVE (reg_info[*p]) = 0; /* If this was the only register active, nothing is active anymore. */ if (lowest_active_reg == highest_active_reg) { lowest_active_reg = NO_LOWEST_ACTIVE_REG; highest_active_reg = NO_HIGHEST_ACTIVE_REG; } else { /* We must scan for the new highest active register, since it isn't necessarily one less than now: consider (a(b)c(d(e)f)g). When group 3 ends, after the f), the new highest active register is 1. */ unsigned char r = *p - 1; while (r > 0 && !IS_ACTIVE (reg_info[r])) r--; /* If we end up at register zero, that means that we saved the registers as the result of an `on_failure_jump', not a `start_memory', and we jumped to past the innermost `stop_memory'. For example, in ((.)*) we save registers 1 and 2 as a result of the *, but when we pop back to the second ), we are at the stop_memory 1. Thus, nothing is active. */ if (r == 0) { lowest_active_reg = NO_LOWEST_ACTIVE_REG; highest_active_reg = NO_HIGHEST_ACTIVE_REG; } else highest_active_reg = r; } /* If just failed to match something this time around with a group that's operated on by a repetition operator, try to force exit from the ``loop'', and restore the register information for this group that we had before trying this last match. */ if ((!MATCHED_SOMETHING (reg_info[*p]) || (re_opcode_t) p[-3] == start_memory) && (p + 2) < pend) { boolean is_a_jump_n = false; p1 = p + 2; mcnt = 0; switch ((re_opcode_t) *p1++) { case jump_n: is_a_jump_n = true; case pop_failure_jump: case maybe_pop_jump: case jump: case dummy_failure_jump: EXTRACT_NUMBER_AND_INCR (mcnt, p1); if (is_a_jump_n) p1 += 2; break; default: /* do nothing */ ; } p1 += mcnt; /* If the next operation is a jump backwards in the pattern to an on_failure_jump right before the start_memory corresponding to this stop_memory, exit from the loop by forcing a failure after pushing on the stack the on_failure_jump's jump in the pattern, and d. */ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump && (re_opcode_t) p1[3] == start_memory && p1[4] == *p) { /* If this group ever matched anything, then restore what its registers were before trying this last failed match, e.g., with `(a*)*b' against `ab' for regstart[1], and, e.g., with `((a*)*(b*)*)*' against `aba' for regend[3]. Also restore the registers for inner groups for, e.g., `((a*)(b*))*' against `aba' (register 3 would otherwise get trashed). */ if (EVER_MATCHED_SOMETHING (reg_info[*p])) { unsigned r; EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; /* Restore this and inner groups' (if any) registers. */ for (r = *p; r < *p + *(p + 1); r++) { regstart[r] = old_regstart[r]; /* xx why this test? */ if ((int) old_regend[r] >= (int) regstart[r]) regend[r] = old_regend[r]; } } p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); PUSH_FAILURE_POINT (p1 + mcnt, d, -2); goto fail; } } /* Move past the register number and the inner group count. */ p += 2; break; /* \ has been turned into a `duplicate' command which is followed by the numeric value of as the register number. */ case duplicate: { register const char *d2, *dend2; int regno = *p++; /* Get which register to match against. */ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); /* Can't back reference a group which we've never matched. */ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) goto fail; /* Where in input to try to start matching. */ d2 = regstart[regno]; /* Where to stop matching; if both the place to start and the place to stop matching are in the same string, then set to the place to stop, otherwise, for now have to use the end of the first string. */ dend2 = ((FIRST_STRING_P (regstart[regno]) == FIRST_STRING_P (regend[regno])) ? regend[regno] : end_match_1); for (;;) { /* If necessary, advance to next segment in register contents. */ while (d2 == dend2) { if (dend2 == end_match_2) break; if (dend2 == regend[regno]) break; /* End of string1 => advance to string2. */ d2 = string2; dend2 = regend[regno]; } /* At end of register contents => success */ if (d2 == dend2) break; /* If necessary, advance to next segment in data. */ PREFETCH (); /* How many characters left in this segment to match. */ mcnt = dend - d; /* Want how many consecutive characters we can match in one shot, so, if necessary, adjust the count. */ if (mcnt > dend2 - d2) mcnt = dend2 - d2; /* Compare that many; failure if mismatch, else move past them. */ if (translate ? bcmp_translate (d, d2, mcnt, translate) : bcmp (d, d2, mcnt)) goto fail; d += mcnt, d2 += mcnt; } } break; /* begline matches the empty string at the beginning of the string (unless `not_bol' is set in `bufp'), and, if `newline_anchor' is set, after newlines. */ case begline: DEBUG_PRINT1 ("EXECUTING begline.\n"); if (AT_STRINGS_BEG (d)) { if (!bufp->not_bol) break; } else if (d[-1] == '\n' && bufp->newline_anchor) { break; } /* In all other cases, we fail. */ goto fail; /* endline is the dual of begline. */ case endline: DEBUG_PRINT1 ("EXECUTING endline.\n"); if (AT_STRINGS_END (d)) { if (!bufp->not_eol) break; } /* We have to ``prefetch'' the next character. */ else if ((d == end1 ? *string2 : *d) == '\n' && bufp->newline_anchor) { break; } goto fail; /* Match at the very beginning of the data. */ case begbuf: DEBUG_PRINT1 ("EXECUTING begbuf.\n"); if (AT_STRINGS_BEG (d)) break; goto fail; /* Match at the very end of the data. */ case endbuf: DEBUG_PRINT1 ("EXECUTING endbuf.\n"); if (AT_STRINGS_END (d)) break; goto fail; /* on_failure_keep_string_jump is used to optimize `.*\n'. It pushes NULL as the value for the string on the stack. Then `pop_failure_point' will keep the current value for the string, instead of restoring it. To see why, consider matching `foo\nbar' against `.*\n'. The .* matches the foo; then the . fails against the \n. But the next thing we want to do is match the \n against the \n; if we restored the string value, we would be back at the foo. Because this is used only in specific cases, we don't need to check all the things that `on_failure_jump' does, to make sure the right things get saved on the stack. Hence we don't share its code. The only reason to push anything on the stack at all is that otherwise we would have to change `anychar's code to do something besides goto fail in this case; that seems worse than this. */ case on_failure_keep_string_jump: DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt); PUSH_FAILURE_POINT (p + mcnt, NULL, -2); break; /* Uses of on_failure_jump: Each alternative starts with an on_failure_jump that points to the beginning of the next alternative. Each alternative except the last ends with a jump that in effect jumps past the rest of the alternatives. (They really jump to the ending jump of the following alternative, because tensioning these jumps is a hassle.) Repeats start with an on_failure_jump that points past both the repetition text and either the following jump or pop_failure_jump back to this on_failure_jump. */ case on_failure_jump: on_failure: DEBUG_PRINT1 ("EXECUTING on_failure_jump"); EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); /* If this on_failure_jump comes right before a group (i.e., the original * applied to a group), save the information for that group and all inner ones, so that if we fail back to this point, the group's information will be correct. For example, in \(a*\)*\1, we need the preceding group, and in \(\(a*\)b*\)\2, we need the inner group. */ /* We can't use `p' to check ahead because we push a failure point to `p + mcnt' after we do this. */ p1 = p; /* We need to skip no_op's before we look for the start_memory in case this on_failure_jump is happening as the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 against aba. */ while (p1 < pend && (re_opcode_t) *p1 == no_op) p1++; if (p1 < pend && (re_opcode_t) *p1 == start_memory) { /* We have a new highest active register now. This will get reset at the start_memory we are about to get to, but we will have saved all the registers relevant to this repetition op, as described above. */ highest_active_reg = *(p1 + 1) + *(p1 + 2); if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) lowest_active_reg = *(p1 + 1); } DEBUG_PRINT1 (":\n"); PUSH_FAILURE_POINT (p + mcnt, d, -2); break; /* A smart repeat ends with `maybe_pop_jump'. We change it to either `pop_failure_jump' or `jump'. */ case maybe_pop_jump: EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); { register unsigned char *p2 = p; /* Compare the beginning of the repeat with what in the pattern follows its end. If we can establish that there is nothing that they would both match, i.e., that we would have to backtrack because of (as in, e.g., `a*a') then we can change to pop_failure_jump, because we'll never have to backtrack. This is not true in the case of alternatives: in `(a|ab)*' we do need to backtrack to the `ab' alternative (e.g., if the string was `ab'). But instead of trying to detect that here, the alternative has put on a dummy failure point which is what we will end up popping. */ /* Skip over open/close-group commands. */ while (p2 + 2 < pend && ((re_opcode_t) *p2 == stop_memory || (re_opcode_t) *p2 == start_memory)) p2 += 3; /* Skip over args, too. */ /* If we're at the end of the pattern, we can change. */ if (p2 == pend) { /* Consider what happens when matching ":\(.*\)" against ":/". I don't really understand this code yet. */ p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" End of pattern: change to `pop_failure_jump'.\n"); } else if ((re_opcode_t) *p2 == exactn || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) { register unsigned char c = *p2 == (unsigned char) endline ? '\n' : p2[2]; p1 = p + mcnt; /* p1[0] ... p1[2] are the `on_failure_jump' corresponding to the `maybe_finalize_jump' of this case. Examine what follows. */ if ((re_opcode_t) p1[3] == exactn && p1[5] != c) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", c, p1[5]); } else if ((re_opcode_t) p1[3] == charset || (re_opcode_t) p1[3] == charset_not) { int not = (re_opcode_t) p1[3] == charset_not; if (c < (unsigned char) (p1[4] * BYTEWIDTH) && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) not = !not; /* `not' is equal to 1 if c would match, which means that we can't change to pop_failure_jump. */ if (!not) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); } } } } p -= 2; /* Point at relative address again. */ if ((re_opcode_t) p[-1] != pop_failure_jump) { p[-1] = (unsigned char) jump; DEBUG_PRINT1 (" Match => jump.\n"); goto unconditional_jump; } /* Note fall through. */ /* The end of a simple repeat has a pop_failure_jump back to its matching on_failure_jump, where the latter will push a failure point. The pop_failure_jump takes off failure points put on by this pop_failure_jump's matching on_failure_jump; we got through the pattern to here from the matching on_failure_jump, so didn't fail. */ case pop_failure_jump: { /* We need to pass separate storage for the lowest and highest registers, even though we don't care about the actual values. Otherwise, we will restore only one register from the stack, since lowest will == highest in `pop_failure_point'. */ unsigned dummy_low_reg, dummy_high_reg; unsigned char *pdummy; const char *sdummy; DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); POP_FAILURE_POINT (sdummy, pdummy, dummy_low_reg, dummy_high_reg, reg_dummy, reg_dummy, reg_info_dummy); } /* Note fall through. */ /* Unconditionally jump (without popping any failure points). */ case jump: unconditional_jump: EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); p += mcnt; /* Do the jump. */ DEBUG_PRINT2 ("(to 0x%x).\n", p); break; /* We need this opcode so we can detect where alternatives end in `group_match_null_string_p' et al. */ case jump_past_alt: DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); goto unconditional_jump; /* Normally, the on_failure_jump pushes a failure point, which then gets popped at pop_failure_jump. We will end up at pop_failure_jump, also, and with a pattern of, say, `a+', we are skipping over the on_failure_jump, so we have to push something meaningless for pop_failure_jump to pop. */ case dummy_failure_jump: DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); /* It doesn't matter what we push for the string here. What the code at `fail' tests is the value for the pattern. */ PUSH_FAILURE_POINT (0, 0, -2); goto unconditional_jump; /* At the end of an alternative, we need to push a dummy failure point in case we are followed by a `pop_failure_jump', because we don't want the failure point for the alternative to be popped. For example, matching `(a|ab)*' against `aab' requires that we match the `ab' alternative. */ case push_dummy_failure: DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); /* See comments just above at `dummy_failure_jump' about the two zeroes. */ PUSH_FAILURE_POINT (0, 0, -2); break; /* Have to succeed matching what follows at least n times. After that, handle like `on_failure_jump'. */ case succeed_n: EXTRACT_NUMBER (mcnt, p + 2); DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); assert (mcnt >= 0); /* Originally, this is how many times we HAVE to succeed. */ if (mcnt > 0) { mcnt--; p += 2; STORE_NUMBER_AND_INCR (p, mcnt); DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt); } else if (mcnt == 0) { DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2); p[2] = (unsigned char) no_op; p[3] = (unsigned char) no_op; goto on_failure; } break; case jump_n: EXTRACT_NUMBER (mcnt, p + 2); DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); /* Originally, this is how many times we CAN jump. */ if (mcnt) { mcnt--; STORE_NUMBER (p + 2, mcnt); goto unconditional_jump; } /* If don't have to jump any more, skip over the rest of command. */ else p += 4; break; case set_number_at: { DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); EXTRACT_NUMBER_AND_INCR (mcnt, p); p1 = p + mcnt; EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt); STORE_NUMBER (p1, mcnt); break; } case wordbound: DEBUG_PRINT1 ("EXECUTING wordbound.\n"); if (AT_WORD_BOUNDARY (d)) break; goto fail; case notwordbound: DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); if (AT_WORD_BOUNDARY (d)) goto fail; break; case wordbeg: DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1))) break; goto fail; case wordend: DEBUG_PRINT1 ("EXECUTING wordend.\n"); if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1) && (!WORDCHAR_P (d) || AT_STRINGS_END (d))) break; goto fail; #ifdef emacs #ifdef emacs19 case before_dot: DEBUG_PRINT1 ("EXECUTING before_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) >= point) goto fail; break; case at_dot: DEBUG_PRINT1 ("EXECUTING at_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) != point) goto fail; break; case after_dot: DEBUG_PRINT1 ("EXECUTING after_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) <= point) goto fail; break; #else /* not emacs19 */ case at_dot: DEBUG_PRINT1 ("EXECUTING at_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point) goto fail; break; #endif /* not emacs19 */ case syntaxspec: DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); mcnt = *p++; goto matchsyntax; case wordchar: DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); mcnt = (int) Sword; matchsyntax: PREFETCH (); if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail; SET_REGS_MATCHED (); break; case notsyntaxspec: DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); mcnt = *p++; goto matchnotsyntax; case notwordchar: DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); mcnt = (int) Sword; matchnotsyntax: PREFETCH (); if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail; SET_REGS_MATCHED (); break; #else /* not emacs */ case wordchar: DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); PREFETCH (); if (!WORDCHAR_P (d)) goto fail; SET_REGS_MATCHED (); d++; break; case notwordchar: DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); PREFETCH (); if (WORDCHAR_P (d)) goto fail; SET_REGS_MATCHED (); d++; break; #endif /* not emacs */ default: abort (); } continue; /* Successfully executed one pattern command; keep going. */ /* We goto here if a matching operation fails. */ fail: if (!FAIL_STACK_EMPTY ()) { /* A restart point is known. Restore to that state. */ DEBUG_PRINT1 ("\nFAIL:\n"); POP_FAILURE_POINT (d, p, lowest_active_reg, highest_active_reg, regstart, regend, reg_info); /* If this failure point is a dummy, try the next one. */ if (!p) goto fail; /* If we failed to the end of the pattern, don't examine *p. */ assert (p <= pend); if (p < pend) { boolean is_a_jump_n = false; /* If failed to a backwards jump that's part of a repetition loop, need to pop this failure point and use the next one. */ switch ((re_opcode_t) *p) { case jump_n: is_a_jump_n = true; case maybe_pop_jump: case pop_failure_jump: case jump: p1 = p + 1; EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) || (!is_a_jump_n && (re_opcode_t) *p1 == on_failure_jump)) goto fail; break; default: /* do nothing */ ; } } if (d >= string1 && d <= end1) dend = end_match_1; } else break; /* Matching at this starting point really fails. */ } /* for (;;) */ if (best_regs_set) goto restore_best_regs; FREE_VARIABLES (); return -1; /* Failure to match. */ } /* re_match_2 */ /* Subroutine definitions for re_match_2. */ /* We are passed P pointing to a register number after a start_memory. Return true if the pattern up to the corresponding stop_memory can match the empty string, and false otherwise. If we find the matching stop_memory, sets P to point to one past its number. Otherwise, sets P to an undefined byte less than or equal to END. We don't handle duplicates properly (yet). */ static boolean group_match_null_string_p (p, end, reg_info) unsigned char **p, *end; register_info_type *reg_info; { int mcnt; /* Point to after the args to the start_memory. */ unsigned char *p1 = *p + 2; while (p1 < end) { /* Skip over opcodes that can match nothing, and return true or false, as appropriate, when we get to one that can't, or to the matching stop_memory. */ switch ((re_opcode_t) *p1) { /* Could be either a loop or a series of alternatives. */ case on_failure_jump: p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); /* If the next operation is not a jump backwards in the pattern. */ if (mcnt >= 0) { /* Go through the on_failure_jumps of the alternatives, seeing if any of the alternatives cannot match nothing. The last alternative starts with only a jump, whereas the rest start with on_failure_jump and end with a jump, e.g., here is the pattern for `a|b|c': /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 /exactn/1/c So, we have to first go through the first (n-1) alternatives and then deal with the last one separately. */ /* Deal with the first (n-1) alternatives, which start with an on_failure_jump (see above) that jumps to right past a jump_past_alt. */ while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) { /* `mcnt' holds how many bytes long the alternative is, including the ending `jump_past_alt' and its number. */ if (!alt_match_null_string_p (p1, p1 + mcnt - 3, reg_info)) return false; /* Move to right after this alternative, including the jump_past_alt. */ p1 += mcnt; /* Break if it's the beginning of an n-th alternative that doesn't begin with an on_failure_jump. */ if ((re_opcode_t) *p1 != on_failure_jump) break; /* Still have to check that it's not an n-th alternative that starts with an on_failure_jump. */ p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) { /* Get to the beginning of the n-th alternative. */ p1 -= 3; break; } } /* Deal with the last alternative: go back and get number of the `jump_past_alt' just before it. `mcnt' contains the length of the alternative. */ EXTRACT_NUMBER (mcnt, p1 - 2); if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) return false; p1 += mcnt; /* Get past the n-th alternative. */ } /* if mcnt > 0 */ break; case stop_memory: assert (p1[1] == **p); *p = p1 + 2; return true; default: if (!common_op_match_null_string_p (&p1, end, reg_info)) return false; } } /* while p1 < end */ return false; } /* group_match_null_string_p */ /* Similar to group_match_null_string_p, but doesn't deal with alternatives: It expects P to be the first byte of a single alternative and END one byte past the last. The alternative can contain groups. */ static boolean alt_match_null_string_p (p, end, reg_info) unsigned char *p, *end; register_info_type *reg_info; { int mcnt; unsigned char *p1 = p; while (p1 < end) { /* Skip over opcodes that can match nothing, and break when we get to one that can't. */ switch ((re_opcode_t) *p1) { /* It's a loop. */ case on_failure_jump: p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; break; default: if (!common_op_match_null_string_p (&p1, end, reg_info)) return false; } } /* while p1 < end */ return true; } /* alt_match_null_string_p */ /* Deals with the ops common to group_match_null_string_p and alt_match_null_string_p. Sets P to one after the op and its arguments, if any. */ static boolean common_op_match_null_string_p (p, end, reg_info) unsigned char **p, *end; register_info_type *reg_info; { int mcnt; boolean ret; int reg_no; unsigned char *p1 = *p; switch ((re_opcode_t) *p1++) { case no_op: case begline: case endline: case begbuf: case endbuf: case wordbeg: case wordend: case wordbound: case notwordbound: #ifdef emacs case before_dot: case at_dot: case after_dot: #endif break; case start_memory: reg_no = *p1; assert (reg_no > 0 && reg_no <= MAX_REGNUM); ret = group_match_null_string_p (&p1, end, reg_info); /* Have to set this here in case we're checking a group which contains a group and a back reference to it. */ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; if (!ret) return false; break; /* If this is an optimized succeed_n for zero times, make the jump. */ case jump: EXTRACT_NUMBER_AND_INCR (mcnt, p1); if (mcnt >= 0) p1 += mcnt; else return false; break; case succeed_n: /* Get to the number of times to succeed. */ p1 += 2; EXTRACT_NUMBER_AND_INCR (mcnt, p1); if (mcnt == 0) { p1 -= 4; EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; } else return false; break; case duplicate: if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) return false; break; case set_number_at: p1 += 4; default: /* All other opcodes mean we cannot match the empty string. */ return false; } *p = p1; return true; } /* common_op_match_null_string_p */ /* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN bytes; nonzero otherwise. */ static int bcmp_translate (s1, s2, len, translate) unsigned char *s1, *s2; register int len; char *translate; { register unsigned char *p1 = s1, *p2 = s2; while (len) { if (translate[*p1++] != translate[*p2++]) return 1; len--; } return 0; } /* Entry points for GNU code. */ /* re_compile_pattern is the GNU regular expression compiler: it compiles PATTERN (of length SIZE) and puts the result in BUFP. Returns 0 if the pattern was valid, otherwise an error string. Assumes the `allocated' (and perhaps `buffer') and `translate' fields are set in BUFP on entry. We call regex_compile to do the actual compilation. */ const char * re_compile_pattern (pattern, length, bufp) const char *pattern; int length; struct re_pattern_buffer *bufp; { reg_errcode_t ret; /* GNU code is written to assume at least RE_NREGS registers will be set (and at least one extra will be -1). */ bufp->regs_allocated = REGS_UNALLOCATED; /* And GNU code determines whether or not to get register information by passing null for the REGS argument to re_match, etc., not by setting no_sub. */ bufp->no_sub = 0; /* Match anchors at newline. */ bufp->newline_anchor = 1; ret = regex_compile (pattern, length, re_syntax_options, bufp); return re_error_msg[(int) ret]; } /* Entry points compatible with 4.2 BSD regex library. We don't define them if this is an Emacs or POSIX compilation. */ #if !defined (emacs) && !defined (_POSIX_SOURCE) /* BSD has one and only one pattern buffer. */ static struct re_pattern_buffer re_comp_buf; char * re_comp (s) const char *s; { reg_errcode_t ret; if (!s) { if (!re_comp_buf.buffer) return "No previous regular expression"; return 0; } if (!re_comp_buf.buffer) { re_comp_buf.buffer = (unsigned char *) malloc (200); if (re_comp_buf.buffer == NULL) return "Memory exhausted"; re_comp_buf.allocated = 200; re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); if (re_comp_buf.fastmap == NULL) return "Memory exhausted"; } /* Since `re_exec' always passes NULL for the `regs' argument, we don't need to initialize the pattern buffer fields which affect it. */ /* Match anchors at newlines. */ re_comp_buf.newline_anchor = 1; ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); /* Yes, we're discarding `const' here. */ return (char *) re_error_msg[(int) ret]; } int re_exec (s) const char *s; { const int len = strlen (s); return 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); } #endif /* not emacs and not _POSIX_SOURCE */ /* POSIX.2 functions. Don't define these for Emacs. */ #ifndef emacs /* regcomp takes a regular expression as a string and compiles it. PREG is a regex_t *. We do not expect any fields to be initialized, since POSIX says we shouldn't. Thus, we set `buffer' to the compiled pattern; `used' to the length of the compiled pattern; `syntax' to RE_SYNTAX_POSIX_EXTENDED if the REG_EXTENDED bit in CFLAGS is set; otherwise, to RE_SYNTAX_POSIX_BASIC; `newline_anchor' to REG_NEWLINE being set in CFLAGS; `fastmap' and `fastmap_accurate' to zero; `re_nsub' to the number of subexpressions in PATTERN. PATTERN is the address of the pattern string. CFLAGS is a series of bits which affect compilation. If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we use POSIX basic syntax. If REG_NEWLINE is set, then . and [^...] don't match newline. Also, regexec will try a match beginning after every newline. If REG_ICASE is set, then we considers upper- and lowercase versions of letters to be equivalent when matching. If REG_NOSUB is set, then when PREG is passed to regexec, that routine will report only success or failure, and nothing about the registers. It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for the return codes and their meanings.) */ int regcomp (preg, pattern, cflags) regex_t *preg; const char *pattern; int cflags; { reg_errcode_t ret; unsigned syntax = (cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; /* regex_compile will allocate the space for the compiled pattern. */ preg->buffer = 0; preg->allocated = 0; preg->used = 0; /* Don't bother to use a fastmap when searching. This simplifies the REG_NEWLINE case: if we used a fastmap, we'd have to put all the characters after newlines into the fastmap. This way, we just try every character. */ preg->fastmap = 0; if (cflags & REG_ICASE) { unsigned i; preg->translate = (char *) malloc (CHAR_SET_SIZE); if (preg->translate == NULL) return (int) REG_ESPACE; /* Map uppercase characters to corresponding lowercase ones. */ for (i = 0; i < CHAR_SET_SIZE; i++) preg->translate[i] = ISUPPER (i) ? tolower (i) : i; } else preg->translate = NULL; /* If REG_NEWLINE is set, newlines are treated differently. */ if (cflags & REG_NEWLINE) { /* REG_NEWLINE implies neither . nor [^...] match newline. */ syntax &= ~RE_DOT_NEWLINE; syntax |= RE_HAT_LISTS_NOT_NEWLINE; /* It also changes the matching behavior. */ preg->newline_anchor = 1; } else preg->newline_anchor = 0; preg->no_sub = !!(cflags & REG_NOSUB); /* POSIX says a null character in the pattern terminates it, so we can use strlen here in compiling the pattern. */ ret = regex_compile (pattern, strlen (pattern), syntax, preg); /* POSIX doesn't distinguish between an unmatched open-group and an unmatched close-group: both are REG_EPAREN. */ if (ret == REG_ERPAREN) ret = REG_EPAREN; return (int) ret; } /* regexec searches for a given pattern, specified by PREG, in the string STRING. If NMATCH is zero or REG_NOSUB was set in the cflags argument to `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at least NMATCH elements, and we set them to the offsets of the corresponding matched substrings. EFLAGS specifies `execution flags' which affect matching: if REG_NOTBOL is set, then ^ does not match at the beginning of the string; if REG_NOTEOL is set, then $ does not match at the end. We return 0 if we find a match and REG_NOMATCH if not. */ int regexec (preg, string, nmatch, pmatch, eflags) const regex_t *preg; const char *string; size_t nmatch; regmatch_t pmatch[]; int eflags; { int ret; struct re_registers regs; regex_t private_preg; int len = strlen (string); boolean want_reg_info = !preg->no_sub && nmatch > 0; private_preg = *preg; private_preg.not_bol = !!(eflags & REG_NOTBOL); private_preg.not_eol = !!(eflags & REG_NOTEOL); /* The user has told us exactly how many registers to return information about, via `nmatch'. We have to pass that on to the matching routines. */ private_preg.regs_allocated = REGS_FIXED; if (want_reg_info) { regs.num_regs = nmatch; regs.start = TALLOC (nmatch, regoff_t); regs.end = TALLOC (nmatch, regoff_t); if (regs.start == NULL || regs.end == NULL) return (int) REG_NOMATCH; } /* Perform the searching operation. */ ret = re_search (&private_preg, string, len, /* start: */ 0, /* range: */ len, want_reg_info ? ®s : (struct re_registers *) 0); /* Copy the register information to the POSIX structure. */ if (want_reg_info) { if (ret >= 0) { unsigned r; for (r = 0; r < nmatch; r++) { pmatch[r].rm_so = regs.start[r]; pmatch[r].rm_eo = regs.end[r]; } } /* If we needed the temporary register info, free the space now. */ free (regs.start); free (regs.end); } /* We want zero return to mean success, unlike `re_search'. */ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; } /* Returns a message corresponding to an error code, ERRCODE, returned from either regcomp or regexec. We don't use PREG here. */ size_t regerror (errcode, preg, errbuf, errbuf_size) int errcode; const regex_t *preg; char *errbuf; size_t errbuf_size; { const char *msg; size_t msg_size; if (errcode < 0 || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0]))) /* Only error codes returned by the rest of the code should be passed to this routine. If we are given anything else, or if other regex code generates an invalid error code, then the program has a bug. Dump core so we can fix it. */ abort (); msg = re_error_msg[errcode]; /* POSIX doesn't require that we do anything in this case, but why not be nice. */ if (! msg) msg = "Success"; msg_size = strlen (msg) + 1; /* Includes the null. */ if (errbuf_size != 0) { if (msg_size > errbuf_size) { strncpy (errbuf, msg, errbuf_size - 1); errbuf[errbuf_size - 1] = 0; } else strcpy (errbuf, msg); } return msg_size; } /* Free dynamically allocated space used by PREG. */ void regfree (preg) regex_t *preg; { if (preg->buffer != NULL) free (preg->buffer); preg->buffer = NULL; preg->allocated = 0; preg->used = 0; if (preg->fastmap != NULL) free (preg->fastmap); preg->fastmap = NULL; preg->fastmap_accurate = 0; if (preg->translate != NULL) free (preg->translate); preg->translate = NULL; } #endif /* not emacs */ /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ shapetools-1.4pl6.orig/vgrep-2.0/regex.h100644 2013 145 44416 5377062217 16107 0ustar dokoswt/* Definitions for data structures and routines for the regular expression library, version 0.12. Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __REGEXP_LIBRARY_H__ #define __REGEXP_LIBRARY_H__ /* POSIX says that must be included (by the caller) before . */ #ifdef VMS /* VMS doesn't have `size_t' in , even though POSIX says it should be there. */ #include #endif /* The following bits are used to determine the regexp syntax we recognize. The set/not-set meanings are chosen so that Emacs syntax remains the value 0. The bits are given in alphabetical order, and the definitions shifted by one from the previous bit; thus, when we add or remove a bit, only one other definition need change. */ typedef unsigned reg_syntax_t; /* If this bit is not set, then \ inside a bracket expression is literal. If set, then such a \ quotes the following character. */ #define RE_BACKSLASH_ESCAPE_IN_LISTS (1) /* If this bit is not set, then + and ? are operators, and \+ and \? are literals. If set, then \+ and \? are operators and + and ? are literals. */ #define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) /* If this bit is set, then character classes are supported. They are: [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. If not set, then character classes are not supported. */ #define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) /* If this bit is set, then ^ and $ are always anchors (outside bracket expressions, of course). If this bit is not set, then it depends: ^ is an anchor if it is at the beginning of a regular expression or after an open-group or an alternation operator; $ is an anchor if it is at the end of a regular expression, or before a close-group or an alternation operator. This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because POSIX draft 11.2 says that * etc. in leading positions is undefined. We already implemented a previous draft which made those constructs invalid, though, so we haven't changed the code back. */ #define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) /* If this bit is set, then special characters are always special regardless of where they are in the pattern. If this bit is not set, then special characters are special only in some contexts; otherwise they are ordinary. Specifically, * + ? and intervals are only special when not after the beginning, open-group, or alternation operator. */ #define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) /* If this bit is set, then *, +, ?, and { cannot be first in an re or immediately after an alternation or begin-group operator. */ #define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) /* If this bit is set, then . matches newline. If not set, then it doesn't. */ #define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) /* If this bit is set, then . doesn't match NUL. If not set, then it does. */ #define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) /* If this bit is set, nonmatching lists [^...] do not match newline. If not set, they do. */ #define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) /* If this bit is set, either \{...\} or {...} defines an interval, depending on RE_NO_BK_BRACES. If not set, \{, \}, {, and } are literals. */ #define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) /* If this bit is set, +, ? and | aren't recognized as operators. If not set, they are. */ #define RE_LIMITED_OPS (RE_INTERVALS << 1) /* If this bit is set, newline is an alternation operator. If not set, newline is literal. */ #define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) /* If this bit is set, then `{...}' defines an interval, and \{ and \} are literals. If not set, then `\{...\}' defines an interval. */ #define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) /* If this bit is set, (...) defines a group, and \( and \) are literals. If not set, \(...\) defines a group, and ( and ) are literals. */ #define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) /* If this bit is set, then \ matches . If not set, then \ is a back-reference. */ #define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) /* If this bit is set, then | is an alternation operator, and \| is literal. If not set, then \| is an alternation operator, and | is literal. */ #define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) /* If this bit is set, then an ending range point collating higher than the starting range point, as in [z-a], is invalid. If not set, then when ending range point collates higher than the starting range point, the range is ignored. */ #define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) /* If this bit is set, then an unmatched ) is ordinary. If not set, then an unmatched ) is invalid. */ #define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) /* This global variable defines the particular regexp syntax to use (for some interfaces). When a regexp is compiled, the syntax used is stored in the pattern buffer, so changing this does not affect already-compiled regexps. */ extern reg_syntax_t re_syntax_options; /* Define combinations of the above bits for the standard possibilities. (The [[[ comments delimit what gets put into the Texinfo file, so don't delete them!) */ /* [[[begin syntaxes]]] */ #define RE_SYNTAX_EMACS 0 #define RE_SYNTAX_AWK \ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ | RE_UNMATCHED_RIGHT_PAREN_ORD) #define RE_SYNTAX_POSIX_AWK \ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS) #define RE_SYNTAX_GREP \ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ | RE_NEWLINE_ALT) #define RE_SYNTAX_EGREP \ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ | RE_NO_BK_VBAR) #define RE_SYNTAX_POSIX_EGREP \ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) /* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ #define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC #define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC /* Syntax bits common to both basic and extended POSIX regex syntax. */ #define _RE_SYNTAX_POSIX_COMMON \ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ | RE_INTERVALS | RE_NO_EMPTY_RANGES) #define RE_SYNTAX_POSIX_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this isn't minimal, since other operators, such as \`, aren't disabled. */ #define RE_SYNTAX_POSIX_MINIMAL_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) #define RE_SYNTAX_POSIX_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ | RE_UNMATCHED_RIGHT_PAREN_ORD) /* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ #define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) /* [[[end syntaxes]]] */ /* Maximum number of duplicates an interval can allow. Some systems (erroneously) define this in other header files, but we want our value, so remove any previous define. */ #ifdef RE_DUP_MAX #undef RE_DUP_MAX #endif #define RE_DUP_MAX ((1 << 15) - 1) /* POSIX `cflags' bits (i.e., information for `regcomp'). */ /* If this bit is set, then use extended regular expression syntax. If not set, then use basic regular expression syntax. */ #define REG_EXTENDED 1 /* If this bit is set, then ignore case when matching. If not set, then case is significant. */ #define REG_ICASE (REG_EXTENDED << 1) /* If this bit is set, then anchors do not match at newline characters in the string. If not set, then anchors do match at newlines. */ #define REG_NEWLINE (REG_ICASE << 1) /* If this bit is set, then report only success or fail in regexec. If not set, then returns differ between not matching and errors. */ #define REG_NOSUB (REG_NEWLINE << 1) /* POSIX `eflags' bits (i.e., information for regexec). */ /* If this bit is set, then the beginning-of-line operator doesn't match the beginning of the string (presumably because it's not the beginning of a line). If not set, then the beginning-of-line operator does match the beginning of the string. */ #define REG_NOTBOL 1 /* Like REG_NOTBOL, except for the end-of-line. */ #define REG_NOTEOL (1 << 1) /* If any error codes are removed, changed, or added, update the `re_error_msg' table in regex.c. */ typedef enum { REG_NOERROR = 0, /* Success. */ REG_NOMATCH, /* Didn't find a match (for regexec). */ /* POSIX regcomp return error codes. (In the order listed in the standard.) */ REG_BADPAT, /* Invalid pattern. */ REG_ECOLLATE, /* Not implemented. */ REG_ECTYPE, /* Invalid character class name. */ REG_EESCAPE, /* Trailing backslash. */ REG_ESUBREG, /* Invalid back reference. */ REG_EBRACK, /* Unmatched left bracket. */ REG_EPAREN, /* Parenthesis imbalance. */ REG_EBRACE, /* Unmatched \{. */ REG_BADBR, /* Invalid contents of \{\}. */ REG_ERANGE, /* Invalid range end. */ REG_ESPACE, /* Ran out of memory. */ REG_BADRPT, /* No preceding re for repetition op. */ /* Error codes we've added. */ REG_EEND, /* Premature end. */ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ } reg_errcode_t; /* This data structure represents a compiled pattern. Before calling the pattern compiler, the fields `buffer', `allocated', `fastmap', `translate', and `no_sub' can be set. After the pattern has been compiled, the `re_nsub' field is available. All other fields are private to the regex routines. */ struct re_pattern_buffer { /* [[[begin pattern_buffer]]] */ /* Space that holds the compiled pattern. It is declared as `unsigned char *' because its elements are sometimes used as array indexes. */ unsigned char *buffer; /* Number of bytes to which `buffer' points. */ unsigned long allocated; /* Number of bytes actually used in `buffer'. */ unsigned long used; /* Syntax setting with which the pattern was compiled. */ reg_syntax_t syntax; /* Pointer to a fastmap, if any, otherwise zero. re_search uses the fastmap, if there is one, to skip over impossible starting points for matches. */ char *fastmap; /* Either a translate table to apply to all characters before comparing them, or zero for no translation. The translation is applied to a pattern when it is compiled and to a string when it is matched. */ char *translate; /* Number of subexpressions found by the compiler. */ size_t re_nsub; /* Zero if this pattern cannot match the empty string, one else. Well, in truth it's used only in `re_search_2', to see whether or not we should use the fastmap, so we don't set this absolutely perfectly; see `re_compile_fastmap' (the `duplicate' case). */ unsigned can_be_null : 1; /* If REGS_UNALLOCATED, allocate space in the `regs' structure for `max (RE_NREGS, re_nsub + 1)' groups. If REGS_REALLOCATE, reallocate space if necessary. If REGS_FIXED, use what's there. */ #define REGS_UNALLOCATED 0 #define REGS_REALLOCATE 1 #define REGS_FIXED 2 unsigned regs_allocated : 2; /* Set to zero when `regex_compile' compiles a pattern; set to one by `re_compile_fastmap' if it updates the fastmap. */ unsigned fastmap_accurate : 1; /* If set, `re_match_2' does not return information about subexpressions. */ unsigned no_sub : 1; /* If set, a beginning-of-line anchor doesn't match at the beginning of the string. */ unsigned not_bol : 1; /* Similarly for an end-of-line anchor. */ unsigned not_eol : 1; /* If true, an anchor at a newline matches. */ unsigned newline_anchor : 1; /* [[[end pattern_buffer]]] */ }; typedef struct re_pattern_buffer regex_t; /* search.c (search_buffer) in Emacs needs this one opcode value. It is defined both in `regex.c' and here. */ #define RE_EXACTN_VALUE 1 /* Type for byte offsets within the string. POSIX mandates this. */ typedef int regoff_t; /* This is the structure we store register match data in. See regex.texinfo for a full description of what registers match. */ struct re_registers { unsigned num_regs; regoff_t *start; regoff_t *end; }; /* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, `re_match_2' returns information about at least this many registers the first time a `regs' structure is passed. */ #ifndef RE_NREGS #define RE_NREGS 30 #endif /* POSIX specification for registers. Aside from the different names than `re_registers', POSIX uses an array of structures, instead of a structure of arrays. */ typedef struct { regoff_t rm_so; /* Byte offset from string's start to substring's start. */ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ } regmatch_t; /* Declarations for routines. */ /* To avoid duplicating every routine declaration -- once with a prototype (if we are ANSI), and once without (if we aren't) -- we use the following macro to declare argument types. This unfortunately clutters up the declarations a bit, but I think it's worth it. */ #if __STDC__ #define _RE_ARGS(args) args #else /* not __STDC__ */ #define _RE_ARGS(args) () #endif /* not __STDC__ */ /* Sets the current default syntax to SYNTAX, and return the old syntax. You can also simply assign to the `re_syntax_options' variable. */ extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); /* Compile the regular expression PATTERN, with length LENGTH and syntax given by the global `re_syntax_options', into the buffer BUFFER. Return NULL if successful, and an error string if not. */ extern const char *re_compile_pattern _RE_ARGS ((const char *pattern, int length, struct re_pattern_buffer *buffer)); /* Compile a fastmap for the compiled pattern in BUFFER; used to accelerate searches. Return 0 if successful and -2 if was an internal error. */ extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); /* Search in the string STRING (with length LENGTH) for the pattern compiled into BUFFER. Start searching at position START, for RANGE characters. Return the starting position of the match, -1 for no match, or -2 for an internal error. Also return register information in REGS (if REGS and BUFFER->no_sub are nonzero). */ extern int re_search _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, int length, int start, int range, struct re_registers *regs)); /* Like `re_search', but search in the concatenation of STRING1 and STRING2. Also, stop searching at index START + STOP. */ extern int re_search_2 _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, int length1, const char *string2, int length2, int start, int range, struct re_registers *regs, int stop)); /* Like `re_search', but return how many characters in STRING the regexp in BUFFER matched, starting at position START. */ extern int re_match _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, int length, int start, struct re_registers *regs)); /* Relates to `re_match' as `re_search_2' relates to `re_search'. */ extern int re_match_2 _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, int length1, const char *string2, int length2, int start, struct re_registers *regs, int stop)); /* Set REGS to hold NUM_REGS registers, storing them in STARTS and ENDS. Subsequent matches using BUFFER and REGS will use this memory for recording register information. STARTS and ENDS must be allocated with malloc, and must each be at least `NUM_REGS * sizeof (regoff_t)' bytes long. If NUM_REGS == 0, then subsequent matches should allocate their own register data. Unless this function is called, the first search or match using PATTERN_BUFFER will allocate its own register data, without freeing the old data. */ extern void re_set_registers _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, unsigned num_regs, regoff_t *starts, regoff_t *ends)); /* 4.2 bsd compatibility. */ extern char *re_comp _RE_ARGS ((const char *)); extern int re_exec _RE_ARGS ((const char *)); /* POSIX compatibility. */ extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags)); extern int regexec _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)); extern size_t regerror _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)); extern void regfree _RE_ARGS ((regex_t *preg)); #endif /* not __REGEXP_LIBRARY_H__ */ /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ shapetools-1.4pl6.orig/vgrep-2.0/search.c100644 2013 145 26552 5371033310 16220 0ustar dokoswt/* search.c - searching subroutines using dfa, kwset and regex for grep. Copyright (C) 1992 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Written August 1992 by Mike Haertel. */ #include #ifdef STDC_HEADERS #include #include #else #define UCHAR_MAX 255 #include extern char *malloc(); #endif #ifdef HAVE_MEMCHR #include #ifdef NEED_MEMORY_H #include #endif #else #ifdef __STDC__ extern void *memchr(); #else extern char *memchr(); #endif #endif #if defined(HAVE_STRING_H) || defined(STDC_HEADERS) #undef bcopy #define bcopy(s, d, n) memcpy((d), (s), (n)) #endif #ifdef isascii #define ISALNUM(C) (isascii(C) && isalnum(C)) #define ISUPPER(C) (isascii(C) && isupper(C)) #else #define ISALNUM(C) isalnum(C) #define ISUPPER(C) isupper(C) #endif #define TOLOWER(C) (ISUPPER(C) ? tolower(C) : (C)) #include "grep.h" #include "dfa.h" #include "kwset.h" #include "regex.h" #define NCHAR (UCHAR_MAX + 1) #if __STDC__ static void Gcompile(char *, size_t); static void Ecompile(char *, size_t); static char *EGexecute(char *, size_t, char **); static void Fcompile(char *, size_t); static char *Fexecute(char *, size_t, char **); #else static void Gcompile(); static void Ecompile(); static char *EGexecute(); static void Fcompile(); static char *Fexecute(); #endif /* Here is the matchers vector for the main program. */ struct matcher matchers[] = { { "default", Gcompile, EGexecute }, { "grep", Gcompile, EGexecute }, { "ggrep", Gcompile, EGexecute }, { "egrep", Ecompile, EGexecute }, { "posix-egrep", Ecompile, EGexecute }, { "gegrep", Ecompile, EGexecute }, { "fgrep", Fcompile, Fexecute }, { "gfgrep", Fcompile, Fexecute }, { 0, 0, 0 }, }; /* For -w, we also consider _ to be word constituent. */ #define WCHAR(C) (ISALNUM(C) || (C) == '_') /* DFA compiled regexp. */ static struct dfa dfa; /* Regex compiled regexp. */ static struct re_pattern_buffer regex; /* KWset compiled pattern. For Ecompile and Gcompile, we compile a list of strings, at least one of which is known to occur in any string matching the regexp. */ static kwset_t kwset; /* Last compiled fixed string known to exactly match the regexp. If kwsexec() returns < lastexact, then we don't need to call the regexp matcher at all. */ static int lastexact; void dfaerror(mesg) char *mesg; { fatal(mesg, 0); } static void kwsinit() { static char trans[NCHAR]; int i; if (match_icase) for (i = 0; i < NCHAR; ++i) trans[i] = TOLOWER(i); if (!(kwset = kwsalloc(match_icase ? trans : (char *) 0))) fatal("memory exhausted", 0); } /* If the DFA turns out to have some set of fixed strings one of which must occur in the match, then we build a kwset matcher to find those strings, and thus quickly filter out impossible matches. */ static void kwsmusts() { struct dfamust *dm; char *err; if (dfa.musts) { kwsinit(); /* First, we compile in the substrings known to be exact matches. The kwset matcher will return the index of the matching string that it chooses. */ for (dm = dfa.musts; dm; dm = dm->next) { if (!dm->exact) continue; ++lastexact; if ((err = kwsincr(kwset, dm->must, strlen(dm->must))) != 0) fatal(err, 0); } /* Now, we compile the substrings that will require the use of the regexp matcher. */ for (dm = dfa.musts; dm; dm = dm->next) { if (dm->exact) continue; if ((err = kwsincr(kwset, dm->must, strlen(dm->must))) != 0) fatal(err, 0); } if ((err = kwsprep(kwset)) != 0) fatal(err, 0); } } static void Gcompile(pattern, size) char *pattern; size_t size; { #ifdef __STDC__ const #endif char *err; re_set_syntax(RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE); dfasyntax(RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE, match_icase); if ((err = re_compile_pattern(pattern, size, ®ex)) != 0) fatal(err, 0); dfainit(&dfa); /* In the match_words and match_lines cases, we use a different pattern for the DFA matcher that will quickly throw out cases that won't work. Then if DFA succeeds we do some hairy stuff using the regex matcher to decide whether the match should really count. */ if (match_words || match_lines) { /* In the whole-word case, we use the pattern: (^|[^A-Za-z_])(userpattern)([^A-Za-z_]|$). In the whole-line case, we use the pattern: ^(userpattern)$. BUG: Using [A-Za-z_] is locale-dependent! */ char *n = malloc(size + 50); int i = 0; strcpy(n, ""); if (match_lines) strcpy(n, "^\\("); if (match_words) strcpy(n, "\\(^\\|[^0-9A-Za-z_]\\)\\("); i = strlen(n); bcopy(pattern, n + i, size); i += size; if (match_words) strcpy(n + i, "\\)\\([^0-9A-Za-z_]\\|$\\)"); if (match_lines) strcpy(n + i, "\\)$"); i += strlen(n + i); dfacomp(n, i, &dfa, 1); } else dfacomp(pattern, size, &dfa, 1); kwsmusts(); } static void Ecompile(pattern, size) char *pattern; size_t size; { #ifdef __STDC__ const #endif char *err; if (strcmp(matcher, "posix-egrep") == 0) { re_set_syntax(RE_SYNTAX_POSIX_EGREP); dfasyntax(RE_SYNTAX_POSIX_EGREP, match_icase); } else { re_set_syntax(RE_SYNTAX_EGREP); dfasyntax(RE_SYNTAX_EGREP, match_icase); } if ((err = re_compile_pattern(pattern, size, ®ex)) != 0) fatal(err, 0); dfainit(&dfa); /* In the match_words and match_lines cases, we use a different pattern for the DFA matcher that will quickly throw out cases that won't work. Then if DFA succeeds we do some hairy stuff using the regex matcher to decide whether the match should really count. */ if (match_words || match_lines) { /* In the whole-word case, we use the pattern: (^|[^A-Za-z_])(userpattern)([^A-Za-z_]|$). In the whole-line case, we use the pattern: ^(userpattern)$. BUG: Using [A-Za-z_] is locale-dependent! */ char *n = malloc(size + 50); int i = 0; strcpy(n, ""); if (match_lines) strcpy(n, "^("); if (match_words) strcpy(n, "(^|[^0-9A-Za-z_])("); i = strlen(n); bcopy(pattern, n + i, size); i += size; if (match_words) strcpy(n + i, ")([^0-9A-Za-z_]|$)"); if (match_lines) strcpy(n + i, ")$"); i += strlen(n + i); dfacomp(n, i, &dfa, 1); } else dfacomp(pattern, size, &dfa, 1); kwsmusts(); } static char * EGexecute(buf, size, endp) char *buf; size_t size; char **endp; { register char *buflim, *beg, *end, save; int backref, start, len; struct kwsmatch kwsm; static struct re_registers regs; /* This is static on account of a BRAIN-DEAD Q@#%!# library interface in regex.c. */ buflim = buf + size; for (beg = end = buf; end < buflim; beg = end + 1) { if (kwset) { /* Find a possible match using the KWset matcher. */ beg = kwsexec(kwset, beg, buflim - beg, &kwsm); if (!beg) goto failure; /* Narrow down to the line containing the candidate, and run it through DFA. */ end = memchr(beg, '\n', buflim - beg); if (!end) end = buflim; while (beg > buf && beg[-1] != '\n') --beg; save = *end; if (kwsm.index < lastexact) goto success; if (!dfaexec(&dfa, beg, end, 0, (int *) 0, &backref)) { *end = save; continue; } *end = save; /* Successful, no backreferences encountered. */ if (!backref) goto success; } else { /* No good fixed strings; start with DFA. */ save = *buflim; beg = dfaexec(&dfa, beg, buflim, 0, (int *) 0, &backref); *buflim = save; if (!beg) goto failure; /* Narrow down to the line we've found. */ end = memchr(beg, '\n', buflim - beg); if (!end) end = buflim; while (beg > buf && beg[-1] != '\n') --beg; /* Successful, no backreferences encountered! */ if (!backref) goto success; } /* If we've made it to this point, this means DFA has seen a probable match, and we need to run it through Regex. */ regex.not_eol = 0; if ((start = re_search(®ex, beg, end - beg, 0, end - beg, ®s)) >= 0) { len = regs.end[0] - start; if (!match_lines && !match_words || match_lines && len == end - beg) goto success; /* If -w, check if the match aligns with word boundaries. We do this iteratively because: (a) the line may contain more than one occurence of the pattern, and (b) Several alternatives in the pattern might be valid at a given point, and we may need to consider a shorter one to find a word boundary. */ if (match_words) while (start >= 0) { if ((start == 0 || !WCHAR(beg[start - 1])) && (len == end - beg || !WCHAR(beg[start + len]))) goto success; if (len > 0) { /* Try a shorter length anchored at the same place. */ --len; regex.not_eol = 1; len = re_match(®ex, beg, start + len, start, ®s); } if (len <= 0) { /* Try looking further on. */ if (start == end - beg) break; ++start; regex.not_eol = 0; start = re_search(®ex, beg, end - beg, start, end - beg - start, ®s); len = regs.end[0] - start; } } } } failure: return 0; success: *endp = end < buflim ? end + 1 : end; return beg; } static void Fcompile(pattern, size) char *pattern; size_t size; { char *beg, *lim, *err; kwsinit(); beg = pattern; do { for (lim = beg; lim < pattern + size && *lim != '\n'; ++lim) ; if ((err = kwsincr(kwset, beg, lim - beg)) != 0) fatal(err, 0); if (lim < pattern + size) ++lim; beg = lim; } while (beg < pattern + size); if ((err = kwsprep(kwset)) != 0) fatal(err, 0); } static char * Fexecute(buf, size, endp) char *buf; size_t size; char **endp; { register char *beg, *try, *end; register size_t len; struct kwsmatch kwsmatch; for (beg = buf; beg <= buf + size; ++beg) { if (!(beg = kwsexec(kwset, beg, buf + size - beg, &kwsmatch))) return 0; len = kwsmatch.size[0]; if (match_lines) { if (beg > buf && beg[-1] != '\n') continue; if (beg + len < buf + size && beg[len] != '\n') continue; goto success; } else if (match_words) for (try = beg; len && try;) { if (try > buf && WCHAR((unsigned char) try[-1])) break; if (try + len < buf + size && WCHAR((unsigned char) try[len])) { try = kwsexec(kwset, beg, --len, &kwsmatch); len = kwsmatch.size[0]; } else goto success; } else goto success; } return 0; success: if ((end = memchr(beg + len, '\n', (buf + size) - (beg + len))) != 0) ++end; else end = buf + size; *endp = end; while (beg > buf && beg[-1] != '\n') --beg; return beg; }