mirror of
https://github.com/djhackersdev/saltytools.git
synced 2026-03-21 17:54:11 -05:00
246 lines
3.6 KiB
C
246 lines
3.6 KiB
C
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include "util/fs.h"
|
|
#include "util/iobuf.h"
|
|
#include "util/log.h"
|
|
|
|
int fs_open(FILE **out, const char *path, const char *mode) {
|
|
FILE *f;
|
|
int r;
|
|
|
|
assert(out != NULL);
|
|
assert(path != NULL);
|
|
assert(mode != NULL);
|
|
|
|
*out = NULL;
|
|
f = fopen(path, mode);
|
|
|
|
if (f == NULL) {
|
|
r = -errno;
|
|
log_write("Error opening \"%s\": %s (%i)", path, strerror(-r), r);
|
|
|
|
return r;
|
|
}
|
|
|
|
*out = f;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void fs_close(FILE *f) {
|
|
if (f != NULL) {
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
int fs_seek_to(FILE *f, size_t off) {
|
|
int r;
|
|
|
|
assert(f != NULL);
|
|
|
|
r = fseek(f, off, SEEK_SET);
|
|
|
|
if (r != 0) {
|
|
r = -errno;
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
int fs_read(FILE *f, struct iobuf *buf) {
|
|
size_t nbytes;
|
|
size_t nread;
|
|
int r;
|
|
|
|
assert(f != NULL);
|
|
assert(buf != NULL);
|
|
assert(buf->pos <= buf->nbytes);
|
|
|
|
nbytes = buf->nbytes - buf->pos;
|
|
nread = fread(buf->bytes + buf->pos, 1, nbytes, f);
|
|
|
|
if (nread < nbytes) {
|
|
r = -errno;
|
|
|
|
if (r != 0) {
|
|
log_write("Read failed: %s (%i)", strerror(-r), r);
|
|
} else {
|
|
r = -ENODATA;
|
|
log_write("Short read: %llu < %llu", (unsigned long long)nread,
|
|
(unsigned long long)nbytes);
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
buf->pos += nbytes;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int fs_write(FILE *f, struct const_iobuf *buf) {
|
|
size_t nbytes;
|
|
size_t nwrit;
|
|
int r;
|
|
|
|
assert(f != NULL);
|
|
assert(buf != NULL);
|
|
assert(buf->pos <= buf->nbytes);
|
|
|
|
nbytes = buf->nbytes - buf->pos;
|
|
nwrit = fwrite(buf->bytes + buf->pos, 1, nbytes, f);
|
|
|
|
if (nwrit < nbytes) {
|
|
r = -errno;
|
|
|
|
if (r != 0) {
|
|
log_write("Write failed: %s (%i)", strerror(-r), r);
|
|
} else {
|
|
r = -EINTR; /* I guess..??? */
|
|
log_write("Short write: %llu < %llu", (unsigned long long)nwrit,
|
|
(unsigned long long)nbytes);
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
buf->pos += nbytes;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int fs_read_file(const char *path, void **out_bytes, size_t *out_nbytes) {
|
|
FILE *f;
|
|
struct iobuf buf;
|
|
void *bytes;
|
|
long nbytes;
|
|
int r;
|
|
|
|
assert(path != NULL);
|
|
assert(out_bytes != NULL);
|
|
assert(out_nbytes != NULL);
|
|
|
|
bytes = NULL;
|
|
*out_bytes = NULL;
|
|
*out_nbytes = 0;
|
|
|
|
r = fs_open(&f, path, "rb");
|
|
|
|
if (r < 0) {
|
|
goto end;
|
|
}
|
|
|
|
r = fseek(f, 0, SEEK_END);
|
|
|
|
if (r != 0) {
|
|
r = -errno;
|
|
log_write("fseek(SEEK_END): %s (%i)", strerror(-r), r);
|
|
|
|
goto end;
|
|
}
|
|
|
|
nbytes = ftell(f);
|
|
r = fseek(f, 0, SEEK_SET);
|
|
|
|
if (r != 0) {
|
|
r = -errno;
|
|
log_write("fseek(SEEK_SET): %s (%i)", strerror(-r), r);
|
|
|
|
goto end;
|
|
}
|
|
|
|
bytes = malloc(nbytes);
|
|
|
|
if (bytes == NULL) {
|
|
r = -ENOMEM;
|
|
|
|
goto end;
|
|
}
|
|
|
|
buf.bytes = bytes;
|
|
buf.nbytes = nbytes;
|
|
buf.pos = 0;
|
|
|
|
r = fs_read(f, &buf);
|
|
|
|
if (r < 0) {
|
|
goto end;
|
|
}
|
|
|
|
*out_bytes = bytes;
|
|
*out_nbytes = nbytes;
|
|
bytes = NULL;
|
|
|
|
end:
|
|
free(bytes);
|
|
fs_close(f);
|
|
|
|
return r;
|
|
}
|
|
|
|
int fs_write_file(const char *path, struct const_iobuf *buf) {
|
|
FILE *f;
|
|
int r;
|
|
|
|
assert(path != NULL);
|
|
assert(buf != NULL);
|
|
|
|
f = NULL;
|
|
r = fs_open(&f, path, "wb");
|
|
|
|
if (r < 0) {
|
|
goto end;
|
|
}
|
|
|
|
r = fs_write(f, buf);
|
|
|
|
if (r < 0) {
|
|
goto end;
|
|
}
|
|
|
|
end:
|
|
fs_close(f);
|
|
|
|
return r;
|
|
}
|
|
|
|
int fs_mkdir(const char *path) {
|
|
struct stat s;
|
|
int r;
|
|
|
|
assert(path != NULL);
|
|
|
|
r = stat(path, &s);
|
|
|
|
if (r == 0) {
|
|
/* Early return on _success_, not failure. */
|
|
return 0;
|
|
}
|
|
|
|
r = -errno;
|
|
|
|
if (r != -ENOENT) {
|
|
log_write("stat(%s): %i (%s)", path, r, strerror(-r));
|
|
|
|
return r;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
r = mkdir(path);
|
|
#else
|
|
r = mkdir(path, 0755);
|
|
#endif
|
|
|
|
if (r != 0) {
|
|
r = -errno;
|
|
}
|
|
|
|
return r;
|
|
}
|