/* */
This source file includes following definitions.
- is_binary
- test
- filesize
1 /*
2 * Copyright (c) 1997, 1998, 1999, 2000, 2006, 2010
3 * Tama Communications Corporation
4 *
5 * This file is part of GNU GLOBAL.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #else
29 #include <strings.h>
30 #endif
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 #ifdef HAVE_FCNTL_H
35 #include <fcntl.h>
36 #else
37 #include <sys/file.h>
38 #endif
39
40 #include "locatestring.h"
41 #include "char.h"
42 #include "die.h"
43 #include "test.h"
44
45 /**
46 * Decide whether or not the @a path is binary file.
47 *
48 * @param[in] path
49 * @return 0: is not binary, 1: is binary
50 */
51 static int
52 is_binary(const char *path)
53 {
54 int ip;
55 char buf[512];
56 int i, size;
57
58 ip = open(path, O_RDONLY);
59 if (ip < 0)
60 die("cannot open file '%s' in read mode.", path);
61 size = read(ip, buf, sizeof(buf));
62 close(ip);
63 if (size < 0)
64 return 1;
65 if (size >= 7 && locatestring(buf, "!<arch>", MATCH_AT_FIRST)) /* ar */
66 return 1;
67 if (size >= 4 && locatestring(buf, "%PDF", MATCH_AT_FIRST)) /* PDF */
68 return 1;
69 for (i = 0; i < size; i++) {
70 if (isbinarychar(buf[i]))
71 return 1;
72 }
73 return 0;
74 }
75 /**
76 * test:
77 *
78 * @param[in] flags file flags <br>
79 * @CODE{"f"} [ -f path ] is @a path a regular file (not a dir, link or pipe etc.)? <br>
80 * @CODE{"d"} [ -d path ] is @a path a dir? <br>
81 * @CODE{"r"} [ -r path ] can we read from @a path? <br>
82 * @CODE{"s"} [ -s path ] has @a path got a non-zero size? <br>
83 * @CODE{"w"} [ -w path ] can we write to @a path? <br>
84 * @CODE{"x"} [ -x path ] is @a path an executable file/program? <br>
85 * @CODE{"b"} [ -b path ] is @a path a binary file?
86 *
87 * @param[in] path path <br>
88 * if @VAR{NULL} then previous path.
89 * @return 0: no, 1: ok
90 *
91 * You can specify more than one character. It assumed 'AND' test.
92 */
93 int
94 test(const char *flags, const char *path)
95 {
96 static struct stat sb;
97 int c;
98
99 if (path != NULL)
100 if (stat(path, &sb) < 0)
101 return 0;
102 while ((c = *flags++) != 0) {
103 switch (c) {
104 case 'b':
105 if (!is_binary(path))
106 return 0;
107 break;
108 case 'f':
109 if (!S_ISREG(sb.st_mode))
110 return 0;
111 break;
112 case 'd':
113 if (!S_ISDIR(sb.st_mode))
114 return 0;
115 break;
116 case 'r':
117 if (access(path, R_OK) < 0)
118 return 0;
119 break;
120 case 's':
121 if (sb.st_size == 0)
122 return 0;
123 break;
124 case 'w':
125 if (access(path, W_OK) < 0)
126 return 0;
127 break;
128 case 'x':
129 #ifdef _WIN32
130 /* Look at file extension to determine executability */
131 if (strlen(path) < 5)
132 return 0;
133 if (!S_ISREG(sb.st_mode))
134 return 0;
135 if (!locatestring(path, ".exe", MATCH_AT_LAST|IGNORE_CASE) &&
136 !locatestring(path, ".com", MATCH_AT_LAST|IGNORE_CASE) &&
137 !locatestring(path, ".bat", MATCH_AT_LAST|IGNORE_CASE))
138 return 0;
139 #else
140 if (access(path, X_OK) < 0)
141 return 0;
142 #endif
143 break;
144 default:
145 break;
146 }
147 }
148 return 1;
149 }
150 /**
151 * filesize: get file size in bytes.
152 *
153 * @param[in] path path of file
154 * @return != -1: file size
155 * == -1: file not found
156 */
157 int
158 filesize(const char *path)
159 {
160 struct stat sb;
161
162 if (stat(path, &sb) < 0)
163 return -1;
164 return sb.st_size;
165 }
/* */