gemini server written in C used with inetd
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
vger/utils.c

124 lines
2.5 KiB

#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <regex.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
#include "utils.h"
#include "vger.h"
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined( __NetBSD__) || defined(__DragonFly__)
#include <string.h>
#else
#include <bsd/string.h>
#endif
/* e*foo() functions are the equivalent of foo() but handle errors.
* In case an error happens:
* The error is printed to stdout
* return 1
*/
#ifdef __OpenBSD__
void
eunveil(const char *path, const char *permissions)
{
if (unveil(path, permissions) == -1) {
status(41, "Error when unveil(), see logs");
stop(EXIT_FAILURE, "unveil on %s failed", path);
}
}
void
epledge(const char *promises, const char *execpromises)
{
if (pledge(promises, execpromises) == -1) {
status(41, "Error when pledge(), see logs");
stop(EXIT_FAILURE, "pledge failed for: %s", promises);
}
}
#endif
size_t
esnprintf(char *str, size_t size, const char *format, ...)
{
/* usage : esnprintf(str, sizeof(str), "%s ... %s", arg1, arg2); */
va_list ap;
size_t ret = 0;
va_start(ap, format);
ret = vsnprintf(str, size, format, ap);
va_end(ap);
if (ret < 0 || ret >= size) {
status(41, "vnsprintf failed: Output trunkated");
stop(EXIT_FAILURE, "vsnprintf: Output trunkated");
}
return ret;
}
int
esetenv(const char *name, const char *value, int overwrite)
{
int ret = 0;
ret = setenv(name, value, overwrite);
if (ret != 0) {
status(41, "setenv() failed, see logs");
stop(EXIT_FAILURE, "setenv() %s:%s", name, value);
}
return ret;
}
void
echdir(const char *path)
{
if (chdir(path) == -1) {
switch (errno) {
case ENOTDIR: /* FALLTHROUGH */
case ENOENT:
status(51, "file not found");
break;
case EACCES:
status(50, "Forbidden path");
break;
default:
status(50, "Internal server error");
break;
}
stop(EXIT_FAILURE, "chdir(%s) failed", path);
}
}
/* read the file fd byte after byte in buffer and write it to stdout
* return number of bytes read
*/
size_t
print_file(FILE *fd)
{
ssize_t nread = 0;
ssize_t datasent = 0;
char *buffer[BUFSIZ];
while ((nread = fread(buffer, 1, sizeof(buffer), fd)) != 0)
datasent += fwrite(buffer, 1, nread, stdout);
return datasent;
}
void
getsubexp(const char *str, regmatch_t m, char *dst)
{
size_t len = 0;
if ((len = m.rm_eo - m.rm_so) > 0) { /* skip empty substring */
len = m.rm_eo - m.rm_so;
memcpy(dst, str + m.rm_so, len);
dst[len] = '\0';
}
}