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

Annotation of pkgsrc/pkgtools/pkg_install/files/create/perform.c, Revision 1.2

1.2     ! jschauma    1: /*     $NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:10 schmonz Exp $  */
1.1       schmonz     2:
                      3: #if 0
                      4: #include <sys/cdefs.h>
                      5: #ifndef lint
                      6: #if 0
                      7: static const char *rcsid = "from FreeBSD Id: perform.c,v 1.38 1997/10/13 15:03:51 jkh Exp";
                      8: #else
1.2     ! jschauma    9: __RCSID("$NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:10 schmonz Exp $");
1.1       schmonz    10: #endif
                     11: #endif
                     12: #endif
                     13:
                     14: /*
                     15:  * FreeBSD install - a package for the installation and maintainance
                     16:  * of non-core utilities.
                     17:  *
                     18:  * Redistribution and use in source and binary forms, with or without
                     19:  * modification, are permitted provided that the following conditions
                     20:  * are met:
                     21:  * 1. Redistributions of source code must retain the above copyright
                     22:  *    notice, this list of conditions and the following disclaimer.
                     23:  * 2. Redistributions in binary form must reproduce the above copyright
                     24:  *    notice, this list of conditions and the following disclaimer in the
                     25:  *    documentation and/or other materials provided with the distribution.
                     26:  *
                     27:  * Jordan K. Hubbard
                     28:  * 18 July 1993
                     29:  *
                     30:  * This is the main body of the create module.
                     31:  *
                     32:  */
                     33:
                     34: #include "lib.h"
                     35: #include "create.h"
                     36:
                     37: #ifdef HAVE_ERR_H
                     38: #include <err.h>
                     39: #endif
                     40:
                     41: #include <signal.h>
                     42:
                     43: #ifdef HAVE_SYS_WAIT_H
                     44: #include <sys/wait.h>
                     45: #endif
                     46:
                     47: #include <unistd.h>
                     48:
                     49: static char *Home;
                     50:
                     51: static void
                     52: make_dist(const char *home, const char *pkg, const char *suffix, const package_t *plist)
                     53: {
                     54:        char    tball[FILENAME_MAX];
                     55:        const plist_t *p;
                     56:        int     ret;
                     57:        char   *args[50];       /* Much more than enough. */
                     58:        int     nargs = 1;
                     59:        int     pipefds[2];
                     60:        FILE   *totar;
                     61:        pid_t   pid;
                     62:
                     63:        if ((args[0] = strrchr(TAR_FULLPATHNAME, '/')) == NULL)
                     64:                args[0] = TAR_FULLPATHNAME;
                     65:        else
                     66:                args[0]++;
                     67:
                     68:        if (*pkg == '/')
                     69:                (void) snprintf(tball, sizeof(tball), "%s.%s", pkg, suffix);
                     70:        else
                     71:                (void) snprintf(tball, sizeof(tball), "%s/%s.%s", home, pkg, suffix);
                     72:
                     73:        args[nargs++] = "-c";
                     74:        args[nargs++] = "-f";
                     75:        args[nargs++] = tball;
                     76:        if (strstr(suffix, "bz")) {
                     77:                args[nargs++] = "--use-compress-program";
                     78:                args[nargs++] = "bzip2";
                     79:        } else if (strchr(suffix, 'z'))/* Compress/gzip? */
                     80:                args[nargs++] = "-z";
                     81:        if (Dereference)
                     82:                args[nargs++] = "-h";
                     83:        if (ExcludeFrom) {
                     84:                args[nargs++] = "-X";
                     85:                args[nargs++] = ExcludeFrom;
                     86:        }
                     87:        args[nargs++] = "-T";   /* Take filenames from file instead of args. */
                     88:        args[nargs++] = "-";    /* Use stdin for the file. */
                     89:        args[nargs] = NULL;
                     90:
                     91:        if (Verbose)
                     92:                printf("Creating gzip'd binary package in '%s'\n", tball);
                     93:
                     94:        /* Set up a pipe for passing the filenames, and fork off a tar process. */
                     95:        if (pipe(pipefds) == -1) {
                     96:                cleanup(0);
                     97:                errx(2, "cannot create pipe");
                     98:        }
                     99:        if ((pid = fork()) == -1) {
                    100:                cleanup(0);
                    101:                errx(2, "cannot fork process for %s", TAR_FULLPATHNAME);
                    102:        }
                    103:        if (pid == 0) {         /* The child */
                    104:                dup2(pipefds[0], 0);
                    105:                close(pipefds[0]);
                    106:                close(pipefds[1]);
                    107:                execvp(TAR_FULLPATHNAME, args);
                    108:                cleanup(0);
                    109:                errx(2, "failed to execute %s command", TAR_FULLPATHNAME);
                    110:        }
                    111:
                    112:        /* Meanwhile, back in the parent process ... */
                    113:        close(pipefds[0]);
                    114:        if ((totar = fdopen(pipefds[1], "w")) == NULL) {
                    115:                cleanup(0);
                    116:                errx(2, "fdopen failed");
                    117:        }
                    118:
                    119:        fprintf(totar, "%s\n", CONTENTS_FNAME);
                    120:        fprintf(totar, "%s\n", COMMENT_FNAME);
                    121:        fprintf(totar, "%s\n", DESC_FNAME);
                    122:
                    123:        if (Install) {
                    124:                fprintf(totar, "%s\n", INSTALL_FNAME);
                    125:        }
                    126:        if (DeInstall) {
                    127:                fprintf(totar, "%s\n", DEINSTALL_FNAME);
                    128:        }
                    129:        if (Require) {
                    130:                fprintf(totar, "%s\n", REQUIRE_FNAME);
                    131:        }
                    132:        if (Display) {
                    133:                fprintf(totar, "%s\n", DISPLAY_FNAME);
                    134:        }
                    135:        if (Mtree) {
                    136:                fprintf(totar, "%s\n", MTREE_FNAME);
                    137:        }
                    138:        if (BuildVersion) {
                    139:                (void) fprintf(totar, "%s\n", BUILD_VERSION_FNAME);
                    140:        }
                    141:        if (BuildInfo) {
                    142:                (void) fprintf(totar, "%s\n", BUILD_INFO_FNAME);
                    143:        }
                    144:        if (SizePkg) {
                    145:                (void) fprintf(totar, "%s\n", SIZE_PKG_FNAME);
                    146:        }
                    147:        if (SizeAll) {
                    148:                (void) fprintf(totar, "%s\n", SIZE_ALL_FNAME);
                    149:        }
1.2     ! jschauma  150:        if (Preserve) {
        !           151:                (void) fprintf(totar, "%s\n", PRESERVE_FNAME);
        !           152:        }
1.1       schmonz   153:
                    154:        for (p = plist->head; p; p = p->next) {
                    155:                if (p->type == PLIST_FILE) {
                    156:                        fprintf(totar, "%s\n", p->name);
                    157:                } else if (p->type == PLIST_CWD || p->type == PLIST_SRC) {
                    158:
                    159:                        /* XXX let PLIST_SRC override PLIST_CWD */
                    160:                        if (p->type == PLIST_CWD && p->next != NULL &&
                    161:                            p->next->type == PLIST_SRC) {
                    162:                                continue;
                    163:                        }
                    164:
                    165:                        fprintf(totar, "-C\n%s\n", p->name);
                    166:                } else if (p->type == PLIST_IGNORE) {
                    167:                        p = p->next;
                    168:                }
                    169:        }
                    170:
                    171:        fclose(totar);
                    172:        wait(&ret);
                    173:        /* assume either signal or bad exit is enough for us */
                    174:        if (ret) {
                    175:                cleanup(0);
                    176:                errx(2, "%s command failed with code %d", TAR_FULLPATHNAME, ret);
                    177:        }
                    178: }
                    179:
                    180: static void
                    181: sanity_check(void)
                    182: {
                    183:        if (!Comment) {
                    184:                cleanup(0);
                    185:                errx(2, "required package comment string is missing (-c comment)");
                    186:        }
                    187:        if (!Desc) {
                    188:                cleanup(0);
                    189:                errx(2, "required package description string is missing (-d desc)");
                    190:        }
                    191:        if (!Contents) {
                    192:                cleanup(0);
                    193:                errx(2, "required package contents list is missing (-f [-]file)");
                    194:        }
                    195: }
                    196:
                    197:
                    198: /*
                    199:  * Clean up those things that would otherwise hang around
                    200:  */
                    201: void
                    202: cleanup(int sig)
                    203: {
                    204:        static int alreadyCleaning;
                    205:        void    (*oldint) (int);
                    206:        void    (*oldhup) (int);
                    207:        oldint = signal(SIGINT, SIG_IGN);
                    208:        oldhup = signal(SIGHUP, SIG_IGN);
                    209:
                    210:        if (!alreadyCleaning) {
                    211:                alreadyCleaning = 1;
                    212:                if (sig)
                    213:                        printf("Signal %d received, cleaning up.\n", sig);
                    214:                leave_playpen(Home);
                    215:                if (sig)
                    216:                        exit(1);
                    217:        }
                    218:        signal(SIGINT, oldint);
                    219:        signal(SIGHUP, oldhup);
                    220: }
                    221:
                    222: int
                    223: pkg_perform(lpkg_head_t *pkgs)
                    224: {
                    225:        const char *pkg;
                    226:        char   *cp;
                    227:        FILE   *pkg_in, *fp;
                    228:        package_t plist;
                    229:        char   *suffix;         /* What we tack on to the end of the finished package */
                    230:        lpkg_t *lpp;
                    231:        char    installed[FILENAME_MAX];
                    232:
                    233:        lpp = TAILQ_FIRST(pkgs);
                    234:        pkg = lpp->lp_name;     /* Only one arg to create */
                    235:
                    236:        /* Preliminary setup */
                    237:        sanity_check();
                    238:        if (Verbose && !PlistOnly)
                    239:                printf("Creating package %s\n", pkg);
                    240:        get_dash_string(&Comment);
                    241:        get_dash_string(&Desc);
                    242:        if (IS_STDIN(Contents))
                    243:                pkg_in = stdin;
                    244:        else {
                    245:                pkg_in = fopen(Contents, "r");
                    246:                if (!pkg_in) {
                    247:                        cleanup(0);
                    248:                        errx(2, "unable to open contents file '%s' for input", Contents);
                    249:                }
                    250:        }
                    251:        plist.head = plist.tail = NULL;
                    252:
                    253:        /* Break the package name into base and desired suffix (if any) */
                    254:        if ((cp = strrchr(pkg, '.')) != NULL) {
                    255:                suffix = cp + 1;
                    256:                *cp = '\0';
                    257:        } else
                    258:                suffix = "tgz";
                    259:
                    260:        /* If a SrcDir override is set, add it now */
                    261:        if (SrcDir) {
                    262:                if (Verbose && !PlistOnly)
                    263:                        printf("Using SrcDir value of %s\n", (realprefix) ? realprefix : SrcDir);
                    264:                add_plist(&plist, PLIST_SRC, SrcDir);
                    265:        }
                    266:
                    267:        /* Stick the dependencies, if any, at the top */
                    268:        if (Pkgdeps) {
                    269:                if (Verbose && !PlistOnly)
                    270:                        printf("Registering depends:");
                    271:                while (Pkgdeps) {
                    272:                        cp = strsep(&Pkgdeps, " \t\n");
                    273:                        if (*cp) {
                    274:                                if (findmatchingname(_pkgdb_getPKGDB_DIR(), cp, note_whats_installed, installed) > 0) {
                    275:                                        add_plist(&plist, PLIST_BLDDEP, installed);
                    276:                                }
                    277:                                add_plist(&plist, PLIST_PKGDEP, cp);
                    278:                                if (Verbose && !PlistOnly)
                    279:                                        printf(" %s", cp);
                    280:                        }
                    281:                }
                    282:                if (Verbose && !PlistOnly)
                    283:                        printf(".\n");
                    284:        }
                    285:
                    286:        /* Put the conflicts directly after the dependencies, if any */
                    287:        if (Pkgcfl) {
                    288:                if (Verbose && !PlistOnly)
                    289:                        printf("Registering conflicts:");
                    290:                while (Pkgcfl) {
                    291:                        cp = strsep(&Pkgcfl, " \t\n");
                    292:                        if (*cp) {
                    293:                                add_plist(&plist, PLIST_PKGCFL, cp);
                    294:                                if (Verbose && !PlistOnly)
                    295:                                        printf(" %s", cp);
                    296:                        }
                    297:                }
                    298:                if (Verbose && !PlistOnly)
                    299:                        printf(".\n");
                    300:        }
                    301:
                    302:        /* Slurp in the packing list */
                    303:        read_plist(&plist, pkg_in);
                    304:
                    305:        if (pkg_in != stdin)
                    306:                fclose(pkg_in);
                    307:
                    308:        /* Prefix should override the packing list */
                    309:        if (Prefix) {
                    310:                delete_plist(&plist, FALSE, PLIST_CWD, NULL);
                    311:                add_plist_top(&plist, PLIST_CWD, Prefix);
                    312:        }
                    313:        /*
                    314:          * Run down the list and see if we've named it, if not stick in a name
                    315:          * at the top.
                    316:          */
                    317:        if (find_plist(&plist, PLIST_NAME) == NULL) {
                    318:                add_plist_top(&plist, PLIST_NAME, basename_of(pkg));
                    319:        }
                    320:
                    321:        /*
                    322:          * We're just here for to dump out a revised plist for the FreeBSD ports
                    323:          * hack.  It's not a real create in progress.
                    324:          */
                    325:        if (PlistOnly) {
                    326:                check_list(Home, &plist, basename_of(pkg));
                    327:                write_plist(&plist, stdout, realprefix);
                    328:                exit(0);
                    329:        }
                    330:
                    331:        /* Make a directory to stomp around in */
                    332:        Home = make_playpen(PlayPen, PlayPenSize, 0);
                    333:        signal(SIGINT, cleanup);
                    334:        signal(SIGHUP, cleanup);
                    335:
                    336:        /* Make first "real contents" pass over it */
                    337:        check_list(Home, &plist, basename_of(pkg));
                    338:        (void) umask(022);      /* make sure gen'ed directories, files
                    339:                                 * don't have group or other write bits. */
                    340:
                    341:        /* Now put the release specific items in */
                    342:        add_plist(&plist, PLIST_CWD, ".");
                    343:        write_file(COMMENT_FNAME, Comment);
                    344:        add_plist(&plist, PLIST_IGNORE, NULL);
                    345:        add_plist(&plist, PLIST_FILE, COMMENT_FNAME);
                    346:        write_file(DESC_FNAME, Desc);
                    347:        add_plist(&plist, PLIST_IGNORE, NULL);
                    348:        add_plist(&plist, PLIST_FILE, DESC_FNAME);
                    349:
                    350:        if (Install) {
                    351:                copy_file(Home, Install, INSTALL_FNAME);
                    352:                add_plist(&plist, PLIST_IGNORE, NULL);
                    353:                add_plist(&plist, PLIST_FILE, INSTALL_FNAME);
                    354:        }
                    355:        if (DeInstall) {
                    356:                copy_file(Home, DeInstall, DEINSTALL_FNAME);
                    357:                add_plist(&plist, PLIST_IGNORE, NULL);
                    358:                add_plist(&plist, PLIST_FILE, DEINSTALL_FNAME);
                    359:        }
                    360:        if (Require) {
                    361:                copy_file(Home, Require, REQUIRE_FNAME);
                    362:                add_plist(&plist, PLIST_IGNORE, NULL);
                    363:                add_plist(&plist, PLIST_FILE, REQUIRE_FNAME);
                    364:        }
                    365:        if (Display) {
                    366:                copy_file(Home, Display, DISPLAY_FNAME);
                    367:                add_plist(&plist, PLIST_IGNORE, NULL);
                    368:                add_plist(&plist, PLIST_FILE, DISPLAY_FNAME);
                    369:                add_plist(&plist, PLIST_DISPLAY, DISPLAY_FNAME);
                    370:        }
                    371:        if (Mtree) {
                    372:                copy_file(Home, Mtree, MTREE_FNAME);
                    373:                add_plist(&plist, PLIST_IGNORE, NULL);
                    374:                add_plist(&plist, PLIST_FILE, MTREE_FNAME);
                    375:                add_plist(&plist, PLIST_MTREE, MTREE_FNAME);
                    376:        }
                    377:        if (BuildVersion) {
                    378:                copy_file(Home, BuildVersion, BUILD_VERSION_FNAME);
                    379:                add_plist(&plist, PLIST_IGNORE, NULL);
                    380:                add_plist(&plist, PLIST_FILE, BUILD_VERSION_FNAME);
                    381:        }
                    382:        if (BuildInfo) {
                    383:                copy_file(Home, BuildInfo, BUILD_INFO_FNAME);
                    384:                add_plist(&plist, PLIST_IGNORE, NULL);
                    385:                add_plist(&plist, PLIST_FILE, BUILD_INFO_FNAME);
                    386:        }
                    387:        if (SizePkg) {
                    388:                copy_file(Home, SizePkg, SIZE_PKG_FNAME);
                    389:                add_plist(&plist, PLIST_IGNORE, NULL);
                    390:                add_plist(&plist, PLIST_FILE, SIZE_PKG_FNAME);
                    391:        }
                    392:        if (SizeAll) {
                    393:                copy_file(Home, SizeAll, SIZE_ALL_FNAME);
                    394:                add_plist(&plist, PLIST_IGNORE, NULL);
                    395:                add_plist(&plist, PLIST_FILE, SIZE_ALL_FNAME);
1.2     ! jschauma  396:        }
        !           397:        if (Preserve) {
        !           398:                copy_file(Home, Preserve, PRESERVE_FNAME);
        !           399:                add_plist(&plist, PLIST_IGNORE, NULL);
        !           400:                add_plist(&plist, PLIST_FILE, PRESERVE_FNAME);
1.1       schmonz   401:        }
                    402:
                    403:        /* Finally, write out the packing list */
                    404:        fp = fopen(CONTENTS_FNAME, "w");
                    405:        if (!fp) {
                    406:                cleanup(0);
                    407:                errx(2, "can't open file %s for writing", CONTENTS_FNAME);
                    408:        }
                    409:        write_plist(&plist, fp, realprefix);
                    410:        if (fclose(fp)) {
                    411:                cleanup(0);
                    412:                errx(2, "error while closing %s", CONTENTS_FNAME);
                    413:        }
                    414:
                    415:        /* And stick it into a tar ball */
                    416:        make_dist(Home, pkg, suffix, &plist);
                    417:
                    418:        /* Cleanup */
                    419:        free(Comment);
                    420:        free(Desc);
                    421:        free_plist(&plist);
                    422:        leave_playpen(Home);
                    423:
                    424:        return TRUE;            /* Success */
                    425: }

CVSweb <webmaster@jp.NetBSD.org>