00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <unistd.h>
00044 #include <sys/types.h>
00045 #include <sys/stat.h>
00046 #include <sys/param.h>
00047 #include <errno.h>
00048 #include "errors.h"
00049 #include "string_utils.h"
00050 #include "file_utils.h"
00051
00052 #if defined(_WIN32)
00053 #define DIR_SEPARATOR '\\'
00054 #define DIR_SEPARATOR_STR "\\"
00055 #else
00056 #define DIR_SEPARATOR '/'
00057 #define DIR_SEPARATOR_STR "/"
00058 #endif
00059
00060 extern int errno;
00061 static char *saved_orig_program_name;
00062
00063 #if defined(KEY) && defined(SHARED_BUILD)
00064
00065
00066
00067 extern int compat_gcc __attribute__((weak));
00068 #endif
00069
00070
00071 char *
00072 drop_path (char *s)
00073 {
00074 char *tail = NULL;
00075 char *t;
00076 for (t = s; *t; t++) {
00077 if (is_dir_separator (*t))
00078 tail = t;
00079 }
00080
00081 if (tail == NULL) {
00082 return s;
00083 } else {
00084 tail++;
00085 return tail;
00086 }
00087 }
00088
00089
00090 char *
00091 directory_path (char *s)
00092 {
00093 char *t, *tail = NULL;
00094 char path[MAXPATHLEN];
00095 for (t = s; *t; t++) {
00096 if (is_dir_separator(*t))
00097 tail = t;
00098 }
00099 if (tail == NULL) {
00100 return NULL;
00101 } else {
00102 return substring_copy (s, 0, tail-s);
00103 }
00104 }
00105
00106 char *
00107 concat_path (char *d, char *f)
00108 {
00109 if ((d == NULL) || (strlen (d) == 0) ||
00110 (strcmp(d, DIR_SEPARATOR_STR) == 0)) {
00111
00112 return concat_strings (DIR_SEPARATOR_STR, f);
00113 } else if ((f == NULL) || (strlen (f) == 0)) {
00114
00115 return d;
00116 } else {
00117 char *path = (char *) malloc(strlen(d) + strlen(f) + 2);
00118 strcpy (path, d);
00119 strcat (path, DIR_SEPARATOR_STR);
00120 strcat (path, f);
00121 return path;
00122 }
00123 }
00124
00125 boolean
00126 file_exists (char *path)
00127 {
00128 int st;
00129 struct stat sbuf;
00130 st = stat(path, &sbuf);
00131 if (st == -1 && (errno == ENOENT || errno == ENOTDIR))
00132 return FALSE;
00133 else
00134 return TRUE;
00135 }
00136
00137 boolean
00138 is_executable (char *path)
00139 {
00140 int st;
00141 struct stat sbuf;
00142 st = stat(path, &sbuf);
00143 if (st == -1 && (errno == ENOENT || errno == ENOTDIR))
00144 return FALSE;
00145 else
00146
00147 #if defined(_WIN32)
00148
00149 return (sbuf.st_mode & (S_IXUSR)) != 0;
00150 #else
00151 return (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) != 0;
00152 #endif
00153 }
00154
00155 boolean
00156 is_directory (char *path)
00157 {
00158
00159 buffer_t buf;
00160 if (*path == NIL) return FALSE;
00161 strcpy(buf, path);
00162 strcat(buf, DIR_SEPARATOR_STR);
00163 strcat(buf, ".");
00164 if (file_exists(buf))
00165 return TRUE;
00166 else
00167 return FALSE;
00168 }
00169
00170 boolean want_directory (char *path)
00171 {
00172 if (is_directory(path))
00173 return TRUE;
00174
00175 #if defined(KEY) && defined(SHARED_BUILD)
00176
00177 if (fullwarn ||
00178 (path[0] == '-' && compat_gcc != TRUE))
00179 warning("%s is not a directory", path);
00180
00181
00182 return TRUE;
00183 #else
00184 if (fullwarn)
00185 warning("%s is not a directory", path);
00186 return TRUE;
00187 #endif
00188 }
00189
00190
00191 boolean
00192 directory_is_writable (char *path)
00193 {
00194 FILE *f;
00195 char *s;
00196 int fd;
00197 #if defined(_WIN32)
00198 s = concat_strings(path, "\\ctm.XXXXXX");
00199
00200 s = mktemp(s);
00201 f = fopen(s, "w");
00202 #else
00203 s = concat_strings(path, "/ctm.XXXXXX");
00204 fd = mkstemp(s);
00205 if (fd == -1)
00206 return FALSE;
00207 f = fdopen(fd, "w");
00208 #endif
00209 if (f == NULL) {
00210 return FALSE;
00211 } else {
00212 fclose (f);
00213 unlink(s);
00214 return TRUE;
00215 }
00216 }
00217
00218 char *
00219 get_cwd (void)
00220 {
00221 char *cwd = getcwd((char *) NULL, MAXPATHLEN);
00222 if (cwd == NULL) {
00223 cwd = getenv("PWD");
00224 if (cwd == NULL) {
00225
00226 cwd = ".";
00227 }
00228 }
00229 return string_copy(cwd);
00230 }
00231
00232 void file_utils_set_program_name(char *name)
00233 {
00234 saved_orig_program_name = name;
00235 }
00236
00237
00238 static char *
00239 get_executable_dir_from_path(char *name)
00240 {
00241 if (is_dir_separator (name[0]))
00242 return name;
00243 #if defined(_WIN32)
00244 else if (name[1] == ':' && is_dir_separator(name[2]))
00245 return name;
00246 #endif
00247 else {
00248
00249 char *path = getenv("PATH");
00250 if (path != NULL) {
00251 char *p = string_copy(path);
00252 char *tmp;
00253 char *dir;
00254 #if defined(_WIN32)
00255 #if defined(__MINGW32__)
00256
00257 while ((dir = strtok(p, ";")) != NULL) {
00258 #else
00259
00260 while ((dir = strtok(p, ":")) != NULL) {
00261 #endif
00262 #else
00263 while ((dir = strtok_r(p, ":", &tmp)) != NULL) {
00264 #endif
00265 if (is_directory(dir)) {
00266 char filename[MAXPATHLEN];
00267 snprintf(filename, MAXPATHLEN, "%s%s%s", dir, DIR_SEPARATOR_STR, name);
00268 if (is_executable(filename)) {
00269 return string_copy(filename);
00270 }
00271 #if defined(_WIN32)
00272 else {
00273
00274
00275
00276
00277 char *suffix = get_suffix(filename);
00278 if (suffix != NULL && strcmp(suffix, "exe") == 0) {
00279
00280 *(suffix-1) = NIL;
00281 }
00282 else {
00283
00284 strcat(filename, ".exe");
00285 }
00286 if (is_executable(filename)) {
00287 return string_copy(filename);
00288 }
00289 }
00290 #endif
00291 }
00292 p = NULL;
00293 }
00294 }
00295 }
00296 return name;
00297 }
00298
00299 char *
00300 get_executable_dir (void)
00301 {
00302 char path[MAXPATHLEN];
00303 int rval = 0;
00304 int i;
00305
00306 #if defined(linux)
00307
00308
00309 rval = readlink ("/proc/self/exe", path, sizeof(path));
00310 #endif
00311 if (rval <= 0) {
00312
00313
00314 char *p = get_executable_dir_from_path(saved_orig_program_name);
00315 strncpy(path, p, sizeof(path));
00316 rval = strlen(path);
00317 } else {
00318 path[rval] = '\0';
00319 }
00320 if (rval > 0) {
00321 for (i=rval-1; i >= 0; i--) {
00322 if (is_dir_separator(path[i])) break;
00323 }
00324 if (i > 0) {
00325
00326
00327 path[i] = '\0';
00328 } else if (i == 0) {
00329
00330 strcpy (path, DIR_SEPARATOR_STR);
00331 }
00332 if (is_directory (path)) {
00333
00334 return string_copy (path);
00335 }
00336 }
00337
00338
00339
00340
00341 return NULL;
00342 }
00343
00344 void
00345 dump_file_to_stdout(char *filename)
00346 {
00347 const int buf_size = 1024;
00348 char buf[buf_size];
00349 FILE *f;
00350 int n;
00351
00352 if (filename == NULL || !file_exists(filename))
00353 internal_error("file does not exist");
00354
00355 f = fopen(filename, "r");
00356 if (f == NULL)
00357 internal_error("cannot open file for read");
00358
00359
00360 while ((n = fread(buf, 1, buf_size, f)) > 0) {
00361 write(1, buf, n);
00362 }
00363 fclose(f);
00364 }