VirtualBox

source: vbox/trunk/src/bldprogs/VBoxCmp.cpp@ 84095

Last change on this file since 84095 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.7 KB
Line 
1/* $Id: VBoxCmp.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * File Compare - Compares two files byte by byte.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
27
28#include <iprt/string.h>
29#include <iprt/stdarg.h>
30
31
32/**
33 * Writes an error message.
34 *
35 * @returns RTEXITCODE_FAILURE.
36 * @param pcszFormat Error message.
37 * @param ... Format argument referenced in the message.
38 */
39static RTEXITCODE printErr(const char *pcszFormat, ...)
40{
41 va_list va;
42
43 fprintf(stderr, "VBoxCmp: ");
44 va_start(va, pcszFormat);
45 vfprintf(stderr, pcszFormat, va);
46 va_end(va);
47
48 return RTEXITCODE_FAILURE;
49}
50
51
52static FILE *openFile(const char *pszFile)
53{
54#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
55 FILE *pFile = fopen(pszFile, "rb");
56#else
57 FILE *pFile = fopen(pszFile, "r");
58#endif
59 if (!pFile)
60 printErr("Failed to open '%s': %s\n", pszFile, strerror(errno));
61 return pFile;
62}
63
64
65static RTEXITCODE compareFiles(FILE *pFile1, FILE *pFile2)
66{
67 if (!pFile1 || !pFile2)
68 return RTEXITCODE_FAILURE;
69
70 uint32_t cMismatches = 1;
71 RTEXITCODE rcRet = RTEXITCODE_SUCCESS;
72 uint64_t off = 0;
73 for (;;)
74 {
75 uint8_t b1;
76 size_t cb1 = fread(&b1, sizeof(b1), 1, pFile1);
77 uint8_t b2;
78 size_t cb2 = fread(&b2, sizeof(b2), 1, pFile2);
79 if (cb1 != 1 || cb2 != 1)
80 break;
81 if (b1 != b2)
82 {
83 printErr("0x%x%08x: %#04x (%3d) != %#04x (%3d)\n", (uint32_t)(off >> 32), (uint32_t)off, b1, b1, b2, b2);
84 rcRet = RTEXITCODE_FAILURE;
85 cMismatches++;
86 if (cMismatches > 128)
87 {
88 printErr("Too many mismatches, giving up\n");
89 return rcRet;
90 }
91 }
92 off++;
93 }
94
95 if (!feof(pFile1) || !feof(pFile2))
96 {
97 if (!feof(pFile1) && ferror(pFile1))
98 rcRet = printErr("Read error on file #1.\n");
99 else if (!feof(pFile2) && ferror(pFile2))
100 rcRet = printErr("Read error on file #2.\n");
101 else if (!feof(pFile2))
102 rcRet = printErr("0x%x%08x: file #1 ends before file #2\n", (uint32_t)(off >> 32), (uint32_t)off);
103 else
104 rcRet = printErr("0x%x%08x: file #2 ends before file #1\n", (uint32_t)(off >> 32), (uint32_t)off);
105 }
106
107 return rcRet;
108}
109
110
111int main(int argc, char *argv[])
112{
113 RTEXITCODE rcExit;
114
115 if (argc == 3)
116 {
117 const char *pszFile1 = argv[1];
118 const char *pszFile2 = argv[2];
119 FILE *pFile1 = openFile(pszFile1);
120 FILE *pFile2 = openFile(pszFile2);
121 rcExit = compareFiles(pFile1, pFile2);
122 if (pFile1)
123 fclose(pFile1);
124 if (pFile2)
125 fclose(pFile2);
126 }
127 else
128 rcExit = printErr("Syntax error: usage: VBoxCmp <file1> <file2>\n");
129 return rcExit;
130}
131
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette