]> bicyclesonthemoon.info Git - ott/enhance/blob - online-core.c
Online bluenh seems to work ok.
[ott/enhance] / online-core.c
1 /*
2 online-core.c
3 Common parts of the online interface
4 03.12.2022
5
6 Copyright (C) 2013, 2014, 2015, 2022  Balthasar SzczepaƄski
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Affero General Public License as
10 published by the Free Software Foundation, either version 3 of the
11 License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21 Requires cgilib (http://www.infodrom.org/projects/cgilib/)
22 */
23
24 #include <string.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <sys/wait.h>
30 #include <sys/time.h>
31 #include <sys/stat.h>
32 #include <stdint.h>
33 #include <inttypes.h>
34
35 #include "cgi.h"
36
37 #include "online-core.h"
38
39 #define FILE_CHUNK 1024
40
41
42 int cp (char *src, char *dst)
43 {
44         pid_t sub;
45         int r;
46         
47         sub = fork();
48         if (sub == 0)
49         {
50                 r = execl(CP_PATH, CP_PATH, src, dst, (char *)0);
51                 exit(r);
52         }
53         waitpid(sub, &r, 0);
54         
55         return r;
56 }
57
58 int rm (char *dst)
59 {
60         pid_t sub;
61         int r;
62         
63         sub = fork();
64         if (sub == 0)
65         {
66                 r = execl(RM_PATH, RM_PATH, "-f", dst, (char *)0);
67                 exit(r);
68         }
69         waitpid(sub, &r, 0);
70         
71         return r;
72 }
73
74 int wget (char *url, char *dst)
75 {
76         pid_t sub;
77         int r;
78         
79         sub = fork();
80         if (sub == 0)
81         {
82                 r = execl(WGET_PATH, WGET_PATH, "-q", "-t", "2", "-U", USERAGENT, "-O", dst, url, (char *)0);
83                 exit(r);
84         }
85         waitpid(sub, &r, 0);
86         
87         return r;
88 }
89
90 void make_tmp_path(char *str, size_t n, unsigned int i, char *ext)
91 {
92         struct timeval tv;
93         
94         gettimeofday(&tv, NULL);
95         
96         snprintf(
97                 str,
98                 n,
99                 "%s/%lu_%u_%llu_%lu%s",
100                 TEMP_PATH,
101                 (long unsigned) getpid(),
102                 i,
103                 (long long unsigned) (tv.tv_sec),
104                 (long unsigned) (tv.tv_usec),
105                 ext
106         );
107 }
108
109 int get_file(s_cgi *cgi, char *name, char *dest, char **path)
110 {
111         char **vl;
112         char *v;
113         s_file *f;
114         int i;
115         int r;
116         
117         vl = cgiGetFiles(cgi);
118         if (vl != NULL)
119         {
120                 for (i=0; vl[i]!= NULL; ++i)
121                 {
122                         if (strcmp(vl[i], name)==0)
123                         {
124                                 f = cgiGetFile(cgi, vl[i]);
125                                 if (f == NULL)
126                                         break;
127                                 if (dest != NULL)
128                                 {
129                                         r = cp(f->tmpfile, dest);
130                                         if (r)
131                                                 return r;
132                                         *path = dest;
133                                 }
134                                 else
135                                         *path = f->tmpfile;
136                                 return 0;
137                         }
138                 }
139         }
140         
141         if (dest == NULL)
142                 return EINVAL;
143         
144         v = cgiGetValue(cgi, name);
145         if (v==NULL)
146                 return EINVAL;
147         r = wget(v, dest);
148         if (r)
149                 return r;
150         *path = dest;
151         return 0;
152 }
153
154 int send_file (char *path, char *content_type, unsigned status)
155 {
156         FILE *f;
157         struct stat st;
158         int64_t size;
159         size_t wr, rd, off;
160         uint8_t buffer[FILE_CHUNK];
161         
162         f = fopen(path, "rb");
163         if (f == NULL)
164                 return EIO;
165         fstat(fileno(f), &st);
166         size = st.st_size;
167         
168         if (status != 0)
169                 fprintf(stdout, "Status: %u\n", status);
170         if (content_type!=NULL)
171                 fprintf(stdout, "Content-type: %s", content_type);
172         fprintf(stdout, "Content-Length: %" PRId64 "\n\n", size);
173         
174         while (size>0)
175         {
176                 rd = fread(buffer, 1, FILE_CHUNK, f);
177                 if (rd == 0)
178                         break;
179                 off =0;
180                 while (off < rd)
181                 {
182                         wr = fwrite(buffer+off, 1, rd - off, stdout);
183                         if (wr == 0)
184                                 break;
185                         off += wr;
186                 }
187                 if (wr == 0)
188                         break;
189                 size -= rd;
190         }
191         
192         fclose (f);
193         return 0;
194 }
195
196 int send_data (const uint8_t *address, size_t size, char *content_type, unsigned status)
197 {
198         size_t wr, off;
199         
200         if (status != 0)
201                 fprintf(stdout, "Status: %u\n", status);
202         if (content_type!=NULL)
203                 fprintf(stdout, "Content-type: %s", content_type);
204         fprintf(stdout, "Content-Length: %" PRId64 "\n\n", (uint64_t)size);
205         
206         off = 0;
207         while (off<size)
208         {
209                 wr = size - off;
210                 if (wr > FILE_CHUNK)
211                         wr = FILE_CHUNK;
212                 wr = fwrite(address +off, 1, wr, stdout);
213                 if (wr == 0)
214                         break;
215                 off += wr;
216         }
217         
218         return 0;
219 }
220
221         
222         
223         
224         
225         
226         
227