/*------------------------------------------------- image_file_init ----- | Function image_file_init | | Purpose: Reads image data in from a file before a subsequent call to | image_init | | | Parameters: image_file (IN) -- open FILE handle with image data | | | Returns: Image instance *-------------------------------------------------------------------*/ Image * image_file_init(FILE * image_file) { Image * retval; char * header = (char *)malloc(sizeof(char) * BUFSIZ); char c; int pos = 0; while ((c = fgetc(image_file)) != EOF && c != '\n') { *(header + (pos * sizeof(char))) = c; pos++; } unsigned int rows = 0; unsigned int columns = 0; header_parse(header, &rows, &columns); unsigned int rowsize = sizeof(char) * (columns + 2); unsigned int row_mem_size = sizeof(char) * (columns + 1); unsigned int row_actual_size = row_mem_size + 8 - ((row_mem_size + 8) % 16); debug("Rowsize is %d\n", rowsize); char ** pixel_chars = malloc(sizeof(char *) * rows); unsigned int row; for (row = 0; row < rows; row++) { *(pixel_chars + (row * row_actual_size)) = (char *) malloc(row_actual_size); char * row_data = malloc(sizeof(char) * 1000); row_data = fgets(row_data, 1000, image_file); if (row_data == NULL || ferror(image_file)) { error("Image data invalid! Expected to read %d rows", rows); exit(EXIT_FAILURE); } *(row_data + columns) = '\0'; *(pixel_chars + (row * row_actual_size)) = strcpy(*(pixel_chars + (row * row_actual_size)), row_data); debug("Allocated row %d at %u", row, *(pixel_chars + (row * row_actual_size))); debug("Allocated row %s", *(pixel_chars + (row * row_actual_size))); } retval = image_init(pixel_chars, rows, columns); free(header); free(pixel_chars); return retval; }
/* ssmtp() -- send the message (exactly one) from stdin to the mailhub SMTP port */ int ssmtp(char *argv[]) { char b[(BUF_SZ + 2)], *buf = b+1, *p, *q; #ifdef MD5AUTH char challenge[(BUF_SZ + 1)]; #endif struct passwd *pw; int i, sock; uid_t uid; bool_t minus_v_save, leadingdot, linestart = True; int timeout = 0; int bufsize = sizeof(b)-1; b[0] = '.'; outbytes = 0; ht = &headers; uid = getuid(); if((pw = getpwuid(uid)) == (struct passwd *)NULL) { die("Could not find password entry for UID %d", uid); } get_arpadate(arpadate); if(read_config() == False) { log_event(LOG_INFO, "%s not found", config_file); } if((p = strtok(pw->pw_gecos, ";,"))) { if((gecos = strdup(p)) == (char *)NULL) { die("ssmtp() -- strdup() failed"); } } revaliases(pw); /* revaliases() may have defined this */ if(uad == (char *)NULL) { uad = append_domain(pw->pw_name); } rt = &rcpt_list; header_parse(stdin); #if 1 /* With FromLineOverride=YES set, try to recover sane MAIL FROM address */ uad = append_domain(uad); #endif from = from_format(uad, override_from); /* Now to the delivery of the message */ (void)signal(SIGALRM, (void(*)())handler); /* Catch SIGALRM */ (void)alarm((unsigned) MAXWAIT); /* Set initial timer */ if(setjmp(TimeoutJmpBuf) != 0) { /* Then the timer has gone off and we bail out */ die("Connection lost in middle of processing"); } if((sock = smtp_open(mailhost, port)) == -1) { die("Cannot open %s:%d", mailhost, port); } else if (use_starttls == False) /* no initial response after STARTTLS */ { if(smtp_okay(sock, buf) == False) die("Invalid response SMTP server"); } /* If user supplied username and password, then try ELHO */ if(auth_user) { outbytes += smtp_write(sock, "EHLO %s", hostname); } else { outbytes += smtp_write(sock, "HELO %s", hostname); } (void)alarm((unsigned) MEDWAIT); if(smtp_okay(sock, buf) == False) { die("%s (%s)", buf, hostname); } /* Try to log in if username was supplied */ if(auth_user) { #ifdef MD5AUTH if(auth_pass == (char *)NULL) { auth_pass = strdup(""); } if(auth_method && strcasecmp(auth_method, "cram-md5") == 0) { outbytes += smtp_write(sock, "AUTH CRAM-MD5"); (void)alarm((unsigned) MEDWAIT); if(smtp_read(sock, buf) != 3) { die("Server rejected AUTH CRAM-MD5 (%s)", buf); } strncpy(challenge, strchr(buf,' ') + 1, sizeof(challenge)); memset(buf, 0, bufsize); crammd5(challenge, auth_user, auth_pass, buf); } else { #endif memset(buf, 0, bufsize); to64frombits(buf, auth_user, strlen(auth_user)); if (use_oldauth) { outbytes += smtp_write(sock, "AUTH LOGIN %s", buf); } else { outbytes += smtp_write(sock, "AUTH LOGIN"); (void)alarm((unsigned) MEDWAIT); if(smtp_read(sock, buf) != 3) { die("Server didn't like our AUTH LOGIN (%s)", buf); } /* we assume server asked us for Username */ memset(buf, 0, bufsize); to64frombits(buf, auth_user, strlen(auth_user)); outbytes += smtp_write(sock, buf); } (void)alarm((unsigned) MEDWAIT); if(smtp_read(sock, buf) != 3) { die("Server didn't accept AUTH LOGIN (%s)", buf); } memset(buf, 0, bufsize); to64frombits(buf, auth_pass, strlen(auth_pass)); #ifdef MD5AUTH } #endif /* We do NOT want the password output to STDERR * even base64 encoded.*/ minus_v_save = minus_v; minus_v = False; outbytes += smtp_write(sock, "%s", buf); minus_v = minus_v_save; (void)alarm((unsigned) MEDWAIT); if(smtp_okay(sock, buf) == False) { die("Authorization failed (%s)", buf); } } /* Send "MAIL FROM:" line */ outbytes += smtp_write(sock, "MAIL FROM:<%s>", uad); (void)alarm((unsigned) MEDWAIT); if(smtp_okay(sock, buf) == 0) { die("%s", buf); } /* Send all the To: adresses */ /* Either we're using the -t option, or we're using the arguments */ if(minus_t) { if(rcpt_list.next == (rcpt_t *)NULL) { die("No recipients specified although -t option used"); } rt = &rcpt_list; while(rt->next) { p = rcpt_remap(rt->string); outbytes += smtp_write(sock, "RCPT TO:<%s>", p); (void)alarm((unsigned)MEDWAIT); if(smtp_okay(sock, buf) == 0) { die("RCPT TO:<%s> (%s)", p, buf); } rt = rt->next; } } else { for(i = 1; (argv[i] != NULL); i++) { p = strtok(argv[i], ","); while(p) { /* RFC822 Address -> "foo@bar" */ q = rcpt_remap(addr_parse(p)); outbytes += smtp_write(sock, "RCPT TO:<%s>", q); (void)alarm((unsigned) MEDWAIT); if(smtp_okay(sock, buf) == 0) { die("RCPT TO:<%s> (%s)", q, buf); } p = strtok(NULL, ","); } } } /* Send DATA */ outbytes += smtp_write(sock, "DATA"); (void)alarm((unsigned) MEDWAIT); if(smtp_read(sock, buf) != 3) { /* Oops, we were expecting "354 send your data" */ die("%s", buf); } outbytes += smtp_write(sock, "Received: by %s (sSMTP sendmail emulation); %s", hostname, arpadate); if(have_from == False) { outbytes += smtp_write(sock, "From: %s", from); } if(have_date == False) { outbytes += smtp_write(sock, "Date: %s", arpadate); } #ifdef HASTO_OPTION if(have_to == False) { outbytes += smtp_write(sock, "To: postmaster"); } #endif ht = &headers; while(ht->next) { outbytes += smtp_write(sock, "%s", ht->string); ht = ht->next; } (void)alarm((unsigned) MEDWAIT); /* End of headers, start body */ outbytes += smtp_write(sock, ""); /*prevent blocking on pipes, we really shouldnt be using stdio functions like fgets in the first place */ fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK); while(!feof(stdin)) { if (!fgets(buf, bufsize, stdin)) { /* if nothing was received, then no transmission * over smtp should be done */ sleep(1); /* don't hang forever when reading from stdin */ if (++timeout >= MEDWAIT) { log_event(LOG_ERR, "killed: timeout on stdin while reading body -- message saved to dead.letter."); die("Timeout on stdin while reading body"); } continue; } /* Trim off \n, double leading .'s */ leadingdot = standardise(buf, &linestart); if (linestart || feof(stdin)) { linestart = True; outbytes += smtp_write(sock, "%s", leadingdot ? b : buf); } else { if (log_level > 0) { log_event(LOG_INFO, "Sent a very long line in chunks"); } if (leadingdot) { outbytes += fd_puts(sock, b, sizeof(b)); } else { outbytes += fd_puts(sock, buf, bufsize); } } (void)alarm((unsigned) MEDWAIT); } if(!linestart) { smtp_write(sock, ""); } /* End of body */ outbytes += smtp_write(sock, "."); (void)alarm((unsigned) MAXWAIT); if(smtp_okay(sock, buf) == 0) { die("%s", buf); } /* Close connection */ (void)signal(SIGALRM, SIG_IGN); outbytes += smtp_write(sock, "QUIT"); (void)smtp_okay(sock, buf); (void)close(sock); log_event(LOG_INFO, "Sent mail for %s (%s) uid=%d username=%s outbytes=%d", from_strip(uad), buf, uid, pw->pw_name, outbytes); return(0); }