]>
Commit | Line | Data |
---|---|---|
59d6bfef KS |
1 | /* |
2 | * udev_utils_file.c - files operations | |
3 | * | |
4 | * Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the | |
8 | * Free Software Foundation version 2 of the License. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 675 Mass Ave, Cambridge, MA 02139, USA. | |
18 | * | |
19 | */ | |
20 | ||
21 | ||
22 | #include <stdlib.h> | |
23 | #include <stdio.h> | |
24 | #include <stddef.h> | |
25 | #include <unistd.h> | |
26 | #include <fcntl.h> | |
27 | #include <errno.h> | |
28 | #include <ctype.h> | |
29 | #include <dirent.h> | |
30 | #include <sys/stat.h> | |
31 | #include <sys/mman.h> | |
32 | ||
59d6bfef | 33 | #include "udev.h" |
59d6bfef KS |
34 | |
35 | int create_path(const char *path) | |
36 | { | |
37 | char p[PATH_SIZE]; | |
38 | char *pos; | |
39 | struct stat stats; | |
40 | ||
41 | strcpy (p, path); | |
42 | pos = strrchr(p, '/'); | |
43 | if (pos == p || pos == NULL) | |
44 | return 0; | |
45 | ||
46 | while (pos[-1] == '/') | |
47 | pos--; | |
48 | ||
49 | pos[0] = '\0'; | |
50 | ||
51 | dbg("stat '%s'\n", p); | |
52 | if (stat (p, &stats) == 0 && (stats.st_mode & S_IFMT) == S_IFDIR) | |
53 | return 0; | |
54 | ||
55 | if (create_path (p) != 0) | |
56 | return -1; | |
57 | ||
58 | dbg("mkdir '%s'\n", p); | |
59 | return mkdir(p, 0755); | |
60 | } | |
61 | ||
0da0efb2 SJR |
62 | int delete_path(const char *path) |
63 | { | |
64 | char p[PATH_SIZE]; | |
65 | char *pos; | |
66 | int retval; | |
67 | ||
68 | strcpy (p, path); | |
69 | pos = strrchr(p, '/'); | |
70 | while (1) { | |
71 | *pos = '\0'; | |
72 | pos = strrchr(p, '/'); | |
73 | ||
74 | /* don't remove the last one */ | |
75 | if ((pos == p) || (pos == NULL)) | |
76 | break; | |
77 | ||
78 | /* remove if empty */ | |
79 | retval = rmdir(p); | |
80 | if (errno == ENOENT) | |
81 | retval = 0; | |
82 | if (retval) { | |
83 | if (errno == ENOTEMPTY) | |
84 | return 0; | |
85 | err("rmdir(%s) failed: %s", p, strerror(errno)); | |
86 | break; | |
87 | } | |
88 | dbg("removed '%s'", p); | |
89 | } | |
90 | return 0; | |
91 | } | |
92 | ||
59d6bfef KS |
93 | /* Reset permissions on the device node, before unlinking it to make sure, |
94 | * that permisions of possible hard links will be removed too. | |
95 | */ | |
96 | int unlink_secure(const char *filename) | |
97 | { | |
98 | int retval; | |
99 | ||
100 | retval = chown(filename, 0, 0); | |
101 | if (retval) | |
df4e89bf | 102 | err("chown(%s, 0, 0) failed: %s", filename, strerror(errno)); |
59d6bfef KS |
103 | |
104 | retval = chmod(filename, 0000); | |
105 | if (retval) | |
df4e89bf | 106 | err("chmod(%s, 0000) failed: %s", filename, strerror(errno)); |
59d6bfef KS |
107 | |
108 | retval = unlink(filename); | |
109 | if (errno == ENOENT) | |
110 | retval = 0; | |
111 | ||
112 | if (retval) | |
df4e89bf | 113 | err("unlink(%s) failed: %s", filename, strerror(errno)); |
59d6bfef KS |
114 | |
115 | return retval; | |
116 | } | |
117 | ||
118 | int file_map(const char *filename, char **buf, size_t *bufsize) | |
119 | { | |
120 | struct stat stats; | |
121 | int fd; | |
122 | ||
123 | fd = open(filename, O_RDONLY); | |
124 | if (fd < 0) { | |
125 | return -1; | |
126 | } | |
127 | ||
128 | if (fstat(fd, &stats) < 0) { | |
129 | close(fd); | |
130 | return -1; | |
131 | } | |
132 | ||
133 | *buf = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0); | |
134 | if (*buf == MAP_FAILED) { | |
135 | close(fd); | |
136 | return -1; | |
137 | } | |
138 | *bufsize = stats.st_size; | |
139 | ||
140 | close(fd); | |
141 | ||
142 | return 0; | |
143 | } | |
144 | ||
145 | void file_unmap(void *buf, size_t bufsize) | |
146 | { | |
147 | munmap(buf, bufsize); | |
148 | } | |
149 | ||
150 | /* return number of chars until the next newline, skip escaped newline */ | |
151 | size_t buf_get_line(const char *buf, size_t buflen, size_t cur) | |
152 | { | |
153 | int escape = 0; | |
154 | size_t count; | |
155 | ||
156 | for (count = cur; count < buflen; count++) { | |
157 | if (!escape && buf[count] == '\n') | |
158 | break; | |
159 | ||
160 | if (buf[count] == '\\') | |
161 | escape = 1; | |
162 | else | |
163 | escape = 0; | |
164 | } | |
165 | ||
166 | return count - cur; | |
167 | } |