Changeset 1102 for trunk/src/kmk


Ignore:
Timestamp:
Sep 23, 2007, 5:30:49 AM (18 years ago)
Author:
bird
Message:

reorged the code. progress option.

File:
1 edited

Legend:

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

    r1101 r1102  
    2828#include <stdio.h>
    2929#include <errno.h>
     30#include <fcntl.h>
     31#ifdef _MSC_VER
     32# include <io.h>
     33#else
     34# include <unistd.h>
     35#endif
     36#include <sys/stat.h>
    3037#include "err.h"
    3138#include "kmkbuiltin.h"
    3239#include "../../lib/md5.h"
    3340
     41//#define MD5SUM_USE_STDIO
    3442
    3543
     
    3745 * Prints the usage and return 1.
    3846 */
    39 static int usage(void)
    40 {
    41     fprintf(stderr,
    42             "usage: md5sum [-bt] file [string ...]\n"
    43             "   or: md5sum [-cbtwq] file\n");
     47static int usage(FILE *pOut)
     48{
     49    fprintf(pOut,
     50            "usage: md5sum [-bt] file(s)\n"
     51            "   or: md5sum [-btwq] -c list-file(s)\n"
     52            "   or: md5sum [-btq] -C MD5 file\n"
     53            "\n"
     54            " -c, --check       Check MD5 and files found in the specified list file(s).\n"
     55            "                   The default is to compute MD5 sums of the specified files\n"
     56            "                   and print them to stdout in list form.\n"
     57            " -C, --check-file  This is followed by an MD5 sum and the file to check.\n"
     58            " -b, --binary      Read files in binary mode. (default)\n"
     59            " -t, --text        Read files in text mode.\n"
     60            " -q, --status      Be quiet.\n"
     61            " -w, --warn        Ignored. Always warn, unless quiet.\n"
     62            " -h, --help        This usage info.\n"
     63            " -v, --version     Show version information and exit.\n"
     64            );
    4465    return 1;
    4566}
     
    135156
    136157/**
    137  * Calculates the md5sum of the sepecified file stream.
    138  *
    139  * @returns errno on failure, 0 on success.
    140  * @param   pFile       The file stream.
    141  * @param   pDigest     Where to store the MD5 digest.
    142  */
    143 static int calc_md5sum(FILE *pFile, unsigned char pDigest[16])
    144 {
    145     int rc  = 0;
    146     int cb;
    147     char abBuf[16384];
    148     struct MD5Context Ctx;
    149 
    150     MD5Init(&Ctx);
    151     for (;;)
    152     {
    153         errno = 0;
    154         cb = (int)fread(abBuf, 1, sizeof(abBuf), pFile);
    155         if (cb > 0)
    156             MD5Update(&Ctx, abBuf, cb);
    157         else if (cb == 0)
    158             break;
    159         else
    160         {
    161             rc = errno;
    162             if (!rc)
    163                 rc = EINVAL;
    164             break;
    165         }
    166     }
    167     MD5Final(pDigest, &Ctx);
    168 
    169     return rc;
    170 }
    171 
    172 
    173 /**
    174  * Checks the if the specified digest matches the digest of the file stream.
    175  *
    176  * @returns 0 on match, -1 on mismatch, errno value (positive) on failure.
    177  * @param   pFile   The file stream.
    178  * @param   Digest  The MD5 digest.
    179  */
    180 static int check_md5sum(FILE *pFile, unsigned char Digest[16])
    181 {
    182     unsigned char DigestFile[16];
    183     int rc;
    184 
    185     rc = calc_md5sum(pFile, DigestFile);
    186     if (!rc)
    187         rc = memcmp(Digest, DigestFile, 16) ? -1 : 0;
    188     return rc;
    189 }
    190 
    191 
    192 /**
    193158 * Opens the specified file for md5 sum calculation.
    194159 *
    195  * @returns File stream on success, NULL and errno on failure.
     160 * @returns Opaque pointer on success, NULL and errno on failure.
    196161 * @param   pszFilename     The filename.
    197162 * @param   fText           Whether text or binary mode should be used.
    198163 */
    199 static FILE *open_file(const char *pszFilename, unsigned fText)
    200 {
     164static void *open_file(const char *pszFilename, unsigned fText)
     165{
     166#if defined(MD5SUM_USE_STDIO)
    201167    FILE *pFile;
    202168
     
    206172        pFile = fopen(pszFilename, "r");
    207173    return pFile;
    208 }
     174
     175#else
     176    int fd;
     177    int fFlags;
     178
     179    /* figure out the appropriate flags. */
     180    fFlags = O_RDONLY;
     181#ifdef O_SEQUENTIAL
     182    fFlags |= _O_SEQUENTIAL;
     183#elif defined(_O_SEQUENTIAL)
     184    fFlags |= _O_SEQUENTIAL;
     185#endif
     186#ifdef _O_BINARY
     187    if (!fText)     fFlags |= _O_BINARY;
     188#elif defined(_O_BINARY
     189    if (!fText)     fFlags |= _O_BINARY;
     190#endif
     191#ifdef O_TEXT
     192    if (fText)      fFlags |= O_TEXT;
     193#elif defined(O_TEXT)
     194    if (fText)      fFlags |= _O_TEXT;
     195#endif
     196
     197    errno = 0;
     198    fd = open(pszFilename, fFlags, 0755);
     199    if (fd >= 0)
     200    {
     201        int *pFd = malloc(sizeof(*pFd));
     202        if (pFd)
     203        {
     204            *pFd = fd;
     205            return pFd;
     206        }
     207        close(fd);
     208        errno = ENOMEM;
     209    }
     210
     211    return NULL;
     212#endif
     213}
     214
     215
     216/**
     217 * Closes a file opened by open_file.
     218 *
     219 * @param   pvFile          The opaque pointer returned by open_file.
     220 */
     221static void close_file(void *pvFile)
     222{
     223#if defined(MD5SUM_USE_STDIO)
     224    fclose((FILE *)pvFile);
     225#else
     226    close(*(int *)pvFile);
     227    free(pvFile);
     228#endif
     229}
     230
     231
     232/**
     233 * Reads from a file opened by open_file.
     234 *
     235 * @returns Number of bytes read on success.
     236 *          0 on EOF.
     237 *          Negated errno on read error.
     238 * @param   pvFile          The opaque pointer returned by open_file.
     239 * @param   pvBuf           Where to put the number of read bytes.
     240 * @param   cbBuf           The max number of bytes to read.
     241 *                          Must be less than a INT_MAX.
     242 */
     243static int read_file(void *pvFile, void *pvBuf, size_t cbBuf)
     244{
     245#if defined(MD5SUM_USE_STDIO)
     246    int cb;
     247
     248    errno = 0;
     249    cb = (int)fread(pvBuf, 1, cbBuf, (FILE *)pvFile);
     250    if (cb >= 0)
     251        return (int)cb;
     252    if (!errno)
     253        return -EINVAL;
     254    return -errno;
     255#else
     256    int cb;
     257
     258    errno = 0;
     259    cb = (int)read(*(int *)pvFile, pvBuf, (int)cbBuf);
     260    if (cb >= 0)
     261        return (int)cb;
     262    if (!errno)
     263        return -EINVAL;
     264    return -errno;
     265#endif
     266}
     267
     268
     269/**
     270 * Gets the size of the file.
     271 * This is informational and not necessarily 100% accurate.
     272 *
     273 * @returns File size.
     274 * @param   pvFile          The opaque pointer returned by open_file
     275 */
     276static double size_file(void *pvFile)
     277{
     278#if defined(_MSC_VER)
     279    __int64 cb;
     280# if defined(MD5SUM_USE_STDIO)
     281    cb = _filelengthi64(fileno((FILE *)pvFile));
     282# else
     283    cb = _filelengthi64(*(int *)pvFile);
     284# endif
     285    if (cb >= 0)
     286        return (double)cb;
     287
     288#elif defined(MD5SUM_USE_STDIO)
     289    struct stat st;
     290    if (!fstat(fileno((FILE *)pvFile), &st))
     291        return st.st_size;
     292
     293#else
     294    struct stat st;
     295    if (!fstat(*(int *)pvFile, &st))
     296        return st.st_size;
     297#endif
     298    return 1024;
     299}
     300
     301
     302/**
     303 * Calculates the md5sum of the sepecified file stream.
     304 *
     305 * @returns errno on failure, 0 on success.
     306 * @param   pvFile      The file stream.
     307 * @param   pDigest     Where to store the MD5 digest.
     308 * @param   fProgress   Whether to show a progress bar.
     309 */
     310static int calc_md5sum(void *pvFile, unsigned char pDigest[16], unsigned fProgress)
     311{
     312    int cb;
     313    int rc = 0;
     314    char abBuf[32*1024];
     315    struct MD5Context Ctx;
     316    unsigned uPercent = 0;
     317    double cbFile = 0.0;
     318    double off = 0.0;
     319
     320    if (fProgress)
     321    {
     322        cbFile = size_file(pvFile);
     323        if (cbFile < 1024*1024)
     324            fProgress = 0;
     325    }
     326
     327    MD5Init(&Ctx);
     328    for (;;)
     329    {
     330        /* process a chunk. */
     331        cb = read_file(pvFile, abBuf, sizeof(abBuf));
     332        if (cb > 0)
     333            MD5Update(&Ctx, abBuf, cb);
     334        else if (!cb)
     335            break;
     336        else
     337        {
     338            rc = -cb;
     339            break;
     340        }
     341
     342        /* update the progress indicator. */
     343        if (fProgress)
     344        {
     345            unsigned uNewPercent;
     346            off += cb;
     347            uNewPercent = (unsigned)((off / cbFile) * 100);
     348            if (uNewPercent != uPercent)
     349            {
     350                if (uPercent)
     351                    printf("\b\b\b\b");
     352                printf("%3d%%", uNewPercent);
     353                fflush(stdout);
     354                uPercent = uNewPercent;
     355            }
     356        }
     357    }
     358    MD5Final(pDigest, &Ctx);
     359
     360    if (fProgress)
     361        printf("\b\b\b\b    \b\b\b\b");
     362
     363    return rc;
     364}
     365
     366
     367/**
     368 * Checks the if the specified digest matches the digest of the file stream.
     369 *
     370 * @returns 0 on match, -1 on mismatch, errno value (positive) on failure.
     371 * @param   pvFile      The file stream.
     372 * @param   Digest      The MD5 digest.
     373 * @param   fProgress   Whether to show an progress indicator on large files.
     374 */
     375static int check_md5sum(void *pvFile, unsigned char Digest[16], unsigned fProgress)
     376{
     377    unsigned char DigestFile[16];
     378    int rc;
     379
     380    rc = calc_md5sum(pvFile, DigestFile, fProgress);
     381    if (!rc)
     382        rc = memcmp(Digest, DigestFile, 16) ? -1 : 0;
     383    return rc;
     384}
     385
     386
     387/**
     388 * Checks if the specified file matches the given MD5 digest.
     389 *
     390 * @returns 0 if it matches, 1 if it doesn't or an error occurs.
     391 * @param   pszFilename The name of the file to check.
     392 * @param   pszDigest   The MD5 digest string.
     393 * @param   fText       Whether to open the file in text or binary mode.
     394 * @param   fQuiet      Whether to go about this in a quiet fashion or not.
     395 * @param   fProgress   Whether to show an progress indicator on large files.
     396 */
     397static int check_one_file(const char *pszFilename, const char *pszDigest, unsigned fText, unsigned fQuiet, unsigned fProgress)
     398{
     399    unsigned char Digest[16];
     400    int rc;
     401
     402    rc = string_to_digest(pszDigest, Digest);
     403    if (!rc)
     404    {
     405        void *pvFile;
     406
     407        pvFile = open_file(pszFilename, fText);
     408        if (pvFile)
     409        {
     410            if (!fQuiet)
     411                fprintf(stdout, "%s: ", pszFilename);
     412            rc = check_md5sum(pvFile, Digest, fProgress);
     413            close_file(pvFile);
     414            if (!fQuiet)
     415            {
     416                fprintf(stdout, "%s\n", !rc ? "OK" : rc < 0 ? "FAILURE" : "ERROR");
     417                fflush(stdout);
     418                if (rc > 0)
     419                    errx(1, "Error reading '%s': %s", pszFilename, strerror(rc));
     420            }
     421            if (rc)
     422                rc = 1;
     423        }
     424        else
     425        {
     426            if (!fQuiet)
     427                errx(1, "Failed to open '%s': %s", pszFilename, strerror(errno));
     428            rc = 1;
     429        }
     430    }
     431    else
     432    {
     433        errx(1, "Malformed MD5 digest '%s'!", pszDigest);
     434        errx(1, "                      %*s^", rc - 1, "");
     435        rc = 1;
     436    }
     437
     438    return rc;
     439}
     440
     441
     442/**
     443 * Checks the specified md5.lst file.
     444 *
     445 * @returns 0 if all checks out file, 1 if one or more fails or there are read errors.
     446 * @param   pszFilename     The name of the file.
     447 * @param   fText           The default mode, text or binary. Only used when fBinaryTextOpt is true.
     448 * @param   fBinaryTextOpt  Whether a -b or -t option was specified and should be used.
     449 * @param   fQuiet          Whether to be quiet.
     450 * @param   fProgress   Whether to show an progress indicator on large files.
     451 */
     452static int check_files(const char *pszFilename, int fText, int fBinaryTextOpt, int fQuiet, unsigned fProgress)
     453{
     454    int rc = 0;
     455    FILE *pFile;
     456
     457    /*
     458     * Try open the md5.lst file and process it line by line.
     459     */
     460    pFile = fopen(pszFilename, "r");
     461    if (pFile)
     462    {
     463        int iLine = 0;
     464        char szLine[8192];
     465        while (fgets(szLine, sizeof(szLine), pFile))
     466        {
     467            const char *pszDigest;
     468            int fLineText;
     469            char *psz;
     470            int rc2;
     471
     472            iLine++;
     473            psz = szLine;
     474
     475            /* leading blanks */
     476            while (*psz == ' ' || *psz == '\t' || *psz == '\n')
     477                psz++;
     478
     479            /* skip blank or comment lines. */
     480            if (!*psz || *psz == '#' || *psz == ';' || *psz == '/')
     481                continue;
     482
     483            /* remove the trailing newline. */
     484            rc2 = (int)strlen(psz);
     485            if (psz[rc2 - 1] == '\n')
     486                psz[rc2 - 1] = '\0';
     487
     488            /* skip to the end of the digest and terminate it. */
     489            pszDigest = psz;
     490            while (*psz != ' ' && *psz != '\t' && *psz)
     491                psz++;
     492            if (*psz)
     493            {
     494                *psz++ = '\0';
     495
     496                /* blanks */
     497                while (*psz == ' ' || *psz == '\t' || *psz == '\n')
     498                    psz++;
     499
     500                /* check for binary asterix */
     501                if (*psz != '*')
     502                    fLineText = fBinaryTextOpt ? fText : 0;
     503                else
     504                {
     505                    fLineText = 0;
     506                    psz++;
     507                }
     508                if (*psz)
     509                {
     510                    unsigned char Digest[16];
     511
     512                    /* the rest is filename. */
     513                    pszFilename = psz;
     514
     515                    /*
     516                     * Do the job.
     517                     */
     518                    rc2 = string_to_digest(pszDigest, Digest);
     519                    if (!rc2)
     520                    {
     521                        void *pvFile = open_file(pszFilename, fLineText);
     522                        if (pvFile)
     523                        {
     524                            if (!fQuiet)
     525                                fprintf(stdout, "%s: ", pszFilename);
     526                            rc2 = check_md5sum(pvFile, Digest, fProgress);
     527                            close_file(pvFile);
     528                            if (!fQuiet)
     529                            {
     530                                fprintf(stdout, "%s\n", !rc2 ? "OK" : rc2 < 0 ? "FAILURE" : "ERROR");
     531                                fflush(stdout);
     532                                if (rc2 > 0)
     533                                    errx(1, "Error reading '%s': %s", pszFilename, strerror(rc2));
     534                            }
     535                            if (rc2)
     536                                rc = 1;
     537                        }
     538                        else
     539                        {
     540                            if (!fQuiet)
     541                                errx(1, "Failed to open '%s': %s", pszFilename, strerror(errno));
     542                            rc = 1;
     543                        }
     544                    }
     545                    else if (!fQuiet)
     546                    {
     547                        errx(1, "%s (%d): Ignoring malformed digest '%s' (digest)", pszFilename, iLine, pszDigest);
     548                        errx(1, "%s (%d):                            %*s^", pszFilename, iLine, rc2 - 1, "");
     549                    }
     550                }
     551                else if (!fQuiet)
     552                    errx(1, "%s (%d): Ignoring malformed line!", pszFilename, iLine);
     553            }
     554            else if (!fQuiet)
     555                errx(1, "%s (%d): Ignoring malformed line!", pszFilename, iLine);
     556        } /* while more lines */
     557
     558        fclose(pFile);
     559    }
     560    else
     561    {
     562        errx(1, "Failed to open '%s': %s", pszFilename, strerror(errno));
     563        rc = 1;
     564    }
     565
     566    return rc;
     567}
     568
     569
     570/**
     571 * Calculates the MD5 sum for one file and prints it.
     572 *
     573 * @returns 0 on success, 1 on any kind of failure.
     574 * @param   pszFilename     The file to process.
     575 * @param   fText           The mode to open the file in.
     576 * @param   fQuiet          Whether to be quiet or verbose about errors.
     577 * @param   fProgress       Whether to show an progress indicator on large files.
     578 */
     579static int md5sum_file(const char *pszFilename, unsigned fText, unsigned fQuiet, unsigned fProgress)
     580{
     581    int rc;
     582    void *pvFile;
     583
     584    /*
     585     * Calcuate and print the MD5 sum for one file.
     586     */
     587    pvFile = open_file(pszFilename, fText);
     588    if (pvFile)
     589    {
     590        unsigned char Digest[16];
     591        rc = calc_md5sum(pvFile, Digest, fProgress);
     592        close_file(pvFile);
     593        if (!rc)
     594        {
     595            char szDigest[36];
     596            digest_to_string(Digest, szDigest);
     597            fprintf(stdout, "%s %s%s\n", szDigest, fText ? "" : "*", pszFilename);
     598            fflush(stdout);
     599        }
     600        else
     601        {
     602            if (!fQuiet)
     603                errx(1, "Failed to open '%s': %s", pszFilename, strerror(rc));
     604            rc = 1;
     605        }
     606    }
     607    else
     608    {
     609        if (!fQuiet)
     610            errx(1, "Failed to open '%s': %s", pszFilename, strerror(errno));
     611        rc = 1;
     612    }
     613    return rc;
     614}
     615
    209616
    210617
     
    222629    int fNewLine = 0;
    223630    int fChecking = 0;
     631    int fProgress = 0;
    224632    int fNoMoreOptions = 0;
    225     unsigned char Digest[16];
    226     const char *pszFilename;
    227     const char *pszDigest;
    228     char szDigest[36];
    229     FILE *pFile;
    230     int rc2;
    231633
    232634    g_progname = argv[0];
     
    236638     */
    237639    if (argc <= 1)
    238         return usage();
     640        return usage(stderr);
    239641
    240642    /*
     
    250652        {
    251653            psz++;
     654
    252655            /* convert long options for gnu just for fun */
    253656            if (*psz == '-')
     
    259662                else if (!strcmp(psz, "-check"))
    260663                    psz = "c";
    261                 else if (!strcmp(psz, "-check-this"))
     664                else if (!strcmp(psz, "-check-file"))
    262665                    psz = "C";
     666                else if (!strcmp(psz, "-progress"))
     667                    psz = "p";
    263668                else if (!strcmp(psz, "-status"))
    264669                    psz = "q";
     
    290695                        break;
    291696
     697                    case 'p':
     698                        fProgress = 1;
     699                        break;
     700
    292701                    case 'q':
    293702                        fQuiet = 1;
     
    297706                        /* ignored */
    298707                        break;
     708
     709                    case 'h':
     710                        usage(stdout);
     711                        return 0;
    299712
    300713                    case 'v':
     
    306719                    case 'C':
    307720                    {
     721                        const char *pszFilename;
     722                        const char *pszDigest;
     723
    308724                        if (psz[1])
    309725                            pszDigest = &psz[1];
     
    315731                            return 1;
    316732                        }
    317                         rc2 = string_to_digest(pszDigest, Digest);
    318                         if (rc2)
    319                         {
    320                             errx(1, "Malformed MD5 digest '%s'!", pszDigest);
    321                             errx(1, "                      %*s^", rc2 - 1, "");
    322                             return 1;
    323                         }
    324 
    325733                        if (i + 1 < argc)
    326734                            pszFilename = argv[++i];
     
    330738                            return 1;
    331739                        }
    332                         pFile = open_file(pszFilename, fText);
    333                         if (pFile)
    334                         {
    335                             rc2 = check_md5sum(pFile, Digest);
    336                             if (!fQuiet)
    337                             {
    338                                 if (rc2 <= 0)
    339                                 {
    340                                     fprintf(stdout, "%s: %s\n", pszFilename, !rc2 ? "OK" : "FAILURE");
    341                                     fflush(stdout);
    342                                 }
    343                                 else
    344                                     errx(1, "Error reading '%s': %s", pszFilename, strerror(rc));
    345                             }
    346                             if (rc2)
    347                                 rc = 1;
    348                             fclose(pFile);
    349                         }
    350                         else
    351                         {
    352                             if (!fQuiet)
    353                                 errx(1, "Failed to open '%s': %s", pszFilename, strerror(errno));
    354                             rc = 1;
    355                         }
     740
     741                        rc |= check_one_file(pszFilename, pszDigest, fText, fQuiet, fProgress && !fQuiet);
    356742                        psz = "\0";
    357743                        break;
     
    360746                    default:
    361747                        errx(1, "Invalid option '%c'! (%s)", *psz, argv[i]);
    362                         return usage();
     748                        return usage(stderr);
    363749                }
    364750            } while (*++psz);
    365751        }
    366752        else if (fChecking)
    367         {
    368             pFile = fopen(argv[i], "r");
    369             if (pFile)
    370             {
    371                 int iLine = 0;
    372                 char szLine[8192];
    373                 while (fgets(szLine, sizeof(szLine), pFile))
    374                 {
    375                     int fLineText;
    376                     char *psz = szLine;
    377                     iLine++;
    378 
    379                     /* leading blanks */
    380                     while (*psz == ' ' || *psz == '\t' || *psz == '\n')
    381                         psz++;
    382 
    383                     /* skip blank or comment lines. */
    384                     if (!*psz || *psz == '#' || *psz == ';' || *psz == '/')
    385                         continue;
    386 
    387                     /* remove the trailing newline. */
    388                     rc2 = (int)strlen(psz);
    389                     if (psz[rc2 - 1] == '\n')
    390                         psz[rc2 - 1] = '\0';
    391 
    392                     /* skip to the end of the digest and terminate it. */
    393                     pszDigest = psz;
    394                     while (*psz != ' ' && *psz != '\t' && *psz)
    395                         psz++;
    396                     if (*psz)
    397                     {
    398                         *psz++ = '\0';
    399 
    400                         /* blanks */
    401                         while (*psz == ' ' || *psz == '\t' || *psz == '\n')
    402                             psz++;
    403 
    404                         /* check for binary asterix */
    405                         if (*psz != '*')
    406                             fLineText = fBinaryTextOpt ? fText : 0;
    407                         else
    408                         {
    409                             fLineText = 0;
    410                             psz++;
    411                         }
    412                         if (*psz)
    413                         {
    414                             /* the rest is filename. */
    415                             pszFilename = psz;
    416 
    417                             /*
    418                              * Do the job.
    419                              */
    420                             rc2 = string_to_digest(pszDigest, Digest);
    421                             if (!rc2)
    422                             {
    423                                 FILE *pFile2 = open_file(pszFilename, fLineText);
    424                                 if (pFile2)
    425                                 {
    426                                     rc2 = check_md5sum(pFile2, Digest);
    427                                     if (!fQuiet)
    428                                     {
    429                                         if (rc2 <= 0)
    430                                         {
    431                                             fprintf(stdout, "%s: %s\n", pszFilename, !rc2 ? "OK" : "FAILURE");
    432                                             fflush(stdout);
    433                                         }
    434                                         else
    435                                             errx(1, "Error reading '%s': %s", pszFilename, strerror(rc));
    436                                     }
    437                                     if (rc2)
    438                                         rc = 1;
    439                                     fclose(pFile2);
    440                                 }
    441                                 else
    442                                 {
    443                                     if (!fQuiet)
    444                                         errx(1, "Failed to open '%s': %s", pszFilename, strerror(errno));
    445                                     rc = 1;
    446                                 }
    447                             }
    448                             else if (!fQuiet)
    449                             {
    450                                 errx(1, "%s (%d): Ignoring malformed digest '%s' (digest)", argv[i], iLine, pszDigest);
    451                                 errx(1, "%s (%d):                            %*s^", argv[i], iLine, rc2 - 1, "");
    452                             }
    453                         }
    454                         else if (!fQuiet)
    455                             errx(1, "%s (%d): Ignoring malformed line!", argv[i], iLine);
    456                     }
    457                     else if (!fQuiet)
    458                         errx(1, "%s (%d): Ignoring malformed line!", argv[i], iLine);
    459                 }
    460 
    461                 fclose(pFile);
    462             }
    463             else
    464             {
    465                 errx(1, "Failed to open '%s': %s", argv[i], strerror(errno));
    466                 rc = 1;
    467             }
    468         }
     753            rc |= check_files(argv[i], fText, fBinaryTextOpt, fQuiet, fProgress && !fQuiet);
    469754        else
    470         {
    471             /*
    472              * Calcuate and print the MD5 sum for one file.
    473              */
    474             pFile = open_file(argv[i], fText);
    475             if (pFile)
    476             {
    477                 rc2 = calc_md5sum(pFile, Digest);
    478                 if (!rc2)
    479                 {
    480                     digest_to_string(Digest, szDigest);
    481                     fprintf(stdout, "%s %s%s\n", szDigest, fText ? "" : "*", argv[i]);
    482                     fflush(stdout);
    483                 }
    484                 else
    485                 {
    486                     if (!fQuiet)
    487                         errx(1, "Failed to open '%s': %s", argv[i], strerror(rc));
    488                     rc = 1;
    489                 }
    490                 fclose(pFile);
    491             }
    492             else
    493             {
    494                 if (!fQuiet)
    495                     errx(1, "Failed to open '%s': %s", argv[i], strerror(errno));
    496                 rc = 1;
    497             }
    498         }
     755            rc |= md5sum_file(argv[i], fText, fQuiet, fProgress && !fQuiet);
    499756        i++;
    500757    }
Note: See TracChangeset for help on using the changeset viewer.