3 const char *sha1_file_directory
= NULL
;
4 struct cache_entry
**active_cache
= NULL
;
5 unsigned int active_nr
= 0, active_alloc
= 0;
7 void usage(const char *err
)
9 fprintf(stderr
, "read-tree: %s\n", err
);
13 static unsigned hexval(char c
)
15 if (c
>= '0' && c
<= '9')
17 if (c
>= 'a' && c
<= 'f')
19 if (c
>= 'A' && c
<= 'F')
24 int get_sha1_hex(char *hex
, unsigned char *sha1
)
27 for (i
= 0; i
< 20; i
++) {
28 unsigned int val
= (hexval(hex
[0]) << 4) | hexval(hex
[1]);
37 char * sha1_to_hex(unsigned char *sha1
)
39 static char buffer
[50];
40 static const char hex
[] = "0123456789abcdef";
44 for (i
= 0; i
< 20; i
++) {
45 unsigned int val
= *sha1
++;
46 *buf
++ = hex
[val
>> 4];
47 *buf
++ = hex
[val
& 0xf];
53 * NOTE! This returns a statically allocated buffer, so you have to be
54 * careful about using it. Do a "strdup()" if you need to save the
57 char *sha1_file_name(unsigned char *sha1
)
60 static char *name
, *base
;
63 char *sha1_file_directory
= getenv(DB_ENVIRONMENT
) ? : DEFAULT_DB_ENVIRONMENT
;
64 int len
= strlen(sha1_file_directory
);
65 base
= malloc(len
+ 60);
66 memcpy(base
, sha1_file_directory
, len
);
67 memset(base
+len
, 0, 60);
70 name
= base
+ len
+ 1;
72 for (i
= 0; i
< 20; i
++) {
73 static char hex
[] = "0123456789abcdef";
74 unsigned int val
= sha1
[i
];
75 char *pos
= name
+ i
*2 + (i
> 0);
76 *pos
++ = hex
[val
>> 4];
77 *pos
= hex
[val
& 0xf];
82 void * read_sha1_file(unsigned char *sha1
, char *type
, unsigned long *size
)
87 int i
, fd
, ret
, bytes
;
89 char *filename
= sha1_file_name(sha1
);
91 fd
= open(filename
, O_RDONLY
);
96 if (fstat(fd
, &st
) < 0) {
100 map
= mmap(NULL
, st
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
102 if (-1 == (int)(long)map
)
105 /* Get the data stream */
106 memset(&stream
, 0, sizeof(stream
));
107 stream
.next_in
= map
;
108 stream
.avail_in
= st
.st_size
;
109 stream
.next_out
= buffer
;
110 stream
.avail_out
= sizeof(buffer
);
112 inflateInit(&stream
);
113 ret
= inflate(&stream
, 0);
114 if (sscanf(buffer
, "%10s %lu", type
, size
) != 2)
116 bytes
= strlen(buffer
) + 1;
121 memcpy(buf
, buffer
+ bytes
, stream
.total_out
- bytes
);
122 bytes
= stream
.total_out
- bytes
;
123 if (bytes
< *size
&& ret
== Z_OK
) {
124 stream
.next_out
= buf
+ bytes
;
125 stream
.avail_out
= *size
- bytes
;
126 while (inflate(&stream
, Z_FINISH
) == Z_OK
)
133 int write_sha1_file(char *buf
, unsigned len
)
138 unsigned char sha1
[20];
142 memset(&stream
, 0, sizeof(stream
));
143 deflateInit(&stream
, Z_BEST_COMPRESSION
);
144 size
= deflateBound(&stream
, len
);
145 compressed
= malloc(size
);
148 stream
.next_in
= buf
;
149 stream
.avail_in
= len
;
150 stream
.next_out
= compressed
;
151 stream
.avail_out
= size
;
152 while (deflate(&stream
, Z_FINISH
) == Z_OK
)
155 size
= stream
.total_out
;
159 SHA1_Update(&c
, compressed
, size
);
160 SHA1_Final(sha1
, &c
);
162 if (write_sha1_buffer(sha1
, compressed
, size
) < 0)
164 printf("%s\n", sha1_to_hex(sha1
));
168 int write_sha1_buffer(unsigned char *sha1
, void *buf
, unsigned int size
)
170 char *filename
= sha1_file_name(sha1
);
173 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_EXCL
, 0666);
175 return (errno
== EEXIST
) ? 0 : -1;
176 write(fd
, buf
, size
);
181 static int error(const char * string
)
183 fprintf(stderr
, "error: %s\n", string
);
187 static int verify_hdr(struct cache_header
*hdr
, unsigned long size
)
190 unsigned char sha1
[20];
192 if (hdr
->signature
!= CACHE_SIGNATURE
)
193 return error("bad signature");
194 if (hdr
->version
!= 1)
195 return error("bad version");
197 SHA1_Update(&c
, hdr
, offsetof(struct cache_header
, sha1
));
198 SHA1_Update(&c
, hdr
+1, size
- sizeof(*hdr
));
199 SHA1_Final(sha1
, &c
);
200 if (memcmp(sha1
, hdr
->sha1
, 20))
201 return error("bad header sha1");
209 unsigned long size
, offset
;
211 struct cache_header
*hdr
;
215 return error("more than one cachefile");
217 sha1_file_directory
= getenv(DB_ENVIRONMENT
);
218 if (!sha1_file_directory
)
219 sha1_file_directory
= DEFAULT_DB_ENVIRONMENT
;
220 if (access(sha1_file_directory
, X_OK
) < 0)
221 return error("no access to SHA1 file directory");
222 fd
= open(".dircache/index", O_RDONLY
);
224 return (errno
== ENOENT
) ? 0 : error("open failed");
227 if (!fstat(fd
, &st
)) {
231 if (size
> sizeof(struct cache_header
))
232 map
= mmap(NULL
, size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
235 if (-1 == (int)(long)map
)
236 return error("mmap failed");
239 if (verify_hdr(hdr
, size
) < 0)
242 active_nr
= hdr
->entries
;
243 active_alloc
= alloc_nr(active_nr
);
244 active_cache
= calloc(active_alloc
, sizeof(struct cache_entry
*));
246 offset
= sizeof(*hdr
);
247 for (i
= 0; i
< hdr
->entries
; i
++) {
248 struct cache_entry
*ce
= map
+ offset
;
249 offset
= offset
+ ce_size(ce
);
250 active_cache
[i
] = ce
;
257 return error("verify header failed");