forked from solene/vger
Connect to unix sockets to interface with user-written programs.
This commit is contained in:
parent
f647ff347a
commit
2afaf5510b
|
@ -1,2 +1,3 @@
|
|||
*.o
|
||||
vger
|
||||
unit_test
|
||||
|
|
4
main.c
4
main.c
|
@ -88,10 +88,10 @@ main(int argc, char **argv)
|
|||
/* *** from here, cgi didn't run *** */
|
||||
|
||||
/* check if path available */
|
||||
check_path(path, sizeof(path));
|
||||
struct stat sb = check_path(path, sizeof(path));
|
||||
|
||||
/* regular file to stdout */
|
||||
display_file(path);
|
||||
display_file(path, sb);
|
||||
|
||||
stop(EXIT_SUCCESS, NULL);
|
||||
}
|
||||
|
|
5
utils.h
5
utils.h
|
@ -1,3 +1,6 @@
|
|||
#ifndef utils_h_INCLUDED
|
||||
#define utils_h_INCLUDED
|
||||
|
||||
void getsubexp(const char *, regmatch_t, char *);
|
||||
void echdir(const char *);
|
||||
void epledge(const char *, const char *);
|
||||
|
@ -6,3 +9,5 @@ int esetenv(const char *, const char *, int);
|
|||
size_t esnprintf(char *, size_t, const char *, ...);
|
||||
size_t print_file(FILE *fd);
|
||||
void set_errmsg(const char *, ...);
|
||||
|
||||
#endif // utils_h_INCLUDED
|
||||
|
|
67
vger.c
67
vger.c
|
@ -1,6 +1,8 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
|
@ -175,20 +177,77 @@ set_rootdir(const char *chroot_dir, const char *cgi_dir, const char *user)
|
|||
}
|
||||
|
||||
ssize_t
|
||||
display_file(const char *path)
|
||||
display_file(const char *path, struct stat sb)
|
||||
{
|
||||
FILE *fd = NULL;
|
||||
const char *file_mime;
|
||||
size_t pathlen = strlen(path);
|
||||
|
||||
/*
|
||||
* special case : path ends with "/". The user requested a dir
|
||||
*/
|
||||
if ((path[strlen(path)-1] == '/') && (doautoidx)) {
|
||||
if ((path[pathlen-1] == '/') && (doautoidx)) {
|
||||
/* no index.gmi, so display autoindex if enabled */
|
||||
_datasiz += autoindex(path);
|
||||
return _datasiz;
|
||||
}
|
||||
|
||||
if (S_ISSOCK(sb.st_mode)) {
|
||||
/* I got these numbers off of a Stack Overflow answer, so take them with a grain of salt. */
|
||||
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined( __NetBSD__) || defined(__DragonFly__)
|
||||
if(pathlen > 104) {
|
||||
#elif defined(__linux__)
|
||||
if(pathlen > 108) {
|
||||
#else
|
||||
#error "I don't know the max path length of a unix socket for this system!"
|
||||
#endif
|
||||
/* If the name is too long. */
|
||||
status(40, "%s", "socket name is too long");
|
||||
return _datasiz;
|
||||
}
|
||||
|
||||
/* Create the socket address (a filename, really). */
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, path, pathlen);
|
||||
|
||||
/* Allocate a UNIX domain socket. */
|
||||
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
/* Connect to the desired socket. */
|
||||
int ret = connect(sock, (const struct sockaddr *) &addr, sizeof(struct sockaddr_un));
|
||||
if (ret == -1) {
|
||||
status(43, "%s", "unable to connect to socket");
|
||||
return _datasiz;
|
||||
}
|
||||
|
||||
/* TODO: Move this to its own function. */
|
||||
file_mime = get_file_mime(path, default_mime);
|
||||
if (strcmp(file_mime, "text/gemini") == 0)
|
||||
status(20, "%s; %s", file_mime, lang);
|
||||
else
|
||||
status(20, "%s", file_mime);
|
||||
|
||||
/* Read data until the socket is closed. */
|
||||
char buffer[BUFSIZ];
|
||||
for (;;) {
|
||||
ret = read(sock, buffer, BUFSIZ);
|
||||
if (ret == -1) {
|
||||
_datasiz += fprintf(stdout, "\n\n\nsocket read error: %i\n", errno);
|
||||
break;
|
||||
} else if (ret == 0) {
|
||||
break; /* end of file */
|
||||
} else {
|
||||
fwrite(buffer, 1, ret, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/* We're done! */
|
||||
close(sock);
|
||||
return _datasiz;
|
||||
}
|
||||
|
||||
/* open the file requested */
|
||||
if ((fd = fopen(path, "r")) != NULL) {
|
||||
file_mime = get_file_mime(path, default_mime);
|
||||
|
@ -398,7 +457,7 @@ remove_double_dot(char *request)
|
|||
memmove(request, pos + 3, strlen(pos) + 1 - 3); /* "/.." = 3 */
|
||||
}
|
||||
|
||||
void
|
||||
struct stat
|
||||
check_path(char *path, size_t pathsiz)
|
||||
{
|
||||
struct stat sb = {0};
|
||||
|
@ -427,6 +486,8 @@ check_path(char *path, size_t pathsiz)
|
|||
if (stat(tmp, &sb) == 0)
|
||||
esnprintf(path, pathsiz, "%s", tmp);
|
||||
}
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
4
vger.h
4
vger.h
|
@ -42,8 +42,8 @@ static char _request[GEMINI_REQUEST_MAX] = {'\0'};
|
|||
ssize_t autoindex(const char *);
|
||||
void cgi(const char *);
|
||||
char * read_request(char *);
|
||||
void check_path(char *, size_t);
|
||||
ssize_t display_file(const char *);
|
||||
struct stat check_path(char *, size_t);
|
||||
ssize_t display_file(const char *, struct stat);
|
||||
int do_cgi(const char *, const char *, const char *, const char *);
|
||||
void drop_privileges(const char *);
|
||||
void set_rootdir(const char *, const char *, const char *);
|
||||
|
|
Loading…
Reference in New Issue