modified: SpatialOmicsCoord.py
[GalaxyCodeBases.git] / c_cpp / etc / md5_sha / md5io.c
blob2ef5a092643fe1a6cc3f6c6243f9900f4c4711ea
1 /*
2 * md5drvr - md5 driver code
4 * @(#) $Revision: 13.1 $
5 * @(#) $Id: md5io.c,v 13.1 2006/08/14 03:16:33 chongo Exp $
6 * @(#) $Source: /usr/local/src/cmd/hash/RCS/md5io.c,v $
8 * This file was written by Landon Curt Noll.
10 * This code has been placed in the public domain. Please do not
11 * copyright this code.
13 * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO
14 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MER-
15 * CHANTABILITY AND FITNESS. IN NO EVENT SHALL LANDON CURT
16 * NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
17 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
19 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * chongo (was here) /\oo/\
23 * http://www.isthe.com/chongo/index.html
25 * Share and enjoy! :-)
27 * See md5drvr.c for version and modification history.
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/time.h>
36 #include <sys/resource.h>
37 #define MD5_IO
38 #include "md5.h"
40 /* global variables */
41 ULONG md5_zero[MD5_MAXBLOCK/sizeof(ULONG)]; /* block of zeros */
45 * MD5Stream - digest a open file stream
47 void
48 MD5Stream(pre_str, pre_len, stream, dig)
49 BYTE *pre_str; /* data prefix or NULL */
50 UINT pre_len; /* length of pre_str */
51 FILE *stream; /* the stream to process */
52 MD5_CTX *dig; /* current digest */
54 ULONG data[MD5_READWORDS]; /* our read buffer */
55 int bytes; /* bytes last read */
56 int ret; /* partial fread return value */
59 * pre-process prefix if needed
61 if (pre_str != NULL) {
62 MD5Update(dig, pre_str, pre_len);
63 MD5COUNT(dig, pre_len);
67 * if we have a partial chunk, try to read until we have a full chunk
69 clearerr(stream);
70 if (dig->datalen > 0) {
72 /* determine what we have so far */
73 bytes = dig->datalen;
75 /* try to read what we need to fill the chunk */
76 while (bytes < MD5_CHUNKSIZE) {
78 /* try to read what we need */
79 ret = fread((char*)data+bytes, 1, MD5_CHUNKSIZE-bytes, stream);
81 /* carefully examine the result */
82 if (ret < 0 || ferror(stream)) {
83 /* error processing */
84 fprintf(stderr, "%s: ", program);
85 perror("read #3 error");
86 exit(1);
87 } else if (ret == 0 || feof(stream)) {
88 /* EOF processing */
89 MD5COUNT(dig, MD5_CHUNKSIZE-dig->datalen);
90 MD5Update(dig, (BYTE *)data+dig->datalen,
91 MD5_CHUNKSIZE-dig->datalen);
92 return;
95 /* note that we have more bytes */
96 bytes += ret;
98 MD5COUNT(dig, MD5_CHUNKSIZE-dig->datalen);
99 MD5Update(dig, (BYTE *)data+dig->datalen, MD5_CHUNKSIZE-dig->datalen);
103 * process the contents of the file
105 while ((bytes = fread((char *)data, 1, MD5_READSIZE, stream)) > 0) {
108 * if we got a partial read, try to read up to a full chunk
110 while (bytes < MD5_READSIZE) {
112 /* try to read more */
113 ret = fread((char *)data+bytes, 1, MD5_READSIZE-bytes, stream);
115 /* carefully examine the result */
116 if (ret < 0 || ferror(stream)) {
117 /* error processing */
118 fprintf(stderr, "%s: ", program);
119 perror("read #1 error");
120 exit(2);
121 } else if (ret == 0 || feof(stream)) {
122 /* EOF processing */
123 MD5Update(dig, (BYTE *)data, bytes);
124 MD5COUNT(dig, bytes);
125 return;
128 /* note that we have more bytes */
129 bytes += ret;
133 * digest the read
135 MD5fullUpdate(dig, (BYTE *)data, bytes);
136 MD5COUNT(dig, bytes);
140 * watch for errors
142 if (bytes < 0 || ferror(stream)) {
143 /* error processing */
144 fprintf(stderr, "%s: ", program);
145 perror("read #2 error");
146 exit(3);
148 return;
153 * MD5File - digest a file
155 void
156 MD5File(pre_str, pre_len, filename, inode, dig)
157 BYTE *pre_str; /* string prefix or NULL */
158 UINT pre_len; /* length of pre_str */
159 char *filename; /* the filename to process */
160 int inode; /* 1 => process inode & filename */
161 MD5_CTX *dig; /* current digest */
163 FILE *inFile; /* the open file stream */
164 struct stat buf; /* stat or lstat of file */
165 struct md5_stat hashbuf; /* stat data to digest */
166 struct md5_stat hashlbuf; /* lstat data to digest */
167 ULONG filename_len; /* length of the filename */
170 * open the file
172 inFile = fopen(filename, "rb");
173 if (inFile == NULL) {
174 fprintf(stderr, "%s: cannot open %s: ", program, filename);
175 perror("");
176 return;
180 * pre-process prefix if needed
182 if (pre_str == NULL) {
183 if (inode) {
184 filename_len = strlen(filename);
185 MD5Update(dig, (BYTE *)filename, filename_len);
186 MD5COUNT(dig, filename_len);
188 } else {
189 if (inode) {
190 MD5Update(dig, pre_str, pre_len);
191 filename_len = strlen(filename);
192 MD5Update(dig, (BYTE *)filename, filename_len);
193 MD5COUNT(dig, pre_len + filename_len);
194 } else {
195 MD5Update(dig, pre_str, pre_len);
196 MD5COUNT(dig, pre_len);
201 * digest file stat and lstat
203 if (inode) {
204 if (fstat(fileno(inFile), &buf) < 0) {
205 printf("%s can't be stated.\n", filename);
206 return;
208 hashbuf.stat_dev = buf.st_dev;
209 hashbuf.stat_ino = buf.st_ino;
210 hashbuf.stat_mode = buf.st_mode;
211 hashbuf.stat_nlink = buf.st_nlink;
212 hashbuf.stat_uid = buf.st_uid;
213 hashbuf.stat_gid = buf.st_gid;
214 hashbuf.stat_size = buf.st_size;
215 hashbuf.stat_mtime = buf.st_mtime;
216 hashbuf.stat_ctime = buf.st_ctime;
217 MD5Update(dig, (BYTE *)&hashbuf, sizeof(hashbuf));
218 if (lstat(filename, &buf) < 0) {
219 printf("%s can't be lstated.\n", filename);
220 return;
222 hashlbuf.stat_dev = buf.st_dev;
223 hashlbuf.stat_ino = buf.st_ino;
224 hashlbuf.stat_mode = buf.st_mode;
225 hashlbuf.stat_nlink = buf.st_nlink;
226 hashlbuf.stat_uid = buf.st_uid;
227 hashlbuf.stat_gid = buf.st_gid;
228 hashlbuf.stat_size = buf.st_size;
229 hashlbuf.stat_mtime = buf.st_mtime;
230 hashlbuf.stat_ctime = buf.st_ctime;
231 MD5Update(dig, (BYTE *)&hashlbuf, sizeof(hashlbuf));
234 * pad with zeros to process file data faster
236 if (dig->datalen > 0) {
237 MD5COUNT(dig, sizeof(hashbuf) + sizeof(hashlbuf) +
238 MD5_CHUNKSIZE - dig->datalen);
239 MD5Update(dig, (BYTE *)md5_zero, MD5_CHUNKSIZE - dig->datalen);
240 } else {
241 MD5COUNT(dig, sizeof(hashbuf) + sizeof(hashlbuf));
246 * process the data stream
248 MD5Stream(NULL, 0, inFile, dig);
249 fclose(inFile);