Annotation of coherent/e/bin/pax/link.c, revision 1.1.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.