+/*
+online-core.c
+Common parts of the online interface
+03.12.2022
+
+Copyright (C) 2013, 2014, 2015, 2022 Balthasar Szczepański
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Requires cgilib (http://www.infodrom.org/projects/cgilib/)
+*/
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "cgi.h"
+
+#include "online-core.h"
+
+#define FILE_CHUNK 1024
+
+
+int cp (char *src, char *dst)
+{
+ pid_t sub;
+ int r;
+
+ sub = fork();
+ if (sub == 0)
+ {
+ r = execl(CP_PATH, src, dst, (char *)0);
+ exit(r);
+ }
+ waitpid(sub, &r, 0);
+
+ return r;
+}
+
+int rm (char *dst)
+{
+ pid_t sub;
+ int r;
+
+ sub = fork();
+ if (sub == 0)
+ {
+ r = execl(RM_PATH, "-f", dst, (char *)0);
+ exit(r);
+ }
+ waitpid(sub, &r, 0);
+
+ return r;
+}
+
+int wget (char *url, char *dst)
+{
+ pid_t sub;
+ int r;
+
+ sub = fork();
+ if (sub == 0)
+ {
+ r = execl(WGET_PATH, "-q", "-t", "2", "-U", USERAGENT, "-O", dst, url, (char *)0);
+ exit(r);
+ }
+ waitpid(sub, &r, 0);
+
+ return r;
+}
+
+void make_tmp_path(char *str, size_t n, unsigned int i, char *ext)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+
+ snprintf(
+ str,
+ n,
+ "%s/%lu_%u_%llu_%lu%s",
+ TEMP_PATH,
+ (long unsigned) getpid(),
+ i,
+ (long long unsigned) (tv.tv_sec),
+ (long unsigned) (tv.tv_usec),
+ ext
+ );
+}
+
+int get_file(s_cgi *cgi, char *name, char *dest, char **path)
+{
+ char **vl;
+ char *v;
+ s_file *f;
+ int i;
+ int r;
+
+ vl = cgiGetFiles(cgi);
+ if (vl != NULL)
+ {
+ for (i=0; vl[i]!= NULL; ++i)
+ {
+ if (strcmp(vl[i], name)==0)
+ {
+ f = cgiGetFile(cgi, vl[i]);
+ if (f == NULL)
+ break;
+ if (dest != NULL)
+ {
+ r = cp(f->tmpfile, dest);
+ if (r)
+ return r;
+ *path = dest;
+ }
+ else
+ *path = f->tmpfile;
+ return 0;
+ }
+ }
+ }
+
+ if (dest == NULL)
+ return EINVAL;
+
+ v = cgiGetValue(cgi, name);
+ if (v==NULL)
+ return EINVAL;
+ r = wget(v, dest);
+ if (r)
+ return r;
+ *path = dest;
+ return 0;
+}
+
+int send_file (char *path, char *content_type, unsigned status)
+{
+ FILE *f;
+ struct stat st;
+ int64_t size;
+ size_t wr, rd, off;
+ uint8_t buffer[FILE_CHUNK];
+
+ f = fopen(path, "rb");
+ if (f == NULL)
+ return EIO;
+ fstat(fileno(f), &st);
+ size = st.st_size;
+
+ if (status != 0)
+ fprintf(stdout, "Status: %u\n", status);
+ if (content_type!=NULL)
+ fprintf(stdout, "Content-type: %s", content_type);
+ fprintf(stdout, "Content-Length: %" PRId64 "\n\n", size);
+
+ while (size>0)
+ {
+ rd = fread(buffer, 1, FILE_CHUNK, f);
+ if (rd == 0)
+ break;
+ off =0;
+ while (off < rd)
+ {
+ wr = fwrite(buffer+off, 1, rd - off, stdout);
+ if (wr == 0)
+ break;
+ off += wr;
+ }
+ if (wr == 0)
+ break;
+ size -= rd;
+ }
+
+ fclose (f);
+ return 0;
+}
+
+int send_data (const uint8_t *address, size_t size, char *content_type, unsigned status)
+{
+ size_t wr, off;
+
+ if (status != 0)
+ fprintf(stdout, "Status: %u\n", status);
+ if (content_type!=NULL)
+ fprintf(stdout, "Content-type: %s", content_type);
+ fprintf(stdout, "Content-Length: %" PRId64 "\n\n", (uint64_t)size);
+
+ off = 0;
+ while (off<size)
+ {
+ wr = size - off;
+ if (wr > FILE_CHUNK)
+ wr = FILE_CHUNK;
+ wr = fwrite(address +off, 1, wr, stdout);
+ if (wr == 0)
+ break;
+ off += wr;
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+
+
\ No newline at end of file