00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *Xrdadler32CVSID = "$Id: Xrdadler32.cc 35287 2010-09-14 21:19:35Z ganis $";
00014
00015 #define _FILE_OFFSET_BITS 64
00016
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <sys/types.h>
00021 #include <sys/stat.h>
00022 #include <unistd.h>
00023 #include <fcntl.h>
00024 #include <errno.h>
00025 #ifdef __linux__
00026 #include <sys/xattr.h>
00027 #endif
00028 #include <zlib.h>
00029
00030 #include "XrdPosix/XrdPosixExtern.hh"
00031 #include "XrdPosix/XrdPosixXrootd.hh"
00032 #include "XrdClient/XrdClientUrlInfo.hh"
00033 #include "XrdClient/XrdClientConst.hh"
00034 #include "XrdClient/XrdClient.hh"
00035 #include "XrdClient/XrdClientEnv.hh"
00036 #include "XrdClient/XrdClientAdmin.hh"
00037 #include "XrdOuc/XrdOucString.hh"
00038
00039 void fSetXattrAdler32(int fd, const char* attr, const char *value)
00040 {
00041 struct stat st;
00042 char mtime[12], attr_val[25];
00043 int rc;
00044
00045 rc = fstat(fd, &st);
00046 if (rc < 0 || strlen(value) != 8)
00047 return;
00048 else
00049 sprintf(mtime, "%ld", st.st_mtime);
00050
00051 strcpy(attr_val, value);
00052 strcat(attr_val, ":");
00053 strcat(attr_val, mtime);
00054
00055 #if defined(__linux__)
00056 rc = fsetxattr(fd, attr, attr_val, strlen(attr_val), 0x0);
00057 #elif defined(__solaris__)
00058 int attrfd;
00059 attrfd = openat(fd, attr, O_XATTR|O_CREAT|O_TRUNC|O_WRONLY);
00060 if (attrfd < 0) return;
00061
00062 rc = write(attrfd, attr_val, strlen(attr_val));
00063
00064
00065
00066
00067 fchmod(attrfd, S_IRWXU|S_IRGRP|S_IROTH);
00068 close(attrfd);
00069 #endif
00070 return;
00071 }
00072
00073 int fGetXattrAdler32(int fd, const char* attr, char *value)
00074 {
00075 struct stat st;
00076 char mtime[12], attr_val[25], *p;
00077 int rc;
00078
00079 rc = fstat(fd, &st);
00080 if (rc < 0)
00081 return(0);
00082 else
00083 sprintf(mtime, "%ld", st.st_mtime);
00084
00085
00086 #if defined(__linux__)
00087 rc = fgetxattr(fd, attr, attr_val, 25);
00088 #elif defined(__solaris__)
00089 int attrfd;
00090 attrfd = openat(fd, attr, O_XATTR|O_RDONLY);
00091 if (attrfd < 0) return(0);
00092
00093 rc = read(attrfd, attr_val, 25);
00094 close(attrfd);
00095 #else
00096 return(0);
00097 #endif
00098
00099 if (rc == -1 || attr_val[8] != ':') return(0);
00100 attr_val[8] = '\0';
00101 attr_val[rc] = '\0';
00102 p = attr_val + 9;
00103
00104 if (strcmp(p, mtime)) return(0);
00105
00106 strcpy(value, attr_val);
00107 return(strlen(value));
00108 }
00109
00110
00111 char get_current_url(const char *oldurl, char *newurl)
00112 {
00113 bool stat;
00114 long id, flags, modtime;
00115 long long size;
00116 XrdOucString url(oldurl);
00117
00118 XrdClientAdmin *adm = new XrdClientAdmin(url.c_str());
00119 if (adm->Connect())
00120 {
00121 XrdClientUrlInfo u(url);
00122
00123 stat = adm->Stat((char *)u.File.c_str(), id, size, flags, modtime);
00124 if (stat && adm->GetCurrentUrl().IsValid())
00125 {
00126 strcpy(newurl, adm->GetCurrentUrl().GetUrl().c_str());
00127 delete adm;
00128 return 1;
00129 }
00130 }
00131 delete adm;
00132 return 0;
00133 }
00134
00135
00136 char getchksum(const char *rooturl, char *chksum)
00137 {
00138 XrdOucString url(rooturl);
00139 char *sum = 0, *ptb, *pte;
00140 long sumlen;
00141 int pte_ptb;
00142
00143 XrdClientAdmin *adm = new XrdClientAdmin(url.c_str());
00144 if (adm->Connect())
00145 {
00146 XrdClientUrlInfo u(url);
00147 sumlen = adm->GetChecksum((kXR_char *)u.File.c_str(), (kXR_char**) &sum);
00148 pte = ptb = sum;
00149 if (sumlen != 0)
00150 {
00151 ptb = strchr(sum, ' ');
00152 ptb++;
00153 pte = strchr(ptb, ' ');
00154 if (pte == NULL) pte = &sum[sumlen];
00155 }
00156 pte_ptb = pte - ptb;
00157 strncpy(chksum, ptb, pte_ptb);
00158 chksum[pte_ptb] = '\0';
00159 free(sum);
00160 delete adm;
00161 return pte_ptb;
00162 }
00163 else
00164 return -1;
00165 }
00166
00167 #define N 64*1024
00168
00169 int main(int argc, char *argv[])
00170 {
00171 char path[2048], chksum[128], buf[N], adler_str[9];
00172 const char attr[] = "user.checksum.adler32";
00173 struct stat stbuf;
00174 int fd, len, rc;
00175 uLong adler;
00176 adler = adler32(0L, Z_NULL, 0);
00177
00178 if (argc == 2 && ! strcmp(argv[1], "-h"))
00179 {
00180 printf("Usage: %s file. Calculating adler32 checksum of a given file.\n", argv[0]);
00181 printf("A file can be local file, stdin (if omitted), or root URL (including via XROOTD_VMP)\n");
00182 return 0;
00183 }
00184
00185 path[0] = '\0';
00186 if (argc > 1)
00187 {
00188 if (!strncmp(argv[1], "root://", 7))
00189 strcpy(path, argv[1]);
00190 else
00191 XrdPosix_URL(argv[1], path, sizeof(path));
00192 }
00193 if (argc == 1 || path[0] == '\0')
00194 {
00195 if (argc > 1)
00196 {
00197 strcpy(path, argv[1]);
00198 rc = stat(path, &stbuf);
00199 if (rc != 0 || ! S_ISREG(stbuf.st_mode) ||
00200 (fd = open(path,O_RDONLY)) < 0)
00201 {
00202 printf("Error_accessing %s\n", path);
00203 return 1;
00204 }
00205 else
00206 if (fGetXattrAdler32(fd, attr, adler_str) == 8)
00207 {
00208 printf("%s %s\n", adler_str, path);
00209 return 0;
00210 }
00211 }
00212 else
00213 {
00214 fd = STDIN_FILENO;
00215 strcpy(path, "-");
00216 }
00217 while ( (len = read(fd, buf, N)) > 0 )
00218 adler = adler32(adler, (const Bytef*)buf, len);
00219
00220 if (fd != STDIN_FILENO)
00221 {
00222 sprintf(adler_str, "%08lx", adler);
00223 fSetXattrAdler32(fd, attr, adler_str);
00224 close(fd);
00225 }
00226 printf("%08lx %s\n", adler, path);
00227 return 0;
00228 }
00229 else
00230 {
00231 EnvPutInt(NAME_DEBUG, -1);
00232 if (!get_current_url(path, path))
00233 {
00234 printf("Error_accessing: %s\n", argv[1]);
00235 return 1;
00236 }
00237
00238 if (getchksum(path, chksum) > 0)
00239 {
00240 printf("%s %s\n", chksum, argv[1]);
00241 return (strcmp(chksum, "Error_accessing:") ? 0 : 1);
00242 }
00243 else
00244 {
00245 EnvPutInt(NAME_READAHEADSIZE, N);
00246 EnvPutInt(NAME_READCACHESIZE, 2*N);
00247 rc = XrdPosixXrootd::Stat(path, &stbuf);
00248 if (rc != 0 || ! S_ISREG(stbuf.st_mode) ||
00249 (fd = XrdPosixXrootd::Open(path, O_RDONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
00250 {
00251 printf("Error_accessing: %s\n", argv[1]);
00252 return 1;
00253 }
00254 while ( (len = XrdPosixXrootd::Read(fd, buf, N)) > 0 )
00255 adler = adler32(adler, (const Bytef*)buf, len);
00256
00257 XrdPosixXrootd::Close(fd);
00258 printf("%08lx %s\n", adler, argv[1]);
00259 return 0;
00260 }
00261 }
00262 }