Jpp test-rotations-new
the software that should make you happy
Loading...
Searching...
No Matches
elog.cc File Reference
#include "elog-version.h"
#include "git-revision.h"
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include "strlcpy.h"

Go to the source code of this file.

Macros

#define closesocket(s)
 
#define O_BINARY   0
 
#define MAX_ATTACHMENTS   50
 
#define NAME_LENGTH   500
 
#define MAX_N_ATTR   50
 
#define TEXT_SIZE   100000
 

Typedefs

typedef int INT
 

Functions

const char * git_revision ()
 
void base64_encode (unsigned char *s, unsigned char *d, int size)
 
int equal_ustring (const char *str1, const char *str2)
 
char * sha256_crypt (const char *key, const char *salt)
 
void do_crypt (char *s, char *d, int size)
 
void stou (char *str)
 
void url_encode (char *ps, int size)
 
void sgets (char *string, int size)
 
void add_crlf (char *buffer, int bufsize)
 
void convert_crlf (char *buffer, int bufsize)
 
int elog_connect (char *host, int port)
 
INT retrieve_elog (char *host, int port, char *subdir, int ssl, char *experiment, char *uname, char *upwd, int message_id, char attrib_name[MAX_N_ATTR][NAME_LENGTH], char attrib[MAX_N_ATTR][NAME_LENGTH], char *text)
 
INT submit_elog (char *host, int port, int ssl, char *subdir, char *experiment, char *uname, char *upwd, int reply, int quote_on_reply, int edit, int download, int suppress, int encoding, 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])
 
int main (int argc, char *argv[])
 

Variables

const char * _git_revision = GIT_REVISION
 
int verbose
 
char text [TEXT_SIZE]
 
char old_text [TEXT_SIZE]
 
char new_text [TEXT_SIZE]
 
const char * map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 
char request [100000]
 
char response [100000]
 
char * content
 

Macro Definition Documentation

◆ closesocket

#define closesocket ( s)
Value:
close(s)

Definition at line 49 of file elog.cc.

◆ O_BINARY

#define O_BINARY   0

Definition at line 51 of file elog.cc.

◆ MAX_ATTACHMENTS

#define MAX_ATTACHMENTS   50

Definition at line 64 of file elog.cc.

◆ NAME_LENGTH

#define NAME_LENGTH   500

Definition at line 65 of file elog.cc.

◆ MAX_N_ATTR

#define MAX_N_ATTR   50

Definition at line 66 of file elog.cc.

◆ TEXT_SIZE

#define TEXT_SIZE   100000

Definition at line 68 of file elog.cc.

Typedef Documentation

◆ INT

typedef int INT

Definition at line 62 of file elog.cc.

Function Documentation

◆ git_revision()

const char * git_revision ( )

Definition at line 77 of file elog.cc.

78{
79 const char *p = _git_revision;
80 if (strrchr(p, '-'))
81 p = strrchr(p, '-')+2;
82 return p;
83}
const char * _git_revision
Definition elog.cc:27

◆ base64_encode()

void base64_encode ( unsigned char * s,
unsigned char * d,
int size )

Definition at line 89 of file elog.cc.

90{
91 unsigned int t, pad;
92 unsigned char *p;
93
94 pad = 3 - strlen((char *) s) % 3;
95 if (pad == 3)
96 pad = 0;
97 p = d;
98 while (*s) {
99 t = (*s++) << 16;
100 if (*s)
101 t |= (*s++) << 8;
102 if (*s)
103 t |= (*s++) << 0;
104
105 *(d + 3) = map[t & 63];
106 t >>= 6;
107 *(d + 2) = map[t & 63];
108 t >>= 6;
109 *(d + 1) = map[t & 63];
110 t >>= 6;
111 *(d + 0) = map[t & 63];
112
113 d += 4;
114 if (d - p >= size - 3)
115 return;
116 }
117 *d = 0;
118 while (pad--)
119 *(--d) = '=';
120}
const char * map
Definition elog.cc:87

◆ equal_ustring()

int equal_ustring ( const char * str1,
const char * str2 )

Definition at line 125 of file elog.cc.

126{
127 if (str1 == NULL && str2 != NULL)
128 return 0;
129 if (str1 != NULL && str2 == NULL)
130 return 0;
131 if (str1 == NULL && str2 == NULL)
132 return 1;
133
134 while (*str1)
135 if (toupper(*str1++) != toupper(*str2++))
136 return 0;
137
138 if (*str2)
139 return 0;
140
141 return 1;
142}

◆ sha256_crypt()

char * sha256_crypt ( const char * key,
const char * salt )

Definition at line 573 of file crypt.cc.

574{
575 /* We don't want to have an arbitrary limit in the size of the
576 password. We can compute an upper bound for the size of the
577 result in advance and so we can prepare the buffer we pass to
578 `sha256_crypt_r'. */
579 static char *buffer;
580 static int buflen;
581 int needed = (sizeof(sha256_salt_prefix) - 1
582 + sizeof(sha256_rounds_prefix) + 9 + 1 + strlen(salt) + 1 + 43 + 1);
583
584 if (buflen < needed) {
585 char *new_buffer = (char *) realloc(buffer, needed);
586 if (new_buffer == NULL)
587 return NULL;
588
589 buffer = new_buffer;
590 buflen = needed;
591 }
592
593 return sha256_crypt_r(key, salt, buffer, buflen);
594}
static const char sha256_salt_prefix[]
Definition crypt.cc:309
static char * sha256_crypt_r(const char *key, const char *salt, char *buffer, int buflen)
Definition crypt.cc:327
static const char sha256_rounds_prefix[]
Definition crypt.cc:312

◆ do_crypt()

void do_crypt ( char * s,
char * d,
int size )

Definition at line 146 of file elog.cc.

147{
148 strlcpy(d, sha256_crypt(s, "$5$") + 4, size);
149}
char * sha256_crypt(const char *key, const char *salt)
Definition crypt.cc:573
size_t strlcpy(char *dst, const char *src, size_t size)
Definition strlcpy.cc:39

◆ stou()

void stou ( char * str)

Definition at line 153 of file elog.cc.

155{
156 int i;
157
158 for (i = 0; i < (int) strlen(str); i++)
159 if (str[i] == ' ' || str[i] == '.' || str[i] == '/' ||
160 str[i] == '\\' || str[i] == '-' || str[i] == '(' || str[i] == ')')
161 str[i] = '_';
162}

◆ url_encode()

void url_encode ( char * ps,
int size )

Definition at line 166 of file elog.cc.

170{
171 unsigned char *pd, *p;
172 unsigned char str[NAME_LENGTH];
173
174 pd = (unsigned char *) str;
175 p = (unsigned char *) ps;
176 while (*p && pd < str + 250) {
177 if (strchr("%&=#?+", *p) || *p > 127) {
178 sprintf((char *) pd, "%%%02X", *p);
179 pd += 3;
180 p++;
181 } else if (*p == ' ') {
182 *pd++ = '+';
183 p++;
184 } else {
185 *pd++ = *p++;
186 }
187 }
188 *pd = '\0';
189 strlcpy(ps, (char *) str, size);
190}
#define NAME_LENGTH
Definition elog.cc:65

◆ sgets()

void sgets ( char * string,
int size )

Definition at line 194 of file elog.cc.

195{
196 char *p;
197
198 do {
199 p = fgets(string, size, stdin);
200 } while (p == NULL);
201
202 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
203 p[strlen(p) - 1] = 0;
204}

◆ add_crlf()

void add_crlf ( char * buffer,
int bufsize )

Definition at line 208 of file elog.cc.

209{
210 char *p;
211 char *tmpbuf;
212
213 tmpbuf = (char *)malloc(bufsize);
214
215 /* convert \n -> \r\n */
216 p = buffer;
217 while ((p = strstr(p, "\n")) != NULL) {
218
219 if (p > buffer && *(p - 1) == '\r') {
220 p++;
221 continue;
222 }
223
224 if ((int) strlen(buffer) + 2 >= bufsize) {
225 free(tmpbuf);
226 return;
227 }
228
229 strlcpy(tmpbuf, p, bufsize);
230 *(p++) = '\r';
231 strlcpy(p, tmpbuf, bufsize - (p - buffer));
232 p++;
233 }
234
235 free(tmpbuf);
236}

◆ convert_crlf()

void convert_crlf ( char * buffer,
int bufsize )

Definition at line 240 of file elog.cc.

241{
242 char *p;
243
244 /* convert '\n' -> \r\n */
245 p = buffer;
246 while ((p = strstr(p, "\\n")) != NULL) {
247
248 if (p - buffer < bufsize - 2) {
249 *(p++) = '\r';
250 *(p++) = '\n';
251 }
252 }
253}

◆ elog_connect()

int elog_connect ( char * host,
int port )

Definition at line 257 of file elog.cc.

258{
259 int status, sock;
260 struct hostent *phe;
261 struct sockaddr_in bind_addr;
262
263 /* create socket */
264 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
265 perror("cannot create socket");
266 return -1;
267 }
268
269 /* compose remote address */
270 memset(&bind_addr, 0, sizeof(bind_addr));
271 bind_addr.sin_family = AF_INET;
272 bind_addr.sin_addr.s_addr = 0;
273 bind_addr.sin_port = htons((unsigned short) port);
274
275 phe = gethostbyname(host);
276 if (phe == NULL) {
277 perror("cannot get host name");
278 return -1;
279 }
280 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
281
282 /* connect to server */
283 status = connect(sock, (const sockaddr*) (&bind_addr), sizeof(bind_addr));
284 if (status != 0) {
285 printf("Cannot connect to host %s, port %d\n", host, port);
286 return -1;
287 }
288
289 if (verbose)
290 printf("Successfully connected to host %s, port %d\n", host, port);
291
292 return sock;
293}
int verbose
Definition elog.cc:70

◆ retrieve_elog()

INT retrieve_elog ( char * host,
int port,
char * subdir,
int ssl,
char * experiment,
char * uname,
char * upwd,
int message_id,
char attrib_name[MAX_N_ATTR][NAME_LENGTH],
char attrib[MAX_N_ATTR][NAME_LENGTH],
char * text )

Definition at line 332 of file elog.cc.

357{
358 int i, n, first, index, sock;
359 char str[256], encrypted_passwd[256], *ph, *ps;
360#ifdef HAVE_SSL
361 SSL *ssl_con = NULL;
362#endif
363
364 if (ssl) /* avoid compiler warning */
365 sock = 0;
366
367 sock = elog_connect(host, port);
368 if (sock < 0)
369 return sock;
370
371#ifdef HAVE_SSL
372 if (ssl)
373 if (ssl_connect(sock, &ssl_con) < 0) {
374 printf("elogd server does not run SSL protocol\n");
375 return -1;
376 }
377#endif
378
379 /* compose request */
380 strcpy(request, "GET /");
381 strlcpy(str, experiment, sizeof(str));
382 url_encode(str, sizeof(str));
383 if (subdir[0] && experiment[0])
384 sprintf(request + strlen(request), "%s/%s/%d?cmd=download", subdir, str, message_id);
385 else if (subdir[0])
386 sprintf(request + strlen(request), "%s/%d?cmd=download", subdir, message_id);
387 else if (experiment[0])
388 sprintf(request + strlen(request), "%s/%d?cmd=download", str, message_id);
389 strcat(request, " HTTP/1.0\r\n");
390
391 sprintf(request + strlen(request), "User-Agent: ELOG\r\n");
392
393 first = 1;
394
395 if (uname[0]) {
396 if (first)
397 sprintf(request + strlen(request), "Cookie: ");
398 first = 0;
399
400 sprintf(request + strlen(request), "unm=%s;", uname);
401 }
402
403 if (upwd[0]) {
404 if (first)
405 sprintf(request + strlen(request), "Cookie: ");
406 first = 0;
407
408 do_crypt(upwd, encrypted_passwd, sizeof(encrypted_passwd));
409 sprintf(request + strlen(request), "upwd=%s;", encrypted_passwd);
410 }
411
412 /* finish cookie line */
413 if (!first)
414 strcat(request, "\r\n");
415
416 strcat(request, "\r\n");
417
418 /* send request */
419#ifdef HAVE_SSL
420 if (ssl)
421 SSL_write(ssl_con, request, strlen(request));
422 else
423#endif
424 send(sock, request, strlen(request), 0);
425 if (verbose) {
426 printf("Request sent to host:\n");
427 puts(request);
428 }
429
430 /* receive response */
431 memset(response, 0, sizeof(response));
432#ifdef HAVE_SSL
433 if (ssl)
434 i = SSL_read(ssl_con, response, sizeof(response) - 1);
435 else
436#endif
437 i = recv(sock, response, sizeof(response) - 1, 0);
438 if (i < 0) {
439 perror("Cannot receive response");
440 return -1;
441 }
442
443 n = i;
444 while (i > 0) {
445#ifdef HAVE_SSL
446 if (ssl)
447 i = SSL_read(ssl_con, response + n, sizeof(response) - 1 - n);
448 else
449#endif
450 i = recv(sock, response + n, sizeof(response) - 1 - n, 0);
451 if (i > 0)
452 n += i;
453 }
454 response[n] = 0;
455
456#ifdef HAVE_SSL
457 if (ssl) {
458 SSL_shutdown(ssl_con);
459 SSL_free(ssl_con);
460 }
461#endif
462
463 closesocket(sock);
464
465 if (verbose) {
466 printf("Response received:\n");
467 puts(response);
468 }
469
470 /* check response status */
471 if (strstr(response, "$@MID@$:")) {
472 /* separate attributes and message */
473
474 ph = strstr(response, "========================================\n");
475
476 /* skip first line */
477 ps = strstr(response, "$@MID@$:");
478 while (*ps && *ps != '\n')
479 ps++;
480 while (*ps && (*ps == '\n' || *ps == '\r'))
481 ps++;
482
483 for (index = 0; index < MAX_N_ATTR; index++) {
484 if (ps >= ph)
485 break;
486
487 strlcpy(attrib_name[index], ps, NAME_LENGTH);
488 if (strchr(attrib_name[index], ':'))
489 *(strchr(attrib_name[index], ':')) = 0;
490
491 ps += strlen(attrib_name[index]) + 2;
492 strlcpy(attrib[index], ps, NAME_LENGTH);
493
494 for (i = 0; i < NAME_LENGTH; i++) {
495 if (attrib[index][i] == '\r' || attrib[index][i] == '\n')
496 attrib[index][i] = 0;
497
498 if (attrib[index][i] == 0)
499 break;
500 }
501
502 ps += strlen(attrib[index]);
503 while (*ps && (*ps == '\n' || *ps == '\r'))
504 ps++;
505 }
506
507 attrib_name[index][0] = 0;
508 attrib[index][0] = 0;
509
510 ph = strchr(ph, '\n') + 1;
511 if (*ph == '\r')
512 ph++;
513
514 strlcpy(text, ph, TEXT_SIZE);
515
516 return 1;
517 }
518
519 if (strstr(response, "302 Found")) {
520 if (strstr(response, "Location:")) {
521 if (strstr(response, "fail"))
522 printf("Error: Invalid user name or password\n");
523 else {
524 strncpy(str, strstr(response, "Location:") + 10, sizeof(str));
525 if (strchr(str, '?'))
526 *strchr(str, '?') = 0;
527 if (strchr(str, '\n'))
528 *strchr(str, '\n') = 0;
529 if (strchr(str, '\r'))
530 *strchr(str, '\r') = 0;
531
532 if (strrchr(str, '/'))
533 printf("Message successfully transmitted, ID=%s\n", strrchr(str, '/') + 1);
534 else
535 printf("Message successfully transmitted, ID=%s\n", str);
536 }
537 }
538 } else if (strstr(response, "Logbook Selection"))
539 printf("Error: No logbook specified\n");
540 else if (strstr(response, "enter password"))
541 printf("Error: Missing or invalid password\n");
542 else if (strstr(response, "form name=form1"))
543 printf("Error: Missing or invalid user name/password\n");
544 else
545 printf("Error transmitting message\n");
546
547 return 0;
548}
char request[100000]
Definition elog.cc:330
void url_encode(char *ps, int size)
Definition elog.cc:166
char text[TEXT_SIZE]
Definition elog.cc:72
#define closesocket(s)
Definition elog.cc:49
void do_crypt(char *s, char *d, int size)
Definition elog.cc:146
char response[100000]
Definition elog.cc:330
#define MAX_N_ATTR
Definition elog.cc:66
int elog_connect(char *host, int port)
Definition elog.cc:257
#define TEXT_SIZE
Definition elog.cc:68
const int n
Definition JPolint.hh:791

◆ submit_elog()

INT submit_elog ( char * host,
int port,
int ssl,
char * subdir,
char * experiment,
char * uname,
char * upwd,
int reply,
int quote_on_reply,
int edit,
int download,
int suppress,
int encoding,
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 at line 552 of file elog.cc.

595{
596 int status, sock, i, n, header_length, content_length, index;
597 char host_name[256], boundary[80], str[80], encrypted_passwd[256], *p;
598 const char* old_encoding;
599 char old_attrib_name[MAX_N_ATTR+1][NAME_LENGTH], old_attrib[MAX_N_ATTR+1][NAME_LENGTH];
600 struct hostent *phe;
601#ifdef HAVE_SSL
602 SSL *ssl_con = NULL;
603#endif
604
605 /* get local host name */
606 gethostname(host_name, sizeof(host_name));
607
608 phe = gethostbyname(host_name);
609 if (phe == NULL) {
610 perror("Cannot retrieve host name");
611 return -1;
612 }
613 phe = gethostbyaddr(phe->h_addr, sizeof(int), AF_INET);
614 if (phe == NULL) {
615 perror("Cannot retrieve host name");
616 return -1;
617 }
618
619 /* if domain name is not in host name, hope to get it from phe */
620 if (strchr(host_name, '.') == NULL)
621 strcpy(host_name, phe->h_name);
622
623 if (edit || download) {
624 if (edit)
625 status = retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, edit,
626 old_attrib_name, old_attrib, old_text);
627 else
628 status = retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, download,
629 old_attrib_name, old_attrib, old_text);
630
631 if (status != 1)
632 return status;
633
634 /* update attributes */
635 for (index = 0; index < n_attr; index++) {
636 for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++)
637 if (equal_ustring(attrib_name[index], old_attrib_name[i]))
638 break;
639
640 if (old_attrib_name[i][0])
641 strlcpy(old_attrib[i], attrib[index], NAME_LENGTH);
642 }
643
644 /* copy attributes */
645 for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++) {
646 strlcpy(attrib_name[i], old_attrib_name[i], NAME_LENGTH);
647 strlcpy(attrib[i], old_attrib[i], NAME_LENGTH);
648 }
649
650 n_attr = i;
651
652 if (text[0] == 0)
654 }
655
656 if (download) {
657 if (strstr(response, "$@MID@$:"))
658 printf("%s", strstr(response, "$@MID@$:"));
659 else
660 printf("%s", response);
661 return 1;
662 }
663
664 if (reply) {
665 status =
666 retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, reply,
667 old_attrib_name, old_attrib, old_text);
668
669 if (status != 1)
670 return status;
671
672 /* update attributes */
673 for (index = 0; index < n_attr; index++) {
674 for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++)
675 if (equal_ustring(attrib_name[index], old_attrib_name[i]))
676 break;
677
678 if (old_attrib_name[i][0])
679 strlcpy(old_attrib[i], attrib[index], NAME_LENGTH);
680 }
681
682 /* copy attributes */
683 for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++) {
684 if (equal_ustring(old_attrib_name[i], "Reply to") || equal_ustring(old_attrib_name[i], "Date")) {
685 attrib_name[i][0] = 0;
686 attrib[i][0] = 0;
687 } else {
688 strlcpy(attrib_name[i], old_attrib_name[i], NAME_LENGTH);
689 strlcpy(attrib[i], old_attrib[i], NAME_LENGTH);
690 }
691 }
692
693 n_attr = i;
694
695 /* check encoding */
696 old_encoding = "plain";
697
698 for (i = 0; i < n_attr; i++)
699 if (equal_ustring(attrib_name[i], "encoding"))
700 break;
701
702 if (i < n_attr)
703 old_encoding = attrib[i];
704
705 if (quote_on_reply) {
706 strlcpy(new_text, text, sizeof(new_text));
707
708 /* precede old text with "> " */
709 text[0] = 0;
710 p = old_text;
711
712 do {
713 if (strchr(p, '\n')) {
714 *strchr(p, '\n') = 0;
715
716 if (old_encoding[0] == 'H') {
717 strlcat(text, "> ", TEXT_SIZE);
719 strlcat(text, "<br>\n", TEXT_SIZE);
720 } else {
721 strlcat(text, "> ", TEXT_SIZE);
723 strlcat(text, "\n", TEXT_SIZE);
724 }
725
726 p += strlen(p) + 1;
727 if (*p == '\n')
728 p++;
729 } else {
730 if (old_encoding[0] == 'H') {
731 strlcat(text, "> ", TEXT_SIZE);
733 strlcat(text, "<p>\n", TEXT_SIZE);
734 } else {
735 strlcat(text, "> ", TEXT_SIZE);
737 strlcat(text, "\n\n", TEXT_SIZE);
738 }
739
740 break;
741 }
742
743 } while (1);
744
746 }
747 }
748
749 sock = elog_connect(host, port);
750 if (sock < 0)
751 return sock;
752
753#ifdef HAVE_SSL
754 if (ssl)
755 if (ssl_connect(sock, &ssl_con) < 0) {
756 printf("elogd server does not run SSL protocol\n");
757 return -1;
758 }
759#endif
760
761 content_length = 100000;
762 for (i = 0; i < MAX_ATTACHMENTS; i++)
763 if (afilename[i][0])
764 content_length += buffer_size[i];
765 content = (char *)malloc(content_length);
766 if (content == NULL) {
767 printf("Not enough memory\n");
768 return -1;
769 }
770
771 /* compose content */
772 srand((unsigned) time(NULL));
773 sprintf(boundary, "---------------------------%04X%04X%04X", rand(), rand(), rand());
774 strcpy(content, boundary);
775 strcat(content, "\r\nContent-Disposition: form-data; name=\"cmd\"\r\n\r\nSubmit\r\n");
776
777 if (uname[0])
778 sprintf(content + strlen(content),
779 "%s\r\nContent-Disposition: form-data; name=\"unm\"\r\n\r\n%s\r\n", boundary, uname);
780
781 if (upwd[0]) {
782 do_crypt(upwd, encrypted_passwd, sizeof(encrypted_passwd));
783 sprintf(content + strlen(content),
784 "%s\r\nContent-Disposition: form-data; name=\"upwd\"\r\n\r\n%s\r\n", boundary,
785 encrypted_passwd);
786 }
787
788 if (experiment[0])
789 sprintf(content + strlen(content),
790 "%s\r\nContent-Disposition: form-data; name=\"exp\"\r\n\r\n%s\r\n", boundary, experiment);
791
792 if (reply)
793 sprintf(content + strlen(content),
794 "%s\r\nContent-Disposition: form-data; name=\"reply_to\"\r\n\r\n%d\r\n", boundary, reply);
795
796 if (edit) {
797 sprintf(content + strlen(content),
798 "%s\r\nContent-Disposition: form-data; name=\"edit_id\"\r\n\r\n%d\r\n", boundary, edit);
799 sprintf(content + strlen(content),
800 "%s\r\nContent-Disposition: form-data; name=\"skiplock\"\r\n\r\n1\r\n", boundary);
801 }
802
803 if (suppress)
804 sprintf(content + strlen(content),
805 "%s\r\nContent-Disposition: form-data; name=\"suppress\"\r\n\r\n1\r\n", boundary);
806
807 if (encoding == 0)
808 sprintf(content + strlen(content),
809 "%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nELCode\r\n", boundary);
810 else if (encoding == 1)
811 sprintf(content + strlen(content),
812 "%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nplain\r\n", boundary);
813 else if (encoding == 2)
814 sprintf(content + strlen(content),
815 "%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nHTML\r\n", boundary);
816
817 for (i = 0; i < n_attr; i++) {
818 strcpy(str, attrib_name[i]);
819 if (str[0]) {
820 stou(str);
821 sprintf(content + strlen(content),
822 "%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", boundary, str, attrib[i]);
823 }
824 }
825
826 if (text[0])
827 sprintf(content + strlen(content),
828 "%s\r\nContent-Disposition: form-data; name=\"Text\"\r\n\r\n%s\r\n%s\r\n",
829 boundary, text, boundary);
830
831 content_length = strlen(content);
832 p = content + content_length;
833
834 for (i = 0; i < MAX_ATTACHMENTS; i++)
835 if (afilename[i][0]) {
836 sprintf(p,
837 "Content-Disposition: form-data; name=\"attfile%d\"; filename=\"%s\"\r\n\r\n",
838 i + 1, afilename[i]);
839
840 content_length += strlen(p);
841 p += strlen(p);
842 memcpy(p, buffer[i], buffer_size[i]);
843 p += buffer_size[i];
844 strcpy(p, boundary);
845 strcat(p, "\r\n");
846
847 content_length += buffer_size[i] + strlen(p);
848 p += strlen(p);
849 }
850
851 /* compose request */
852 strcpy(request, "POST /");
853 if (subdir[0])
854 sprintf(request + strlen(request), "%s/", subdir);
855 if (experiment[0]) {
856 strcpy(str, experiment);
857 url_encode(str, sizeof(str));
858 sprintf(request + strlen(request), "%s/", str);
859 }
860 strcat(request, " HTTP/1.0\r\n");
861
862 sprintf(request + strlen(request), "Content-Type: multipart/form-data; boundary=%s\r\n", boundary);
863 if (port != 80)
864 sprintf(str, "%s:%d", host, port);
865 else
866 sprintf(str, "%s", host);
867 sprintf(request + strlen(request), "Host: %s\r\n", str);
868 sprintf(request + strlen(request), "User-Agent: ELOG\r\n");
869 sprintf(request + strlen(request), "Content-Length: %d\r\n", content_length);
870
871 strcat(request, "\r\n");
872
873 header_length = strlen(request);
874
875 /*
876 {
877 FILE *f;
878 f = fopen("elog.log", "w");
879 fwrite(request, header_length+content_length, 1, f);
880 fclose(f);
881 }
882 */
883
884 /* send request */
885#ifdef HAVE_SSL
886 if (ssl)
887 SSL_write(ssl_con, request, header_length);
888 else
889#endif
890 send(sock, request, header_length, 0);
891 if (verbose) {
892 printf("Request sent to host:\n");
893 puts(request);
894 }
895
896 /* send content */
897#ifdef HAVE_SSL
898 if (ssl)
899 SSL_write(ssl_con, content, content_length);
900 else
901#endif
902 send(sock, content, content_length, 0);
903 if (verbose) {
904 printf("Content sent to host:\n");
905 puts(content);
906 }
907
908 /* receive response */
909 memset(response, 0, sizeof(response));
910#ifdef HAVE_SSL
911 if (ssl)
912 i = SSL_read(ssl_con, response, sizeof(response) - 1);
913 else
914#endif
915 i = recv(sock, response, sizeof(response) - 1, 0);
916 if (i < 0) {
917 perror("Cannot receive response");
918 return -1;
919 }
920
921 /* discard remainder of response */
922 n = i;
923 while (i > 0) {
924#ifdef HAVE_SSL
925 if (ssl)
926 i = SSL_read(ssl_con, response + n, sizeof(response) - 1 - n);
927 else
928#endif
929 i = recv(sock, response + n, sizeof(response) - 1 - n, 0);
930 if (i > 0)
931 n += i;
932 }
933 response[n] = 0;
934
935#ifdef HAVE_SSL
936 if (ssl) {
937 SSL_shutdown(ssl_con);
938 SSL_free(ssl_con);
939 }
940#endif
941
942 closesocket(sock);
943
944 if (verbose) {
945 printf("Response received:\n");
946 puts(response);
947 }
948
949 /* check response status */
950 if (strstr(response, "302 Found")) {
951 if (strstr(response, "Location:")) {
952 if (strstr(response, "has moved"))
953 printf("Error: elogd server has moved to another location\n");
954 else if (strstr(response, "fail"))
955 printf("Error: Invalid user name or password\n");
956 else {
957 strncpy(str, strstr(response, "Location:") + 10, sizeof(str));
958 if (strchr(str, '?'))
959 *strchr(str, '?') = 0;
960 if (strchr(str, '\n'))
961 *strchr(str, '\n') = 0;
962 if (strchr(str, '\r'))
963 *strchr(str, '\r') = 0;
964
965 if (strrchr(str, '/'))
966 printf("Message successfully transmitted, ID=%s\n", strrchr(str, '/') + 1);
967 else
968 printf("Message successfully transmitted, ID=%s\n", str);
969 }
970 } else
971 printf("Message successfully transmitted\n");
972 } else if (strstr(response, "Logbook Selection"))
973 printf("Error: No logbook specified\n");
974 else if (strstr(response, "enter password"))
975 printf("Error: Missing or invalid password\n");
976 else if (strstr(response, "Error: Attribute")) {
977 if (strstr(response, "not existing")) {
978 strncpy(str, strstr(response, "Error: Attribute") + 27, sizeof(str));
979 if (strchr(str, '<'))
980 *strchr(str, '<') = 0;
981 printf("Error: Non existing attribute option \"%s\"\n", str);
982 } else {
983 strncpy(str, strstr(response, "Error: Attribute") + 20, sizeof(str));
984 if (strchr(str, '<'))
985 *strchr(str, '<') = 0;
986 printf("Error: Missing required attribute \"%s\"\n", str);
987 }
988 }
989 else if (strstr(response, "form name=form1"))
990 printf("Error: Missing or invalid user name/password\n");
991 else
992 printf("Error transmitting message\n");
993
994 return 1;
995}
static const size_t buffer_size
char old_text[TEXT_SIZE]
Definition elog.cc:72
INT retrieve_elog(char *host, int port, char *subdir, int ssl, char *experiment, char *uname, char *upwd, int message_id, char attrib_name[MAX_N_ATTR][NAME_LENGTH], char attrib[MAX_N_ATTR][NAME_LENGTH], char *text)
Definition elog.cc:332
void stou(char *str)
Definition elog.cc:153
char * content
Definition elog.cc:330
char new_text[TEXT_SIZE]
Definition elog.cc:72
#define MAX_ATTACHMENTS
Definition elog.cc:64
int equal_ustring(const char *str1, const char *str2)
Definition elog.cc:125
size_t strlcat(char *dst, const char *src, size_t size)
Definition strlcpy.cc:72

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 999 of file elog.cc.

1000{
1001 char str[1000], uname[80], upwd[80];
1002 char host_name[256], logbook[32], textfile[256], subdir[256];
1003 char *buffer[MAX_ATTACHMENTS], attachment[MAX_ATTACHMENTS][256];
1004 INT att_size[MAX_ATTACHMENTS];
1005 INT i, n, fh, n_att, n_attr, port, reply, quote_on_reply, edit, download, encoding, suppress, size, ssl,
1006 text_flag;
1007 char attr_name[MAX_N_ATTR][NAME_LENGTH], attrib[MAX_N_ATTR][NAME_LENGTH];
1008
1009 text[0] = textfile[0] = uname[0] = upwd[0] = suppress = quote_on_reply = 0;
1010 host_name[0] = logbook[0] = subdir[0] = 0;
1011 n_att = n_attr = reply = edit = download = encoding = 0;
1012 port = 80;
1013 ssl = 0;
1014 text_flag = 0;
1015
1016 for (i = 0; i < MAX_ATTACHMENTS; i++) {
1017 attachment[i][0] = 0;
1018 buffer[i] = NULL;
1019 att_size[i] = 0;
1020 }
1021
1022 /* parse command line parameters */
1023 for (i = 1; i < argc; i++) {
1024 if (argv[i][0] == '-' && argv[i][1] == 'v')
1025 verbose = 1;
1026 else if (argv[i][0] == '-' && argv[i][1] == 's')
1027 ssl = 1;
1028 else if (argv[i][0] == '-' && argv[i][1] == 'q')
1029 quote_on_reply = 1;
1030 else if (argv[i][0] == '-' && argv[i][1] == 'x')
1031 suppress = 1;
1032 else {
1033 if (argv[i][0] == '-') {
1034 if (i + 1 >= argc || argv[i + 1][0] == '-')
1035 goto usage;
1036 if (argv[i][1] == 'h')
1037 strcpy(host_name, argv[++i]);
1038 else if (argv[i][1] == 'p')
1039 port = atoi(argv[++i]);
1040 else if (argv[i][1] == 'l')
1041 strcpy(logbook, argv[++i]);
1042 else if (argv[i][1] == 'd')
1043 strcpy(subdir, argv[++i]);
1044 else if (argv[i][1] == 'u') {
1045 strcpy(uname, argv[++i]);
1046 strcpy(upwd, argv[++i]);
1047 } else if (argv[i][1] == 'a') {
1048 strcpy(str, argv[++i]);
1049 if (strchr(str, '=')) {
1050 strcpy(attrib[n_attr], strchr(str, '=') + 1);
1051 *strchr(str, '=') = 0;
1052 strcpy(attr_name[n_attr], str);
1053 n_attr++;
1054 } else {
1055 printf("Error: Attributes must be supplied in the form \"-a <attribute>=<value>\".\n");
1056 return 1;
1057 }
1058 } else if (argv[i][1] == 'f')
1059 strcpy(attachment[n_att++], argv[++i]);
1060 else if (argv[i][1] == 'r')
1061 reply = atoi(argv[++i]);
1062 else if (argv[i][1] == 'e')
1063 edit = atoi(argv[++i]);
1064 else if (argv[i][1] == 'w') {
1065 if (argv[i+1][0] == 'l')
1066 download = -1;
1067 else
1068 download = atoi(argv[++i]);
1069 } else if (argv[i][1] == 'n')
1070 encoding = atoi(argv[++i]);
1071 else if (argv[i][1] == 'm') {
1072 strcpy(textfile, argv[++i]);
1073 text_flag = 1;
1074 } else {
1075 usage:
1076 printf("%s ", ELOGID);
1077 printf("revision %s\n", git_revision());
1078 printf("\nusage: elog\n");
1079 printf("elog -h <hostname> [-p port] [-d subdir]\n");
1080 printf(" Location where elogd is running\n");
1081 printf(" -l logbook/experiment Name of logbook or experiment\n");
1082 printf(" -s Use SSL for communication\n");
1083 printf(" [-v] For verbose output\n");
1084 printf(" [-u username password] Wser name and password\n");
1085 printf(" [-f <attachment>] (up to %d attachments)\n", MAX_ATTACHMENTS);
1086 printf(" -a <attribute>=<value> (up to %d attributes)\n", MAX_N_ATTR);
1087 printf(" [-r <id>] Reply to existing message\n");
1088 printf(" [-q] Quote original text on reply\n");
1089 printf(" [-e <id>] Edit existing message\n");
1090 printf(" [-w <id>|last] Download existing message (last message)\n");
1091 printf(" [-x] Suppress email notification\n");
1092 printf(" [-n 0|1|2] Encoding: 0:ELcode,1:plain,2:HTML\n");
1093 printf(" -m <textfile>] | <text>\n");
1094 printf("\nArguments with blanks must be enclosed in quotes\n");
1095 printf("The elog message can either be submitted on the command line, piped in like\n");
1096 printf("\"cat text | elog -h ... -l ... -a ...\" or in a file with the -m flag.\n");
1097 printf("Multiple attributes and attachments can be supplied\n");
1098 return 1;
1099 }
1100 } else {
1101 strcpy(text, argv[i]);
1102 convert_crlf(text, sizeof(text));
1103 text_flag = 1;
1104 }
1105 }
1106 }
1107
1108#ifndef HAVE_SSL
1109 if (ssl) {
1110 printf("SLL support not compiled into this program\n");
1111 return 1;
1112 }
1113#endif
1114
1115#if defined( _MSC_VER )
1116 {
1117 WSADATA WSAData;
1118
1119 /* Start windows sockets */
1120 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
1121 return -1;
1122 }
1123#endif
1124
1125 if (host_name[0] == 0) {
1126 printf("Please specify hostname.\n");
1127 return 1;
1128 }
1129
1130 if (logbook[0] == 0) {
1131 printf("Please specify logbook with the \"-l\" flag.\n");
1132 return 1;
1133 }
1134
1135 if (n_attr == 0 && !edit && !reply && !download) {
1136 printf("Please specify attribute(s) with the \"-a\" flag.\n");
1137 return 1;
1138 }
1139
1140 fh = -1;
1141
1142 if (textfile[0]) {
1143 fh = open(textfile, O_RDONLY | O_BINARY);
1144 if (fh < 0) {
1145 printf("Message file \"%s\" does not exist.\n", textfile);
1146 return 1;
1147 }
1148
1149 size = (INT) lseek(fh, 0, SEEK_END);
1150 lseek(fh, 0, SEEK_SET);
1151
1152 if (size > (INT) (sizeof(text) - 1)) {
1153 printf("Message file \"%s\" is too long (%zd bytes max).\n", textfile, sizeof(text));
1154 return 1;
1155 }
1156
1157 i = read(fh, text, size);
1158
1159 if (i < size) {
1160 printf("Cannot fully read message from file %s.\n", textfile);
1161 return 1;
1162 }
1163
1164 close(fh);
1165 }
1166
1167 if (text_flag == 0 && !edit && !download) {
1168 /* read from stdin */
1169
1170 n = 0;
1171
1172 do {
1173 i = getchar();
1174
1175 text[n++] = i;
1176
1177 } while (i != EOF);
1178
1179 if (n > 0)
1180 text[n - 1] = 0;
1181 }
1182
1183 /* change CR -> CRLF for unix text files */
1184 add_crlf(text, sizeof(text));
1185
1186 /*---- open attachment file ----*/
1187
1188 for (i = 0; i < MAX_ATTACHMENTS; i++) {
1189 if (!attachment[i][0])
1190 break;
1191
1192 fh = open(attachment[i], O_RDONLY | O_BINARY);
1193 if (fh < 0) {
1194 printf("Attachment file \"%s\" does not exist.\n", attachment[i]);
1195 return 1;
1196 }
1197
1198 att_size[i] = lseek(fh, 0, SEEK_END);
1199 lseek(fh, 0, SEEK_SET);
1200
1201 buffer[i] = (char *)malloc(att_size[i] + 1);
1202
1203 n = read(fh, buffer[i], att_size[i]);
1204 if (n < att_size[i]) {
1205 printf("Cannot fully read attachment file \"%s\".\n", attachment[i]);
1206 return 1;
1207 }
1208 buffer[i][n] = 0;
1209
1210 close(fh);
1211 }
1212
1213 /* now submit message */
1214 submit_elog(host_name, port, ssl, subdir, logbook,
1215 uname, upwd, reply, quote_on_reply, edit, download, suppress, encoding, attr_name, attrib, n_attr, text,
1216 attachment, buffer, att_size);
1217
1218 for (i = 0; i < MAX_ATTACHMENTS; i++)
1219 if (buffer[i])
1220 free(buffer[i]);
1221
1222 return 0;
1223}
static const char ELOGID[]
void convert_crlf(char *buffer, int bufsize)
Definition elog.cc:240
#define O_BINARY
Definition elog.cc:51
int INT
Definition elog.cc:62
const char * git_revision()
Definition elog.cc:77
void add_crlf(char *buffer, int bufsize)
Definition elog.cc:208
INT submit_elog(char *host, int port, int ssl, char *subdir, char *experiment, char *uname, char *upwd, int reply, int quote_on_reply, int edit, int download, int suppress, int encoding, 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 elog.cc:552
bool read(Vec &v, std::istream &is)
Read a Vec(tor) from a stream.
Definition io_ascii.hh:142
void close(std::istream *pf)
Close file.
T * open(const std::string &file_name)
Open file.

Variable Documentation

◆ _git_revision

const char* _git_revision = GIT_REVISION

Definition at line 27 of file elog.cc.

◆ verbose

int verbose

Definition at line 70 of file elog.cc.

◆ text

char text[TEXT_SIZE]

Definition at line 72 of file elog.cc.

◆ old_text

char old_text[TEXT_SIZE]

Definition at line 72 of file elog.cc.

◆ new_text

char new_text[TEXT_SIZE]

Definition at line 72 of file elog.cc.

◆ map

const char* map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

Definition at line 87 of file elog.cc.

◆ request

char request[100000]

Definition at line 330 of file elog.cc.

◆ response

char response[100000]

Definition at line 330 of file elog.cc.

◆ content

char * content

Definition at line 330 of file elog.cc.