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/ln.c

    r2466 r3192  
    6161#include "kmkbuiltin.h"
    6262
    63 static int      fflag;                          /* Unlink existing files. */
    64 static int      hflag;                          /* Check new name for symlink first. */
    65 static int      iflag;                          /* Interactive mode. */
    66 static int      sflag;                          /* Symbolic, not hard, link. */
    67 static int      vflag;                          /* Verbose output. */
    68                                         /* System link call. */
    69 static int (*linkf)(const char *, const char *);
    70 static char     linkch;
     63/*********************************************************************************************************************************
     64*   Structures and Typedefs                                                                                                      *
     65*********************************************************************************************************************************/
     66typedef struct LNINSTANCE
     67{
     68    PKMKBUILTINCTX pCtx;
     69    int fflag;                          /* Unlink existing files. */
     70    int hflag;                          /* Check new name for symlink first. */
     71    int iflag;                          /* Interactive mode. */
     72    int sflag;                          /* Symbolic, not hard, link. */
     73    int vflag;                          /* Verbose output. */
     74    int (*linkf)(const char *, const char *); /* System link call. */
     75    char        linkch;
     76} LNINSTANCE;
     77typedef LNINSTANCE *PLNINSTANCE;
     78
    7179static struct option long_options[] =
    7280{
     
    7785
    7886
    79 static int      linkit(const char *, const char *, int);
    80 static int      usage(FILE *);
     87static int      linkit(PLNINSTANCE,const char *, const char *, int);
     88static int      usage(PKMKBUILTINCTX, int);
    8189
    8290
    8391int
    84 kmk_builtin_ln(int argc, char *argv[], char **envp)
    85 {
     92kmk_builtin_ln(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx)
     93{
     94        LNINSTANCE This;
    8695        struct stat sb;
    8796        char *sourcedir;
     
    8998
    9099        /* initialize globals. */
    91         fflag = hflag = iflag = sflag = vflag = 0;
    92         linkch = 0;
    93         linkf = NULL;
     100        This.pCtx = pCtx;
     101        This.fflag = 0;
     102        This.hflag = 0;
     103        This.iflag = 0;
     104        This.sflag = 0;
     105        This.vflag = 0;
     106        This.linkch = 0;
     107        This.linkf = NULL;
    94108
    95109        /* kmk: reset getopt() and set program name. */
    96         g_progname = argv[0];
    97110        opterr = 1;
    98111        optarg = NULL;
     
    103116                switch (ch) {
    104117                case 'f':
    105                         fflag = 1;
    106                         iflag = 0;
     118                        This.fflag = 1;
     119                        This.iflag = 0;
    107120                        break;
    108121                case 'h':
    109122                case 'n':
    110                         hflag = 1;
     123                        This.hflag = 1;
    111124                        break;
    112125                case 'i':
    113                         iflag = 1;
    114                         fflag = 0;
     126                        This.iflag = 1;
     127                        This.fflag = 0;
    115128                        break;
    116129                case 's':
    117                         sflag = 1;
     130                        This.sflag = 1;
    118131                        break;
    119132                case 'v':
    120                         vflag = 1;
     133                        This.vflag = 1;
    121134                        break;
    122135                case 261:
    123                         usage(stdout);
     136                        usage(pCtx, 0);
    124137                        return 0;
    125138                case 262:
     
    127140                case '?':
    128141                default:
    129                         return usage(stderr);
     142                        return usage(pCtx, 1);
    130143                }
    131144
     
    133146        argc -= optind;
    134147
    135         linkf = sflag ? symlink : link;
    136         linkch = sflag ? '-' : '=';
     148        This.linkf = This.sflag ? symlink : link;
     149        This.linkch = This.sflag ? '-' : '=';
    137150
    138151        switch(argc) {
    139152        case 0:
    140                 return usage(stderr);
     153                return usage(pCtx, 1);
    141154                /* NOTREACHED */
    142155        case 1:                         /* ln target */
    143                 return linkit(argv[0], ".", 1);
     156                return linkit(&This, argv[0], ".", 1);
    144157        case 2:                         /* ln target source */
    145                 return linkit(argv[0], argv[1], 0);
     158                return linkit(&This, argv[0], argv[1], 0);
    146159        default:
    147160                ;
     
    149162                                        /* ln target1 target2 directory */
    150163        sourcedir = argv[argc - 1];
    151         if (hflag && lstat(sourcedir, &sb) == 0 && S_ISLNK(sb.st_mode)) {
     164        if (This.hflag && lstat(sourcedir, &sb) == 0 && S_ISLNK(sb.st_mode)) {
    152165                /*
    153166                 * We were asked not to follow symlinks, but found one at
     
    155168                 */
    156169                errno = ENOTDIR;
    157                 return err(1, "st_mode: %s", sourcedir);
     170                return err(pCtx, 1, "st_mode: %s", sourcedir);
    158171        }
    159172        if (stat(sourcedir, &sb))
    160                 return err(1, "stat: %s", sourcedir);
     173                return err(pCtx, 1, "stat: %s", sourcedir);
    161174        if (!S_ISDIR(sb.st_mode))
    162                 return usage(stderr);
     175                return usage(pCtx, 1);
    163176        for (exitval = 0; *argv != sourcedir; ++argv)
    164                 exitval |= linkit(*argv, sourcedir, 1);
     177                exitval |= linkit(&This, *argv, sourcedir, 1);
    165178        return exitval;
    166179}
    167180
    168181static int
    169 linkit(const char *target, const char *source, int isdir)
     182linkit(PLNINSTANCE pThis, const char *target, const char *source, int isdir)
    170183{
    171184        struct stat sb;
     
    174187        char path[PATH_MAX];
    175188
    176         if (!sflag) {
     189        if (!pThis->sflag) {
    177190                /* If target doesn't exist, quit now. */
    178191                if (stat(target, &sb)) {
    179                         warn("stat: %s", target);
     192                        warn(pThis->pCtx, "stat: %s", target);
    180193                        return (1);
    181194                }
     
    183196                if (S_ISDIR(sb.st_mode)) {
    184197                        errno = EISDIR;
    185                         warn("st_mode: %s", target);
     198                        warn(pThis->pCtx, "st_mode: %s", target);
    186199                        return (1);
    187200                }
     
    194207        if (isdir ||
    195208            (lstat(source, &sb) == 0 && S_ISDIR(sb.st_mode)) ||
    196             (!hflag && stat(source, &sb) == 0 && S_ISDIR(sb.st_mode))) {
     209            (!pThis->hflag && stat(source, &sb) == 0 && S_ISDIR(sb.st_mode))) {
    197210#if defined(_MSC_VER) || defined(__OS2__)
    198211                char *p2 = strrchr(target, '\\');
     
    210223                    (ssize_t)sizeof(path)) {
    211224                        errno = ENAMETOOLONG;
    212                         warn("snprintf: %s", target);
     225                        warn(pThis->pCtx, "snprintf: %s", target);
    213226                        return (1);
    214227                }
     
    221234         * and interactively if -i was specified.
    222235         */
    223         if (fflag && exists) {
     236        if (pThis->fflag && exists) {
    224237                if (unlink(source)) {
    225                         warn("unlink: %s", source);
    226                         return (1);
    227                 }
    228         } else if (iflag && exists) {
     238                        warn(pThis->pCtx, "unlink: %s", source);
     239                        return (1);
     240                }
     241        } else if (pThis->iflag && exists) {
    229242                fflush(stdout);
    230243                fprintf(stderr, "replace %s? ", source);
     
    234247                        ch = getchar();
    235248                if (first != 'y' && first != 'Y') {
    236                         fprintf(stderr, "not replaced\n");
     249                        kmk_builtin_ctx_printf(pThis->pCtx, 1, "not replaced\n");
    237250                        return (1);
    238251                }
    239252
    240253                if (unlink(source)) {
    241                         warn("unlink: %s", source);
     254                        warn(pThis->pCtx, "unlink: %s", source);
    242255                        return (1);
    243256                }
     
    245258
    246259        /* Attempt the link. */
    247         if ((*linkf)(target, source)) {
    248                 warn("%s: %s", linkf == link ? "link" : "symlink", source);
     260        if ((*pThis->linkf)(target, source)) {
     261                warn(pThis->pCtx, "%s: %s", pThis->linkf == link ? "link" : "symlink", source);
    249262                return (1);
    250263        }
    251         if (vflag)
    252                 (void)printf("%s %c> %s\n", source, linkch, target);
     264        if (pThis->vflag)
     265                kmk_builtin_ctx_printf(pThis->pCtx, 0, "%s %c> %s\n", source, pThis->linkch, target);
    253266        return (0);
    254267}
    255268
    256269static int
    257 usage(FILE *pf)
    258 {
    259         fprintf(pf, "usage: %s [-fhinsv] source_file [target_file]\n"
    260                                 "   or: %s [-fhinsv] source_file ... target_dir\n"
    261                 "   or: %s source_file target_file\n"
    262                                 "   or: %s --help\n"
    263                                 "   or: %s --version\n",
    264                 g_progname, g_progname, g_progname, g_progname, g_progname);
     270usage(PKMKBUILTINCTX pCtx, int fIsErr)
     271{
     272        kmk_builtin_ctx_printf(pCtx,fIsErr,
     273                "usage: %s [-fhinsv] source_file [target_file]\n"
     274                "   or: %s [-fhinsv] source_file ... target_dir\n"
     275                "   or: %s source_file target_file\n"
     276                "   or: %s --help\n"
     277                "   or: %s --version\n",
     278                pCtx->pszProgName, pCtx->pszProgName, pCtx->pszProgName,
     279                pCtx->pszProgName, pCtx->pszProgName);
    265280        return 1;
    266281}
     282
     283#ifdef KMK_BUILTIN_STANDALONE
     284int main(int argc, char **argv, char **envp)
     285{
     286        KMKBUILTINCTX Ctx = { "kmk_ln", NULL };
     287        return kmk_builtin_ln(argc, argv, envp, &Ctx);
     288}
     289#endif
     290
Note: See TracChangeset for help on using the changeset viewer.