beans

simple pastebin server
git clone git://git.bitsmanent.org/beans
Log | Files | Refs | LICENSE

commit 53623d8cb7d97e3adc08f7f65a92b940dc2fa3e2
Author: Claudio Alessi <smoppy@gmail.com>
Date:   Sun,  6 Jan 2019 23:47:01 +0100

Working concept (very dirty).

Diffstat:
ALICENSE | 21+++++++++++++++++++++
AMakefile | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abeans.c | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aconfig.mk | 25+++++++++++++++++++++++++
4 files changed, 240 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,21 @@ +MIT/X Consortium License + +© 2019 Claudio Alessi <smoppy at gmail dot com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile @@ -0,0 +1,57 @@ +# beans - simple pastebin server +# See LICENSE file for copyright and license details. + +include config.mk + +APPNAME=beans +SRC = ${APPNAME}.c +OBJ = ${SRC:.c=.o} + +all: options ${APPNAME} + +options: + @echo ${APPNAME} build options: + @echo "CFLAGS = ${CFLAGS}" + @echo "LDFLAGS = ${LDFLAGS}" + @echo "CC = ${CC}" + +.c.o: + @echo CC $< + @${CC} -c ${CFLAGS} $< + +${OBJ}: config.mk + +${APPNAME}: ${OBJ} + @echo CC -o $@ + @${CC} -o $@ ${OBJ} ${LDFLAGS} + +clean: + @echo cleaning + @rm -f ${APPNAME} ${OBJ} ${APPNAME}-${VERSION}.tar.gz + +dist: clean + @echo creating dist tarball + @mkdir -p ${APPNAME}-${VERSION} + @cp -R LICENSE Makefile README config.mk \ + ${APPNAME}.1 ${SRC} ${APPNAME}-${VERSION} + @tar -cf ${APPNAME}-${VERSION}.tar ${APPNAME}-${VERSION} + @gzip ${APPNAME}-${VERSION}.tar + @rm -rf ${APPNAME}-${VERSION} + +install: all + @echo installing executable file to ${DESTDIR}${PREFIX}/bin + @mkdir -p ${DESTDIR}${PREFIX}/bin + @cp -f ${APPNAME} ${DESTDIR}${PREFIX}/bin + @chmod 755 ${DESTDIR}${PREFIX}/bin/${APPNAME} + @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1 + @mkdir -p ${DESTDIR}${MANPREFIX}/man1 + @sed "s/VERSION/${VERSION}/g" < ${APPNAME}.1 > ${DESTDIR}${MANPREFIX}/man1/${APPNAME}.1 + @chmod 644 ${DESTDIR}${MANPREFIX}/man1/${APPNAME}.1 + +uninstall: + @echo removing executable file from ${DESTDIR}${PREFIX}/bin + @rm -f ${DESTDIR}${PREFIX}/bin/${APPNAME} + @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 + @rm -f ${DESTDIR}${MANPREFIX}/man1/${APPNAME}.1 + +.PHONY: all options clean dist install uninstall diff --git a/beans.c b/beans.c @@ -0,0 +1,137 @@ +/* beans is a simple pastebin server */ + +#include <errno.h> +#include <netdb.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> + +#define PORT "2023" +#define BACKLOG 32 /* XXX What's a reasonable value? */ +#define BASEURI "https://paste.bitmanent.org/p" + +void +die(const char *errstr, ...) { + va_list ap; + + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(1); +} + +int +bindon(char *port) { + struct addrinfo hints, *res; + int sd = 0, e; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + if((e = getaddrinfo(NULL, port, &hints, &res))) + die("getaddrinfo(): %s\n", gai_strerror(e)); + if((sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) + die("socket(): %s\n", strerror(errno)); + if(bind(sd, res->ai_addr, res->ai_addrlen) == -1) + die("bind(): %s\n", strerror(errno)); + if(listen(sd, BACKLOG) == -1) + die("listen(): %s\n", strerror(errno)); + return sd; +} + +void * +ecalloc(size_t nmemb, size_t size) { + void *p; + + if(!(p = calloc(nmemb, size))) + die("Cannot allocate memory.\n"); + return p; +} + +char * +readall(int sd, int *len) { + char *buf; + int sz = 512, r, l = 0; + + buf = ecalloc(1, sz); + while((r = read(sd, &buf[l], sz - l)) != -1) { + if(!r) + break; + l += r; + if(l == sz) { + sz *= 2; + if(!(buf = realloc(buf, sz))) + die("realloc()\n"); + } + } + if(r == -1) { + free(buf); + return NULL; + } + if(len) + *len = l; + buf[l] = '\0'; + return buf; +} + +void +sout(int sd, char *fmt, ...) { + va_list ap; + char buf[4096]; + int sz; + + va_start(ap, fmt); + sz = vsnprintf(buf, sizeof buf, fmt, ap); + va_end(ap); + send(sd, buf, sz, 0); +} + +int +main(int argc, char *argv[]) { + struct sockaddr_storage conn; + socklen_t size; + int sd, csd, len, tmpsd; + char tmpfn[64] = {0}, *buf, *p; + + sd = bindon(PORT); + size = sizeof conn; + while(1) { + csd = accept(sd, (struct sockaddr *)&conn, &size); + if(csd == -1) { + fprintf(stderr, "accept(): %s", strerror(errno)); + continue; + } + buf = readall(csd, &len); + if(!(buf && len)) { + sout(csd, "Nothing pasted.\n"); + close(csd); + continue; + } + snprintf(tmpfn, sizeof tmpfn, "/tmp/beans.XXXXXX"); + tmpsd = mkstemp(tmpfn); + if(tmpsd == -1) { + fprintf(stderr, "mkstemp()\n"); + free(buf); + close(csd); + continue; + } + if(write(tmpsd, buf, len) == -1) + fprintf(stderr, "write(): %s\n", strerror(errno)); + p = strchr(tmpfn, '.'); + if(p && ++p) + sout(csd, "%s/%s\n", BASEURI, p); + else + sout(csd, "Paste error.\n"); + close(csd); + close(tmpsd); + free(buf); + } + close(sd); + return 0; +} diff --git a/config.mk b/config.mk @@ -0,0 +1,25 @@ +# beans - simple pastebin server +VERSION = 0.1 + +# Customize below to fit your system + +# paths +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +# includes and libs +INCS = +LIBS = + +# flags +CPPFLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" +#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} +CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} +LDFLAGS = -s ${LIBS} + +# Solaris +#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" +#LDFLAGS = ${LIBS} + +# compiler and linker +CC = cc