| git.druid.rocks | index | druid520 | q | src/ | util.c |
src/util.c
#include "config.h"
#ifdef OS_NETBSD_C
#define _NETBSD_SOURCE 1
#endif
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "q.h"
void
die(const char* msg)
{
fprintf(stderr, "err: %s.\n", msg);
exit(1);
}
long
pathfits(const char* a, const char* b)
{
size_t an = strlen(a);
size_t bn = strlen(b);
if(bn > (size_t)MAXPATH - 16 || an > (size_t)MAXPATH - 16 - bn)
{
return 0;
}
return 1;
}
long
bufcat(char* dst, size_t max, size_t* off, const char* str)
{
size_t n = strlen(str);
if(*off >= max || n >= max - *off)
{
return 0;
}
memcpy(dst + *off, str, n);
*off = *off + n;
dst[*off] = '\0';
return 1;
}
long
pathjoin(char* dst, size_t max, const char* a, const char* b)
{
size_t off = 0;
if(bufcat(dst, max, &off, a) == 0)
{
return 0;
}
if(bufcat(dst, max, &off, "/") == 0)
{
return 0;
}
if(bufcat(dst, max, &off, b) == 0)
{
return 0;
}
return 1;
}
/* copy src into dst, nul included, 0 on overflow -- the checked
* replacement for strcpy the rest of q uses so a too-long value dies
* loudly rather than silently truncating. */
long
copystr(char* dst, size_t max, const char* src)
{
size_t n = strlen(src);
if(n >= max)
{
return 0;
}
memcpy(dst, src, n);
dst[n] = '\0';
return 1;
}
/* returns bytes read (0..max), -1 if path couldn't be opened, or -2 if
* the file holds MORE than max bytes -- fread alone can't tell "read
* exactly max because that's the whole file" from "clipped a bigger file
* at max", so callers that care get their own signal. the extra fgetc
* after filling buf asks "is there really nothing left". */
long
readfile(const char* path, char* buf, long max)
{
FILE* f;
long n;
int extra;
f = fopen(path, "rb");
if(f == NULL)
{
return -1;
}
n = (long)fread(buf, 1, (size_t)max, f);
extra = fgetc(f);
fclose(f);
if(extra != EOF)
{
return -2;
}
return n;
}
long
writefile(const char* path, const char* buf, long n)
{
FILE* f;
long w;
f = fopen(path, "wb");
if(f == NULL)
{
return -1;
}
w = (long)fwrite(buf, 1, (size_t)n, f);
fclose(f);
if(w != n)
{
return -1;
}
return w;
}