/*fax.c - send a fax over the Internet using the remote printer protocol. Copyright (c) 1994 by Matthew Belmonte. Licence is hereby granted to use, to copy, and to distribute this software, in its original form or in modified form, provided that such copies and distributions include this copyright and licence notice in its entirety, and provided that any additions, modifications, or other features not present in the original program are clearly noted. No fee may be charged for a distribution of this program or of any program based upon it, except for reasonable fees to cover the costs of storage media and handling. This software is provided 'as is', with no warranty, express or implied, including but not limited to warranties of merchantability or fitness for a particular purpose. The user of this software assumes liability for any and all damages, whether direct or consequential, arising from its use. The author of this software will not be liable for any such damages. */ #define HOSTNAME "salk.edu" /*change this to your own hostname*/ #define MAX_NUMBER_LENGTH 32 /*phone numbers can't be longer than this*/ #include #include #include #include #include #include char to_ascii(c) char c; { return(c <= 25 ? 'A'+c : c <= 51 ? 'a'+c-26 : c <= 61 ? '0'+c-52 : c == 62 ? '+' : '/'); } void main(argc, argv) int argc; char *argv[]; { register int num_chars_in_triplet, num_triplets_on_line, i, arg, number_length; register long reg; FILE *sendmail; struct passwd *sender_info; char phone_number[MAX_NUMBER_LENGTH+1]; if(argc == 1) { fprintf(stderr, "usage: %s NUMBER [NAME]\nNUMBER is the complete telephone number, including the country code (the\ncountry code for the United States is 1). The NUMBER may contain separators\nsuch as spaces, '-', '/', and '+', but cannot contain any letter of the\nalphabet. The recipient's NAME, if given, will appear on the cover sheet and\nmust begin with a letter of the alphabet. The symbol '/' within the NAME\nbegins a new line.\nThis program reads from standard input, and treats as PostScript any input\nthat begins with `%%!'.\n\nFor general information on fax servers, mail tpc-faq@town.hall.org. For a\ncurrent list of service areas, mail tpc-coverage@town.hall.org\n", argv[0]); exit(2); } arg = 0; number_length = 0; do { arg++; for(i = 0; (argv[arg][i] != '\0') && !(((argv[arg][i] >= 'A') && (argv[arg][i] <= 'Z')) || ((argv[arg][i] >= 'a') && (argv[arg][i] <= 'z'))); i++) if((argv[arg][i] >= '0') && (argv[arg][i] <= '9')) phone_number[number_length++] = argv[arg][i]; } while((argv[arg][i] == '\0') && (arg < argc-1)); if(number_length < 5) { fprintf(stderr, "Missing or incomplete phone number.\n"); exit(EX_NOHOST); } if((sender_info = getpwuid(getuid())) == NULL) { fprintf(stderr, "Couldn't get sender information from passwd file.\n"); exit(EX_OSFILE); } if((sendmail = popen("/usr/lib/sendmail -t -v", "w")) == NULL) { perror((char *)0); exit(errno); } fprintf(sendmail, "From: %s <%s@%s>\nTo: remote-printer", sender_info->pw_gecos, sender_info->pw_name, HOSTNAME); if(argv[arg][i] != '\0') { putc('.', sendmail); do { while(argv[arg][i] != '\0') { putc(((argv[arg][i] == '.') || (argv[arg][i] == '/') || (argv[arg][i] == '-') || (argv[arg][i] == '+') || ((argv[arg][i] >= '0') && (argv[arg][i] <= '9')) || ((argv[arg][i] >= 'A') && (argv[arg][i] <= 'Z')) || ((argv[arg][i] >= 'a') && (argv[arg][i] <= 'z')))? argv[arg][i]: '_', sendmail); i++; } if(++arg != argc) { putc('_', sendmail); i = 0; } } while(arg != argc); } putc('@', sendmail); do { putc(phone_number[--number_length], sendmail); putc('.', sendmail); } while(number_length != 0); fprintf(sendmail, "tpc.int\n"); if((i = getchar()) != '%') { fprintf(sendmail, "\n%c", i); while((i = getchar()) != EOF) putc(i, sendmail); } else if((i = getchar()) != '!') { fprintf(sendmail, "\n%%%c", i); while((i = getchar()) != EOF) putc(i, sendmail); } else { i = getchar(); fprintf(sendmail, "Mime-Version: 1.0\nContent-Type: application/postscript\nContent-Transfer-Encoding: base64\n\nJS%c%c", to_ascii(4 + ((i >> 6) & 0x3)), to_ascii(i & 0x3f)); num_triplets_on_line = 1; while(i != EOF) /*see RFC 1521 on base64 encoding*/ { for(reg = 0L, num_chars_in_triplet = 0; (num_chars_in_triplet != 3) && ((i = getchar()) != EOF); num_chars_in_triplet++) reg = (reg << 8) | (((long)i) & 0xff); /*up to 3 bytes are in the shift register; convert them to a 4-character ASCII sequence:*/ switch(num_chars_in_triplet) { case 3: for(i = 0; i != 4; i++) { putc(to_ascii((reg >> 18) & 0x3f), sendmail); reg <<= 6; } break; case 2: putc(to_ascii((reg >> 10) & 0x3f), sendmail); putc(to_ascii((reg >> 4) & 0x3f), sendmail); putc(to_ascii((reg << 2) & 0x3f), sendmail); putc('=', sendmail); break; case 1: putc(to_ascii((reg >> 2) & 0x3f), sendmail); putc(to_ascii((reg << 4) & 0x3f), sendmail); putc('=', sendmail); putc('=', sendmail); } /*don't let lines grow longer than 76 characters (19 encoded triplets)*/ if(++num_triplets_on_line == 19) { putc('\n', sendmail); num_triplets_on_line = 0; } } } putc('\n', sendmail); putc('.', sendmail); putc('\n', sendmail); exit(pclose(sendmail)); }