1: #ifndef lint 2: static char *sccsid = "@(#)inews.c 1.4 (Berkeley) 3/20/86"; 3: #endif 4: 5: /* 6: * Itty-bitty inews for talking to remote server. 7: * Simply accept input on stdin (or via a named file) and dump this 8: * to the server; add a From: and Path: line if missing in the original. 9: * 10: * Steven Grady (grady@ucbvax.Berkeley.EDU) 11: */ 12: 13: #include <stdio.h> 14: #include <pwd.h> 15: #include <ctype.h> 16: #include <strings.h> 17: #include "../common/conf.h" 18: #include "../common/response_codes.h" 19: 20: extern FILE *ser_wr_fp; 21: 22: main(argc, argv) 23: int argc; 24: char *argv[]; 25: { 26: char line[256], s[256]; 27: int seen_fromline, in_header; 28: 29: ++argv; 30: while (argc > 1) 31: if (*argv[0] == '-') { 32: ++argv; 33: --argc; 34: } else 35: break; 36: 37: if (argc > 1) { 38: if (freopen(*argv, "r", stdin) == NULL) { 39: perror(*argv); 40: exit(1); 41: } 42: } 43: 44: if (server_init(SERVER_HOST) < 0) 45: exit(1); /* Connect to the server */ 46: 47: put_server("POST"); 48: (void) get_server(line, sizeof(line)); 49: if (*line != CHAR_CONT) { 50: if (atoi(line) == ERR_NOPOST) { 51: fprintf(stderr, 52: "Sorry, you can't post from this machine.\n"); 53: exit(1); 54: } else { 55: fprintf(stderr, "Remote error: %s\n", line); 56: exit(1); 57: } 58: } 59: 60: in_header = 1; 61: while (gets(s) != NULL) { 62: if (s[0] == '.') /* Single . is eof, so put in extra one */ 63: (void) fputc('.', ser_wr_fp); 64: if (in_header && strneql(s, "From:", sizeof("From:")-1)) 65: seen_fromline = 1; 66: if (in_header && s[0] == '\0') { 67: in_header = 0; 68: if (!seen_fromline) 69: gen_frompath(); 70: } 71: fprintf(ser_wr_fp, "%s\r\n", s); 72: } 73: 74: append_signature(); 75: 76: fprintf(ser_wr_fp, ".\r\n"); 77: (void) fflush(ser_wr_fp); 78: (void) get_server(line, sizeof(line)); 79: if (*line != CHAR_OK) { 80: if (atoi(line) == ERR_POSTFAIL) { 81: fprintf(stderr, 82: "Article not accepted by server; not posted.\n"); 83: exit(1); 84: } else { 85: fprintf(stderr, "Remote error: %s\n", line); 86: exit(1); 87: } 88: } 89: 90: /* 91: * Close server sends the server a 92: * "quit" command for us, which is why we don't send it. 93: */ 94: 95: close_server(); 96: } 97: 98: /* 99: * append_signature -- append the person's .signature file if 100: * they have one. 101: */ 102: 103: append_signature() 104: { 105: char line[256], sigfile[256]; 106: char *cp; 107: struct passwd *passwd; 108: FILE *fp; 109: char *index(); 110: 111: passwd = getpwuid(getuid()); 112: if (passwd == NULL) 113: return; 114: 115: (void) strcpy(sigfile, passwd->pw_dir); 116: (void) strcat(sigfile, "/"); 117: (void) strcat(sigfile, ".signature"); 118: 119: fp = fopen(sigfile, "r"); 120: if (fp != NULL) 121: while (fgets(line, sizeof(line), fp)) { 122: if (cp = index(line, '\n')) 123: *cp = '\0'; 124: fprintf(ser_wr_fp, "%s\r\n", line); 125: } 126: } 127: 128: /* 129: * gen_frompath -- generate From: and Path: lines, in the form 130: * 131: * From: user@host.domain (full_name) 132: * Path: host!user 133: * 134: * This routine should only be called if the message doesn't have 135: * a From: line in it. 136: */ 137: 138: gen_frompath() 139: { 140: char host_name[256]; 141: char *full_name; 142: char *cp; 143: struct passwd *passwd; 144: char *index(), *getenv(); 145: 146: passwd = getpwuid(getuid()); 147: 148: full_name = getenv("NAME"); 149: if (full_name == NULL) { 150: full_name = passwd->pw_gecos; 151: if ((cp = index(full_name, ','))) 152: *cp = '\0'; 153: } 154: 155: (void) gethostname(host_name, sizeof (host_name)); 156: 157: #ifdef DOMAIN 158: fprintf(ser_wr_fp, "From: %s@%s.%s (", 159: passwd->pw_name, 160: host_name, 161: DOMAIN); 162: #else 163: fprintf(ser_wr_fp, "From: %s@%s (", 164: passwd->pw_name, 165: host_name); 166: #endif 167: 168: for (cp = full_name; *cp != '\0'; ++cp) 169: if (*cp != '&') 170: putc(*cp, ser_wr_fp); 171: else { /* Stupid & hack. God damn it. */ 172: putc(toupper(passwd->pw_name[0]), ser_wr_fp); 173: fprintf(ser_wr_fp, passwd->pw_name+1); 174: } 175: 176: fprintf(ser_wr_fp, ")\r\n"); 177: 178: fprintf(ser_wr_fp, "Path: %s!%s\r\n", host_name, passwd->pw_name); 179: } 180: 181: 182: /* 183: * strneql -- determine if two strings are equal in the first n 184: * characters, ignoring case. 185: * 186: * Parameters: "a" and "b" are the pointers 187: * to characters to be compared. 188: * "n" is the number of characters to compare. 189: * 190: * Returns: 1 if the strings are equal, 0 otherwise. 191: * 192: * Side effects: None. 193: */ 194: 195: strneql(a, b, n) 196: register char *a, *b; 197: int n; 198: { 199: char lower(); 200: 201: while (n && lower(*a) == lower(*b)) { 202: if (*a == '\0') 203: return (1); 204: a++; 205: b++; 206: n--; 207: } 208: if (n) 209: return (0); 210: else 211: return (1); 212: } 213: 214: /* 215: * lower -- convert a character to lower case, if it's 216: * upper case. 217: * 218: * Parameters: "c" is the character to be 219: * converted. 220: * 221: * Returns: "c" if the character is not 222: * upper case, otherwise the lower 223: * case eqivalent of "c". 224: * 225: * Side effects: None. 226: */ 227: 228: char lower(c) 229: register char c; 230: { 231: if (isascii(c) && isupper(c)) 232: c = c - 'A' + 'a'; 233: return(c); 234: }