#endif
#include "strlcpy.h"
typedef int INT;
#define MAX_ATTACHMENTS 50
#define NAME_LENGTH 500
#define MAX_N_ATTR 50
#define TEXT_SIZE 100000
int verbose;
char text[TEXT_SIZE], old_text[TEXT_SIZE], new_text[TEXT_SIZE];
/*------------------------------------------------------------------*/
const char *git_revision()
{
const char *p = _git_revision;
if (strrchr(p, '-'))
p = strrchr(p, '-')+2;
return p;
}
/*------------------------------------------------------------------*/
const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void base64_encode(unsigned char *s, unsigned char *d, int size)
{
unsigned int t, pad;
unsigned char *p;
pad = 3 - strlen((char *) s) % 3;
if (pad == 3)
pad = 0;
p = d;
while (*s) {
t = (*s++) << 16;
if (*s)
t |= (*s++) << 8;
if (*s)
t |= (*s++) << 0;
*(d + 3) = map[t & 63];
t >>= 6;
*(d + 2) = map[t & 63];
t >>= 6;
*(d + 1) = map[t & 63];
t >>= 6;
*(d + 0) = map[t & 63];
d += 4;
if (d - p >= size - 3)
return;
}
*d = 0;
while (pad--)
*(--d) = '=';
}
/*---- string comparison -------------------------------------------*/
int equal_ustring(const char *str1, const char *str2)
{
if (str1 == NULL && str2 != NULL)
return 0;
if (str1 != NULL && str2 == NULL)
return 0;
if (str1 == NULL && str2 == NULL)
return 1;
while (*str1)
if (toupper(*str1++) != toupper(*str2++))
return 0;
if (*str2)
return 0;
return 1;
}
char *sha256_crypt(const char *key, const char *salt);
void do_crypt(char *s, char *d, int size)
{
strlcpy(d, sha256_crypt(s, "$5$") + 4, size);
}
/*-------------------------------------------------------------------*/
void stou(char *str)
/* convert all special characters to underscores in a string */
{
int i;
for (i = 0; i < (int) strlen(str); i++)
if (str[i] == ' ' || str[i] == '.' || str[i] == '/' ||
str[i] == '\\' || str[i] == '-' || str[i] == '(' || str[i] == ')')
str[i] = '_';
}
/*------------------------------------------------------------------*/
void url_encode(char *ps, int size)
/********************************************************************\
Encode the given string in-place by adding %XX escapes
\********************************************************************/
{
unsigned char *pd, *p;
unsigned char str[NAME_LENGTH];
pd = (unsigned char *) str;
p = (unsigned char *) ps;
while (*p && pd < str + 250) {
if (strchr("%&=#?+", *p) || *p > 127) {
sprintf((char *) pd, "%%%02X", *p);
pd += 3;
p++;
} else if (*p == ' ') {
*pd++ = '+';
p++;
} else {
*pd++ = *p++;
}
}
*pd = '\0';
strlcpy(ps, (char *) str, size);
}
/*------------------------------------------------------------------*/
void sgets(char *string, int size)
{
char *p;
do {
p = fgets(string, size, stdin);
} while (p == NULL);
if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
p[strlen(p) - 1] = 0;
}
/*------------------------------------------------------------------*/
void add_crlf(char *buffer, int bufsize)
{
char *p;
char *tmpbuf;
tmpbuf = (char *)malloc(bufsize);
/* convert \n -> \r\n */
p = buffer;
while ((p = strstr(p, "\n")) != NULL) {
if (p > buffer && *(p - 1) == '\r') {
p++;
continue;
}
if ((int) strlen(buffer) + 2 >= bufsize) {
free(tmpbuf);
return;
}
strlcpy(tmpbuf, p, bufsize);
*(p++) = '\r';
strlcpy(p, tmpbuf, bufsize - (p - buffer));
p++;
}
free(tmpbuf);
}
/*------------------------------------------------------------------*/
void convert_crlf(char *buffer, int bufsize)
{
char *p;
/* convert '\n' -> \r\n */
p = buffer;
while ((p = strstr(p, "\\n")) != NULL) {
if (p - buffer < bufsize - 2) {
*(p++) = '\r';
*(p++) = '\n';
}
}
}
/*------------------------------------------------------------------*/
int elog_connect(char *host, int port)
{
int status, sock;
struct hostent *phe;
struct sockaddr_in bind_addr;
/* create socket */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("cannot create socket");
return -1;
}
/* compose remote address */
memset(&bind_addr, 0, sizeof(bind_addr));
bind_addr.sin_family = AF_INET;
bind_addr.sin_addr.s_addr = 0;
bind_addr.sin_port = htons((unsigned short) port);
phe = gethostbyname(host);
if (phe == NULL) {
perror("cannot get host name");
return -1;
}
memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
/* connect to server */
status = connect(sock, (const sockaddr*) (&bind_addr), sizeof(bind_addr));
if (status != 0) {
printf("Cannot connect to host %s, port %d\n", host, port);
return -1;
}
if (verbose)
printf("Successfully connected to host %s, port %d\n", host, port);
return sock;
}
/*------------------------------------------------------------------*/
#ifdef HAVE_SSL
int ssl_connect(int sock, SSL ** ssl_con)
{
SSL_METHOD *meth;
SSL_CTX *ctx;
X509 *cert = NULL;
int i;
SSL_library_init();
SSL_load_error_strings();
meth = (SSL_METHOD *) TLSv1_2_method();
ctx = SSL_CTX_new(meth);
*ssl_con = SSL_new(ctx);
SSL_set_fd(*ssl_con, sock);
if (SSL_connect(*ssl_con) <= 0)
return -1;
cert = SSL_get_peer_certificate(*ssl_con);
if (cert == NULL)
return -1;
i = SSL_get_verify_result(*ssl_con);
if (i != X509_V_OK)
printf("Possibly invalid certificate, continue on your own risk!\n");
return 0;
}
#endif
/*------------------------------------------------------------------*/
char request[100000], response[100000], *content;
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)
/********************************************************************\
Routine: retrive_elog
Purpose: Retrive an ELog entry for edit/reply
Input:
char *host Host name where ELog server runs
int port ELog server port number
char *subdir Subdirectoy to elog server
int ssl Flag for using SSL layer
char *uname User name
char *upwd User password
int message_id Message to retrieve
char *attrib_name Attribute names
char *attrib Attribute values
char *text Message text
Function value:
EL_SUCCESS Successful completion
\********************************************************************/
{
int i, n, first, index, sock;
char str[256], encrypted_passwd[256], *ph, *ps;
#ifdef HAVE_SSL
SSL *ssl_con = NULL;
#endif
if (ssl) /* avoid compiler warning */
sock = 0;
sock = elog_connect(host, port);
if (sock < 0)
return sock;
#ifdef HAVE_SSL
if (ssl)
if (ssl_connect(sock, &ssl_con) < 0) {
printf("elogd server does not run SSL protocol\n");
return -1;
}
#endif
/* compose request */
strcpy(request, "GET /");
strlcpy(str, experiment, sizeof(str));
url_encode(str, sizeof(str));
if (subdir[0] && experiment[0])
sprintf(request + strlen(request), "%s/%s/%d?cmd=download", subdir, str, message_id);
else if (subdir[0])
sprintf(request + strlen(request), "%s/%d?cmd=download", subdir, message_id);
else if (experiment[0])
sprintf(request + strlen(request), "%s/%d?cmd=download", str, message_id);
strcat(request, " HTTP/1.0\r\n");
sprintf(request + strlen(request), "User-Agent: ELOG\r\n");
first = 1;
if (uname[0]) {
if (first)
sprintf(request + strlen(request), "Cookie: ");
first = 0;
sprintf(request + strlen(request), "unm=%s;", uname);
}
if (upwd[0]) {
if (first)
sprintf(request + strlen(request), "Cookie: ");
first = 0;
do_crypt(upwd, encrypted_passwd, sizeof(encrypted_passwd));
sprintf(request + strlen(request), "upwd=%s;", encrypted_passwd);
}
/* finish cookie line */
if (!first)
strcat(request, "\r\n");
strcat(request, "\r\n");
/* send request */
#ifdef HAVE_SSL
if (ssl)
SSL_write(ssl_con, request, strlen(request));
else
#endif
send(sock, request, strlen(request), 0);
if (verbose) {
printf("Request sent to host:\n");
puts(request);
}
/* receive response */
memset(response, 0, sizeof(response));
#ifdef HAVE_SSL
if (ssl)
i = SSL_read(ssl_con, response, sizeof(response) - 1);
else
#endif
i = recv(sock, response, sizeof(response) - 1, 0);
if (i < 0) {
perror("Cannot receive response");
return -1;
}
n = i;
while (i > 0) {
#ifdef HAVE_SSL
if (ssl)
i = SSL_read(ssl_con, response + n, sizeof(response) - 1 - n);
else
#endif
i = recv(sock, response + n, sizeof(response) - 1 - n, 0);
if (i > 0)
n += i;
}
response[n] = 0;
#ifdef HAVE_SSL
if (ssl) {
SSL_shutdown(ssl_con);
SSL_free(ssl_con);
}
#endif
closesocket(sock);
if (verbose) {
printf("Response received:\n");
puts(response);
}
/* check response status */
if (strstr(response, "$@MID@$:")) {
/* separate attributes and message */
ph = strstr(response, "========================================\n");
/* skip first line */
ps = strstr(response, "$@MID@$:");
while (*ps && *ps != '\n')
ps++;
while (*ps && (*ps == '\n' || *ps == '\r'))
ps++;
for (index = 0; index < MAX_N_ATTR; index++) {
if (ps >= ph)
break;
strlcpy(attrib_name[index], ps, NAME_LENGTH);
if (strchr(attrib_name[index], ':'))
*(strchr(attrib_name[index], ':')) = 0;
ps += strlen(attrib_name[index]) + 2;
strlcpy(attrib[index], ps, NAME_LENGTH);
for (i = 0; i < NAME_LENGTH; i++) {
if (attrib[index][i] == '\r' || attrib[index][i] == '\n')
attrib[index][i] = 0;
if (attrib[index][i] == 0)
break;
}
ps += strlen(attrib[index]);
while (*ps && (*ps == '\n' || *ps == '\r'))
ps++;
}
attrib_name[index][0] = 0;
attrib[index][0] = 0;
ph = strchr(ph, '\n') + 1;
if (*ph == '\r')
ph++;
strlcpy(text, ph, TEXT_SIZE);
return 1;
}
if (strstr(response, "302 Found")) {
if (strstr(response, "Location:")) {
if (strstr(response, "fail"))
printf("Error: Invalid user name or password\n");
else {
strncpy(str, strstr(response, "Location:") + 10, sizeof(str));
if (strchr(str, '?'))
*strchr(str, '?') = 0;
if (strchr(str, '\n'))
*strchr(str, '\n') = 0;
if (strchr(str, '\r'))
*strchr(str, '\r') = 0;
if (strrchr(str, '/'))
printf("Message successfully transmitted, ID=%s\n", strrchr(str, '/') + 1);
else
printf("Message successfully transmitted, ID=%s\n", str);
}
}
} else if (strstr(response, "Logbook Selection"))
printf("Error: No logbook specified\n");
else if (strstr(response, "enter password"))
printf("Error: Missing or invalid password\n");
else if (strstr(response, "form name=form1"))
printf("Error: Missing or invalid user name/password\n");
else
printf("Error transmitting message\n");
return 0;
}
/*------------------------------------------------------------------*/
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])
/********************************************************************\
Routine: submit_elog
Purpose: Submit an ELog entry
Input:
char *host Host name where ELog server runs
in port ELog server port number
int ssl SSL flag
char *subdir Subdirectoy to elog server
char *uname User name
char *upwd User password
int reply Reply to existing message
int edit Edit existing message
int download Download existing message
int suppress Suppress Email notification
int encoding 0:ELCode,1:plain,2:HTML
char *attrib_name Attribute names
char *attrib Attribute values
char *text Message text
char afilename[] File names of attachments
char *buffer[] Attachment contents
INT buffer_size[] Size of buffer in bytes
Function value:
EL_SUCCESS Successful completion
\********************************************************************/
{
int status, sock, i, n, header_length, content_length, index;
char host_name[256], boundary[80], str[80], encrypted_passwd[256], *p;
const char* old_encoding;
char old_attrib_name[MAX_N_ATTR+1][NAME_LENGTH], old_attrib[MAX_N_ATTR+1][NAME_LENGTH];
struct hostent *phe;
#ifdef HAVE_SSL
SSL *ssl_con = NULL;
#endif
/* get local host name */
gethostname(host_name, sizeof(host_name));
phe = gethostbyname(host_name);
if (phe == NULL) {
perror("Cannot retrieve host name");
return -1;
}
phe = gethostbyaddr(phe->h_addr, sizeof(int), AF_INET);
if (phe == NULL) {
perror("Cannot retrieve host name");
return -1;
}
/* if domain name is not in host name, hope to get it from phe */
if (strchr(host_name, '.') == NULL)
strcpy(host_name, phe->h_name);
if (edit || download) {
if (edit)
status = retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, edit,
old_attrib_name, old_attrib, old_text);
else
status = retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, download,
old_attrib_name, old_attrib, old_text);
if (status != 1)
return status;
/* update attributes */
for (index = 0; index < n_attr; index++) {
for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++)
if (equal_ustring(attrib_name[index], old_attrib_name[i]))
break;
if (old_attrib_name[i][0])
strlcpy(old_attrib[i], attrib[index], NAME_LENGTH);
}
/* copy attributes */
for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++) {
strlcpy(attrib_name[i], old_attrib_name[i], NAME_LENGTH);
strlcpy(attrib[i], old_attrib[i], NAME_LENGTH);
}
n_attr = i;
if (text[0] == 0)
strlcpy(text, old_text, TEXT_SIZE);
}
if (download) {
if (strstr(response, "$@MID@$:"))
printf("%s", strstr(response, "$@MID@$:"));
else
printf("%s", response);
return 1;
}
if (reply) {
status =
retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, reply,
old_attrib_name, old_attrib, old_text);
if (status != 1)
return status;
/* update attributes */
for (index = 0; index < n_attr; index++) {
for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++)
if (equal_ustring(attrib_name[index], old_attrib_name[i]))
break;
if (old_attrib_name[i][0])
strlcpy(old_attrib[i], attrib[index], NAME_LENGTH);
}
/* copy attributes */
for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++) {
if (equal_ustring(old_attrib_name[i], "Reply to") || equal_ustring(old_attrib_name[i], "Date")) {
attrib_name[i][0] = 0;
attrib[i][0] = 0;
} else {
strlcpy(attrib_name[i], old_attrib_name[i], NAME_LENGTH);
strlcpy(attrib[i], old_attrib[i], NAME_LENGTH);
}
}
n_attr = i;
/* check encoding */
old_encoding = "plain";
for (i = 0; i < n_attr; i++)
if (equal_ustring(attrib_name[i], "encoding"))
break;
if (i < n_attr)
old_encoding = attrib[i];
if (quote_on_reply) {
strlcpy(new_text, text, sizeof(new_text));
/* precede old text with "> " */
text[0] = 0;
p = old_text;
do {
if (strchr(p, '\n')) {
*strchr(p, '\n') = 0;
if (old_encoding[0] == 'H') {
strlcat(text, "> ", TEXT_SIZE);
strlcat(text, p, TEXT_SIZE);
strlcat(text, "
\n", TEXT_SIZE);
} else {
strlcat(text, "> ", TEXT_SIZE);
strlcat(text, p, TEXT_SIZE);
strlcat(text, "\n", TEXT_SIZE);
}
p += strlen(p) + 1;
if (*p == '\n')
p++;
} else {
if (old_encoding[0] == 'H') {
strlcat(text, "> ", TEXT_SIZE);
strlcat(text, p, TEXT_SIZE);
strlcat(text, "\n", TEXT_SIZE);
} else {
strlcat(text, "> ", TEXT_SIZE);
strlcat(text, p, TEXT_SIZE);
strlcat(text, "\n\n", TEXT_SIZE);
}
break;
}
} while (1);
strlcat(text, new_text, TEXT_SIZE);
}
}
sock = elog_connect(host, port);
if (sock < 0)
return sock;
#ifdef HAVE_SSL
if (ssl)
if (ssl_connect(sock, &ssl_con) < 0) {
printf("elogd server does not run SSL protocol\n");
return -1;
}
#endif
content_length = 100000;
for (i = 0; i < MAX_ATTACHMENTS; i++)
if (afilename[i][0])
content_length += buffer_size[i];
content = (char *)malloc(content_length);
if (content == NULL) {
printf("Not enough memory\n");
return -1;
}
/* compose content */
srand((unsigned) time(NULL));
sprintf(boundary, "---------------------------%04X%04X%04X", rand(), rand(), rand());
strcpy(content, boundary);
strcat(content, "\r\nContent-Disposition: form-data; name=\"cmd\"\r\n\r\nSubmit\r\n");
if (uname[0])
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"unm\"\r\n\r\n%s\r\n", boundary, uname);
if (upwd[0]) {
do_crypt(upwd, encrypted_passwd, sizeof(encrypted_passwd));
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"upwd\"\r\n\r\n%s\r\n", boundary,
encrypted_passwd);
}
if (experiment[0])
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"exp\"\r\n\r\n%s\r\n", boundary, experiment);
if (reply)
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"reply_to\"\r\n\r\n%d\r\n", boundary, reply);
if (edit) {
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"edit_id\"\r\n\r\n%d\r\n", boundary, edit);
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"skiplock\"\r\n\r\n1\r\n", boundary);
}
if (suppress)
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"suppress\"\r\n\r\n1\r\n", boundary);
if (encoding == 0)
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nELCode\r\n", boundary);
else if (encoding == 1)
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nplain\r\n", boundary);
else if (encoding == 2)
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nHTML\r\n", boundary);
for (i = 0; i < n_attr; i++) {
strcpy(str, attrib_name[i]);
if (str[0]) {
stou(str);
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", boundary, str, attrib[i]);
}
}
if (text[0])
sprintf(content + strlen(content),
"%s\r\nContent-Disposition: form-data; name=\"Text\"\r\n\r\n%s\r\n%s\r\n",
boundary, text, boundary);
content_length = strlen(content);
p = content + content_length;
for (i = 0; i < MAX_ATTACHMENTS; i++)
if (afilename[i][0]) {
sprintf(p,
"Content-Disposition: form-data; name=\"attfile%d\"; filename=\"%s\"\r\n\r\n",
i + 1, afilename[i]);
content_length += strlen(p);
p += strlen(p);
memcpy(p, buffer[i], buffer_size[i]);
p += buffer_size[i];
strcpy(p, boundary);
strcat(p, "\r\n");
content_length += buffer_size[i] + strlen(p);
p += strlen(p);
}
/* compose request */
strcpy(request, "POST /");
if (subdir[0])
sprintf(request + strlen(request), "%s/", subdir);
if (experiment[0]) {
strcpy(str, experiment);
url_encode(str, sizeof(str));
sprintf(request + strlen(request), "%s/", str);
}
strcat(request, " HTTP/1.0\r\n");
sprintf(request + strlen(request), "Content-Type: multipart/form-data; boundary=%s\r\n", boundary);
if (port != 80)
sprintf(str, "%s:%d", host, port);
else
sprintf(str, "%s", host);
sprintf(request + strlen(request), "Host: %s\r\n", str);
sprintf(request + strlen(request), "User-Agent: ELOG\r\n");
sprintf(request + strlen(request), "Content-Length: %d\r\n", content_length);
strcat(request, "\r\n");
header_length = strlen(request);
/*
{
FILE *f;
f = fopen("elog.log", "w");
fwrite(request, header_length+content_length, 1, f);
fclose(f);
}
*/
/* send request */
#ifdef HAVE_SSL
if (ssl)
SSL_write(ssl_con, request, header_length);
else
#endif
send(sock, request, header_length, 0);
if (verbose) {
printf("Request sent to host:\n");
puts(request);
}
/* send content */
#ifdef HAVE_SSL
if (ssl)
SSL_write(ssl_con, content, content_length);
else
#endif
send(sock, content, content_length, 0);
if (verbose) {
printf("Content sent to host:\n");
puts(content);
}
/* receive response */
memset(response, 0, sizeof(response));
#ifdef HAVE_SSL
if (ssl)
i = SSL_read(ssl_con, response, sizeof(response) - 1);
else
#endif
i = recv(sock, response, sizeof(response) - 1, 0);
if (i < 0) {
perror("Cannot receive response");
return -1;
}
/* discard remainder of response */
n = i;
while (i > 0) {
#ifdef HAVE_SSL
if (ssl)
i = SSL_read(ssl_con, response + n, sizeof(response) - 1 - n);
else
#endif
i = recv(sock, response + n, sizeof(response) - 1 - n, 0);
if (i > 0)
n += i;
}
response[n] = 0;
#ifdef HAVE_SSL
if (ssl) {
SSL_shutdown(ssl_con);
SSL_free(ssl_con);
}
#endif
closesocket(sock);
if (verbose) {
printf("Response received:\n");
puts(response);
}
/* check response status */
if (strstr(response, "302 Found")) {
if (strstr(response, "Location:")) {
if (strstr(response, "has moved"))
printf("Error: elogd server has moved to another location\n");
else if (strstr(response, "fail"))
printf("Error: Invalid user name or password\n");
else {
strncpy(str, strstr(response, "Location:") + 10, sizeof(str));
if (strchr(str, '?'))
*strchr(str, '?') = 0;
if (strchr(str, '\n'))
*strchr(str, '\n') = 0;
if (strchr(str, '\r'))
*strchr(str, '\r') = 0;
if (strrchr(str, '/'))
printf("Message successfully transmitted, ID=%s\n", strrchr(str, '/') + 1);
else
printf("Message successfully transmitted, ID=%s\n", str);
}
} else
printf("Message successfully transmitted\n");
} else if (strstr(response, "Logbook Selection"))
printf("Error: No logbook specified\n");
else if (strstr(response, "enter password"))
printf("Error: Missing or invalid password\n");
else if (strstr(response, "Error: Attribute")) {
if (strstr(response, "not existing")) {
strncpy(str, strstr(response, "Error: Attribute") + 27, sizeof(str));
if (strchr(str, '<'))
*strchr(str, '<') = 0;
printf("Error: Non existing attribute option \"%s\"\n", str);
} else {
strncpy(str, strstr(response, "Error: Attribute") + 20, sizeof(str));
if (strchr(str, '<'))
*strchr(str, '<') = 0;
printf("Error: Missing required attribute \"%s\"\n", str);
}
}
else if (strstr(response, "form name=form1"))
printf("Error: Missing or invalid user name/password\n");
else
printf("Error transmitting message\n");
return 1;
}
/*------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
char str[1000], uname[80], upwd[80];
char host_name[256], logbook[32], textfile[256], subdir[256];
char *buffer[MAX_ATTACHMENTS], attachment[MAX_ATTACHMENTS][256];
INT att_size[MAX_ATTACHMENTS];
INT i, n, fh, n_att, n_attr, port, reply, quote_on_reply, edit, download, encoding, suppress, size, ssl,
text_flag;
char attr_name[MAX_N_ATTR][NAME_LENGTH], attrib[MAX_N_ATTR][NAME_LENGTH];
text[0] = textfile[0] = uname[0] = upwd[0] = suppress = quote_on_reply = 0;
host_name[0] = logbook[0] = subdir[0] = 0;
n_att = n_attr = reply = edit = download = encoding = 0;
port = 80;
ssl = 0;
text_flag = 0;
for (i = 0; i < MAX_ATTACHMENTS; i++) {
attachment[i][0] = 0;
buffer[i] = NULL;
att_size[i] = 0;
}
/* parse command line parameters */
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-' && argv[i][1] == 'v')
verbose = 1;
else if (argv[i][0] == '-' && argv[i][1] == 's')
ssl = 1;
else if (argv[i][0] == '-' && argv[i][1] == 'q')
quote_on_reply = 1;
else if (argv[i][0] == '-' && argv[i][1] == 'x')
suppress = 1;
else {
if (argv[i][0] == '-') {
if (i + 1 >= argc || argv[i + 1][0] == '-')
goto usage;
if (argv[i][1] == 'h')
strcpy(host_name, argv[++i]);
else if (argv[i][1] == 'p')
port = atoi(argv[++i]);
else if (argv[i][1] == 'l')
strcpy(logbook, argv[++i]);
else if (argv[i][1] == 'd')
strcpy(subdir, argv[++i]);
else if (argv[i][1] == 'u') {
strcpy(uname, argv[++i]);
strcpy(upwd, argv[++i]);
} else if (argv[i][1] == 'a') {
strcpy(str, argv[++i]);
if (strchr(str, '=')) {
strcpy(attrib[n_attr], strchr(str, '=') + 1);
*strchr(str, '=') = 0;
strcpy(attr_name[n_attr], str);
n_attr++;
} else {
printf("Error: Attributes must be supplied in the form \"-a =\".\n");
return 1;
}
} else if (argv[i][1] == 'f')
strcpy(attachment[n_att++], argv[++i]);
else if (argv[i][1] == 'r')
reply = atoi(argv[++i]);
else if (argv[i][1] == 'e')
edit = atoi(argv[++i]);
else if (argv[i][1] == 'w') {
if (argv[i+1][0] == 'l')
download = -1;
else
download = atoi(argv[++i]);
} else if (argv[i][1] == 'n')
encoding = atoi(argv[++i]);
else if (argv[i][1] == 'm') {
strcpy(textfile, argv[++i]);
text_flag = 1;
} else {
usage:
printf("%s ", ELOGID);
printf("revision %s\n", git_revision());
printf("\nusage: elog\n");
printf("elog -h [-p port] [-d subdir]\n");
printf(" Location where elogd is running\n");
printf(" -l logbook/experiment Name of logbook or experiment\n");
printf(" -s Use SSL for communication\n");
printf(" [-v] For verbose output\n");
printf(" [-u username password] Wser name and password\n");
printf(" [-f ] (up to %d attachments)\n", MAX_ATTACHMENTS);
printf(" -a = (up to %d attributes)\n", MAX_N_ATTR);
printf(" [-r ] Reply to existing message\n");
printf(" [-q] Quote original text on reply\n");
printf(" [-e ] Edit existing message\n");
printf(" [-w |last] Download existing message (last message)\n");
printf(" [-x] Suppress email notification\n");
printf(" [-n 0|1|2] Encoding: 0:ELcode,1:plain,2:HTML\n");
printf(" -m ] | \n");
printf("\nArguments with blanks must be enclosed in quotes\n");
printf("The elog message can either be submitted on the command line, piped in like\n");
printf("\"cat text | elog -h ... -l ... -a ...\" or in a file with the -m flag.\n");
printf("Multiple attributes and attachments can be supplied\n");
return 1;
}
} else {
strcpy(text, argv[i]);
convert_crlf(text, sizeof(text));
text_flag = 1;
}
}
}
#ifndef HAVE_SSL
if (ssl) {
printf("SLL support not compiled into this program\n");
return 1;
}
#endif
#if defined( _MSC_VER )
{
WSADATA WSAData;
/* Start windows sockets */
if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
return -1;
}
#endif
if (host_name[0] == 0) {
printf("Please specify hostname.\n");
return 1;
}
if (logbook[0] == 0) {
printf("Please specify logbook with the \"-l\" flag.\n");
return 1;
}
if (n_attr == 0 && !edit && !reply && !download) {
printf("Please specify attribute(s) with the \"-a\" flag.\n");
return 1;
}
fh = -1;
if (textfile[0]) {
fh = open(textfile, O_RDONLY | O_BINARY);
if (fh < 0) {
printf("Message file \"%s\" does not exist.\n", textfile);
return 1;
}
size = (INT) lseek(fh, 0, SEEK_END);
lseek(fh, 0, SEEK_SET);
if (size > (INT) (sizeof(text) - 1)) {
printf("Message file \"%s\" is too long (%zd bytes max).\n", textfile, sizeof(text));
return 1;
}
i = read(fh, text, size);
if (i < size) {
printf("Cannot fully read message from file %s.\n", textfile);
return 1;
}
close(fh);
}
if (text_flag == 0 && !edit && !download) {
/* read from stdin */
n = 0;
do {
i = getchar();
text[n++] = i;
} while (i != EOF);
if (n > 0)
text[n - 1] = 0;
}
/* change CR -> CRLF for unix text files */
add_crlf(text, sizeof(text));
/*---- open attachment file ----*/
for (i = 0; i < MAX_ATTACHMENTS; i++) {
if (!attachment[i][0])
break;
fh = open(attachment[i], O_RDONLY | O_BINARY);
if (fh < 0) {
printf("Attachment file \"%s\" does not exist.\n", attachment[i]);
return 1;
}
att_size[i] = lseek(fh, 0, SEEK_END);
lseek(fh, 0, SEEK_SET);
buffer[i] = (char *)malloc(att_size[i] + 1);
n = read(fh, buffer[i], att_size[i]);
if (n < att_size[i]) {
printf("Cannot fully read attachment file \"%s\".\n", attachment[i]);
return 1;
}
buffer[i][n] = 0;
close(fh);
}
/* now submit message */
submit_elog(host_name, port, ssl, subdir, logbook,
uname, upwd, reply, quote_on_reply, edit, download, suppress, encoding, attr_name, attrib, n_attr, text,
attachment, buffer, att_size);
for (i = 0; i < MAX_ATTACHMENTS; i++)
if (buffer[i])
free(buffer[i]);
return 0;
}