XRootD
XrdCrc32c.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C r c 3 2 . c c */
4 /* */
5 /* (c) 2021 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <iostream>
32 
33 #include <fcntl.h>
34 #include <cstdio>
35 #include <unistd.h>
36 
37 #include <sys/stat.h>
38 #include <cstring>
39 #include <sys/types.h>
40 #include <sys/uio.h>
41 
42 #include "XrdOuc/XrdOucCRC.hh"
43 #include "XrdSys/XrdSysE2T.hh"
44 
45 
46 namespace
47 {const char *pgm = "xrdcrc32c";
48 }
49 
50 #ifndef O_DIRECT
51 #define O_DIRECT 0
52 #endif
53 
54 /******************************************************************************/
55 /* F a t a l */
56 /******************************************************************************/
57 
58 void Fatal(const char *op, const char *target)
59 {
60 
61 // Generate the message
62 //
63  std::cerr <<"xrdcrc32c: Unable to "<<op<<' '<<target<<"; "<<XrdSysE2T(errno)<<std::endl;
64  exit(3);
65 }
66 
67 /******************************************************************************/
68 /* U s a g e */
69 /******************************************************************************/
70 
71 void Usage(int rc)
72 {
73  std::cerr <<"\nUsage: xrdcrc32c [opts] [<path> | -]\n"
74  "\n<path> the path to the file whose checksum if to be computed."
75  "\n- compute checksum from data presented at standard in;"
76  "\n example: xrdcp <url> - | xrdcrc32c -\n"
77  "\nopts: -d -h -n -s -x\n"
78  "\n-d read data directly into the buffer, do not use the file cache."
79  "\n-h display usage information (arguments ignored)."
80  "\n-n do not end output with a newline character."
81  "\n-s do not include file path in output result."
82  "\n-x do not print leading zeroes in the checksum, if any."
83  <<std::endl;
84  exit(rc);
85 }
86 
87 /******************************************************************************/
88 /* m a i n */
89 /******************************************************************************/
90 
91 int main(int argc, char *argv[])
92 {
93 // extern char *optarg;
94  extern int optind, opterr, optopt;
95  static const int buffSZ = 1024*1024;
96  const char *fPath, *fmt = "%08x";
97  int bytes, fd, opts = O_RDONLY;
98  uint32_t csVal = 0;
99  bool addPath = true, addNL = true;
100  char csBuff[16], c;
101 
102 // Process the options
103 //
104  opterr = 0;
105  if (argc > 1 && '-' == *argv[1])
106  while ((c = getopt(argc,argv,"dhnsx")) && ((unsigned char)c != 0xff))
107  { switch(c)
108  {
109  case 'd': opts |= O_DIRECT;
110  break;
111  case 'h': Usage(0);
112  break;
113  case 'n': addNL = false;
114  break;
115  case 's': addPath = false;
116  break;
117  case 'x': fmt = "%x";
118  break;
119  default: std::cerr <<pgm <<'-' <<char(optopt) <<" option is invalid" <<std::endl;
120  Usage(1);
121  break;
122  }
123  }
124 
125 // Get the source argument
126 //
127  if (optind < argc && strcmp(argv[optind], "-"))
128  {fPath = argv[optind];
129  if ((fd = open(fPath, opts)) < 0) Fatal("open", fPath);
130  } else {
131  fPath = "stdin";
132  fd = STDIN_FILENO;
133  }
134 
135 // Allocate a 1 megabyte page aligned buffer
136 //
137  void *buffP;
138  int rc = posix_memalign(&buffP, sysconf(_SC_PAGESIZE), buffSZ);
139  if (rc) {errno = rc; Fatal("allocate buffer to read", fPath);}
140 
141 // Compute the checksum
142 //
143  while((bytes = read(fd, buffP, buffSZ)) > 0)
144  {csVal = XrdOucCRC::Calc32C(buffP, bytes, csVal);}
145 
146 // Check if we ended with an error
147 //
148  if (bytes < 0) Fatal("read", fPath);
149 
150 // Produce the result
151 //
152  sprintf(csBuff, fmt, csVal);
153  std::cout <<(char *)csBuff;
154  if (addPath) std::cout << ' ' <<fPath;
155  if (addNL) std::cout << std::endl;
156 
157 // All done
158 //
159  free(buffP);
160  return 0;
161 }
int main(int argc, char *argv[])
Definition: XrdCrc32c.cc:91
void Fatal(const char *op, const char *target)
Definition: XrdCrc32c.cc:58
void Usage(int rc)
Definition: XrdCrc32c.cc:71
#define O_DIRECT
Definition: XrdCrc32c.cc:51
int optopt
int optind
int open(const char *path, int oflag,...)
ssize_t read(int fildes, void *buf, size_t nbyte)
struct myOpts opts
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:104
static uint32_t Calc32C(const void *data, size_t count, uint32_t prevcs=0)
Definition: XrdOucCRC.cc:190