Annotation of coherent/e/bin/pax/link.c, revision 1.1

1.1     ! root        1: /* $Source: /src386/usr/bin/pax/link.c,v $
        !             2:  *
        !             3:  * $Revision: 1.1 $
        !             4:  *
        !             5:  * link.c - functions for handling multiple file links 
        !             6:  *
        !             7:  * DESCRIPTION
        !             8:  *
        !             9:  *     These function manage the link chains which are used to keep track
        !            10:  *     of outstanding links during archive reading and writing.
        !            11:  *
        !            12:  * AUTHOR
        !            13:  *
        !            14:  *     Mark H. Colburn, NAPS International ([email protected])
        !            15:  *
        !            16:  * Sponsored by The USENIX Association for public distribution. 
        !            17:  *
        !            18:  * Copyright (c) 1989 Mark H. Colburn.
        !            19:  * All rights reserved.
        !            20:  *
        !            21:  * Redistribution and use in source and binary forms are permitted
        !            22:  * provided that the above copyright notice is duplicated in all such 
        !            23:  * forms and that any documentation, advertising materials, and other 
        !            24:  * materials related to such distribution and use acknowledge that the 
        !            25:  * software was developed * by Mark H. Colburn and sponsored by The 
        !            26:  * USENIX Association. 
        !            27:  *
        !            28:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            29:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            30:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            31:  *
        !            32:  * $Log:       link.c,v $
        !            33:  * Revision 1.1  92/08/28  08:02:14  bin
        !            34:  * Initial revision
        !            35:  * 
        !            36:  * Revision 1.1  89/02/14  16:47:58  jep
        !            37:  * Initial revision
        !            38:  * 
        !            39:  * Revision 1.1  88/12/23  18:02:12  mark
        !            40:  * Initial revision
        !            41:  * 
        !            42:  */
        !            43: 
        !            44: #ifndef lint
        !            45: static char *ident = "$Id: link.c,v 1.1 92/08/28 08:02:14 bin Exp Locker: bin $";
        !            46: static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
        !            47: #endif /* ! lint */
        !            48: 
        !            49: 
        !            50: /* Headers */
        !            51: 
        !            52: #include "pax.h"
        !            53: 
        !            54: 
        !            55: /* Defines */
        !            56: 
        !            57: /*
        !            58:  * Address link information base. 
        !            59:  */
        !            60: #define        LINKHASH(ino)   (linkbase + (ino) % NEL(linkbase))
        !            61: 
        !            62: /*
        !            63:  * Number of array elements. 
        !            64:  */
        !            65: #define        NEL(a)          (sizeof(a) / sizeof(*(a)))
        !            66: 
        !            67: 
        !            68: 
        !            69: /* Internal Identifiers */
        !            70: 
        !            71: static Link    *linkbase[256]; /* Unresolved link information */
        !            72: 
        !            73: 
        !            74: /* linkfrom - find a file to link from 
        !            75:  *
        !            76:  * DESCRIPTION
        !            77:  *
        !            78:  *     Linkfrom searches the link chain to see if there is a file in the
        !            79:  *     link chain which has the same inode number as the file specified
        !            80:  *     by the stat block pointed at by asb.  If a file is found, the
        !            81:  *     name is returned to the caller, otherwise a NULL is returned.
        !            82:  *
        !            83:  * PARAMETERS
        !            84:  *
        !            85:  *     char    *name   - name of the file which we are attempting
        !            86:  *                        to find a link for
        !            87:  *     Stat    *asb    - stat structure of file to find a link to
        !            88:  *
        !            89:  * RETURNS
        !            90:  *
        !            91:  *     Returns a pointer to a link structure, or NULL if unsuccessful. 
        !            92:  *
        !            93:  */
        !            94: 
        !            95: #if __STDC__
        !            96: 
        !            97: Link *linkfrom(char *name, Stat *asb)
        !            98: 
        !            99: #else
        !           100:     
        !           101: Link *linkfrom(name, asb)
        !           102: char           *name;
        !           103: Stat           *asb;
        !           104: 
        !           105: #endif
        !           106: {
        !           107:     Link           *linkp;
        !           108:     Link           *linknext;
        !           109:     Path           *path;
        !           110:     Path           *pathnext;
        !           111:     Link          **abase;
        !           112: 
        !           113:     for (linkp = *(abase = LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {
        !           114:        if (linkp->l_nlink == 0) {
        !           115:            if (linkp->l_name) {
        !           116:                free((char *) linkp->l_name);
        !           117:            }
        !           118:            if (linknext = linkp->l_forw) {
        !           119:                linknext->l_back = linkp->l_back;
        !           120:            }
        !           121:            if (linkp->l_back) {
        !           122:                linkp->l_back->l_forw = linkp->l_forw;
        !           123:            }
        !           124:            free((char *) linkp);
        !           125:            *abase = (Link *)NULL;
        !           126:        } else if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {
        !           127:            /* 
        !           128:             * check to see if a file with the name "name" exists in the 
        !           129:             * chain of files which we have for this particular link
        !           130:             */
        !           131:            for (path = linkp->l_path; path; path = pathnext) {
        !           132:                if (strcmp(path->p_name, name) == 0) {
        !           133:                    --linkp->l_nlink;
        !           134:                    if (path->p_name) {
        !           135:                        free(path->p_name);
        !           136:                    }
        !           137:                    if (pathnext = path->p_forw) {
        !           138:                        pathnext->p_back = path->p_back;
        !           139:                    }
        !           140:                    if (path->p_back) {
        !           141:                        path->p_back->p_forw = pathnext;
        !           142:                    }
        !           143:                    if (linkp->l_path == path) {
        !           144:                        linkp->l_path = pathnext;
        !           145:                    }
        !           146:                    free(path);
        !           147:                    return (linkp);
        !           148:                }
        !           149:                pathnext = path->p_forw;
        !           150:            }
        !           151:            return((Link *)NULL);
        !           152:        } else {
        !           153:            linknext = linkp->l_forw;
        !           154:        }
        !           155:     }
        !           156:     return ((Link *)NULL);
        !           157: }
        !           158: 
        !           159: 
        !           160: 
        !           161: /* islink - determine whether a given file really a link
        !           162:  *
        !           163:  * DESCRIPTION
        !           164:  *
        !           165:  *     Islink searches the link chain to see if there is a file in the
        !           166:  *     link chain which has the same inode number as the file specified
        !           167:  *     by the stat block pointed at by asb.  If a file is found, a
        !           168:  *     non-zero value is returned to the caller, otherwise a 0 is
        !           169:  *     returned.
        !           170:  *
        !           171:  * PARAMETERS
        !           172:  *
        !           173:  *     char    *name   - name of file to check to see if it is link.
        !           174:  *     Stat    *asb    - stat structure of file to find a link to
        !           175:  *
        !           176:  * RETURNS
        !           177:  *
        !           178:  *     Returns a pointer to a link structure, or NULL if unsuccessful. 
        !           179:  *
        !           180:  */
        !           181: 
        !           182: #if __STDC__
        !           183: 
        !           184: Link *islink(char *name, Stat *asb)
        !           185: 
        !           186: #else
        !           187:     
        !           188: Link *islink(name, asb)
        !           189: char           *name;
        !           190: Stat           *asb;
        !           191: 
        !           192: #endif
        !           193: {
        !           194:     Link           *linkp;
        !           195:     Link           *linknext;
        !           196: 
        !           197:     for (linkp = *(LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {
        !           198:        if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {
        !           199:            if (strcmp(name, linkp->l_name) == 0) {
        !           200:                return ((Link *)NULL);
        !           201:            } 
        !           202:            return (linkp);
        !           203:        } else {
        !           204:            linknext = linkp->l_forw;
        !           205:        }
        !           206:     }
        !           207:     return ((Link *)NULL);
        !           208: }
        !           209: 
        !           210: 
        !           211: /* linkto  - remember a file with outstanding links 
        !           212:  *
        !           213:  * DESCRIPTION
        !           214:  *
        !           215:  *     Linkto adds the specified file to the link chain.  Any subsequent
        !           216:  *     calls to linkfrom which have the same inode will match the file
        !           217:  *     just entered.  If not enough space is available to make the link
        !           218:  *     then the item is not added to the link chain, and a NULL is
        !           219:  *     returned to the calling function.
        !           220:  *
        !           221:  * PARAMETERS
        !           222:  *
        !           223:  *     char    *name   - name of file to remember
        !           224:  *     Stat    *asb    - pointer to stat structure of file to remember
        !           225:  *
        !           226:  * RETURNS
        !           227:  *
        !           228:  *     Returns a pointer to the associated link structure, or NULL when 
        !           229:  *     linking is not possible. 
        !           230:  *
        !           231:  */
        !           232: 
        !           233: #if __STDC__
        !           234: 
        !           235: Link *linkto(char *name, Stat *asb)
        !           236: 
        !           237: #else
        !           238:     
        !           239: Link *linkto(name, asb)
        !           240: char           *name;
        !           241: Stat           *asb;
        !           242: 
        !           243: #endif
        !           244: {
        !           245:     Link           *linkp;
        !           246:     Link           *linknext;
        !           247:     Path           *path;
        !           248:     Link          **abase;
        !           249: 
        !           250:     for (linkp = *(LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {
        !           251:        if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {
        !           252:            if ((path = (Path *) mem_get(sizeof(Path))) == (Path *)NULL || 
        !           253:                (path->p_name = mem_str(name)) == (char *)NULL) {
        !           254:                return((Link *)NULL);
        !           255:            }
        !           256:            if (path->p_forw = linkp->l_path) {
        !           257:                if (linkp->l_path->p_forw) {
        !           258:                    linkp->l_path->p_forw->p_back = path;
        !           259:                }
        !           260:            } else {
        !           261:                linkp->l_path = path;
        !           262:            }
        !           263:            path->p_back = (Path *)NULL;
        !           264:            return(linkp);
        !           265:        } else {
        !           266:            linknext = linkp->l_forw;
        !           267:        }
        !           268:     }
        !           269:     /*
        !           270:      * This is a brand new link, for which there is no other information
        !           271:      */
        !           272: 
        !           273:     if ((asb->sb_mode & S_IFMT) == S_IFDIR
        !           274:        || (linkp = (Link *) mem_get(sizeof(Link))) == (Link *)NULL
        !           275:        || (linkp->l_name = mem_str(name)) == (char *)NULL) {
        !           276:        return ((Link *)NULL);
        !           277:     }
        !           278:     linkp->l_dev = asb->sb_dev;
        !           279:     linkp->l_ino = asb->sb_ino;
        !           280:     linkp->l_nlink = asb->sb_nlink - 1;
        !           281:     linkp->l_size = asb->sb_size;
        !           282:     linkp->l_path = (Path *)NULL;
        !           283:     if (linkp->l_forw = *(abase = LINKHASH(asb->sb_ino))) {
        !           284:        linkp->l_forw->l_back = linkp;
        !           285:     } else {
        !           286:        *abase = linkp;
        !           287:     }
        !           288:     linkp->l_back = (Link *)NULL;
        !           289:     return (linkp);
        !           290: }
        !           291: 
        !           292: 
        !           293: /* linkleft - complain about files with unseen links 
        !           294:  *
        !           295:  * DESCRIPTION
        !           296:  *
        !           297:  *     Linksleft scans through the link chain to see if there were any
        !           298:  *     files which have outstanding links that were not processed by the
        !           299:  *     archive.  For each file in the link chain for which there was not
        !           300:  *     a file,  and error message is printed.
        !           301:  */
        !           302: 
        !           303: #if __STDC__
        !           304: 
        !           305: void linkleft(void)
        !           306: 
        !           307: #else
        !           308:     
        !           309: void linkleft()
        !           310: 
        !           311: #endif
        !           312: {
        !           313:     Link           *lp;
        !           314:     Link          **base;
        !           315: 
        !           316:     for (base = linkbase; base < linkbase + NEL(linkbase); ++base) {
        !           317:        for (lp = *base; lp; lp = lp->l_forw) {
        !           318:            if (lp->l_nlink) {
        !           319:                warn(lp->l_path->p_name, "Unseen link(s)");
        !           320:            }
        !           321:        }
        !           322:     }
        !           323: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.