Ignore:
Timestamp:
Mar 26, 2018, 10:25:56 PM (7 years ago)
Author:
bird
Message:

kmkbuiltin: funnel output thru output.c (usually via err.c).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kmkbuiltin/install.c

    r3145 r3192  
    122122#endif
    123123
    124 static gid_t gid;
    125 static uid_t uid;
    126 static int dobackup, docompare, dodir, dopreserve, dostrip, nommap, safecopy, verbose, mode_given;
    127 static mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
    128 static const char *suffix = BACKUP_SUFFIX;
    129 static int ignore_perm_errors;
    130 static int hard_link_files_when_possible;
    131 static int dos2unix;
    132 
     124/*********************************************************************************************************************************
     125*   Structures and Typedefs                                                                                                      *
     126*********************************************************************************************************************************/
     127typedef struct INSTALLINSTANCE
     128{
     129    PKMKBUILTINCTX pCtx;
     130
     131    gid_t gid;
     132    uid_t uid;
     133    int dobackup, docompare, dodir, dopreserve, dostrip, nommap, safecopy, verbose, mode_given;
     134    mode_t mode;
     135    const char *suffix;
     136    int ignore_perm_errors;
     137    int hard_link_files_when_possible;
     138    int dos2unix;
     139} INSTALLINSTANCE;
     140typedef INSTALLINSTANCE *PINSTALLINSTANCE;
     141
     142
     143/*********************************************************************************************************************************
     144*   Global Variables                                                                                                             *
     145*********************************************************************************************************************************/
    133146static struct option long_options[] =
    134147{
     
    145158
    146159
    147 static int      copy(int, const char *, int *, const char *);
     160static int      copy(PINSTALLINSTANCE, int, const char *, int *, const char *);
    148161static int      compare(int, size_t, int, size_t);
    149 static int      create_newfile(const char *, int, struct stat *);
     162static int      create_newfile(PINSTALLINSTANCE, const char *, int, struct stat *);
    150163static int      create_tempfile(const char *, char *, size_t);
    151 static int      install(const char *, const char *, u_long, u_int);
    152 static int      install_dir(char *);
    153 static u_long   numeric_id(const char *, const char *);
    154 static int      strip(const char *);
    155 static int      usage(FILE *);
     164static int      install(PINSTALLINSTANCE, const char *, const char *, u_long, u_int);
     165static int      install_dir(PINSTALLINSTANCE, char *);
     166static u_long   numeric_id(PINSTALLINSTANCE, const char *, const char *);
     167static int      strip(PINSTALLINSTANCE, const char *);
     168static int      usage(PKMKBUILTINCTX, int);
    156169static char    *last_slash(const char *);
    157170static KBOOL    needs_dos2unix_conversion(const char *pszFilename);
     
    159172
    160173int
    161 kmk_builtin_install(int argc, char *argv[], char ** envp)
    162 {
     174kmk_builtin_install(int argc, char *argv[], char ** envp, PKMKBUILTINCTX pCtx)
     175{
     176        INSTALLINSTANCE This;
    163177        struct stat from_sb, to_sb;
    164178        mode_t *set;
     
    170184        (void)envp;
    171185
    172         /* reinitialize globals */
    173         mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
    174         suffix = BACKUP_SUFFIX;
    175         gid = 0;
    176         uid = 0;
    177         dobackup = docompare = dodir = dopreserve = dostrip = nommap = safecopy = verbose = mode_given = 0;
    178         ignore_perm_errors = geteuid() != 0;
    179         hard_link_files_when_possible = 0;
    180         dos2unix = 0;
     186        /* Initialize global instance data. */
     187        This.pCtx = pCtx;
     188        This.mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
     189        This.suffix = BACKUP_SUFFIX;
     190        This.gid = 0;
     191        This.uid = 0;
     192        This.dobackup = 0;
     193        This.docompare = 0;
     194        This.dodir = 0;
     195        This.dopreserve = 0;
     196        This.dostrip = 0;
     197        This.nommap = 0;
     198        This.safecopy = 0;
     199        This.verbose = 0;
     200        This.mode_given = 0;
     201        This.ignore_perm_errors = geteuid() != 0;
     202        This.hard_link_files_when_possible = 0;
     203        This.dos2unix = 0;
    181204
    182205        /* reset getopt and set progname. */
    183         g_progname = argv[0];
    184206        opterr = 1;
    185207        optarg = NULL;
     
    192214                switch(ch) {
    193215                case 'B':
    194                         suffix = optarg;
     216                        This.suffix = optarg;
    195217                        /* FALLTHROUGH */
    196218                case 'b':
    197                         dobackup = 1;
     219                        This.dobackup = 1;
    198220                        break;
    199221                case 'C':
    200                         docompare = 1;
     222                        This.docompare = 1;
    201223                        break;
    202224                case 'c':
     
    204226                        break;
    205227                case 'd':
    206                         dodir = 1;
     228                        This.dodir = 1;
    207229                        break;
    208230                case 'f':
     
    210232                        flags = optarg;
    211233                        if (strtofflags(&flags, &fset, NULL))
    212                                 return errx(EX_USAGE, "%s: invalid flag", flags);
     234                                return errx(pCtx, EX_USAGE, "%s: invalid flag", flags);
    213235                        iflags |= SETFLAGS;
    214236#else
     
    220242                        break;
    221243                case 'M':
    222                         nommap = 1;
     244                        This.nommap = 1;
    223245                        break;
    224246                case 'm':
    225247                        if (!(set = bsd_setmode(optarg)))
    226                                 return errx(EX_USAGE, "invalid file mode: %s",
    227                                             optarg);
    228                         mode = bsd_getmode(set, 0);
     248                                return errx(pCtx, EX_USAGE, "invalid file mode: %s", optarg);
     249                        This.mode = bsd_getmode(set, 0);
    229250                        free(set);
    230                         mode_given = 1;
     251                        This.mode_given = 1;
    231252                        break;
    232253                case 'o':
     
    234255                        break;
    235256                case 'p':
    236                         docompare = dopreserve = 1;
     257                        This.docompare = This.dopreserve = 1;
    237258                        break;
    238259                case 'S':
    239                         safecopy = 1;
     260                        This.safecopy = 1;
    240261                        break;
    241262                case 's':
    242                         dostrip = 1;
     263                        This.dostrip = 1;
    243264                        break;
    244265                case 'v':
    245                         verbose = 1;
     266                        This.verbose = 1;
    246267                        break;
    247268                case 261:
    248                         usage(stdout);
     269                        usage(pCtx, 0);
    249270                        return 0;
    250271                case 262:
    251272                        return kbuild_version(argv[0]);
    252273                case 263:
    253                         ignore_perm_errors = 1;
     274                        This.ignore_perm_errors = 1;
    254275                        break;
    255276                case 264:
    256                         ignore_perm_errors = 0;
     277                        This.ignore_perm_errors = 0;
    257278                        break;
    258279                case 265:
    259                         hard_link_files_when_possible = 1;
     280                        This.hard_link_files_when_possible = 1;
    260281                        break;
    261282                case 266:
    262                         hard_link_files_when_possible = 0;
     283                        This.hard_link_files_when_possible = 0;
    263284                        break;
    264285                case 267:
    265                         dos2unix = 1;
     286                        This.dos2unix = 1;
    266287                        break;
    267288                case 268:
    268                         dos2unix = -1;
     289                        This.dos2unix = -1;
    269290                        break;
    270291                case '?':
    271292                default:
    272                         return usage(stderr);
     293                        return usage(pCtx, 1);
    273294                }
    274295        argc -= optind;
     
    276297
    277298        /* some options make no sense when creating directories */
    278         if (dostrip && dodir) {
    279                 warnx("-d and -s may not be specified together");
    280                 return usage(stderr);
     299        if (This.dostrip && This.dodir) {
     300                warnx(pCtx, "-d and -s may not be specified together");
     301                return usage(pCtx, 1);
    281302        }
    282303
    283304        /* must have at least two arguments, except when creating directories */
    284         if (argc == 0 || (argc == 1 && !dodir))
    285                 return usage(stderr);
     305        if (argc == 0 || (argc == 1 && !This.dodir))
     306                return usage(pCtx, 1);
    286307
    287308        /*   and unix2dos doesn't combine well with a couple of other options. */
    288         if (dos2unix != 0) {
    289                 if (docompare) {
    290                         warnx("-C/-p and --dos2unix/unix2dos may not be specified together");
    291                         return usage(stderr);
    292                 }
    293                 if (dostrip) {
    294                         warnx("-s and --dos2unix/unix2dos may not be specified together");
    295                         return usage(stderr);
     309        if (This.dos2unix != 0) {
     310                if (This.docompare) {
     311                        warnx(pCtx, "-C/-p and --dos2unix/unix2dos may not be specified together");
     312                        return usage(pCtx, 1);
     313                }
     314                if (This.dostrip) {
     315                        warnx(pCtx, "-s and --dos2unix/unix2dos may not be specified together");
     316                        return usage(pCtx, 1);
    296317                }
    297318        }
    298319
    299320        /* need to make a temp copy so we can compare stripped version */
    300         if (docompare && dostrip)
    301                 safecopy = 1;
     321        if (This.docompare && This.dostrip)
     322                This.safecopy = 1;
    302323
    303324        /* get group and owner id's */
     
    310331#endif
    311332                {
    312                         gid = (gid_t)numeric_id(group, "group");
    313                         if (gid == (gid_t)-1)
     333                        This.gid = (gid_t)numeric_id(&This, group, "group");
     334                        if (This.gid == (gid_t)-1)
    314335                                return 1;
    315336                }
    316337        } else
    317                 gid = (gid_t)-1;
     338                This.gid = (gid_t)-1;
    318339
    319340        if (owner != NULL) {
     
    325346#endif
    326347                {
    327                         uid = (uid_t)numeric_id(owner, "user");
    328                         if (uid == (uid_t)-1)
     348                        This.uid = (uid_t)numeric_id(&This, owner, "user");
     349                        if (This.uid == (uid_t)-1)
    329350                                return 1;
    330351                }
    331352        } else
    332                 uid = (uid_t)-1;
    333 
    334         if (dodir) {
     353                This.uid = (uid_t)-1;
     354
     355        if (This.dodir) {
    335356                for (; *argv != NULL; ++argv) {
    336                         int rc = install_dir(*argv);
     357                        int rc = install_dir(&This, *argv);
    337358                        if (rc)
    338359                                return rc;
     
    345366        if (!no_target && S_ISDIR(to_sb.st_mode)) {
    346367                for (; *argv != to_name; ++argv) {
    347                         int rc = install(*argv, to_name, fset, iflags | DIRECTORY);
     368                        int rc = install(&This, *argv, to_name, fset, iflags | DIRECTORY);
    348369                        if (rc)
    349370                                return rc;
     
    354375        /* can't do file1 file2 directory/file */
    355376        if (argc != 2) {
    356                 warnx("wrong number or types of arguments");
    357                 return usage(stderr);
     377                warnx(pCtx, "wrong number or types of arguments");
     378                return usage(pCtx, 1);
    358379        }
    359380
    360381        if (!no_target) {
    361382                if (stat(*argv, &from_sb))
    362                         return err(EX_OSERR, "%s", *argv);
     383                        return err(pCtx, EX_OSERR, "%s", *argv);
    363384                if (!S_ISREG(to_sb.st_mode)) {
    364385                        errno = EFTYPE;
    365                         return err(EX_OSERR, "%s", to_name);
     386                        return err(pCtx, EX_OSERR, "%s", to_name);
    366387                }
    367388                if (to_sb.st_dev == from_sb.st_dev &&
     
    369390                    to_sb.st_ino == from_sb.st_ino &&
    370391                    to_sb.st_ino != 0 &&
    371                     !hard_link_files_when_possible)
    372                         return errx(EX_USAGE,
     392                    !This.hard_link_files_when_possible)
     393                        return errx(pCtx, EX_USAGE,
    373394                                    "%s and %s are the same file", *argv, to_name);
    374395        }
    375         return install(*argv, to_name, fset, iflags);
    376 }
     396        return install(&This, *argv, to_name, fset, iflags);
     397}
     398
     399#ifdef KMK_BUILTIN_STANDALONE
     400int main(int argc, char **argv, char **envp)
     401{
     402        KMKBUILTINCTX Ctx = { "kmk_install", NULL };
     403        return kmk_builtin_install(argc, argv, envp, &Ctx);
     404}
     405#endif
    377406
    378407static u_long
    379 numeric_id(const char *name, const char *type)
     408numeric_id(PINSTALLINSTANCE pThis, const char *name, const char *type)
    380409{
    381410        u_long val;
     
    389418        val = strtoul(name, &ep, 10);
    390419        if (errno)
    391                 return err(-1, "%s", name);
     420                return err(pThis->pCtx, -1, "%s", name);
    392421        if (*ep != '\0')
    393                 return errx(-1, "unknown %s %s", type, name);
     422                return errx(pThis->pCtx, -1, "unknown %s %s", type, name);
    394423        return (val);
    395424}
     
    400429 */
    401430static int
    402 install(const char *from_name, const char *to_name, u_long fset, u_int flags)
     431install(PINSTALLINSTANCE pThis, const char *from_name, const char *to_name, u_long fset, u_int flags)
    403432{
    404433        struct stat from_sb, temp_sb, to_sb;
     
    428457            ) {
    429458                if (stat(from_name, &from_sb))
    430                         return err(EX_OSERR, "%s", from_name);
     459                        return err(pThis->pCtx, EX_OSERR, "%s", from_name);
    431460                if (!S_ISREG(from_sb.st_mode)) {
    432461                        errno = EFTYPE;
    433                         return err(EX_OSERR, "%s", from_name);
     462                        return err(pThis->pCtx, EX_OSERR, "%s", from_name);
    434463                }
    435464                /* Build the target path. */
     
    450479        if (target && !S_ISREG(to_sb.st_mode)) {
    451480                errno = EFTYPE;
    452                 warn("%s", to_name);
     481                warn(pThis->pCtx, "%s", to_name);
    453482                return EX_OK;
    454483        }
    455484
    456485        /* Only copy safe if the target exists. */
    457         tempcopy = safecopy && target;
     486        tempcopy = pThis->safecopy && target;
    458487
    459488        /* Try hard linking if wanted and possible. */
    460         if (hard_link_files_when_possible)
     489        if (pThis->hard_link_files_when_possible)
    461490        {
    462491#ifdef KBUILD_OS_OS2
     
    466495                if (devnull) {
    467496                        why_not = "/dev/null";
    468                 } else if (dostrip) {
     497                } else if (pThis->dostrip) {
    469498                        why_not = "strip (-s)";
    470                 } else if (docompare) {
     499                } else if (pThis->docompare) {
    471500                        why_not = "compare (-C)";
    472                 } else if (dobackup) {
     501                } else if (pThis->dobackup) {
    473502                        why_not = "backup (-b/-B)";
    474                 } else if (safecopy) {
     503                } else if (pThis->safecopy) {
    475504                        why_not = "safe copy (-S)";
    476505                } else if (lstat(from_name, &temp_sb)) {
     
    481510                        why_not = "not regular file";
    482511# if defined(KBUILD_OS_WINDOWS) || defined(KBUILD_OS_OS2)
    483                 } else if ((mode & S_IWUSR) != (from_sb.st_mode & S_IWUSR)) {
     512                } else if ((pThis->mode & S_IWUSR) != (from_sb.st_mode & S_IWUSR)) {
    484513# else
    485                 } else if (mode != (from_sb.st_mode & ALLPERMS)) {
     514                } else if (pThis->mode != (from_sb.st_mode & ALLPERMS)) {
    486515# endif
    487                         printf("install: warning: Not hard linking, mode differs: 0%03o, desires 0%03o\n"
    488                                "install: src path '%s'\n"
    489                                "install: dst path '%s'\n",
    490                                (from_sb.st_mode & ALLPERMS), mode, from_name, to_name);
     516                        kmk_builtin_ctx_printf(pThis->pCtx, 0,
     517                                "install: warning: Not hard linking, mode differs: 0%03o, desires 0%03o\n"
     518                                "install: src path '%s'\n"
     519                                "install: dst path '%s'\n",
     520                                (from_sb.st_mode & ALLPERMS), pThis->mode, from_name, to_name);
    491521                        why_not = NULL;
    492                 } else if (uid != (uid_t)-1 && gid != from_sb.st_uid) {
     522                } else if (pThis->uid != (uid_t)-1 && pThis->uid != from_sb.st_uid) {
    493523                        why_not = "uid mismatch";
    494                 } else if (gid != (gid_t)-1 && gid != from_sb.st_gid) {
     524                } else if (pThis->gid != (gid_t)-1 && pThis->gid != from_sb.st_gid) {
    495525                        why_not = "gid mismatch";
    496                 } else if (dos2unix > 0 && needs_dos2unix_conversion(from_name)) {
     526                } else if (pThis->dos2unix > 0 && needs_dos2unix_conversion(from_name)) {
    497527                        why_not = "dos2unix";
    498                 } else if (dos2unix < 0 && needs_unix2dos_conversion(from_name)) {
     528                } else if (pThis->dos2unix < 0 && needs_unix2dos_conversion(from_name)) {
    499529                        why_not = "unix2dos";
    500530                } else {
     
    505535                        }
    506536                        if (rcLink == 0) {
    507                             if (verbose)
    508                                     printf("install: %s -> %s (hardlinked)\n", from_name, to_name);
     537                            if (pThis->verbose)
     538                                    kmk_builtin_ctx_printf(pThis->pCtx, 0,
     539                                                           "install: %s -> %s (hardlinked)\n", from_name, to_name);
    509540                            goto l_done;
    510541                        }
    511                         if (verbose)
    512                                 printf("install: hard linking '%s' to '%s' failed: %s\n",
     542                        if (pThis->verbose)
     543                                kmk_builtin_ctx_printf(pThis->pCtx, 0, "install: hard linking '%s' to '%s' failed: %s\n",
    513544                                       to_name, from_name, strerror(errno));
    514545                        why_not = NULL;
    515546                }
    516547#endif
    517                 if (verbose && why_not)
    518                     printf("install: not hard linking '%s' to '%s' because: %s\n",
    519                            to_name, from_name, why_not);
     548                if (pThis->verbose && why_not)
     549                    kmk_builtin_ctx_printf(pThis->pCtx, 0, "install: not hard linking '%s' to '%s' because: %s\n",
     550                                           to_name, from_name, why_not);
    520551
    521552                /* Can't hard link or we failed, continue as nothing happend. */
     
    523554
    524555        if (!devnull && (from_fd = open(from_name, O_RDONLY | O_BINARY, 0)) < 0)
    525                 return err(EX_OSERR, "%s", from_name);
     556                return err(pThis->pCtx, EX_OSERR, "%s", from_name);
    526557
    527558        /* If we don't strip, we can compare first. */
    528         if (docompare && !dostrip && target) {
     559        if (pThis->docompare && !pThis->dostrip && target) {
    529560                if ((to_fd = open(to_name, O_RDONLY | O_BINARY, 0)) < 0) {
    530                         rc = err(EX_OSERR, "%s", to_name);
     561                        rc = err(pThis->pCtx, EX_OSERR, "%s", to_name);
    531562                        goto l_done;
    532563                }
     
    549580                            sizeof(tempfile));
    550581                        if (to_fd < 0) {
    551                                 rc = err(EX_OSERR, "%s", tempfile);
     582                                rc = err(pThis->pCtx, EX_OSERR, "%s", tempfile);
    552583                                goto l_done;
    553584                        }
    554585                } else {
    555                         if ((to_fd = create_newfile(to_name, target,
    556                             &to_sb)) < 0) {
    557                                 rc = err(EX_OSERR, "%s", to_name);
     586                        if ((to_fd = create_newfile(pThis, to_name, target, &to_sb)) < 0) {
     587                                rc = err(pThis->pCtx, EX_OSERR, "%s", to_name);
    558588                                goto l_done;
    559589                        }
    560                         if (verbose)
    561                                 (void)printf("install: %s -> %s\n",
    562                                     from_name, to_name);
     590                        if (pThis->verbose)
     591                                kmk_builtin_ctx_printf(pThis->pCtx, 0, "install: %s -> %s\n", from_name, to_name);
    563592                }
    564593                if (!devnull) {
    565                         rc = copy(from_fd, from_name, &to_fd, tempcopy ? tempfile : to_name);
     594                        rc = copy(pThis, from_fd, from_name, &to_fd, tempcopy ? tempfile : to_name);
    566595                        if (rc)
    567596                                goto l_done;
     
    569598        }
    570599
    571         if (dostrip) {
     600        if (pThis->dostrip) {
    572601#if defined(__EMX__) || defined(_MSC_VER)
    573602                /* close before we strip. */
     
    575604                to_fd = -1;
    576605#endif
    577                 rc = strip(tempcopy ? tempfile : to_name);
     606                rc = strip(pThis, tempcopy ? tempfile : to_name);
    578607                if (rc)
    579608                        goto l_done;
     
    588617                to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY | O_BINARY, 0);
    589618                if (to_fd < 0) {
    590                         rc = err(EX_OSERR, "stripping %s", to_name);
     619                        rc = err(pThis->pCtx, EX_OSERR, "stripping %s", to_name);
    591620                        goto l_done;
    592621                }
     
    596625         * Compare the stripped temp file with the target.
    597626         */
    598         if (docompare && dostrip && target) {
     627        if (pThis->docompare && pThis->dostrip && target) {
    599628                temp_fd = to_fd;
    600629
    601630                /* Re-open to_fd using the real target name. */
    602631                if ((to_fd = open(to_name, O_RDONLY | O_BINARY, 0)) < 0) {
    603                         rc = err(EX_OSERR, "%s", to_name);
     632                        rc = err(pThis->pCtx, EX_OSERR, "%s", to_name);
    604633                        goto l_done;
    605634                }
     
    609638                        (void)unlink(tempfile);
    610639                        errno = serrno;
    611                         rc = err(EX_OSERR, "%s", tempfile);
     640                        rc = err(pThis->pCtx, EX_OSERR, "%s", tempfile);
    612641                        goto l_done;
    613642                }
     
    649678                        (void)chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS);
    650679#endif
    651                 if (dobackup) {
    652                         if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s", to_name,
    653                             suffix) != strlen(to_name) + strlen(suffix)) {
     680                if (pThis->dobackup) {
     681                        if (   (size_t)snprintf(backup, MAXPATHLEN, "%s%s", to_name, pThis->suffix)
     682                            != strlen(to_name) + strlen(pThis->suffix)) {
    654683                                unlink(tempfile);
    655                                 rc = errx(EX_OSERR, "%s: backup filename too long",
     684                                rc = errx(pThis->pCtx, EX_OSERR, "%s: backup filename too long",
    656685                                          to_name);
    657686                                goto l_done;
    658687                        }
    659                         if (verbose)
    660                                 (void)printf("install: %s -> %s\n", to_name, backup);
     688                        if (pThis->verbose)
     689                                kmk_builtin_ctx_printf(pThis->pCtx, 0, "install: %s -> %s\n", to_name, backup);
    661690                        if (rename(to_name, backup) < 0) {
    662691                                serrno = errno;
    663692                                unlink(tempfile);
    664693                                errno = serrno;
    665                                 rc = err(EX_OSERR, "rename: %s to %s", to_name,
     694                                rc = err(pThis->pCtx, EX_OSERR, "rename: %s to %s", to_name,
    666695                                         backup);
    667696                                goto l_done;
    668697                        }
    669698                }
    670                 if (verbose)
    671                         (void)printf("install: %s -> %s\n", from_name, to_name);
     699                if (pThis->verbose)
     700                        kmk_builtin_ctx_printf(pThis->pCtx, 0, "install: %s -> %s\n", from_name, to_name);
    672701                if (rename(tempfile, to_name) < 0) {
    673702                        serrno = errno;
    674703                        unlink(tempfile);
    675704                        errno = serrno;
    676                         rc = err(EX_OSERR, "rename: %s to %s",
    677                                  tempfile, to_name);
     705                        rc = err(pThis->pCtx, EX_OSERR, "rename: %s to %s", tempfile, to_name);
    678706                        goto l_done;
    679707                }
     
    682710                (void) close(to_fd);
    683711                if ((to_fd = open(to_name, O_RDONLY | O_BINARY, 0)) < 0) {
    684                         rc = err(EX_OSERR, "%s", to_name);
     712                        rc = err(pThis->pCtx, EX_OSERR, "%s", to_name);
    685713                        goto l_done;
    686714                }
     
    690718         * Preserve the timestamp of the source file if necessary.
    691719         */
    692         if (dopreserve && !files_match && !devnull) {
     720        if (pThis->dopreserve && !files_match && !devnull) {
    693721                tvb[0].tv_sec = from_sb.st_atime;
    694722                tvb[0].tv_usec = 0;
     
    702730                (void)unlink(to_name);
    703731                errno = serrno;
    704                 rc = err(EX_OSERR, "%s", to_name);
     732                rc = err(pThis->pCtx, EX_OSERR, "%s", to_name);
    705733                goto l_done;
    706734        }
     
    720748#endif
    721749
    722         if ((gid != (gid_t)-1 && gid != to_sb.st_gid) ||
    723             (uid != (uid_t)-1 && uid != to_sb.st_uid))
    724                 if (fchown(to_fd, uid, gid) == -1) {
    725                         if (errno == EPERM && ignore_perm_errors) {
    726                                 warn("%s: ignoring chown uid=%d gid=%d failure", to_name, (int)uid, (int)gid);
     750        if ((pThis->gid != (gid_t)-1 && pThis->gid != to_sb.st_gid) ||
     751            (pThis->uid != (uid_t)-1 && pThis->uid != to_sb.st_uid))
     752                if (fchown(to_fd, pThis->uid, pThis->gid) == -1) {
     753                        if (errno == EPERM && pThis->ignore_perm_errors) {
     754                                warn(pThis->pCtx, "%s: ignoring chown uid=%d gid=%d failure",
     755                                     to_name, (int)pThis->uid, (int)pThis->gid);
    727756                        } else {
    728757                                serrno = errno;
    729758                                (void)unlink(to_name);
    730759                                errno = serrno;
    731                                 rc = err(EX_OSERR,"%s: chown/chgrp", to_name);
     760                                rc = err(pThis->pCtx, EX_OSERR,"%s: chown/chgrp", to_name);
    732761                                goto l_done;
    733762                        }
    734763                }
    735764
    736         if (mode != (to_sb.st_mode & ALLPERMS))
    737                 if (fchmod(to_fd, mode)) {
     765        if (pThis->mode != (to_sb.st_mode & ALLPERMS))
     766                if (fchmod(to_fd, pThis->mode)) {
    738767                        serrno = errno;
    739                         if (serrno == EPERM && ignore_perm_errors) {
    740                                 fchmod(to_fd, mode & (ALLPERMS & ~0007000));
     768                        if (serrno == EPERM && pThis->ignore_perm_errors) {
     769                                fchmod(to_fd, pThis->mode & (ALLPERMS & ~0007000));
    741770                                errno = errno;
    742                                 warn("%s: ignoring chmod 0%o failure", to_name, (int)(mode & ALLPERMS));
     771                                warn(pThis->pCtx, "%s: ignoring chmod 0%o failure", to_name, (int)(pThis->mode & ALLPERMS));
    743772                        } else  {
    744773                                serrno = errno;
    745774                                (void)unlink(to_name);
    746775                                errno = serrno;
    747                                 rc = err(EX_OSERR, "%s: chmod", to_name);
     776                                rc = err(pThis->pCtx, EX_OSERR, "%s: chmod", to_name);
    748777                                goto l_done;
    749778                        }
     
    758787         */
    759788#ifdef UF_IMMUTABLE
    760         if (!devnull && (flags & SETFLAGS ||
    761             (from_sb.st_flags & ~UF_NODUMP) != to_sb.st_flags) &&
    762             fchflags(to_fd,
    763             flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) {
     789        if (   !devnull
     790            && (flags & SETFLAGS || (from_sb.st_flags & ~UF_NODUMP) != to_sb.st_flags)
     791            && fchflags(to_fd, flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) {
    764792                if (flags & SETFLAGS) {
    765793                        if (errno == EOPNOTSUPP)
    766                                 warn("%s: chflags", to_name);
     794                                warn(pThis->pCtx, "%s: chflags", to_name);
    767795                        else {
    768796                                serrno = errno;
    769797                                (void)unlink(to_name);
    770798                                errno = serrno;
    771                                 rc = err(EX_OSERR, "%s: chflags", to_name);
     799                                rc = err(pThis->pCtx, EX_OSERR, "%s: chflags", to_name);
    772800                                goto l_done;
    773801                        }
     
    851879 */
    852880int
    853 create_newfile(const char *path, int target, struct stat *sbp)
     881create_newfile(PINSTALLINSTANCE pThis, const char *path, int target, struct stat *sbp)
    854882{
    855883        char backup[MAXPATHLEN];
     
    868896#endif
    869897
    870                 if (dobackup) {
    871                         if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s",
    872                             path, suffix) != strlen(path) + strlen(suffix)) {
    873                                 errx(EX_OSERR, "%s: backup filename too long",
    874                                      path);
     898                if (pThis->dobackup) {
     899                        if (   (size_t)snprintf(backup, MAXPATHLEN, "%s%s", path, pThis->suffix)
     900                            != strlen(path) + strlen(pThis->suffix)) {
     901                                errx(pThis->pCtx, EX_OSERR, "%s: backup filename too long", path);
    875902                                errno = ENAMETOOLONG;
    876903                                return -1;
    877904                        }
    878                         (void)snprintf(backup, MAXPATHLEN, "%s%s",
    879                             path, suffix);
    880                         if (verbose)
    881                                 (void)printf("install: %s -> %s\n",
    882                                     path, backup);
     905                        (void)snprintf(backup, MAXPATHLEN, "%s%s", path, pThis->suffix);
     906                        if (pThis->verbose)
     907                                kmk_builtin_ctx_printf(pThis->pCtx, 0, "install: %s -> %s\n", path, backup);
    883908                        if (rename(path, backup) < 0) {
    884                                 err(EX_OSERR, "rename: %s to %s", path, backup);
     909                                err(pThis->pCtx, EX_OSERR, "rename: %s to %s", path, backup);
    885910                                return -1;
    886911                        }
     
    899924 * Write error handler.
    900925 */
    901 static int write_error(int *ptr_to_fd, const char *to_name, int nw)
     926static int write_error(PINSTALLINSTANCE pThis, int *ptr_to_fd, const char *to_name, int nw)
    902927{
    903928    int serrno = errno;
     
    906931    (void)unlink(to_name);
    907932    errno = nw > 0 ? EIO : serrno;
    908     return err(EX_OSERR, "%s", to_name);
     933    return err(pThis->pCtx, EX_OSERR, "%s", to_name);
    909934}
    910935
     
    912937 * Read error handler.
    913938 */
    914 static int read_error(const char *from_name, int *ptr_to_fd, const char *to_name)
     939static int read_error(PINSTALLINSTANCE pThis, const char *from_name, int *ptr_to_fd, const char *to_name)
    915940{
    916941    int serrno = errno;
     
    919944    (void)unlink(to_name);
    920945    errno = serrno;
    921     return err(EX_OSERR, "%s", from_name);
     946    return err(pThis->pCtx, EX_OSERR, "%s", from_name);
    922947}
    923948
     
    927952 */
    928953static int
    929 copy(int from_fd, const char *from_name, int *ptr_to_fd, const char *to_name)
     954copy(PINSTALLINSTANCE pThis, int from_fd, const char *from_name, int *ptr_to_fd, const char *to_name)
    930955{
    931956        KBOOL fPendingCr = K_FALSE;
     
    937962        /* Rewind file descriptors. */
    938963        if (lseek(from_fd, (off_t)0, SEEK_SET) == (off_t)-1)
    939                 return err(EX_OSERR, "lseek: %s", from_name);
     964                return err(pThis->pCtx, EX_OSERR, "lseek: %s", from_name);
    940965        if (lseek(to_fd, (off_t)0, SEEK_SET) == (off_t)-1)
    941                 return err(EX_OSERR, "lseek: %s", to_name);
    942 
    943         if (dos2unix == 0) {
     966                return err(pThis->pCtx, EX_OSERR, "lseek: %s", to_name);
     967
     968        if (pThis->dos2unix == 0) {
    944969                /*
    945970                 * Copy bytes, no conversion.
     
    947972                while ((nr = read(from_fd, buf, sizeof(buf))) > 0)
    948973                        if ((nw = write(to_fd, buf, nr)) != nr)
    949                                 return write_error(ptr_to_fd, to_name, nw);
    950         } else if (dos2unix > 0) {
     974                                return write_error(pThis, ptr_to_fd, to_name, nw);
     975        } else if (pThis->dos2unix > 0) {
    951976                /*
    952977                 * CRLF -> LF is a reduction, so we can work with full buffers.
     
    956981                                && buf[0] != '\n'
    957982                                && (nw = write(to_fd, "\r", 1)) != 1)
    958                                 return write_error(ptr_to_fd, to_name, nw);
     983                                return write_error(pThis, ptr_to_fd, to_name, nw);
    959984
    960985                        fPendingCr = dos2unix_convert_to_unix(buf, nr, buf, &cchDst);
     
    962987                        nw = write(to_fd, buf, cchDst);
    963988                        if (nw != (int)cchDst)
    964                                 return write_error(ptr_to_fd, to_name, nw);
     989                                return write_error(pThis, ptr_to_fd, to_name, nw);
    965990                }
    966991        } else {
     
    9781003                                && pchSrc[0] != '\n'
    9791004                                && (nw = write(to_fd, "\r", 1))!= 1)
    980                                 return write_error(ptr_to_fd, to_name, nw);
     1005                                return write_error(pThis, ptr_to_fd, to_name, nw);
    9811006
    9821007                        fPendingCr = dos2unix_convert_to_dos(pchSrc, nr, buf, &cchDst);
     
    9841009                        nw = write(to_fd, buf, cchDst);
    9851010                        if (nw != (int)cchDst)
    986                                 return write_error(ptr_to_fd, to_name, nw);
     1011                                return write_error(pThis, ptr_to_fd, to_name, nw);
    9871012                }
    9881013        }
     
    9901015        /* Check for read error. */
    9911016        if (nr != 0)
    992                 return read_error(from_name, ptr_to_fd, to_name);
     1017                return read_error(pThis, from_name, ptr_to_fd, to_name);
    9931018
    9941019        /* When converting, we might have a pending final CR to write. */
    995     if (   fPendingCr
    996                 && (nw = write(to_fd, "\r", 1))!= 1)
    997                 return write_error(ptr_to_fd, to_name, nw);
     1020        if (   fPendingCr
     1021            && (nw = write(to_fd, "\r", 1))!= 1)
     1022                return write_error(pThis, ptr_to_fd, to_name, nw);
    9981023
    9991024    return EX_OK;
     
    10051030 */
    10061031static int
    1007 strip(const char *to_name)
     1032strip(PINSTALLINSTANCE pThis, const char *to_name)
    10081033{
    10091034#if defined(__EMX__) || defined(_MSC_VER)
     
    10111036        if (stripbin == NULL)
    10121037                stripbin = "strip";
     1038        (void)pThis;
    10131039        return spawnlp(P_WAIT, stripbin, stripbin, to_name, NULL);
    10141040#else
     
    10231049                (void)unlink(to_name);
    10241050                errno = serrno;
    1025                 return err(EX_TEMPFAIL, "fork");
     1051                return err(pThis->pCtx, EX_TEMPFAIL, "fork");
    10261052        case 0:
    10271053                stripbin = getenv("STRIPBIN");
     
    10291055                        stripbin = "strip";
    10301056                execlp(stripbin, stripbin, to_name, (char *)NULL);
    1031                 err(EX_OSERR, "exec(%s)", stripbin);
     1057                err(pThis->pCtx, EX_OSERR, "exec(%s)", stripbin);
    10321058                exit(EX_OSERR);
    10331059        default:
     
    10361062                        (void)unlink(to_name);
    10371063                        errno = serrno;
    1038                         return err(EX_SOFTWARE, "waitpid");
     1064                        return err(pThis->pCtx, EX_SOFTWARE, "waitpid");
    10391065                        /* NOTREACHED */
    10401066                }
     
    10491075 */
    10501076static int
    1051 install_dir(char *path)
     1077install_dir(PINSTALLINSTANCE pThis, char *path)
    10521078{
    10531079        char *p;
     
    10671093                        if (stat(path, &sb)) {
    10681094                                if (errno != ENOENT || mkdir(path, 0755) < 0) {
    1069                                         return err(EX_OSERR, "mkdir %s", path);
     1095                                        return err(pThis->pCtx, EX_OSERR, "mkdir %s", path);
    10701096                                        /* NOTREACHED */
    1071                                 } else if (verbose)
    1072                                         (void)printf("install: mkdir %s\n",
    1073                                                      path);
     1097                                } else if (pThis->verbose)
     1098                                        kmk_builtin_ctx_printf(pThis->pCtx, 0, "install: mkdir %s\n", path);
    10741099                        } else if (!S_ISDIR(sb.st_mode))
    1075                                 return errx(EX_OSERR, "%s exists but is not a directory", path);
     1100                                return errx(pThis->pCtx, EX_OSERR, "%s exists but is not a directory", path);
    10761101                        if (!(*p = ch))
    10771102                                break;
    10781103                }
    10791104
    1080         if ((gid != (gid_t)-1 || uid != (uid_t)-1) && chown(path, uid, gid))
    1081                 warn("chown %u:%u %s", uid, gid, path);
    1082         if (chmod(path, mode))
    1083                 warn("chmod %o %s", mode, path);
     1105        if ((pThis->gid != (gid_t)-1 || pThis->uid != (uid_t)-1) && chown(path, pThis->uid, pThis->gid))
     1106                warn(pThis->pCtx, "chown %u:%u %s", pThis->uid, pThis->gid, path);
     1107        if (chmod(path, pThis->mode))
     1108                warn(pThis->pCtx, "chmod %o %s", pThis->mode, path);
    10841109        return EX_OK;
    10851110}
     
    10901115 */
    10911116static int
    1092 usage(FILE *pf)
    1093 {
    1094         fprintf(pf,
     1117usage(PKMKBUILTINCTX pCtx, int fIsErr)
     1118{
     1119        kmk_builtin_ctx_printf(pCtx, fIsErr,
    10951120"usage: %s [-bCcpSsv] [--[no-]hard-link-files-when-possible]\n"
    10961121"            [--[no-]ignore-perm-errors] [-B suffix] [-f flags] [-g group]\n"
     
    11011126"   or: %s --help\n"
    11021127"   or: %s --version\n",
    1103                         g_progname, g_progname, g_progname, g_progname, g_progname);
     1128                pCtx->pszProgName, pCtx->pszProgName, pCtx->pszProgName,
     1129                pCtx->pszProgName, pCtx->pszProgName);
    11041130        return EX_USAGE;
    11051131}
Note: See TracChangeset for help on using the changeset viewer.