FILE *dgen_freopen(const char *relative, const char *file, unsigned int mode, FILE *f) { size_t size; size_t file_size; char *tmp; int e = errno; const char *fmode = fopen_mode(mode); char *path = NULL; if ((file == NULL) || (file[0] == '\0') || (fmode == NULL)) goto error; /* Try to open the file in the current directory if DGEN_CURRENT is specified. */ if (mode & DGEN_CURRENT) { FILE *fd; if (f == NULL) fd = fopen(file, fmode); else fd = freopen(file, fmode, f); if (fd != NULL) return fd; } if (path_type(file, ~0u) != PATH_TYPE_UNSPECIFIED) size = 0; else if ((relative == NULL) || (path_type(relative, ~0u) == PATH_TYPE_UNSPECIFIED)) { if ((path = dgen_dir(NULL, &size, relative)) == NULL) goto error; } else { if ((path = strdup(relative)) == NULL) goto error; size = strlen(path); } if (mode & (DGEN_WRITE | DGEN_APPEND)) mkdir(path, 0777); /* XXX make that recursive */ file_size = strlen(file); if ((tmp = realloc(path, (size + !!size + file_size + 1))) == NULL) goto error; path = tmp; if (size) path[(size++)] = DGEN_DIRSEP[0]; memcpy(&path[size], file, file_size); size += file_size; path[size] = '\0'; errno = e; if (f == NULL) f = fopen(path, fmode); else f = freopen(path, fmode, f); e = errno; free(path); errno = e; return f; error: free(path); errno = EACCES; return NULL; }
FILE *dgen_fopen(const char *dir, const char *file, unsigned int mode) { size_t size; size_t space; const char *fmode = fopen_mode(mode); #ifndef __MINGW32__ struct passwd *pwd = getpwuid(geteuid()); #endif char path[PATH_MAX]; if ((file == NULL) || (file[0] == '\0') || (fmode == NULL)) { fprintf(stderr,"dgen_fopen: error opening file ... \n"); goto error; } /* Try to open the file in the current directory if DGEN_CURRENT is specified. */ if (mode & DGEN_CURRENT) { FILE *fd = fopen(file, fmode); if (fd != NULL) return fd; } #ifndef __MINGW32__ if ((pwd == NULL) || (pwd->pw_dir == NULL)) { fprintf(stderr,"path error ..\n"); goto error; } strncpy(path, pwd->pw_dir, sizeof(path)); #else /* __MINGW32__ */ if (SHGetFolderPath(NULL, (CSIDL_APPDATA | CSIDL_FLAG_CREATE), 0, 0, path) != S_OK) goto error; #endif /* __MINGW32__ */ path[(sizeof(path) - 1)] = '\0'; size = strlen(path); space = (sizeof(path) - size); size += (size_t)snprintf(&path[size], space, DGEN_DIRSEP DGEN_BASEDIR DGEN_DIRSEP); if (size >= sizeof(path)) goto error; space = (sizeof(path) - size); fprintf(stderr,"dgen_fopen: path='%s'\n",path); if (mode & (DGEN_WRITE | DGEN_APPEND)) mkdir(path, 0777); if (dir != NULL) { size += (size_t)snprintf(&path[size], space, "%s" DGEN_DIRSEP, dir); if (size >= sizeof(path)) goto error; space = (sizeof(path) - size); if (mode & (DGEN_WRITE | DGEN_APPEND)) mkdir(path, 0777); } size += (size_t)snprintf(&path[size], space, "%s", file); if (size >= sizeof(path)) goto error; file = path; return fopen(file, fmode); error: errno = EACCES; return NULL; }