Use "-Wall -O2" for the compiler to get more warnings.
[git.git] / read-tree.c
1 /*
2  * GIT - The information manager from hell
3  *
4  * Copyright (C) Linus Torvalds, 2005
5  */
6 #include "cache.h"
7
8 static void create_directories(const char *path)
9 {
10         int len = strlen(path);
11         char *buf = malloc(len + 1);
12         const char *slash = path;
13
14         while ((slash = strchr(slash+1, '/')) != NULL) {
15                 len = slash - path;
16                 memcpy(buf, path, len);
17                 buf[len] = 0;
18                 mkdir(buf, 0700);
19         }
20 }
21
22 static int create_file(const char *path)
23 {
24         int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
25         if (fd < 0) {
26                 if (errno == ENOENT) {
27                         create_directories(path);
28                         fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
29                 }
30         }
31         return fd;
32 }
33
34 static int unpack(unsigned char *sha1)
35 {
36         void *buffer;
37         unsigned long size;
38         char type[20];
39
40         buffer = read_sha1_file(sha1, type, &size);
41         if (!buffer)
42                 usage("unable to read sha1 file");
43         if (strcmp(type, "tree"))
44                 usage("expected a 'tree' node");
45         while (size) {
46                 int len = strlen(buffer)+1;
47                 unsigned char *sha1 = buffer + len;
48                 char *path = strchr(buffer, ' ')+1;
49                 char *data;
50                 unsigned long filesize;
51                 unsigned int mode;
52                 int fd;
53
54                 if (size < len + 20 || sscanf(buffer, "%o", &mode) != 1)
55                         usage("corrupt 'tree' file");
56                 buffer = sha1 + 20;
57                 size -= len + 20;
58                 data = read_sha1_file(sha1, type, &filesize);
59                 if (!data || strcmp(type, "blob"))
60                         usage("tree file refers to bad file data");
61                 fd = create_file(path);
62                 if (fd < 0)
63                         usage("unable to create file");
64                 if (write(fd, data, filesize) != filesize)
65                         usage("unable to write file");
66                 fchmod(fd, mode);
67                 close(fd);
68                 free(data);
69         }
70         return 0;
71 }
72
73 int main(int argc, char **argv)
74 {
75         unsigned char sha1[20];
76
77         if (argc != 2)
78                 usage("read-tree <key>");
79         if (get_sha1_hex(argv[1], sha1) < 0)
80                 usage("read-tree <key>");
81         sha1_file_directory = getenv(DB_ENVIRONMENT);
82         if (!sha1_file_directory)
83                 sha1_file_directory = DEFAULT_DB_ENVIRONMENT;
84         if (unpack(sha1) < 0)
85                 usage("unpack failed");
86         return 0;
87 }