]>
Commit | Line | Data |
---|---|---|
4cf40131 | 1 | #include "util.h" |
69e3f52d | 2 | #include <sys/mman.h> |
4cf40131 ACM |
3 | |
4 | int mkdir_p(char *path, mode_t mode) | |
5 | { | |
6 | struct stat st; | |
7 | int err; | |
8 | char *d = path; | |
9 | ||
10 | if (*d != '/') | |
11 | return -1; | |
12 | ||
13 | if (stat(path, &st) == 0) | |
14 | return 0; | |
15 | ||
16 | while (*++d == '/'); | |
17 | ||
18 | while ((d = strchr(d, '/'))) { | |
19 | *d = '\0'; | |
20 | err = stat(path, &st) && mkdir(path, mode); | |
21 | *d++ = '/'; | |
22 | if (err) | |
23 | return -1; | |
24 | while (*d == '/') | |
25 | ++d; | |
26 | } | |
27 | return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; | |
28 | } | |
29 | ||
9e201442 ACM |
30 | static int slow_copyfile(const char *from, const char *to) |
31 | { | |
32 | int err = 0; | |
33 | char *line = NULL; | |
34 | size_t n; | |
35 | FILE *from_fp = fopen(from, "r"), *to_fp; | |
36 | ||
37 | if (from_fp == NULL) | |
38 | goto out; | |
39 | ||
40 | to_fp = fopen(to, "w"); | |
41 | if (to_fp == NULL) | |
42 | goto out_fclose_from; | |
43 | ||
44 | while (getline(&line, &n, from_fp) > 0) | |
45 | if (fputs(line, to_fp) == EOF) | |
46 | goto out_fclose_to; | |
47 | err = 0; | |
48 | out_fclose_to: | |
49 | fclose(to_fp); | |
50 | free(line); | |
51 | out_fclose_from: | |
52 | fclose(from_fp); | |
53 | out: | |
54 | return err; | |
55 | } | |
56 | ||
4cf40131 ACM |
57 | int copyfile(const char *from, const char *to) |
58 | { | |
59 | int fromfd, tofd; | |
60 | struct stat st; | |
61 | void *addr; | |
62 | int err = -1; | |
63 | ||
64 | if (stat(from, &st)) | |
65 | goto out; | |
66 | ||
9e201442 ACM |
67 | if (st.st_size == 0) /* /proc? do it slowly... */ |
68 | return slow_copyfile(from, to); | |
69 | ||
4cf40131 ACM |
70 | fromfd = open(from, O_RDONLY); |
71 | if (fromfd < 0) | |
72 | goto out; | |
73 | ||
74 | tofd = creat(to, 0755); | |
75 | if (tofd < 0) | |
76 | goto out_close_from; | |
77 | ||
78 | addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0); | |
79 | if (addr == MAP_FAILED) | |
80 | goto out_close_to; | |
81 | ||
82 | if (write(tofd, addr, st.st_size) == st.st_size) | |
83 | err = 0; | |
84 | ||
85 | munmap(addr, st.st_size); | |
86 | out_close_to: | |
87 | close(tofd); | |
88 | if (err) | |
89 | unlink(to); | |
90 | out_close_from: | |
91 | close(fromfd); | |
92 | out: | |
93 | return err; | |
94 | } | |
c82ee828 ACM |
95 | |
96 | unsigned long convert_unit(unsigned long value, char *unit) | |
97 | { | |
98 | *unit = ' '; | |
99 | ||
100 | if (value > 1000) { | |
101 | value /= 1000; | |
102 | *unit = 'K'; | |
103 | } | |
104 | ||
105 | if (value > 1000) { | |
106 | value /= 1000; | |
107 | *unit = 'M'; | |
108 | } | |
109 | ||
110 | if (value > 1000) { | |
111 | value /= 1000; | |
112 | *unit = 'G'; | |
113 | } | |
114 | ||
115 | return value; | |
116 | } |