LCOV - code coverage report
Current view: top level - progs - melog.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 218 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 4 0

            Line data    Source code
       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              : 
      35              : typedef int INT;
      36              : 
      37              : #define MAX_ATTACHMENTS  10
      38              : #define NAME_LENGTH     100
      39              : #define MAX_N_ATTR       20
      40              : 
      41              : int verbose;
      42              : 
      43              : /*------------------------------------------------------------------*/
      44              : 
      45              : const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      46              : 
      47            0 : void base64_encode(char *s, char *d)
      48              : {
      49              :    unsigned int t, pad;
      50              : 
      51            0 :    pad = 3 - strlen(s) % 3;
      52            0 :    while (*s) {
      53            0 :       t = (*s++) << 16;
      54            0 :       if (*s)
      55            0 :          t |= (*s++) << 8;
      56            0 :       if (*s)
      57            0 :          t |= (*s++) << 0;
      58              : 
      59            0 :       *(d + 3) = map[t & 63];
      60            0 :       t >>= 6;
      61            0 :       *(d + 2) = map[t & 63];
      62            0 :       t >>= 6;
      63            0 :       *(d + 1) = map[t & 63];
      64            0 :       t >>= 6;
      65            0 :       *(d + 0) = map[t & 63];
      66              : 
      67            0 :       d += 4;
      68              :    }
      69            0 :    *d = 0;
      70            0 :    while (pad--)
      71            0 :       *(--d) = '=';
      72            0 : }
      73              : 
      74              : /*------------------------------------------------------------------*/
      75              : 
      76            0 : void sgets(char *string, int size)
      77              : {
      78              :    char *p;
      79              : 
      80              :    do {
      81            0 :       p = fgets(string, size, stdin);
      82            0 :    } while (p == NULL);
      83              : 
      84            0 :    if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
      85            0 :       p[strlen(p) - 1] = 0;
      86            0 : }
      87              : 
      88              : /*------------------------------------------------------------------*/
      89              : 
      90              : char request[600000], response[10000], content[600000];
      91              : 
      92            0 : INT 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 host_name[256], 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              :    /* get local host name */
     142            0 :    gethostname(host_name, sizeof(host_name));
     143              : 
     144            0 :    phe = gethostbyname(host_name);
     145            0 :    if (phe == NULL) {
     146            0 :       perror("Cannot retrieve host name");
     147            0 :       return -1;
     148              :    }
     149            0 :    phe = gethostbyaddr(phe->h_addr, sizeof(int), AF_INET);
     150            0 :    if (phe == NULL) {
     151            0 :       perror("Cannot retrieve host name");
     152            0 :       return -1;
     153              :    }
     154              : 
     155              :    /* if domain name is not in host name, hope to get it from phe */
     156            0 :    if (strchr(host_name, '.') == NULL)
     157            0 :       strcpy(host_name, phe->h_name);
     158              : 
     159              :    /* create socket */
     160            0 :    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
     161            0 :       perror("cannot create socket");
     162            0 :       return -1;
     163              :    }
     164              : 
     165              :    /* compose remote address */
     166            0 :    memset(&bind_addr, 0, sizeof(bind_addr));
     167            0 :    bind_addr.sin_family = AF_INET;
     168            0 :    bind_addr.sin_addr.s_addr = 0;
     169            0 :    bind_addr.sin_port = htons((unsigned short) port);
     170              : 
     171            0 :    phe = gethostbyname(host);
     172            0 :    if (phe == NULL) {
     173            0 :       perror("cannot get host name");
     174            0 :       return -1;
     175              :    }
     176            0 :    memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
     177              : 
     178              :    /* connect to server */
     179            0 :    status = connect(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
     180            0 :    if (status != 0) {
     181            0 :       printf("Cannot connect to host %s, port %d\n", host, port);
     182            0 :       return -1;
     183              :    }
     184              : 
     185            0 :    if (verbose)
     186            0 :       printf("Successfully connected to host %s, port %d\n", host, port);
     187              : 
     188              :    /* compose content */
     189            0 :    strcpy(boundary, "---------------------------7d0bf1a60904bc");
     190            0 :    strcpy(content, boundary);
     191            0 :    strcat(content, "\r\nContent-Disposition: form-data; name=\"cmd\"\r\n\r\nSubmit\r\n");
     192              : 
     193            0 :    if (uname[0])
     194            0 :       snprintf(content + strlen(content), sizeof(content) - strlen(content),
     195              :               "%s\r\nContent-Disposition: form-data; name=\"unm\"\r\n\r\n%s\r\n",
     196              :               boundary, uname);
     197              : 
     198            0 :    if (upwd[0]) {
     199            0 :       base64_encode(upwd, str);
     200            0 :       snprintf(content + strlen(content), sizeof(content) - strlen(content),
     201              :               "%s\r\nContent-Disposition: form-data; name=\"upwd\"\r\n\r\n%s\r\n",
     202              :               boundary, str);
     203              :    }
     204              : 
     205            0 :    if (experiment[0])
     206            0 :       snprintf(content + strlen(content), sizeof(content) - strlen(content),
     207              :               "%s\r\nContent-Disposition: form-data; name=\"exp\"\r\n\r\n%s\r\n",
     208              :               boundary, experiment);
     209              : 
     210            0 :    for (i = 0; i < n_attr; i++)
     211            0 :       snprintf(content + strlen(content), sizeof(content) - strlen(content),
     212              :               "%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", boundary,
     213            0 :               attrib_name[i], attrib[i]);
     214              : 
     215            0 :    snprintf(content + strlen(content), sizeof(content) - strlen(content),
     216              :            "%s\r\nContent-Disposition: form-data; name=\"Text\"\r\n\r\n%s\r\n%s\r\n",
     217              :            boundary, text, boundary);
     218              : 
     219            0 :    content_length = strlen(content);
     220            0 :    p = content + content_length;
     221              : 
     222            0 :    for (i = 0; i < MAX_ATTACHMENTS; i++)
     223            0 :       if (afilename[i][0]) {
     224            0 :          snprintf(p, sizeof(content) - strlen(content),
     225              :                  "Content-Disposition: form-data; name=\"attfile%d\"; filename=\"%s\"\r\n\r\n",
     226            0 :                  i + 1, afilename[i]);
     227              : 
     228            0 :          content_length += strlen(p);
     229            0 :          p += strlen(p);
     230            0 :          memcpy(p, buffer[i], buffer_size[i]);
     231            0 :          p += buffer_size[i];
     232            0 :          strcpy(p, boundary);
     233            0 :          strcat(p, "\r\n");
     234              : 
     235            0 :          content_length += buffer_size[i] + strlen(p);
     236            0 :          p += strlen(p);
     237              :       }
     238              : 
     239              :    /* compose request */
     240            0 :    snprintf(request, sizeof(request), "POST /EL/ HTTP/1.0\r\n");
     241            0 :    snprintf(request + strlen(request), sizeof(request) - strlen(request),
     242              :             "Content-Type: multipart/form-data; boundary=%s\r\n", boundary);
     243            0 :    snprintf(request + strlen(request), sizeof(request) - strlen(request), "Host: %s\r\n", host_name);
     244            0 :    snprintf(request + strlen(request), sizeof(request) - strlen(request), "User-Agent: ELOG\r\n");
     245            0 :    snprintf(request + strlen(request), sizeof(request) - strlen(request), "Content-Length: %d\r\n", content_length);
     246              : 
     247            0 :    if (passwd[0]) {
     248            0 :       base64_encode(passwd, str);
     249            0 :       snprintf(request + strlen(request),  sizeof(request) - strlen(request), "Cookie: elog_wpwd=%s\r\n", str);
     250              :    }
     251              : 
     252            0 :    strcat(request, "\r\n");
     253              : 
     254            0 :    header_length = strlen(request);
     255            0 :    memcpy(request + header_length, content, content_length);
     256              : 
     257              :    /*
     258              :       {
     259              :       FILE *f;
     260              :       f = fopen("elog.log", "w");
     261              :       fwrite(request, header_length+content_length, 1, f);
     262              :       fclose(f);
     263              :       }
     264              :     */
     265              : 
     266              :    /* send request */
     267            0 :    if (verbose) {
     268            0 :       printf("Request sent to host:\n");
     269            0 :       puts(request);
     270              :    }
     271              : 
     272            0 :    send(sock, request, header_length + content_length, 0);
     273              : 
     274              :    /* receive response */
     275            0 :    i = recv(sock, response, 10000, 0);
     276            0 :    if (i < 0) {
     277            0 :       perror("Cannot receive response");
     278            0 :       return -1;
     279              :    }
     280              : 
     281              :    /* discard remainder of response */
     282            0 :    n = i;
     283            0 :    while (i > 0) {
     284            0 :       i = recv(sock, response + n, 10000, 0);
     285            0 :       if (i > 0)
     286            0 :          n += i;
     287              :    }
     288            0 :    response[n] = 0;
     289              : 
     290            0 :    closesocket(sock);
     291              : 
     292            0 :    if (verbose) {
     293            0 :       printf("Response received:\n");
     294            0 :       puts(response);
     295              :    }
     296              : 
     297              :    /* check response status */
     298            0 :    if (strstr(response, "302 Found"))
     299            0 :       printf("Message successfully transmitted\n");
     300            0 :    else if (strstr(response, "Logbook Selection"))
     301            0 :       printf("No logbook specified\n\n");
     302            0 :    else if (strstr(response, "Enter password"))
     303            0 :       printf("Missing or invalid password\n");
     304            0 :    else if (strstr(response, "login"))
     305            0 :       printf("Missing or invalid user name/password\n");
     306              :    else
     307            0 :       printf("Error transmitting message\n");
     308              : 
     309            0 :    return 1;
     310              : }
     311              : 
     312              : /*------------------------------------------------------------------*/
     313              : 
     314            0 : int main(int argc, char *argv[])
     315              : {
     316              :    char str[1000], text[10000], uname[80], upwd[80];
     317              :    char host_name[256], logbook[32], textfile[256], password[80];
     318              :    char *buffer[MAX_ATTACHMENTS], attachment[MAX_ATTACHMENTS][256];
     319              :    INT att_size[MAX_ATTACHMENTS];
     320              :    INT i, n, fh, n_att, n_attr, size, port;
     321              :    char attr_name[MAX_N_ATTR][NAME_LENGTH], attrib[MAX_N_ATTR][NAME_LENGTH];
     322              : 
     323            0 :    text[0] = textfile[0] = uname[0] = upwd[0] = 0;
     324            0 :    host_name[0] = logbook[0] = password[0] = n_att = n_attr = 0;
     325            0 :    port = 80;
     326            0 :    for (i = 0; i < MAX_ATTACHMENTS; i++) {
     327            0 :       attachment[i][0] = 0;
     328            0 :       buffer[i] = NULL;
     329            0 :       att_size[i] = 0;
     330              :    }
     331              : 
     332              :    /* parse command line parameters */
     333            0 :    for (i = 1; i < argc; i++) {
     334            0 :       if (argv[i][0] == '-' && argv[i][1] == 'v')
     335            0 :          verbose = 1;
     336              :       else {
     337            0 :          if (argv[i][0] == '-') {
     338            0 :             if (i + 1 >= argc || argv[i + 1][0] == '-')
     339            0 :                goto usage;
     340            0 :             if (argv[i][1] == 'h')
     341            0 :                strcpy(host_name, argv[++i]);
     342            0 :             else if (argv[i][1] == 'p')
     343            0 :                port = atoi(argv[++i]);
     344            0 :             else if (argv[i][1] == 'l')
     345            0 :                strcpy(logbook, argv[++i]);
     346            0 :             else if (argv[i][1] == 'w')
     347            0 :                strcpy(password, argv[++i]);
     348            0 :             else if (argv[i][1] == 'u') {
     349            0 :                strcpy(uname, argv[++i]);
     350            0 :                strcpy(upwd, argv[++i]);
     351            0 :             } else if (argv[i][1] == 'a') {
     352            0 :                strcpy(str, argv[++i]);
     353            0 :                if (strchr(str, '=')) {
     354            0 :                   strcpy(attrib[n_attr], strchr(str, '=') + 1);
     355            0 :                   *strchr(str, '=') = 0;
     356            0 :                   strcpy(attr_name[n_attr], str);
     357            0 :                   n_attr++;
     358              :                } else {
     359              :                   printf
     360            0 :                       ("Error: Attributes must be supplied in the form \"-a <attribute>=<value>\".\n");
     361            0 :                   return 0;
     362              :                }
     363            0 :             } else if (argv[i][1] == 'f')
     364            0 :                strcpy(attachment[n_att++], argv[++i]);
     365            0 :             else if (argv[i][1] == 'm')
     366            0 :                strcpy(textfile, argv[++i]);
     367              :             else {
     368            0 :              usage:
     369            0 :                printf("\nusage: elog -h <hostname> [-p port]\n");
     370            0 :                printf("           [-l logbook/experiment]\n");
     371            0 :                printf("           [-v]                     for verbose output\n");
     372              :                printf
     373            0 :                    ("           [-w password]            write password defined on server\n");
     374            0 :                printf("           [-u username password]   user name and password\n");
     375            0 :                printf("           [-f <attachment>]        (up to %d times)\n",
     376              :                       MAX_ATTACHMENTS);
     377            0 :                printf("           -a <attribute>=<value>   (up to %d times)\n",
     378              :                       MAX_N_ATTR);
     379            0 :                printf("           -m <textfile>] | <text>\n");
     380            0 :                printf("\nArguments with blanks must be enclosed in quotes\n");
     381            0 :                printf("The elog message can either be submitted on the command line\n");
     382              :                printf
     383            0 :                    ("or in a file with the -m flag. Multiple attributes and attachments\n");
     384            0 :                printf("can be supplied\n");
     385            0 :                return 0;
     386              :             }
     387              :          } else
     388            0 :             strcpy(text, argv[i]);
     389              :       }
     390              :    }
     391              : 
     392            0 :    if (host_name[0] == 0 || n_attr == 0 || (text[0] == 0 && textfile[0] == 0))
     393            0 :       goto usage;
     394              : 
     395              :   /*---- open text file ----*/
     396              : 
     397            0 :    if (textfile[0]) {
     398            0 :       fh = open(textfile, O_RDONLY | O_BINARY);
     399            0 :       if (fh < 0) {
     400            0 :          printf("Message file \"%s\" does not exist.\n", textfile);
     401            0 :          return 0;
     402              :       }
     403              : 
     404            0 :       size = lseek(fh, 0, SEEK_END);
     405            0 :       lseek(fh, 0, SEEK_SET);
     406              : 
     407            0 :       if (size > (int)sizeof(text) - 1) {
     408            0 :          printf("Message file \"%s\" is too long (%d bytes max).\n", textfile,
     409              :                 (int)sizeof(text));
     410            0 :          return 0;
     411              :       }
     412              : 
     413            0 :       memset(text, 0, sizeof(text));
     414            0 :       i = read(fh, text, size);
     415            0 :       if (i < size) {
     416            0 :          printf("Cannot fully read message file \"%s\".\n", textfile);
     417            0 :          return 0;
     418              :       }
     419              : 
     420            0 :       close(fh);
     421              :    }
     422              : 
     423              :   /*---- open attachment file ----*/
     424              : 
     425            0 :    for (i = 0; i < MAX_ATTACHMENTS; i++) {
     426            0 :       if (!attachment[i][0])
     427            0 :          break;
     428              : 
     429            0 :       fh = open(attachment[i], O_RDONLY | O_BINARY);
     430            0 :       if (fh < 0) {
     431            0 :          printf("Attachment file \"%s\" does not exist.\n", attachment[i]);
     432            0 :          return 0;
     433              :       }
     434              : 
     435            0 :       att_size[i] = lseek(fh, 0, SEEK_END);
     436            0 :       lseek(fh, 0, SEEK_SET);
     437              : 
     438            0 :       buffer[i] = (char*)malloc(att_size[i] + 1);
     439            0 :       if (buffer[i] == NULL || att_size[i] > 500 * 1024) {
     440            0 :          printf("Attachment file \"%s\" is too long (500k max).\n", attachment[i]);
     441            0 :          return 0;
     442              :       }
     443              : 
     444            0 :       n = read(fh, buffer[i], att_size[i]);
     445            0 :       if (n < att_size[i]) {
     446            0 :          printf("Cannot fully read attachment file \"%s\".\n", attachment[i]);
     447            0 :          return 0;
     448              :       }
     449            0 :       buffer[i][n] = 0;
     450              : 
     451            0 :       close(fh);
     452              :    }
     453              : 
     454              :    /* now submit message */
     455            0 :    submit_elog(host_name, port, logbook, password,
     456              :                uname, upwd,
     457              :                attr_name, attrib, n_attr, text, attachment, buffer, att_size);
     458              : 
     459            0 :    for (i = 0; i < MAX_ATTACHMENTS; i++)
     460            0 :       if (buffer[i])
     461            0 :          free(buffer[i]);
     462              : 
     463            0 :    return 1;
     464              : }
        

Generated by: LCOV version 2.0-1