MIDAS
Loading...
Searching...
No Matches
melog.cxx
Go to the documentation of this file.
1/********************************************************************\
2
3 Name: elog.c
4 Created by: Stefan Ritt
5
6 Contents: Electronic logbook utility
7
8 $Id:$
9
10\********************************************************************/
11
12#include <stdio.h>
13#include <sys/types.h>
14#include <fcntl.h>
15#include <stdarg.h>
16#include <string.h>
17#include <stdlib.h>
18
19#ifdef _MSC_VER
20#include <windows.h>
21#include <io.h>
22#else
23#include <netdb.h>
24#include <netinet/in.h>
25#include <sys/socket.h>
26#include <sys/time.h>
27#include <unistd.h>
28#include <signal.h>
29#define closesocket(s) close(s)
30#ifndef O_BINARY
31#define O_BINARY 0
32#endif
33#endif
34
35typedef int INT;
36
37#define MAX_ATTACHMENTS 10
38#define NAME_LENGTH 100
39#define MAX_N_ATTR 20
40
42
43/*------------------------------------------------------------------*/
44
45const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
46
47void base64_encode(char *s, char *d)
48{
49 unsigned int t, pad;
50
51 pad = 3 - strlen(s) % 3;
52 while (*s) {
53 t = (*s++) << 16;
54 if (*s)
55 t |= (*s++) << 8;
56 if (*s)
57 t |= (*s++) << 0;
58
59 *(d + 3) = map[t & 63];
60 t >>= 6;
61 *(d + 2) = map[t & 63];
62 t >>= 6;
63 *(d + 1) = map[t & 63];
64 t >>= 6;
65 *(d + 0) = map[t & 63];
66
67 d += 4;
68 }
69 *d = 0;
70 while (pad--)
71 *(--d) = '=';
72}
73
74/*------------------------------------------------------------------*/
75
76void sgets(char *string, int size)
77{
78 char *p;
79
80 do {
81 p = fgets(string, size, stdin);
82 } while (p == NULL);
83
84 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
85 p[strlen(p) - 1] = 0;
86}
87
88/*------------------------------------------------------------------*/
89
90char request[600000], response[10000], content[600000];
91
92INT submit_elog(char *host, int port, char *experiment, char *passwd,
93 char *uname, char *upwd,
94 char attrib_name[MAX_N_ATTR][NAME_LENGTH],
95 char attrib[MAX_N_ATTR][NAME_LENGTH],
96 int n_attr,
97 char *text,
98 char afilename[MAX_ATTACHMENTS][256],
99 char *buffer[MAX_ATTACHMENTS], INT buffer_size[MAX_ATTACHMENTS])
100/********************************************************************\
101
102 Routine: submit_elog
103
104 Purpose: Submit an ELog entry
105
106 Input:
107 char *host Host name where ELog server runs
108 in port ELog server port number
109 char *passwd Write password
110 char *uname User name
111 char *upwd User password
112 int run Run number
113 char *attrib_name Attribute names
114 char *attrib Attribute values
115 char *text Message text
116
117 char afilename[] File names of attachments
118 char *buffer[] Attachment contents
119 INT buffer_size[] Size of buffer in bytes
120
121 Function value:
122 EL_SUCCESS Successful completion
123
124\********************************************************************/
125{
126 int status, sock, i, n, header_length, content_length;
127 struct hostent *phe;
128 struct sockaddr_in bind_addr;
129 char boundary[80], str[80], *p;
130
131#if defined( _MSC_VER )
132 {
133 WSADATA WSAData;
134
135 /* Start windows sockets */
136 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
137 return -1;
138 }
139#endif
140
141 /* create socket */
142 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
143 perror("cannot create socket");
144 return -1;
145 }
146
147 /* compose remote address */
148 memset(&bind_addr, 0, sizeof(bind_addr));
149 bind_addr.sin_family = AF_INET;
150 bind_addr.sin_addr.s_addr = 0;
151 bind_addr.sin_port = htons((unsigned short) port);
152
153 phe = gethostbyname(host);
154 if (phe == NULL) {
155 perror("cannot get host name");
156 return -1;
157 }
158 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
159
160 /* connect to server */
161 status = connect(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
162 if (status != 0) {
163 printf("Cannot connect to host %s, port %d\n", host, port);
164 return -1;
165 }
166
167 if (verbose)
168 printf("Successfully connected to host %s, port %d\n", host, port);
169
170 /* compose content */
171 strcpy(boundary, "---------------------------7d0bf1a60904bc");
172 strcpy(content, boundary);
173 strcat(content, "\r\nContent-Disposition: form-data; name=\"cmd\"\r\n\r\nSubmit elog\r\n");
174
175 if (uname[0])
176 snprintf(content + strlen(content), sizeof(content) - strlen(content),
177 "%s\r\nContent-Disposition: form-data; name=\"unm\"\r\n\r\n%s\r\n",
178 boundary, uname);
179
180 if (upwd[0]) {
181 base64_encode(upwd, str);
182 snprintf(content + strlen(content), sizeof(content) - strlen(content),
183 "%s\r\nContent-Disposition: form-data; name=\"upwd\"\r\n\r\n%s\r\n",
184 boundary, str);
185 }
186
187 if (experiment[0])
188 snprintf(content + strlen(content), sizeof(content) - strlen(content),
189 "%s\r\nContent-Disposition: form-data; name=\"exp\"\r\n\r\n%s\r\n",
190 boundary, experiment);
191
192 for (i = 0; i < n_attr; i++)
193 snprintf(content + strlen(content), sizeof(content) - strlen(content),
194 "%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", boundary,
195 attrib_name[i], attrib[i]);
196
197 snprintf(content + strlen(content), sizeof(content) - strlen(content),
198 "%s\r\nContent-Disposition: form-data; name=\"Text\"\r\n\r\n%s\r\n%s\r\n",
199 boundary, text, boundary);
200
201 content_length = strlen(content);
202 p = content + content_length;
203
204 for (i = 0; i < MAX_ATTACHMENTS; i++)
205 if (afilename[i][0]) {
206 snprintf(p, sizeof(content) - strlen(content),
207 "Content-Disposition: form-data; name=\"attfile%d\"; filename=\"%s\"\r\n\r\n",
208 i + 1, afilename[i]);
209
210 content_length += strlen(p);
211 p += strlen(p);
212 memcpy(p, buffer[i], buffer_size[i]);
213 p += buffer_size[i];
214 strcpy(p, boundary);
215 strcat(p, "\r\n");
216
217 content_length += buffer_size[i] + strlen(p);
218 p += strlen(p);
219 }
220
221 /* compose request */
222 snprintf(request, sizeof(request), "POST / HTTP/1.0\r\n");
223 snprintf(request + strlen(request), sizeof(request) - strlen(request),
224 "Content-Type: multipart/form-data; boundary=%s\r\n", boundary);
225 snprintf(request + strlen(request), sizeof(request) - strlen(request), "Host: %s:%d\r\n", host, port);
226 snprintf(request + strlen(request), sizeof(request) - strlen(request), "User-Agent: ELOG\r\n");
227 snprintf(request + strlen(request), sizeof(request) - strlen(request), "Content-Length: %d\r\n", content_length);
228
229 if (passwd[0]) {
230 base64_encode(passwd, str);
231 snprintf(request + strlen(request), sizeof(request) - strlen(request), "Cookie: elog_wpwd=%s\r\n", str);
232 }
233
234 strcat(request, "\r\n");
235
236 header_length = strlen(request);
237 memcpy(request + header_length, content, content_length);
238
239 /*
240 {
241 FILE *f;
242 f = fopen("elog.log", "w");
243 fwrite(request, header_length+content_length, 1, f);
244 fclose(f);
245 }
246 */
247
248 /* send request */
249 if (verbose) {
250 printf("Request sent to host:\n");
251 puts(request);
252 }
253
254 send(sock, request, header_length + content_length, 0);
255
256 /* receive response */
257 i = recv(sock, response, 10000, 0);
258 if (i < 0) {
259 perror("Cannot receive response");
260 return -1;
261 }
262
263 /* discard remainder of response */
264 n = i;
265 while (i > 0) {
266 i = recv(sock, response + n, 10000, 0);
267 if (i > 0)
268 n += i;
269 }
270 response[n] = 0;
271
272 closesocket(sock);
273
274 if (verbose) {
275 printf("Response received:\n");
276 puts(response);
277 }
278
279 /* check response status */
280 if (strstr(response, "302 Found"))
281 printf("Message successfully transmitted\n");
282 else if (strstr(response, "Logbook Selection"))
283 printf("No logbook specified\n\n");
284 else if (strstr(response, "Enter password"))
285 printf("Missing or invalid password\n");
286 else if (strstr(response, "login"))
287 printf("Missing or invalid user name/password\n");
288 else
289 printf("Error transmitting message\n");
290
291 return 1;
292}
293
294/*------------------------------------------------------------------*/
295
296int main(int argc, char *argv[])
297{
298 char str[1000], text[10000], uname[80], upwd[80];
299 char host_name[256], logbook[32], textfile[256], password[80];
300 char *buffer[MAX_ATTACHMENTS], attachment[MAX_ATTACHMENTS][256];
301 INT att_size[MAX_ATTACHMENTS];
302 INT i, n, fh, n_att, n_attr, size, port;
303 char attr_name[MAX_N_ATTR][NAME_LENGTH], attrib[MAX_N_ATTR][NAME_LENGTH];
304
305 text[0] = textfile[0] = uname[0] = upwd[0] = 0;
306 host_name[0] = logbook[0] = password[0] = n_att = n_attr = 0;
307 port = 80;
308 for (i = 0; i < MAX_ATTACHMENTS; i++) {
309 attachment[i][0] = 0;
310 buffer[i] = NULL;
311 att_size[i] = 0;
312 }
313
314 /* parse command line parameters */
315 for (i = 1; i < argc; i++) {
316 if (argv[i][0] == '-' && argv[i][1] == 'v')
317 verbose = 1;
318 else {
319 if (argv[i][0] == '-') {
320 if (i + 1 >= argc || argv[i + 1][0] == '-')
321 goto usage;
322 if (argv[i][1] == 'h')
323 strcpy(host_name, argv[++i]);
324 else if (argv[i][1] == 'p')
325 port = atoi(argv[++i]);
326 else if (argv[i][1] == 'l')
327 strcpy(logbook, argv[++i]);
328 else if (argv[i][1] == 'w')
329 strcpy(password, argv[++i]);
330 else if (argv[i][1] == 'u') {
331 strcpy(uname, argv[++i]);
332 strcpy(upwd, argv[++i]);
333 } else if (argv[i][1] == 'a') {
334 strcpy(str, argv[++i]);
335 if (strchr(str, '=')) {
336 strcpy(attrib[n_attr], strchr(str, '=') + 1);
337 *strchr(str, '=') = 0;
338 strcpy(attr_name[n_attr], str);
339 n_attr++;
340 } else {
341 printf
342 ("Error: Attributes must be supplied in the form \"-a <attribute>=<value>\".\n");
343 return 0;
344 }
345 } else if (argv[i][1] == 'f')
346 strcpy(attachment[n_att++], argv[++i]);
347 else if (argv[i][1] == 'm')
348 strcpy(textfile, argv[++i]);
349 else {
350 usage:
351 printf("\nusage: elog -h <hostname> [-p port]\n");
352 printf(" [-l logbook/experiment]\n");
353 printf(" [-v] for verbose output\n");
354 printf
355 (" [-w password] write password defined on server\n");
356 printf(" [-u username password] user name and password\n");
357 printf(" [-f <attachment>] (up to %d times)\n",
359 printf(" -a <attribute>=<value> (up to %d times)\n",
360 MAX_N_ATTR);
361 printf(" -m <textfile>] | <text>\n");
362 printf("\nArguments with blanks must be enclosed in quotes\n");
363 printf("The elog message can either be submitted on the command line\n");
364 printf
365 ("or in a file with the -m flag. Multiple attributes and attachments\n");
366 printf("can be supplied\n");
367 return 0;
368 }
369 } else
370 strcpy(text, argv[i]);
371 }
372 }
373
374 if (host_name[0] == 0 || n_attr == 0 || (text[0] == 0 && textfile[0] == 0))
375 goto usage;
376
377 /*---- open text file ----*/
378
379 if (textfile[0]) {
380 fh = open(textfile, O_RDONLY | O_BINARY);
381 if (fh < 0) {
382 printf("Message file \"%s\" does not exist.\n", textfile);
383 return 0;
384 }
385
386 size = lseek(fh, 0, SEEK_END);
387 lseek(fh, 0, SEEK_SET);
388
389 if (size > (int)sizeof(text) - 1) {
390 printf("Message file \"%s\" is too long (%d bytes max).\n", textfile,
391 (int)sizeof(text));
392 return 0;
393 }
394
395 memset(text, 0, sizeof(text));
396 i = read(fh, text, size);
397 if (i < size) {
398 printf("Cannot fully read message file \"%s\".\n", textfile);
399 return 0;
400 }
401
402 close(fh);
403 }
404
405 /*---- open attachment file ----*/
406
407 for (i = 0; i < MAX_ATTACHMENTS; i++) {
408 if (!attachment[i][0])
409 break;
410
411 fh = open(attachment[i], O_RDONLY | O_BINARY);
412 if (fh < 0) {
413 printf("Attachment file \"%s\" does not exist.\n", attachment[i]);
414 return 0;
415 }
416
417 att_size[i] = lseek(fh, 0, SEEK_END);
418 lseek(fh, 0, SEEK_SET);
419
420 buffer[i] = (char*)malloc(att_size[i] + 1);
421 if (buffer[i] == NULL || att_size[i] > 500 * 1024) {
422 printf("Attachment file \"%s\" is too long (500k max).\n", attachment[i]);
423 return 0;
424 }
425
426 n = read(fh, buffer[i], att_size[i]);
427 if (n < att_size[i]) {
428 printf("Cannot fully read attachment file \"%s\".\n", attachment[i]);
429 return 0;
430 }
431 buffer[i][n] = 0;
432
433 close(fh);
434 }
435
436 /* now submit message */
437 submit_elog(host_name, port, logbook, password,
438 uname, upwd,
439 attr_name, attrib, n_attr, text, attachment, buffer, att_size);
440
441 for (i = 0; i < MAX_ATTACHMENTS; i++)
442 if (buffer[i])
443 free(buffer[i]);
444
445 return 1;
446}
static void usage()
int main()
Definition hwtest.cxx:23
DWORD n[4]
Definition mana.cxx:247
char host_name[HOST_NAME_LENGTH]
Definition mana.cxx:242
INT i
Definition mdump.cxx:32
void sgets(char *string, int size)
Definition melog.cxx:76
int verbose
Definition melog.cxx:41
#define O_BINARY
Definition melog.cxx:31
int INT
Definition melog.cxx:35
char content[600000]
Definition melog.cxx:90
char response[10000]
Definition melog.cxx:90
const char * map
Definition melog.cxx:45
INT submit_elog(char *host, int port, char *experiment, char *passwd, char *uname, char *upwd, char attrib_name[MAX_N_ATTR][NAME_LENGTH], char attrib[MAX_N_ATTR][NAME_LENGTH], int n_attr, char *text, char afilename[MAX_ATTACHMENTS][256], char *buffer[MAX_ATTACHMENTS], INT buffer_size[MAX_ATTACHMENTS])
Definition melog.cxx:92
#define closesocket(s)
Definition melog.cxx:29
char request[600000]
Definition melog.cxx:90
void base64_encode(char *s, char *d)
Definition melog.cxx:47
#define MAX_ATTACHMENTS
Definition melog.cxx:37
#define MAX_N_ATTR
Definition melog.cxx:39
#define NAME_LENGTH
Definition melog.cxx:38
int INT
Definition midas.h:129
#define read(n, a, f)
char str[256]
Definition odbhist.cxx:33
DWORD status
Definition odbhist.cxx:39
double d
Definition system.cxx:1313