[BACK]Return to pl.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / pkgsrc / pkgtools / pkg_install / files / create

Annotation of pkgsrc/pkgtools/pkg_install/files/create/pl.c, Revision 1.7

1.7     ! grant       1: /*     $NetBSD: pl.c,v 1.30 2004/01/15 09:33:39 agc Exp $      */
1.1       schmonz     2:
1.3       jlam        3: #if HAVE_CONFIG_H
                      4: #include "config.h"
                      5: #endif
1.4       jlam        6: #include <nbcompat.h>
1.3       jlam        7: #if HAVE_SYS_CDEFS_H
1.1       schmonz     8: #include <sys/cdefs.h>
1.3       jlam        9: #endif
1.1       schmonz    10: #ifndef lint
                     11: #if 0
                     12: static const char *rcsid = "from FreeBSD Id: pl.c,v 1.11 1997/10/08 07:46:35 charnier Exp";
                     13: #else
1.7     ! grant      14: __RCSID("$NetBSD: pl.c,v 1.30 2004/01/15 09:33:39 agc Exp $");
1.1       schmonz    15: #endif
                     16: #endif
                     17:
                     18: /*
                     19:  * FreeBSD install - a package for the installation and maintainance
                     20:  * of non-core utilities.
                     21:  *
                     22:  * Redistribution and use in source and binary forms, with or without
                     23:  * modification, are permitted provided that the following conditions
                     24:  * are met:
                     25:  * 1. Redistributions of source code must retain the above copyright
                     26:  *    notice, this list of conditions and the following disclaimer.
                     27:  * 2. Redistributions in binary form must reproduce the above copyright
                     28:  *    notice, this list of conditions and the following disclaimer in the
                     29:  *    documentation and/or other materials provided with the distribution.
                     30:  *
                     31:  * Jordan K. Hubbard
                     32:  * 18 July 1993
                     33:  *
                     34:  * Routines for dealing with the packing list.
                     35:  *
                     36:  */
                     37:
                     38: #include "lib.h"
                     39: #include "create.h"
1.3       jlam       40: #if HAVE_ERR_H
1.1       schmonz    41: #include <err.h>
                     42: #endif
1.3       jlam       43: #if HAVE_MD5_H
1.1       schmonz    44: #include <md5.h>
                     45: #endif
                     46:
                     47: /*
                     48:  * Check that any symbolic link is relative to the prefix
                     49:  */
                     50: static void
                     51: CheckSymlink(char *name, char *prefix, size_t prefixcc)
                     52: {
                     53:        char    newtgt[MAXPATHLEN];
                     54:        char    oldtgt[MAXPATHLEN];
                     55:        char   *slash;
                     56:        int     slashc;
                     57:        int     cc;
                     58:        int     i;
                     59:
                     60:        if ((cc = readlink(name, oldtgt, sizeof(oldtgt) - 1)) > 0) {
                     61:                oldtgt[cc] = 0;
                     62:                if (strncmp(oldtgt, prefix, prefixcc) == 0 && oldtgt[prefixcc] == '/') {
                     63:                        for (slashc = 0, slash = &name[prefixcc + 1]; (slash = strchr(slash, '/')) != (char *) NULL; slash++, slashc++) {
                     64:                        }
                     65:                        for (cc = i = 0; i < slashc; i++) {
1.6       jlam       66:                                strlcpy(&newtgt[cc], "../", sizeof(newtgt) - cc);
1.1       schmonz    67:                                cc += 3;
                     68:                        }
1.6       jlam       69:                        strlcpy(&newtgt[cc], &oldtgt[prefixcc + 1], sizeof(newtgt) - cc);
1.1       schmonz    70:                        (void) fprintf(stderr, "Full pathname symlink `%s' is target of `%s' - adjusting to `%s'\n", oldtgt, name, newtgt);
                     71:                        if (unlink(name) != 0) {
                     72:                                warn("can't unlink `%s'", name);
                     73:                        } else if (symlink(newtgt, name) != 0) {
                     74:                                warn("can't symlink `%s' called `%s'", newtgt, name);
                     75:                        }
                     76:                }
                     77:        }
                     78: }
                     79:
                     80: /*
                     81:  * (Reversed) comparison routine for directory name sorting
                     82:  */
                     83: static int
                     84: dircmp(const void *vp1, const void *vp2)
                     85: {
                     86:        return strcmp((const char *) vp2, (const char *) vp1);
                     87: }
                     88:
                     89: /*
                     90:  * Re-order the PLIST_DIR_RM entries into reverse alphabetic order
                     91:  */
                     92: static void
                     93: reorder(package_t *pkg, int dirc)
                     94: {
                     95:        plist_t *p;
                     96:        char  **dirv;
                     97:        int     i;
                     98:
                     99:        if ((dirv = (char **) calloc(dirc, sizeof(char *))) == (char **) NULL) {
                    100:                warn("No directory re-ordering will be done");
                    101:        } else {
                    102:                for (p = pkg->head, i = 0; p; p = p->next) {
                    103:                        if (p->type == PLIST_DIR_RM) {
                    104:                                dirv[i++] = p->name;
                    105:                        }
                    106:                }
                    107:                qsort(dirv, dirc, sizeof(char *), dircmp);
                    108:                for (p = pkg->head, i = 0; p; p = p->next) {
                    109:                        if (p->type == PLIST_DIR_RM) {
                    110:                                p->name = dirv[i++];
                    111:                        }
                    112:                }
                    113:                (void) free(dirv);
                    114:        }
                    115: }
                    116:
                    117: /*
                    118:  * Check a list for files that require preconversion
                    119:  */
                    120: void
                    121: check_list(char *home, package_t *pkg, const char *PkgName)
                    122: {
                    123:        struct stat st;
                    124:        plist_t *tmp;
                    125:        plist_t *p;
1.7     ! grant     126:        char    buf[ChecksumHeaderLen + LegibleChecksumLen];
        !           127:        char    target[FILENAME_MAX + SymlinkHeaderLen];
1.1       schmonz   128:        char    name[FILENAME_MAX];
                    129:        char   *cwd = home;
                    130:        char   *srcdir = NULL;
                    131:        int     dirc;
1.7     ! grant     132:        int     cc;
1.1       schmonz   133:
                    134:        /* Open Package Database for writing */
1.2       jschauma  135:        if (update_pkgdb && !pkgdb_open(ReadWrite)) {
1.1       schmonz   136:                cleanup(0);
1.2       jschauma  137:                err(EXIT_FAILURE, "can't open pkgdb");
1.1       schmonz   138:        }
                    139:
                    140:        for (dirc = 0, p = pkg->head; p; p = p->next) {
                    141:                switch (p->type) {
                    142:                case PLIST_CWD:
                    143:                        cwd = p->name;
                    144:                        break;
                    145:                case PLIST_IGNORE:
                    146:                        p = p->next;
                    147:                        break;
                    148:                case PLIST_SRC:
                    149:                        srcdir = p->name;
                    150:                        break;
                    151:                case PLIST_DIR_RM:
                    152:                        dirc++;
                    153:                        break;
                    154:                case PLIST_FILE:
                    155:                        /*
                    156:                         * pkgdb handling - usually, we enter files
                    157:                         * into the pkgdb as soon as they hit the disk,
                    158:                         * but as they are present before pkg_create
                    159:                         * starts, it's ok to do this somewhere here
                    160:                         */
                    161:                        if (update_pkgdb) {
                    162:                                char   *s, t[FILENAME_MAX];
                    163:
1.3       jlam      164:                                (void) snprintf(t, sizeof(t), "%s%s%s",
                    165:                                        cwd,
                    166:                                        (strcmp(cwd, "/") == 0) ? "" : "/",
                    167:                                        p->name);
1.1       schmonz   168:
                    169:                                s = pkgdb_retrieve(t);
                    170: #ifdef PKGDB_DEBUG
                    171:                                fprintf(stderr, "pkgdb_retrieve(\"%s\")=\"%s\"\n", t, s);       /* pkgdb-debug - HF */
                    172: #endif
                    173:                                if (s && PlistOnly)
                    174:                                        warnx("Overwriting %s - "
                    175:                                            "pkg %s bogus/conflicting?", t, s);
                    176:                                else {
                    177:                                        pkgdb_store(t, PkgName);
                    178: #ifdef PKGDB_DEBUG
                    179:                                        fprintf(stderr, "pkgdb_store(\"%s\", \"%s\")\n", t, PkgName);   /* pkgdb-debug - HF */
                    180: #endif
                    181:                                }
                    182:                        }
                    183:
                    184:                        if (cwd == home) {
                    185:                                /* no @cwd yet */
                    186:                                (void) snprintf(name, sizeof(name), "%s/%s", srcdir ? srcdir : cwd, p->name);
                    187:                        } else {
                    188:                                /* after @cwd */
                    189:                                /* prepend DESTDIR if set?  - HF */
1.3       jlam      190:                                (void) snprintf(name, sizeof(name), "%s%s%s",
                    191:                                        cwd,
                    192:                                        (strcmp(cwd, "/") == 0) ? "" : "/",
                    193:                                        p->name);
1.1       schmonz   194:                        }
                    195:                        if (lstat(name, &st) < 0) {
                    196:                                warnx("can't stat `%s'", name);
                    197:                                continue;
                    198:                        }
                    199:                        switch (st.st_mode & S_IFMT) {
                    200:                        case S_IFDIR:
                    201:                                p->type = PLIST_DIR_RM;
                    202:                                dirc++;
                    203:                                continue;
                    204:                        case S_IFLNK:
                    205:                                if (RelativeLinks) {
                    206:                                        CheckSymlink(name, cwd, strlen(cwd));
                    207:                                }
1.7     ! grant     208:                                (void) strlcpy(target, SYMLINK_HEADER,
        !           209:                                    sizeof(target));
        !           210:                                if ((cc = readlink(name, &target[SymlinkHeaderLen],
        !           211:                                          sizeof(target) - SymlinkHeaderLen)) < 0) {
        !           212:                                        warnx("can't readlink `%s'", name);
        !           213:                                        continue;
        !           214:                                }
        !           215:                                target[SymlinkHeaderLen + cc] = 0x0;
        !           216:                                tmp = new_plist_entry();
        !           217:                                tmp->name = strdup(target);
        !           218:                                tmp->type = PLIST_COMMENT;
        !           219:                                tmp->next = p->next;
        !           220:                                tmp->prev = p;
        !           221:                                if (p == pkg->tail) {
        !           222:                                        pkg->tail = tmp;
        !           223:                                }
        !           224:                                p->next = tmp;
        !           225:                                p = tmp;
1.1       schmonz   226:                                break;
                    227:                        case S_IFCHR:
                    228:                                warnx("Warning - char special device `%s' in PLIST", name);
                    229:                                break;
                    230:                        case S_IFBLK:
                    231:                                warnx("Warning - block special device `%s' in PLIST", name);
                    232:                                break;
                    233:                        default:
1.3       jlam      234:                                (void) strlcpy(buf, CHECKSUM_HEADER,
                    235:                                    sizeof(buf));
1.1       schmonz   236:                                if (MD5File(name, &buf[ChecksumHeaderLen]) != (char *) NULL) {
                    237:                                        tmp = new_plist_entry();
                    238:                                        tmp->name = strdup(buf);
                    239:                                        tmp->type = PLIST_COMMENT;      /* PLIST_MD5 - HF */
                    240:                                        tmp->next = p->next;
                    241:                                        tmp->prev = p;
                    242:                                        if (p == pkg->tail) {
                    243:                                                pkg->tail = tmp;
                    244:                                        }
                    245:                                        p->next = tmp;
                    246:                                        p = tmp;
                    247:                                }
                    248:                                break;
                    249:                        }
                    250:                        break;
                    251:                default:
                    252:                        break;
                    253:                }
                    254:        }
                    255:
                    256:        if (update_pkgdb) {
                    257:                pkgdb_close();
                    258:        }
                    259:
                    260:        if (ReorderDirs && dirc > 0) {
                    261:                reorder(pkg, dirc);
                    262:        }
                    263: }

CVSweb <webmaster@jp.NetBSD.org>