static BOOLEAN message_has_content(const char *filename, BOOLEAN *nonspaces) { FILE *fp; char *buffer = NULL; BOOLEAN in_headers = TRUE; *nonspaces = FALSE; if (!filename || (fp = fopen(filename, "r")) == NULL) { CTRACE((tfp, "Failed to open file %s for reading!\n", NONNULL(filename))); return FALSE; } while (LYSafeGets(&buffer, fp) != NULL) { char *cp = buffer; char firstnonblank = '\0'; LYTrimNewline(cp); for (; *cp; cp++) { if (!firstnonblank && isgraph(UCH(*cp))) { firstnonblank = *cp; } else if (!isspace(UCH(*cp))) { *nonspaces = TRUE; } } if (firstnonblank && firstnonblank != '>') { if (!in_headers) { LYCloseInput(fp); FREE(buffer); return TRUE; } } if (!firstnonblank) { in_headers = FALSE; } } FREE(buffer); LYCloseInput(fp); return FALSE; }
int ProcessMailcapEntry( FILE *fp, struct MailcapEntry *mc, AcceptMedia media ) { size_t rawentryalloc = 2000; size_t len; size_t need; char *rawentry, *s, *t; char *LineBuf = 0; rawentry = malloc( ( rawentryalloc ) * sizeof( char ) ); if ( rawentry == 0 ) { ExitWithError( gettext( "Memory exhausted! Program aborted!" ) ); } rawentry[0] = 0; while ( LYSafeGets( &LineBuf, fp ) == 0 ) { LYTrimNewline( LineBuf ); if ( LineBuf[0] != '#' && LineBuf[0] ) { len = strlen( LineBuf ); need = len + strlen( rawentry ) + 1; if ( rawentryalloc < need ) { rawentryalloc = rawentryalloc + need + 2000; rawentry = realloc( rawentry, ( rawentryalloc ) * sizeof( char ) ); if ( rawentry == 0 ) { ExitWithError( gettext( "Memory exhausted! Program aborted!" ) ); } } if ( len && LineBuf[ len + -1 ] == '\\' ) { LineBuf[ len + -1 ] = 0; strcat( rawentry, LineBuf ); } else { strcat( rawentry, LineBuf ); break; } } } if ( LineBuf ) { free( LineBuf ); LineBuf = 0; } t = s = LYSkipBlanks( rawentry ); if ( s[0] == 0 ) { if ( rawentry ) { free( rawentry ); rawentry = 0; } return 0; } else { s = strchr( rawentry, ';' ); if ( s == 0 ) { if ( WWW_TraceFlag && ( WWW_TraceMask & 8 ) ) { fprintf( TraceFP( ), "ProcessMailcapEntry: Ignoring invalid mailcap entry: %s\n", rawentry ); } if ( rawentry ) { free( rawentry ); rawentry = 0; } return 0; } else { s[0] = 0; s++; if ( strncasecomp( t, "text/html", 9 ) == 0 || strncasecomp( t, "text/plain", 10 ) == 0 ) { s = &s[ -1 ]; s[0] = ';'; if ( WWW_TraceFlag && ( WWW_TraceMask & 8 ) ) { fprintf( TraceFP( ), "ProcessMailcapEntry: Ignoring mailcap entry: %s\n", rawentry ); } if ( rawentry ) { free( rawentry ); rawentry = 0; } return 0; } else { LYRemoveBlanks( rawentry ); LYLowerCase( rawentry ); *(int*)&mc->needsterminal = 0; *(int*)&mc->copiousoutput = 0; *(int*)&mc->needtofree = 1; *(int*)&mc->testcommand = 0; *(int*)&mc->label = 0; *(int*)&mc->printcommand = 0; *(int*)&mc->contenttype[0] = 0; HTSACopy( &mc->contenttype, rawentry ); *(int*)&mc->quality = 0x3f800000; *(int*)&mc->maxbytes = 0; t = GetCommand( s, &mc->command ); if ( t ) { s = LYSkipBlanks( t ); for ( ; s; ) { char *arg, *eq, *mallocd_string; t = GetCommand( s, &mallocd_string ); arg = mallocd_string; eq = strchr( arg, '=' ); if ( eq ) { eq[0] = 0; eq++; eq = LYSkipBlanks( eq ); } if ( arg && arg[0] ) { arg = Cleanse( arg ); if ( strcmp( arg, "needsterminal" ) == 0 ) *(int*)&mc->needsterminal = 1; else { if ( strcmp( arg, "copiousoutput" ) == 0 ) *(int*)&mc->copiousoutput = 1; else if ( eq && strcmp( arg, "test" ) == 0 ) { *(int*)&mc->testcommand = 0; HTSACopy( &mc->testcommand, eq ); TrimCommand( &mc->testcommand ); if ( WWW_TraceFlag && ( WWW_TraceMask & 8 ) ) { fprintf( TraceFP( ), "ProcessMailcapEntry: Found testcommand:%s\n", &mc->testcommand ); } } else if ( eq && strcmp( arg, "description" ) == 0 ) mc->label = eq; else if ( eq && strcmp( arg, "label" ) == 0 ) mc->label = eq; else if ( eq && strcmp( arg, "print" ) == 0 ) mc->printcommand = eq; else if ( eq == 0 || strcmp( arg, "textualnewlines" ) ) { if ( eq && strcmp( arg, "q" ) == 0 ) { mc->quality = atof( eq ); if ( mc->quality > 0 && mc->quality < 0.001000000000 ) *(int*)&mc->quality = 0x3a83126f; } else if ( eq && strcmp( arg, "mxb" ) == 0 ) { mc->maxbytes = atol( eq ); if ( mc->maxbytes < 0 ) *(int*)&mc->maxbytes = 0; } else { if ( strcmp( arg, "notes" ) && arg[0] && WWW_TraceFlag && ( WWW_TraceMask & 8 ) ) { fprintf( TraceFP( ), "ProcessMailcapEntry: Ignoring mailcap flag '%s'.\n", arg ); } } } } } if ( mallocd_string ) { free( mallocd_string ); mallocd_string = 0; } s = t; } } if ( rawentry ) { free( rawentry ); rawentry = 0; } if ( PassesTest( mc ) ) { if ( WWW_TraceFlag && ( WWW_TraceMask & 8 ) ) { fprintf( TraceFP( ), "ProcessMailcapEntry Setting up conversion %s : %s\n", &mc->contenttype[0], &mc->command ); } HTSetPresentation( &mc->contenttype[0], &mc->command, &mc->testcommand, mc->quality, 3.000000000000, 0.000000000000, mc->maxbytes, media ); } if ( mc->command ) { free( &mc->command ); *(int*)&mc->command = 0; } if ( mc->testcommand ) { free( &mc->testcommand ); *(int*)&mc->testcommand = 0; } if ( mc->contenttype[0] ) { free( &mc->contenttype[0] ); *(int*)&mc->contenttype[0] = 0; } return 1; } } } }
/* * This function is called from HTLoadNews() to have the user * create a file with news headers and a body for posting of * a new message (based on a newspost://nntp_host/newsgroups * or snewspost://secure_nntp_host/newsgroups URL), or to post * a followup (based on a newsreply://nntp_host/newsgroups or * snewsreply://secure_nntp_host/newsgroups URL). The group * or comma-separated list of newsgroups is passed without * a lead slash, and followup is TRUE for newsreply or * snewsreply URLs. - FM */ char *LYNewsPost(char *newsgroups, BOOLEAN followup) { char user_input[MAX_LINE]; char CJKinput[MAX_LINE]; char *cp = NULL; const char *kp = NULL; int c = 0; /* user input */ int len; FILE *fd = NULL; char my_tempfile[LY_MAXPATH]; FILE *fc = NULL; char CJKfile[LY_MAXPATH]; char *postfile = NULL; char *NewsGroups = NULL; char *References = NULL; char *org = NULL; FILE *fp = NULL; BOOLEAN nonempty = FALSE; BOOLEAN nonspaces = FALSE; /* * Make sure a non-zero length newspost, newsreply, snewspost or snewsreply * path was sent to us. - FM */ if (isEmpty(newsgroups)) return (postfile); /* * Return immediately if we do get called, maybe by some quirk of HTNews.c, * when we shouldn't. - kw */ if (no_newspost) return (postfile); /* * Open a temporary file for the headers and message body. - FM */ #ifdef __DJGPP__ if ((fd = LYOpenTemp(my_tempfile, HTML_SUFFIX, BIN_W)) == NULL) #else if ((fd = LYOpenTemp(my_tempfile, HTML_SUFFIX, "w")) == NULL) #endif /* __DJGPP__ */ { HTAlert(CANNOT_OPEN_TEMP); return (postfile); } /* * If we're using a Japanese display character set, open a temporary file * for a conversion to JIS. - FM */ CJKfile[0] = '\0'; if (current_char_set == UCGetLYhndl_byMIME("euc-jp") || current_char_set == UCGetLYhndl_byMIME("shift_jis")) { if ((fc = LYOpenTemp(CJKfile, HTML_SUFFIX, "w")) == NULL) { HTAlert(CANNOT_OPEN_TEMP); LYRemoveTemp(my_tempfile); return (postfile); } } /* * The newsgroups could be a comma-seperated list. It need not have * spaces, but deal with any that may also have been hex escaped. - FM */ StrAllocCopy(NewsGroups, newsgroups); if ((cp = strstr(NewsGroups, ";ref="))) { *cp = '\0'; cp += 5; if (*cp == '<') { StrAllocCopy(References, cp); } else { StrAllocCopy(References, "<"); StrAllocCat(References, cp); StrAllocCat(References, ">"); } HTUnEscape(References); if (!((cp = strchr(References, '@')) && cp > References + 1 && isalnum(UCH(cp[1])))) { FREE(References); } } HTUnEscape(NewsGroups); if (!*NewsGroups) { LYCloseTempFP(fd); /* Close the temp file. */ goto cleanup; } /* * Allow ^C to cancel the posting, i.e., don't let SIGINTs exit Lynx. */ signal(SIGINT, terminate_message); term_message = FALSE; /* * Show the list of newsgroups. - FM */ LYclear(); LYmove(2, 0); scrollok(LYwin, TRUE); /* Enable scrolling. */ LYaddstr(gettext("You will be posting to:")); LYaddstr("\n\t"); LYaddstr(NewsGroups); LYaddch('\n'); /* * Get the mail address for the From header, offering personal_mail_address * as default. */ LYaddstr(gettext("\n\n Please provide your mail address for the From: header\n")); sprintf(user_input, "From: %.*s", (int) sizeof(user_input) - 8, NonNull(personal_mail_address)); if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0 || term_message) { HTInfoMsg(NEWS_POST_CANCELLED); LYCloseTempFP(fd); /* Close the temp file. */ scrollok(LYwin, FALSE); /* Stop scrolling. */ goto cleanup; } fprintf(fd, "%s\n", user_input); /* * Get the Subject header, offering the current document's title as the * default if this is a followup rather than a new post. - FM */ LYaddstr(gettext("\n\n Please provide or edit the Subject: header\n")); strcpy(user_input, "Subject: "); if ((followup == TRUE && nhist > 0) && (kp = HText_getTitle()) != NULL) { /* * Add the default subject. */ kp = LYSkipCBlanks(kp); #ifdef CJK_EX /* 1998/05/15 (Fri) 09:10:38 */ if (HTCJK == JAPANESE) { CJKinput[0] = '\0'; switch (kanji_code) { case EUC: TO_EUC((const unsigned char *) kp, (unsigned char *) CJKinput); kp = CJKinput; break; case SJIS: TO_SJIS((const unsigned char *) kp, (unsigned char *) CJKinput); kp = CJKinput; break; default: break; } } #endif if (strncasecomp(kp, "Re:", 3)) { strcat(user_input, "Re: "); } len = (int) strlen(user_input); LYstrncpy(user_input + len, kp, (int) sizeof(user_input) - len - 1); } cp = NULL; if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0 || term_message) { HTInfoMsg(NEWS_POST_CANCELLED); LYCloseTempFP(fd); /* Close the temp file. */ scrollok(LYwin, FALSE); /* Stop scrolling. */ goto cleanup; } fprintf(fd, "%s\n", user_input); /* * Add Organization: header. */ StrAllocCopy(cp, "Organization: "); if ((org = LYGetEnv("ORGANIZATION")) != NULL) { StrAllocCat(cp, org); } else if ((org = LYGetEnv("NEWS_ORGANIZATION")) != NULL) { StrAllocCat(cp, org); } #ifdef UNIX else if ((fp = fopen("/etc/organization", TXT_R)) != NULL) { char *buffer = 0; if (LYSafeGets(&buffer, fp) != NULL) { if (user_input[0] != '\0') { LYTrimNewline(buffer); StrAllocCat(cp, buffer); } } FREE(buffer); LYCloseInput(fp); } #else #ifdef _WINDOWS /* 1998/05/14 (Thu) 17:47:01 */ else { char *p, fname[LY_MAXPATH]; strcpy(fname, LynxSigFile); p = strrchr(fname, '/'); if (p != 0 && (p - fname) < sizeof(fname) - 15) { strcpy(p + 1, "LYNX_ETC.TXT"); if ((fp = fopen(fname, TXT_R)) != NULL) { if (fgets(user_input, sizeof(user_input), fp) != NULL) { if ((org = strchr(user_input, '\n')) != NULL) { *org = '\0'; } if (user_input[0] != '\0') { StrAllocCat(cp, user_input); } } LYCloseInput(fp); } } } #endif /* _WINDOWS */ #endif /* !UNIX */ LYstrncpy(user_input, cp, (sizeof(user_input) - 16)); FREE(cp); LYaddstr(gettext("\n\n Please provide or edit the Organization: header\n")); if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0 || term_message) { HTInfoMsg(NEWS_POST_CANCELLED); LYCloseTempFP(fd); /* Close the temp file. */ scrollok(LYwin, FALSE); /* Stop scrolling. */ goto cleanup; } fprintf(fd, "%s\n", user_input); if (References) { fprintf(fd, "References: %s\n", References); } /* * Add Newsgroups Summary and Keywords headers. */ fprintf(fd, "Newsgroups: %s\nSummary: \nKeywords: \n\n", NewsGroups); /* * Have the user create the message body. */ if (!no_editor && non_empty(editor)) { if (followup && nhist > 0) { /* * Ask if the user wants to include the original message. */ if (term_message) { _statusline(INC_ORIG_MSG_PROMPT); } else if (HTConfirm(INC_ORIG_MSG_PROMPT) == YES) { /* * The 'TRUE' will add the reply ">" in front of every line. * We're assuming that if the display character set is Japanese * and the document did not have a CJK charset, any non-EUC or * non-SJIS 8-bit characters in it where converted to 7-bit * equivalents. - FM */ print_wwwfile_to_fd(fd, FALSE, TRUE); } } LYCloseTempFP(fd); /* Close the temp file. */ scrollok(LYwin, FALSE); /* Stop scrolling. */ if (term_message || LYCharIsINTERRUPT(c)) goto cleanup; /* * Spawn the user's editor on the news file. */ edit_temporary_file(my_tempfile, "", SPAWNING_EDITOR_FOR_NEWS); nonempty = message_has_content(my_tempfile, &nonspaces); } else { /* * Use the built in line editior. */ LYaddstr(gettext("\n\n Please enter your message below.")); LYaddstr(gettext("\n When you are done, press enter and put a single period (.)")); LYaddstr(gettext("\n on a line and press enter again.")); LYaddstr("\n\n"); LYrefresh(); *user_input = '\0'; if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0 || term_message) { HTInfoMsg(NEWS_POST_CANCELLED); LYCloseTempFP(fd); /* Close the temp file. */ scrollok(LYwin, FALSE); /* Stop scrolling. */ goto cleanup; } while (!STREQ(user_input, ".") && !term_message) { LYaddch('\n'); fprintf(fd, "%s\n", user_input); if (!nonempty && strlen(user_input)) nonempty = TRUE; *user_input = '\0'; if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0) { HTInfoMsg(NEWS_POST_CANCELLED); LYCloseTempFP(fd); /* Close the temp file. */ scrollok(LYwin, FALSE); /* Stop scrolling. */ goto cleanup; } } fprintf(fd, "\n"); LYCloseTempFP(fd); /* Close the temp file. */ scrollok(LYwin, FALSE); /* Stop scrolling. */ } if (nonempty) { /* * Confirm whether to post, and if so, whether to append the sig file. * - FM */ LYStatusLine = (LYlines - 1); c = HTConfirm(POST_MSG_PROMPT); LYStatusLine = -1; if (c != YES) { LYclear(); /* clear the screen */ goto cleanup; } } else { HTAlert(gettext("Message has no original text!")); if (!nonspaces || HTConfirmDefault(POST_MSG_PROMPT, NO) != YES) goto cleanup; } if ((LynxSigFile != NULL) && (fp = fopen(LynxSigFile, TXT_R)) != NULL) { char *msg = NULL; HTSprintf0(&msg, APPEND_SIG_FILE, LynxSigFile); LYStatusLine = (LYlines - 1); if (term_message) { _user_message(APPEND_SIG_FILE, LynxSigFile); } else if (HTConfirm(msg) == YES) { if ((fd = LYAppendToTxtFile(my_tempfile)) != NULL) { char *buffer = NULL; fputs("-- \n", fd); while (LYSafeGets(&buffer, fp) != NULL) { fputs(buffer, fd); } LYCloseOutput(fd); } } LYCloseInput(fp); FREE(msg); LYStatusLine = -1; } LYclear(); /* clear the screen */ /* * If we are using a Japanese display character set, convert the contents * of the temp file to JIS (nothing should change if it does not, in fact, * contain EUC or SJIS di-bytes). Otherwise, use the temp file as is. - * FM */ if (CJKfile[0] != '\0') { if ((fd = fopen(my_tempfile, TXT_R)) != NULL) { char *buffer = NULL; while (LYSafeGets(&buffer, fd) != NULL) { TO_JIS((unsigned char *) buffer, (unsigned char *) CJKinput); fputs(CJKinput, fc); } LYCloseTempFP(fc); StrAllocCopy(postfile, CJKfile); LYCloseInput(fd); LYRemoveTemp(my_tempfile); strcpy(my_tempfile, CJKfile); CJKfile[0] = '\0'; } else { StrAllocCopy(postfile, my_tempfile); } } else { StrAllocCopy(postfile, my_tempfile); } if (!followup) { /* * If it's not a followup, the current document most likely is the * group listing, so force a to have the article show up in the list * after the posting. Note, that if it's a followup via a link in a * news article, the user must do a reload manually on returning to the * group listing. - FM */ LYforce_no_cache = TRUE; } LYStatusLine = (LYlines - 1); HTUserMsg(POSTING_TO_NEWS); LYStatusLine = -1; /* * Come here to cleanup and exit. */ cleanup: #ifndef VMS signal(SIGINT, cleanup_sig); #endif /* !VMS */ term_message = FALSE; if (!postfile) LYRemoveTemp(my_tempfile); LYRemoveTemp(CJKfile); FREE(NewsGroups); FREE(References); return (postfile); }