/* * Pop the specified hist entry, link and line number from the history list but * don't actually remove the entry, just return it. * (This procedure is badly named :) */ void LYpop_num(int number, DocInfo *doc) { if (number >= 0 && (nhist + nhist_extra) > number) { doc->link = HDOC(number).link; doc->line = HDOC(number).line; StrAllocCopy(doc->title, HDOC(number).title); StrAllocCopy(doc->address, HDOC(number).address); BStrCopy(doc->post_data, HDOC(number).post_data); StrAllocCopy(doc->post_content_type, HDOC(number).post_content_type); StrAllocCopy(doc->bookmark, HDOC(number).bookmark); doc->isHEAD = HDOC(number).isHEAD; doc->safe = HDOC(number).safe; doc->internal_link = HDOC(number).internal_link; /* ?? */ #ifdef DISP_PARTIAL /* assume we pop the 'doc' to show it soon... */ LYSetNewline(doc->line); /* reinitialize */ #endif /* DISP_PARTIAL */ if (TRACE) { CTRACE((tfp, "LYpop_num(%d)\n", number)); CTRACE((tfp, " link %d\n", doc->link)); CTRACE((tfp, " line %d\n", doc->line)); CTRACE((tfp, " title %s\n", NonNull(doc->title))); CTRACE((tfp, " address %s\n", NonNull(doc->address))); } } }
/* FIXME What is the relationship to are_different() from the mainloop?! */ static int are_identical(HistInfo * doc, DocInfo *doc1) { return (STREQ(doc1->address, doc->hdoc.address) && BINEQ(doc1->post_data, doc->hdoc.post_data) && !strcmp(NonNull(doc1->bookmark), NonNull(doc->hdoc.bookmark)) && doc1->isHEAD == doc->hdoc.isHEAD); }
_nc_get_driver(TERMINAL_CONTROL_BLOCK * TCB, const char *name, int *errret) { int code = ERR; size_t i; TERM_DRIVER *res = (TERM_DRIVER *) 0; TERM_DRIVER *use = 0; T((T_CALLED("_nc_get_driver(%p, %s, %p)"), (void *) TCB, NonNull(name), (void *) errret)); assert(TCB != 0); for (i = 0; i < SIZEOF(DriverTable); i++) { res = DriverTable[i].driver; if (res->CanHandle(TCB, name, errret)) { use = res; break; } } if (use != 0) { TCB->drv = use; code = OK; } returnCode(code); }
/* * Call this with in_out pointing to data filled in by x_getpwnam() or by * x_getpwnam(). It finds the user's logon name, if possible. As a side * effect, it updates in_out to fill in possibly more-relevant data, i.e., * in case there is more than one alias for the same uid. */ char * x_getlogin(uid_t uid, struct passwd *in_out) { char *login_name = NULL; login_name = login_alias(x_getenv("LOGNAME"), uid, in_out); if (IsEmpty(login_name)) { login_name = login_alias(x_getenv("USER"), uid, in_out); } #ifdef HAVE_GETLOGIN /* * Of course getlogin() will fail if we're started from a window-manager, * since there's no controlling terminal to fuss with. For that reason, we * tried first to get something useful from the user's $LOGNAME or $USER * environment variables. */ if (IsEmpty(login_name)) { TRACE2(("...try getlogin\n")); login_name = login_alias(getlogin(), uid, in_out); } #endif if (IsEmpty(login_name)) login_name = in_out->pw_name; if (!IsEmpty(login_name)) login_name = x_strdup(login_name); TRACE2(("x_getloginid ->%s\n", NonNull(login_name))); return login_name; }
void LYstore_message2(const char *message, const char *argument) { if (message != NULL) { char *temp = NULL; HTSprintf0(&temp, message, NonNull(argument)); to_stack(temp); } }
static void AddPropertyToTree( char * s_property, char * s_family, enum ft_format s_format, size_t s_array, enum ag_combined s_combined, enum ag_index s_index_type, size_t s_length, enum fc_change s_change, char * s_read, char * s_write, char * s_data, char * s_other, enum external_type et ) { struct property_node * n ; struct { struct property_node * key ; char other[0] ; } * opaque ; NonNull( s_property ) NonNull( s_family ) NonNull( s_read ) NonNull( s_write ) NonNull( s_data ) NonNull( s_other ) n = create_property_node( s_property, s_family, s_format, s_array, s_combined, s_index_type, s_length, s_change, s_read, s_write, s_data, s_other, et ) ; opaque = tsearch( (void *) n, &property_tree, property_compare ) ; if ( opaque->key != n ) { // already exists LEVEL_DEBUG("Duplicate property entry: %s,%s,%s,%s,%s,%s",s_property,s_family,s_read,s_write,s_data,s_other); owfree( n ) ; } else { LEVEL_DEBUG("New property entry: %s,%s,%s,%s,%s,%s",s_property,s_family,s_read,s_write,s_data,s_other); } }
_nc_tic_dir(const char *path) { T(("_nc_tic_dir %s", NonNull(path))); if (!KeepTicDirectory) { if (path != 0) { TicDirectory = path; HaveTicDirectory = TRUE; } else if (!HaveTicDirectory && use_terminfo_vars()) { char *envp; if ((envp = getenv("TERMINFO")) != 0) return _nc_tic_dir(envp); } } return TicDirectory ? TicDirectory : TERMINFO; }
static void dump_keyword(const KEYWORD * const q) { if (!q->kw_type) { dump_update(q->kw_name); flt_message("%s%c%s", q->kw_name, dump_eqls_ch, NonNull(q->kw_attr)); if (q->kw_flag) flt_message("%c%s", dump_eqls_ch, q->kw_flag); flt_message("\n"); } }
/* Create new or find old sub-anchor ** --------------------------------- ** ** This one is for a named child. ** The parent anchor must already exist. */ PRIVATE HTChildAnchor * HTAnchor_findNamedChild ARGS2( HTParentAnchor0 *, parent, CONST char *, tag) { HTChildAnchor *child; if (parent && tag && *tag) { /* TBL */ if (parent->children) { /* ** Parent has children. Search them. */ HTChildAnchor sample; sample.tag = (char*)tag; /* for compare_anchors() only */ child = (HTChildAnchor *)HTBTree_search(parent->children, &sample); if (child != NULL) { CTRACE((tfp, "Child anchor %p of parent %p with name `%s' already exists.\n", (void *)child, (void *)parent, tag)); return(child); } } else { /* parent doesn't have any children yet : create family */ parent->children = HTBTree_new(compare_anchors); } child = HTChildAnchor_new(parent); CTRACE((tfp, "HTAnchor: New Anchor %p named `%s' is child of %p\n", (void *)child, NonNull(tag), (void *)child->parent)); StrAllocCopy(child->tag, tag); /* should be set before HTBTree_add */ HTBTree_add(parent->children, child); return(child); } else { CTRACE((tfp, "HTAnchor_findNamedChild called with NULL parent.\n")); return(NULL); } }
/* * LYdownload_options writes out the current download choices to a file so that * the user can select downloaders in the same way that they select all other * links. Download links look like: * LYNXDOWNLOAD://Method=<#>/File=<STRING>/SugFile=<STRING> */ int LYdownload_options(char **newfile, char *data_file) { static char tempfile[LY_MAXPATH] = "\0"; char *downloaded_url = NULL; char *sug_filename = NULL; FILE *fp0; lynx_list_item_type *cur_download; int count; /* * Get a suggested filename. */ StrAllocCopy(sug_filename, *newfile); change_sug_filename(sug_filename); if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return (-1); StrAllocCopy(downloaded_url, *newfile); LYLocalFileToURL(newfile, tempfile); LYStrNCpy(LYValidDownloadFile, data_file, (sizeof(LYValidDownloadFile) - 1)); LYforce_no_cache = TRUE; /* don't cache this doc */ BeginInternalPage(fp0, DOWNLOAD_OPTIONS_TITLE, DOWNLOAD_OPTIONS_HELP); fprintf(fp0, "<pre>\n"); fprintf(fp0, "<em>%s</em> %s\n", gettext("Downloaded link:"), downloaded_url); FREE(downloaded_url); fprintf(fp0, "<em>%s</em> %s\n", gettext("Suggested file name:"), sug_filename); fprintf(fp0, "\n%s\n", (user_mode == NOVICE_MODE) ? gettext("Standard download options:") : gettext("Download options:")); if (!no_disk_save) { #if defined(DIRED_SUPPORT) /* * Disable save to disk option for local files. */ if (!lynx_edit_mode) #endif /* DIRED_SUPPORT */ { fprintf(fp0, " <a href=\"%s//Method=-1/File=%s/SugFile=%s%s\">%s</a>\n", STR_LYNXDOWNLOAD, data_file, NonNull(lynx_save_space), sug_filename, gettext("Save to disk")); /* * If it is not a binary file, offer the opportunity to view the * downloaded temporary file (see HTSaveToFile). */ if (SuffixIs(data_file, HTML_SUFFIX) || SuffixIs(data_file, TEXT_SUFFIX)) { char *target = NULL; char *source = LYAddPathToSave(data_file); LYLocalFileToURL(&target, source); fprintf(fp0, " <a href=\"%s\">%s</a>\n", target, gettext("View temporary file")); FREE(source); FREE(target); } } } else { fprintf(fp0, " <em>%s</em>\n", gettext("Save to disk disabled.")); } if (user_mode == NOVICE_MODE) fprintf(fp0, "\n%s\n", gettext("Local additions:")); if (downloaders != NULL) { for (count = 0, cur_download = downloaders; cur_download != NULL; cur_download = cur_download->next, count++) { if (!no_download || cur_download->always_enabled) { fprintf(fp0, " <a href=\"%s//Method=%d/File=%s/SugFile=%s\">", STR_LYNXDOWNLOAD, count, data_file, sug_filename); fprintf(fp0, "%s", (cur_download->name ? cur_download->name : gettext("No Name Given"))); fprintf(fp0, "</a>\n"); } } } fprintf(fp0, "</pre>\n"); EndInternalPage(fp0); LYCloseTempFP(fp0); LYRegisterUIPage(*newfile, UIP_DOWNLOAD_OPTIONS); /* * Free off temp copy. */ FREE(sug_filename); return (0); }
_nc_captoinfo(const char *cap, const char *s, int const parameterized) { const char *capstart; stackptr = 0; onstack = 0; seenm = 0; seenn = 0; seenr = 0; param = 1; DEBUG_THIS(("_nc_captoinfo params %d, %s", parameterized, s)); dp = init_string(); /* skip the initial padding (if we haven't been told not to) */ capstart = 0; if (s == 0) s = ""; if (parameterized >= 0 && isdigit(UChar(*s))) for (capstart = s;; s++) if (!(isdigit(UChar(*s)) || *s == '*' || *s == '.')) break; while (*s != '\0') { switch (*s) { case '%': s++; if (parameterized < 1) { dp = save_char(dp, '%'); break; } switch (*s++) { case '%': dp = save_string(dp, "%%"); break; case 'r': if (seenr++ == 1) { _nc_warning("saw %%r twice in %s", cap); } break; case 'm': if (seenm++ == 1) { _nc_warning("saw %%m twice in %s", cap); } break; case 'n': if (seenn++ == 1) { _nc_warning("saw %%n twice in %s", cap); } break; case 'i': dp = save_string(dp, "%i"); break; case '6': case 'B': getparm(param, 1); dp = save_string(dp, "%{10}%/%{16}%*"); getparm(param, 1); dp = save_string(dp, "%{10}%m%+"); break; case '8': case 'D': getparm(param, 2); dp = save_string(dp, "%{2}%*%-"); break; case '>': getparm(param, 2); /* %?%{x}%>%t%{y}%+%; */ dp = save_string(dp, "%?"); s += cvtchar(s); dp = save_string(dp, "%>%t"); s += cvtchar(s); dp = save_string(dp, "%+%;"); break; case 'a': if ((*s == '=' || *s == '+' || *s == '-' || *s == '*' || *s == '/') && (s[1] == 'p' || s[1] == 'c') && s[2] != '\0') { int l; l = 2; if (*s != '=') getparm(param, 1); if (s[1] == 'p') { getparm(param + s[2] - '@', 1); if (param != onstack) { pop(); param--; } l++; } else l += cvtchar(s + 2); switch (*s) { case '+': dp = save_string(dp, "%+"); break; case '-': dp = save_string(dp, "%-"); break; case '*': dp = save_string(dp, "%*"); break; case '/': dp = save_string(dp, "%/"); break; case '=': if (seenr) { if (param == 1) onstack = 2; else if (param == 2) onstack = 1; else onstack = param; } else onstack = param; break; } s += l; break; } getparm(param, 1); s += cvtchar(s); dp = save_string(dp, "%+"); break; case '+': getparm(param, 1); s += cvtchar(s); dp = save_string(dp, "%+%c"); pop(); break; case 's': #ifdef WATERLOO s += cvtchar(s); getparm(param, 1); dp = save_string(dp, "%-"); #else getparm(param, 1); dp = save_string(dp, "%s"); pop(); #endif /* WATERLOO */ break; case '-': s += cvtchar(s); getparm(param, 1); dp = save_string(dp, "%-%c"); pop(); break; case '.': getparm(param, 1); dp = save_string(dp, "%c"); pop(); break; case '0': /* not clear any of the historical termcaps did this */ if (*s == '3') { ++s; goto see03; } if (*s == '2') { ++s; goto see02; } goto invalid; case '2': see02: getparm(param, 1); dp = save_string(dp, "%2d"); pop(); break; case '3': see03: getparm(param, 1); dp = save_string(dp, "%3d"); pop(); break; case 'd': getparm(param, 1); dp = save_string(dp, "%d"); pop(); break; case 'f': param++; break; case 'b': param--; break; case '\\': dp = save_string(dp, "%\\"); break; default: invalid: dp = save_char(dp, '%'); s--; _nc_warning("unknown %% code %s (%#x) in %s", unctrl((chtype) *s), UChar(*s), cap); break; } break; default: dp = save_char(dp, *s++); break; } } /* * Now, if we stripped off some leading padding, add it at the end * of the string as mandatory padding. */ if (capstart) { dp = save_string(dp, "$<"); for (s = capstart;; s++) if (isdigit(UChar(*s)) || *s == '*' || *s == '.') dp = save_char(dp, *s); else break; dp = save_string(dp, "/>"); } (void) save_char(dp, '\0'); DEBUG_THIS(("... _nc_captoinfo %s", NonNull(my_string))); return (my_string); }
/* * Utility for listing visited links, making any repeated links the most * current in the list. - FM */ void LYAddVisitedLink(DocInfo *doc) { VisitedLink *tmp; HTList *cur; const char *title = (doc->title ? doc->title : NO_TITLE); if (isEmpty(doc->address)) { PrevVisitedLink = NULL; return; } /* * Exclude POST or HEAD replies, and bookmark, menu or list files. - FM */ if (doc->post_data || doc->isHEAD || doc->bookmark || ( /* special url or a temp file */ (!StrNCmp(doc->address, "LYNX", 4) || !StrNCmp(doc->address, "file://localhost/", 17)))) { int related = 1; /* First approximation only */ if (LYIsUIPage(doc->address, UIP_HISTORY) || LYIsUIPage(doc->address, UIP_VLINKS) || LYIsUIPage(doc->address, UIP_SHOWINFO) || isLYNXMESSAGES(doc->address) || ((related = 0) != 0) || #ifdef DIRED_SUPPORT LYIsUIPage(doc->address, UIP_DIRED_MENU) || LYIsUIPage(doc->address, UIP_UPLOAD_OPTIONS) || LYIsUIPage(doc->address, UIP_PERMIT_OPTIONS) || #endif /* DIRED_SUPPORT */ LYIsUIPage(doc->address, UIP_PRINT_OPTIONS) || LYIsUIPage(doc->address, UIP_DOWNLOAD_OPTIONS) || LYIsUIPage(doc->address, UIP_OPTIONS_MENU) || isLYNXEDITMAP(doc->address) || isLYNXKEYMAP(doc->address) || LYIsUIPage(doc->address, UIP_LIST_PAGE) || #ifdef USE_ADDRLIST_PAGE LYIsUIPage(doc->address, UIP_ADDRLIST_PAGE) || #endif LYIsUIPage(doc->address, UIP_CONFIG_DEF) || LYIsUIPage(doc->address, UIP_LYNXCFG) || isLYNXCOOKIE(doc->address) || LYIsUIPage(doc->address, UIP_TRACELOG)) { if (!related) PrevVisitedLink = NULL; return; } } if (!Visited_Links) { Visited_Links = HTList_new(); #ifdef LY_FIND_LEAKS atexit(Visited_Links_free); #endif Latest_last.prev_latest = &Latest_first; Latest_first.next_latest = &Latest_last; Latest_last.next_latest = NULL; /* Find bugs quick! */ Latest_first.prev_latest = NULL; Last_by_first = Latest_tree = First_tree = NULL; } cur = Visited_Links; while (NULL != (tmp = (VisitedLink *) HTList_nextObject(cur))) { if (!strcmp(NonNull(tmp->address), NonNull(doc->address))) { PrevVisitedLink = PrevActiveVisitedLink = tmp; /* Already visited. Update the last-visited info. */ if (tmp->next_latest == &Latest_last) /* optimization */ return; /* Remove from "latest" chain */ tmp->prev_latest->next_latest = tmp->next_latest; tmp->next_latest->prev_latest = tmp->prev_latest; /* Insert at the end of the "latest" chain */ Latest_last.prev_latest->next_latest = tmp; tmp->prev_latest = Latest_last.prev_latest; tmp->next_latest = &Latest_last; Latest_last.prev_latest = tmp; return; } } if ((tmp = typecalloc(VisitedLink)) == NULL) outofmem(__FILE__, "LYAddVisitedLink"); StrAllocCopy(tmp->address, doc->address); LYformTitle(&(tmp->title), title); /* First-visited chain */ HTList_appendObject(Visited_Links, tmp); /* At end */ tmp->prev_first = Last_by_first; Last_by_first = tmp; /* Tree structure */ if (PrevVisitedLink) { VisitedLink *a = PrevVisitedLink; VisitedLink *b = a->next_tree; int l = PrevVisitedLink->level; /* Find last on the deeper levels */ while (b && b->level > l) a = b, b = b->next_tree; if (!b) /* a == Latest_tree */ Latest_tree = tmp; tmp->next_tree = a->next_tree; a->next_tree = tmp; tmp->level = PrevVisitedLink->level + 1; } else { if (Latest_tree) Latest_tree->next_tree = tmp; tmp->level = 0; tmp->next_tree = NULL; Latest_tree = tmp; } PrevVisitedLink = PrevActiveVisitedLink = tmp; if (!First_tree) First_tree = tmp; /* "latest" chain */ Latest_last.prev_latest->next_latest = tmp; tmp->prev_latest = Latest_last.prev_latest; tmp->next_latest = &Latest_last; Latest_last.prev_latest = tmp; return; }
static void send_file_to_mail(DocInfo *newdoc, char *content_base, char *content_location) { static BOOLEAN first_mail_preparsed = TRUE; #if USE_VMS_MAILER BOOLEAN isPMDF = LYMailPMDF(); FILE *hfd; char hdrfile[LY_MAXPATH]; #endif BOOL use_mime; #if !CAN_PIPE_TO_MAILER char my_temp[LY_MAXPATH]; #endif BOOL use_cte; BOOL use_type; const char *disp_charset; FILE *outfile_fp; char *buffer = NULL; char *subject = NULL; bstring *user_response = NULL; if (!LYSystemMail()) return; if (LYPreparsedSource && first_mail_preparsed && HTisDocumentSource()) { if (HTConfirmDefault(CONFIRM_MAIL_SOURCE_PREPARSED, NO) == YES) { LYaddstr(" Ok..."); first_mail_preparsed = FALSE; } else { CancelPrint(MAIL_REQUEST_CANCELLED); } } _statusline(MAIL_ADDRESS_PROMPT); BStrCopy0(user_response, NonNull(personal_mail_address)); if (LYgetBString(&user_response, FALSE, 0, RECALL_MAIL) < 0 || isBEmpty(user_response)) { CancelPrint(MAIL_REQUEST_CANCELLED); } /* * Determine which mail headers should be sent. Use Content-Type and * MIME-Version headers only if needed. We need them if we are mailing * HTML source, or if we have 8-bit characters and will be sending * Content-Transfer-Encoding to indicate this. We will append a charset * parameter to the Content-Type if we do not have an "x-" charset, and we * will include the Content-Transfer-Encoding only if we are appending the * charset parameter, because indicating an 8-bit transfer without also * indicating the charset can cause problems with many mailers. - FM & KW */ disp_charset = LYCharSet_UC[current_char_set].MIMEname; use_cte = HTLoadedDocumentEightbit(); if (!(use_cte && strncasecomp(disp_charset, "x-", 2))) { disp_charset = NULL; #if USE_VMS_MAILER use_cte = FALSE; #endif } #if USE_VMS_MAILER use_type = (BOOL) (disp_charset || HTisDocumentSource()); #endif /* * Use newdoc->title as a subject instead of sug_filename: MORE readable * and 8-bit letters shouldn't be a problem - LP */ /* change_sug_filename(sug_filename); */ subject = subject_translate8bit(newdoc->title); if (newdoc->isHEAD) { /* * Special case for mailing HEAD responce: this is rather technical * information, show URL. */ FREE(subject); StrAllocCopy(subject, "HEAD "); StrAllocCat(subject, newdoc->address); } #if USE_VMS_MAILER if (StrChr(user_response->str, '@') && !StrChr(user_response->str, ':') && !StrChr(user_response->str, '%') && !StrChr(user_response->str, '"')) { char *temp = 0; HTSprintf0(&temp, mail_adrs, user_response->str); BStrCopy0(user_response, temp); FREE(temp); } outfile_fp = LYOpenTemp(my_temp, (HTisDocumentSource()) ? HTML_SUFFIX : TEXT_SUFFIX, "w"); if (outfile_fp == NULL) { CannotPrint(UNABLE_TO_OPEN_TEMPFILE); } if (isPMDF) { if ((hfd = LYOpenTemp(hdrfile, TEXT_SUFFIX, "w")) == NULL) { CannotPrint(UNABLE_TO_OPEN_TEMPFILE); } if (use_type) { fprintf(hfd, "Mime-Version: 1.0\n"); if (use_cte) { fprintf(hfd, "Content-Transfer-Encoding: 8bit\n"); } } if (HTisDocumentSource()) { /* * Add Content-Type, Content-Location, and Content-Base headers for * HTML source. - FM */ fprintf(hfd, "Content-Type: text/html"); if (disp_charset != NULL) { fprintf(hfd, "; charset=%s\n", disp_charset); } else { fprintf(hfd, "\n"); } fprintf(hfd, "Content-Base: %s\n", content_base); fprintf(hfd, "Content-Location: %s\n", content_location); } else { /* * Add Content-Type: text/plain if we have 8-bit characters and a * valid charset for non-source documents. - FM */ if (disp_charset != NULL) { fprintf(hfd, "Content-Type: text/plain; charset=%s\n", disp_charset); } } /* * X-URL header. - FM */ fprintf(hfd, "X-URL: %s\n", newdoc->address); /* * For PMDF, put the subject in the header file and close it. - FM */ fprintf(hfd, "Subject: %.70s\n\n", subject); LYCloseTempFP(hfd); } /* * Write the contents to a temp file. */ if (LYPrependBaseToSource && HTisDocumentSource()) { /* * Added the document's base as a BASE tag to the top of the message * body. May create technically invalid HTML, but will help get any * partial or relative URLs resolved properly if no BASE tag is present * to replace it. - FM */ fprintf(outfile_fp, "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n", newdoc->address, content_base); } else if (!isPMDF) { fprintf(outfile_fp, "X-URL: %s\n\n", newdoc->address); } print_wwwfile_to_fd(outfile_fp, TRUE, FALSE); /* MAIL */ if (keypad_mode) printlist(outfile_fp, FALSE); LYCloseTempFP(outfile_fp); buffer = NULL; if (isPMDF) { /* * Now set up the command. - FM */ HTSprintf0(&buffer, "%s %s %s,%s %s", system_mail, system_mail_flags, hdrfile, my_temp, user_response->str); } else { /* * For "generic" VMS MAIL, include the subject in the command. - FM */ remove_quotes(subject); HTSprintf0(&buffer, "%s %s/subject=\"%.70s\" %s %s", system_mail, system_mail_flags, subject, my_temp, user_response->str); } stop_curses(); SetOutputMode(O_TEXT); printf(MAILING_FILE); LYSystem(buffer); LYSleepAlert(); start_curses(); SetOutputMode(O_BINARY); if (isPMDF) (void) LYRemoveTemp(hdrfile); (void) LYRemoveTemp(my_temp); #else /* !VMS (Unix or DOS) */ #if CAN_PIPE_TO_MAILER outfile_fp = LYPipeToMailer(); #else outfile_fp = LYOpenTemp(my_temp, TEXT_SUFFIX, "w"); #endif if (outfile_fp == NULL) { CannotPrint(MAIL_REQUEST_FAILED); } /* * Determine which mail headers should be sent. Use Content-Type and * MIME-Version headers only if needed. We need them if we are mailing * HTML source, or if we have 8-bit characters and will be sending * Content-Transfer-Encoding to indicate this. * * Send Content-Transfer-Encoding only if the document has 8-bit * characters. Send a charset parameter only if the document has 8-bit * characters and we seem to have a valid charset. - kw */ use_cte = HTLoadedDocumentEightbit(); disp_charset = LYCharSet_UC[current_char_set].MIMEname; /* * Don't send a charset if we have a CJK character set selected, since it * may not be appropriate for mail... Also don't use an unofficial "x-" * charset. - kw */ if (!use_cte || LYHaveCJKCharacterSet || strncasecomp(disp_charset, "x-", 2) == 0) { disp_charset = NULL; } #ifdef NOTDEFINED /* Enable this if indicating an 8-bit transfer without also indicating the * charset causes problems. - kw */ if (use_cte && !disp_charset) use_cte = FALSE; #endif /* NOTDEFINED */ use_type = (BOOL) (disp_charset || HTisDocumentSource()); use_mime = (BOOL) (use_cte || use_type); if (use_mime) { fprintf(outfile_fp, "Mime-Version: 1.0\n"); if (use_cte) { fprintf(outfile_fp, "Content-Transfer-Encoding: 8bit\n"); } } if (HTisDocumentSource()) { /* * Add Content-Type, Content-Location, and Content-Base headers for * HTML source. - FM */ fprintf(outfile_fp, "Content-Type: text/html"); if (disp_charset != NULL) { fprintf(outfile_fp, "; charset=%s\n", disp_charset); } else { fprintf(outfile_fp, "\n"); } } else { /* * Add Content-Type: text/plain if we have 8-bit characters and a * valid charset for non-source documents. - KW */ if (disp_charset != NULL) { fprintf(outfile_fp, "Content-Type: text/plain; charset=%s\n", disp_charset); } } /* * If we are using MIME headers, add content-base and content-location if * we have them. This will always be the case if the document is source. * - kw */ if (use_mime) { if (content_base) fprintf(outfile_fp, "Content-Base: %s\n", content_base); if (content_location) fprintf(outfile_fp, "Content-Location: %s\n", content_location); } /* * Add the To, Subject, and X-URL headers. - FM */ fprintf(outfile_fp, "To: %s\nSubject: %s\n", user_response->str, subject); fprintf(outfile_fp, "X-URL: %s\n\n", newdoc->address); if (LYPrependBaseToSource && HTisDocumentSource()) { /* * Added the document's base as a BASE tag to the top of the message * body. May create technically invalid HTML, but will help get any * partial or relative URLs resolved properly if no BASE tag is present * to replace it. - FM */ fprintf(outfile_fp, "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n", newdoc->address, content_base); } print_wwwfile_to_fd(outfile_fp, TRUE, FALSE); /* MAIL */ if (keypad_mode) printlist(outfile_fp, FALSE); #if CAN_PIPE_TO_MAILER pclose(outfile_fp); #else LYCloseOutput(outfile_fp); LYSendMailFile(user_response->str, my_temp, subject, "", ""); (void) LYRemoveTemp(my_temp); /* Delete the tmpfile. */ #endif /* CAN_PIPE_TO_MAILER */ #endif /* USE_VMS_MAILER */ done: /* send_file_to_mail() */ BStrFree(user_response); FREE(buffer); FREE(subject); return; }
/* also called later, if charset-affecting modes change, for instance */ void vl_ctype_init(int print_lo, int print_hi) { #if OPT_LOCALE char *save_ctype = setlocale(LC_CTYPE, NULL); #endif int c; TRACE((T_CALLED "vl_ctype_init() lo=%d, hi=%d\n", print_lo, print_hi)); /* If we're using the locale functions, set our flags based on its * tables. Note that just because you have 'setlocale()' doesn't mean * that the tables are present or correct. But this is a start. * * NOTE: Solaris8 and some versions of M$ incorrectly classify tab as a * printable character (ANSI C says control characters are not printable). * Ignore that (the former fixes it in Solaris9). */ #if OPT_LOCALE TRACE(("wide_locale:%s\n", NonNull(vl_wide_enc.locale))); TRACE(("narrow_locale:%s\n", NonNull(vl_narrow_enc.locale))); TRACE(("current_locale:%s\n", NonNull(save_ctype))); if (vl_narrow_enc.locale) setlocale(LC_CTYPE, vl_narrow_enc.locale); else if (vl_wide_enc.locale) setlocale(LC_CTYPE, vl_wide_enc.locale); for (c = 0; c < N_chars; c++) { if (print_hi > 0 && c > print_hi) { vlCTYPE(c) = 0; } else if (okCTYPE2(vl_narrow_enc)) { vlCTYPE(c) = vl_ctype_bits(c, -TRUE); vl_uppercase[c] = (char) toupper(c); vl_lowercase[c] = (char) tolower(c); } else { /* fallback to built-in character tables */ if (okCTYPE2(vl_wide_enc)) { vlCTYPE(c) = vl_ctype_latin1[c]; } else { vlCTYPE(c) = vl_ctype_ascii[c]; } vl_uppercase[c] = (char) c; vl_lowercase[c] = (char) c; if (isAlpha(c)) { if (isUpper(c)) { vl_lowercase[c] = (char) (c ^ DIFCASE); } else { vl_uppercase[c] = (char) (c ^ DIFCASE); } } } } #else /* ! OPT_LOCALE */ (void) memset((char *) vl_chartypes_, 0, sizeof(vl_chartypes_)); /* control characters */ for (c = 0; c < ' '; c++) vlCTYPE(c) |= vl_cntrl; vlCTYPE(127) |= vl_cntrl; /* lowercase */ for (c = 'a'; c <= 'z'; c++) vlCTYPE(c) |= vl_lower; #if OPT_ISO_8859 for (c = 0xc0; c <= 0xd6; c++) vlCTYPE(c) |= vl_lower; for (c = 0xd8; c <= 0xde; c++) vlCTYPE(c) |= vl_lower; #endif /* uppercase */ for (c = 'A'; c <= 'Z'; c++) vlCTYPE(c) |= vl_upper; #if OPT_ISO_8859 for (c = 0xdf; c <= 0xf6; c++) vlCTYPE(c) |= vl_upper; for (c = 0xf8; c <= 0xff; c++) vlCTYPE(c) |= vl_upper; #endif /* * If you want to do this properly, compile-in locale support. */ for (c = 0; c < N_chars; c++) { vl_uppercase[c] = (char) c; vl_lowercase[c] = (char) c; if (isAlpha(c)) { if (isUpper(c)) { vl_lowercase[c] = (char) (c ^ DIFCASE); } else { vl_uppercase[c] = (char) (c ^ DIFCASE); } } } /* digits */ for (c = '0'; c <= '9'; c++) vlCTYPE(c) |= vl_digit; #ifdef vl_xdigit /* hex digits */ for (c = '0'; c <= '9'; c++) vlCTYPE(c) |= vl_xdigit; for (c = 'a'; c <= 'f'; c++) vlCTYPE(c) |= vl_xdigit; for (c = 'A'; c <= 'F'; c++) vlCTYPE(c) |= vl_xdigit; #endif /* punctuation */ for (c = '!'; c <= '/'; c++) vlCTYPE(c) |= vl_punct; for (c = ':'; c <= '@'; c++) vlCTYPE(c) |= vl_punct; for (c = '['; c <= '`'; c++) vlCTYPE(c) |= vl_punct; for (c = L_CURLY; c <= '~'; c++) vlCTYPE(c) |= vl_punct; #if OPT_ISO_8859 for (c = 0xa1; c <= 0xbf; c++) vlCTYPE(c) |= vl_punct; #endif /* printable */ for (c = ' '; c <= '~'; c++) vlCTYPE(c) |= vl_print; /* whitespace */ vlCTYPE(' ') |= vl_space; #if OPT_ISO_8859 vlCTYPE(0xa0) |= vl_space; #endif vlCTYPE('\t') |= vl_space; vlCTYPE('\r') |= vl_space; vlCTYPE('\n') |= vl_space; vlCTYPE('\f') |= vl_space; #endif /* OPT_LOCALE */ /* legal in pathnames */ vlCTYPE('.') |= vl_pathn; vlCTYPE('_') |= vl_pathn; vlCTYPE('~') |= vl_pathn; vlCTYPE('-') |= vl_pathn; vlCTYPE('/') |= vl_pathn; /* legal in "identifiers" */ vlCTYPE('_') |= vl_ident | vl_qident; vlCTYPE(':') |= vl_qident; #if SYS_VMS vlCTYPE('$') |= vl_ident | vl_qident; #endif c = print_lo; /* * Guard against setting printing-high before printing-low while we have a * buffer which may be repainted and possibly trashing the display. */ if (c == 0 && print_hi >= 254) c = 160; if (c < HIGHBIT) c = HIGHBIT; TRACE(("Forcing printable for [%d..min(%d,%d)]\n", c, print_hi - 1, N_chars - 1)); while (c <= print_hi && c < N_chars) vlCTYPE(c++) |= vl_print; #if DISP_X11 for (c = 0; c < N_chars; c++) { if (isPrint(c) && !gui_isprint(c)) { vlCTYPE(c) &= ~vl_print; } } #endif /* backspacers: ^H, rubout */ vlCTYPE('\b') |= vl_bspace; vlCTYPE(127) |= vl_bspace; /* wildcard chars for most shells */ vlCTYPE('*') |= vl_wild; vlCTYPE('?') |= vl_wild; #if !OPT_VMS_PATH #if SYS_UNIX vlCTYPE('~') |= vl_wild; #endif vlCTYPE(L_BLOCK) |= vl_wild; vlCTYPE(R_BLOCK) |= vl_wild; vlCTYPE(L_CURLY) |= vl_wild; vlCTYPE(R_CURLY) |= vl_wild; vlCTYPE('$') |= vl_wild; vlCTYPE('`') |= vl_wild; #endif /* ex mode line specifiers */ vlCTYPE(',') |= vl_linespec; vlCTYPE('%') |= vl_linespec; vlCTYPE('-') |= vl_linespec; vlCTYPE('+') |= vl_linespec; vlCTYPE(';') |= vl_linespec; vlCTYPE('.') |= vl_linespec; vlCTYPE('$') |= vl_linespec; vlCTYPE('\'') |= vl_linespec; /* fences */ vlCTYPE(L_CURLY) |= vl_fence; vlCTYPE(R_CURLY) |= vl_fence; vlCTYPE(L_PAREN) |= vl_fence; vlCTYPE(R_PAREN) |= vl_fence; vlCTYPE(L_BLOCK) |= vl_fence; vlCTYPE(R_BLOCK) |= vl_fence; #if OPT_VMS_PATH vlCTYPE(L_BLOCK) |= vl_pathn; vlCTYPE(R_BLOCK) |= vl_pathn; vlCTYPE(L_ANGLE) |= vl_pathn; vlCTYPE(R_ANGLE) |= vl_pathn; vlCTYPE('$') |= vl_pathn; vlCTYPE(':') |= vl_pathn; vlCTYPE(';') |= vl_pathn; #endif #if OPT_MSDOS_PATH vlCTYPE(BACKSLASH) |= vl_pathn; vlCTYPE(':') |= vl_pathn; #endif #if OPT_WIDE_CTYPES /* scratch-buffer-names (usually superset of vl_pathn) */ vlCTYPE(SCRTCH_LEFT[0]) |= vl_scrtch; vlCTYPE(SCRTCH_RIGHT[0]) |= vl_scrtch; vlCTYPE(' ') |= vl_scrtch; /* ...to handle "[Buffer List]" */ #endif for (c = 0; c < N_chars; c++) { if (!(isSpace(c))) vlCTYPE(c) |= vl_nonspace; if (isDigit(c)) vlCTYPE(c) |= vl_linespec; if (isAlpha(c) || isDigit(c)) vlCTYPE(c) |= vl_ident | vl_pathn | vl_qident; #if OPT_WIDE_CTYPES if (isSpace(c) || isPrint(c)) vlCTYPE(c) |= vl_shpipe; if (ispath(c)) vlCTYPE(c) |= vl_scrtch; #endif } #if OPT_LOCALE if (save_ctype != 0) (void) setlocale(LC_CTYPE, save_ctype); #endif returnVoid(); }
/* * 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); }
PRIVATE char *blat_cmd( char *mail_cmd, char *filename, char *address, char *subject, char *ccaddr, char *mail_addr) { static char *b_cmd; #ifdef USE_ALT_BLAT_MAILER HTSprintf0(&b_cmd, "%s %s -t \"%s\" -s \"%s\" %s%s%s%s", mail_cmd, filename, address, subject, system_mail_flags, ccaddr? " -c \"" : "", NonNull(ccaddr), ccaddr? "\"" : ""); #else /* !USE_ALT_BLAT_MAILER */ static char bl_cmd_file[512]; FILE *fp; #ifdef __CYGWIN__ char dosname[LY_MAXPATH]; #endif bl_cmd_file[0] = '\0'; if ((fp = LYOpenTemp(bl_cmd_file, ".blt", "w")) == NULL) { HTAlert(FORM_MAILTO_FAILED); return NULL; } #ifdef __CYGWIN__ cygwin_conv_to_full_win32_path(filename, dosname); fprintf(fp, "%s\n", dosname); #else fprintf(fp, "%s\n", filename); #endif fprintf(fp, "-t\n%s\n", address); if (subject) fprintf(fp, "-s\n%s\n", subject); if (!isEmpty(mail_addr)) { fprintf(fp, "-f\n%s\n", mail_addr); } if (!isEmpty(ccaddr)) { fprintf(fp, "-c\n%s\n", ccaddr); } LYCloseOutput(fp); #ifdef __CYGWIN__ cygwin_conv_to_full_win32_path(bl_cmd_file, dosname); HTSprintf0(&b_cmd, "%s \"@%s\"", mail_cmd, dosname); #else HTSprintf0(&b_cmd, "%s @%s", mail_cmd, bl_cmd_file); #endif #endif /* USE_ALT_BLAT_MAILER */ return b_cmd; }
int showlist(DocInfo *newdoc, BOOLEAN titles) { int cnt; int refs, hidden_links; static char tempfile[LY_MAXPATH]; static BOOLEAN last_titles = TRUE; FILE *fp0; char *Address = NULL, *Title = NULL, *cp = NULL; char *LinkTitle = NULL; /* Rel stored as property of link, not of dest */ BOOLEAN intern_w_post = FALSE; const char *desc = "unknown field or link"; void *helper; refs = HText_sourceAnchors(HTMainText); hidden_links = HText_HiddenLinkCount(HTMainText); if (refs <= 0 && hidden_links > 0 && LYHiddenLinks != HIDDENLINKS_SEPARATE) { HTUserMsg(NO_VISIBLE_REFS_FROM_DOC); return (-1); } if (refs <= 0 && hidden_links <= 0) { HTUserMsg(NO_REFS_FROM_DOC); return (-1); } if ((fp0 = InternalPageFP(tempfile, titles == last_titles)) == 0) return (-1); LYLocalFileToURL(&(newdoc->address), tempfile); LYRegisterUIPage(newdoc->address, titles ? UIP_LIST_PAGE : UIP_ADDRLIST_PAGE); last_titles = titles; LYforce_HTML_mode = TRUE; /* force this file to be HTML */ LYforce_no_cache = TRUE; /* force this file to be new */ #ifdef EXP_ADDRLIST_PAGE if (titles != TRUE) BeginInternalPage(fp0, ADDRLIST_PAGE_TITLE, LIST_PAGE_HELP); else #endif BeginInternalPage(fp0, LIST_PAGE_TITLE, LIST_PAGE_HELP); StrAllocCopy(Address, HTLoadedDocumentURL()); LYEntify(&Address, FALSE); fprintf(fp0, "%s%s<p>\n", gettext("References in "), (non_empty(Address) ? Address : gettext("this document:"))); FREE(Address); if (refs > 0) { fprintf(fp0, "<%s compact>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol" : "ul")); if (hidden_links > 0) fprintf(fp0, "<lh><em>%s</em>\n", gettext("Visible links:")); } if (hidden_links > 0) { if (LYHiddenLinks == HIDDENLINKS_IGNORE) hidden_links = 0; } helper = NULL; /* init */ for (cnt = 1; cnt <= refs; cnt++) { HTChildAnchor *child = HText_childNextNumber(cnt, &helper); HTAnchor *dest_intl = NULL; HTAnchor *dest; HTParentAnchor *parent; char *address; const char *title; if (child == 0) { /* * child should not be 0 unless form field numbering is on and cnt * is the number of a form input field. HText_FormDescNumber() * will set desc to a description of what type of input field this * is. We'll list it to ensure that the link numbers on the list * page match the numbering in the original document, but won't * create a forward link to the form. - FM && LE * * Changed to create a fake hidden link, to get the numbering right * in connection with always treating this file as * HIDDENLINKS_MERGE in GridText.c - kw */ if (fields_are_numbered()) { HText_FormDescNumber(cnt, &desc); fprintf(fp0, "<li><a id=%d href=\"#%d\">form field</a> = <em>%s</em>\n", cnt, cnt, desc); } continue; } #ifndef DONT_TRACK_INTERNAL_LINKS dest_intl = HTAnchor_followTypedLink(child, HTInternalLink); #endif dest = dest_intl ? dest_intl : HTAnchor_followLink(child); parent = HTAnchor_parent(dest); if (!intern_w_post && dest_intl && HTMainAnchor && HTMainAnchor->post_data && parent->post_data && BINEQ(HTMainAnchor->post_data, parent->post_data)) { /* * Set flag to note that we had at least one internal link, if the * document from which we are generating the list has associated * POST data; after an extra check that the link destination really * has the same POST data so that we can believe it is an internal * link. */ intern_w_post = TRUE; } address = HTAnchor_address(dest); title = titles ? HTAnchor_title(parent) : NULL; if (dest_intl) { HTSprintf0(&LinkTitle, "(internal)"); } else if (titles && child->type && dest == child->dest && !strncmp(HTAtom_name(child->type), "RelTitle: ", 10)) { HTSprintf0(&LinkTitle, "(%s)", HTAtom_name(child->type) + 10); } else { FREE(LinkTitle); } StrAllocCopy(Address, address); FREE(address); LYEntify(&Address, TRUE); if (non_empty(title)) { LYformTitle(&Title, title); LYEntify(&Title, TRUE); if (*Title) { cp = findPoundSelector(Address); } else { FREE(Title); } } fprintf(fp0, "<li><a href=\"%s\"%s>%s%s%s%s%s</a>\n", Address, dest_intl ? " TYPE=\"internal link\"" : "", NonNull(LinkTitle), ((HTAnchor *) parent != dest) && Title ? "in " : "", (char *) (Title ? Title : Address), (Title && cp) ? " - " : "", (Title && cp) ? (cp + 1) : ""); FREE(Address); FREE(Title); } FREE(LinkTitle); if (hidden_links > 0) { if (refs > 0) fprintf(fp0, "\n</%s>\n\n<p>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol" : "ul")); fprintf(fp0, "<%s compact>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol continue" : "ul")); fprintf(fp0, "<lh><em>%s</em>\n", gettext("Hidden links:")); } for (cnt = 0; cnt < hidden_links; cnt++) { StrAllocCopy(Address, HText_HiddenLinkAt(HTMainText, cnt)); LYEntify(&Address, FALSE); if (isEmpty(Address)) { FREE(Address); continue; } fprintf(fp0, "<li><a href=\"%s\">%s</a>\n", Address, Address); FREE(Address); } fprintf(fp0, "\n</%s>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol" : "ul")); EndInternalPage(fp0); LYCloseTempFP(fp0); /* * Make necessary changes to newdoc before returning to caller. If the * intern_w_post flag is set, we keep the POST data in newdoc that have * been passed in. They should be the same as in the loaded document for * which we generated the list. In that case the file we have written will * be associated with the same POST data when it is loaded after we are * done here, so that following one of the links we have marked as * "internal link" can lead back to the underlying document with the right * address+post_data combination. - kw */ if (intern_w_post) { newdoc->internal_link = TRUE; } else { LYFreePostData(newdoc); newdoc->internal_link = FALSE; } newdoc->isHEAD = FALSE; newdoc->safe = FALSE; return (0); }
/* * LYShowInfo prints a page of info about the current file and the link that * the cursor is on. */ int LYShowInfo(DocInfo *doc, DocInfo *newdoc, char *owner_address) { static char tempfile[LY_MAXPATH] = "\0"; int url_type; FILE *fp0; char *Title = NULL; const char *cp; char *temp = NULL; char *buffer = NULL; BOOLEAN LYInfoAdvanced = (BOOL) (user_mode == ADVANCED_MODE); #ifdef DIRED_SUPPORT struct stat dir_info; const char *name; #endif /* DIRED_SUPPORT */ if (LYReuseTempfiles) { fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); } else { (void) LYRemoveTemp(tempfile); fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); } if (fp0 == NULL) { HTAlert(CANNOT_OPEN_TEMP); return (-1); } /* * Point the address pointer at this Url */ LYLocalFileToURL(&newdoc->address, tempfile); if (nlinks > 0 && links[doc->link].lname != NULL && (url_type = is_url(links[doc->link].lname)) != 0 && (url_type == LYNXEXEC_URL_TYPE || url_type == LYNXPROG_URL_TYPE)) { char *last_slash = strrchr(links[doc->link].lname, '/'); int next_to_last = (int) strlen(links[doc->link].lname) - 1; if ((last_slash - links[doc->link].lname) == next_to_last) { links[doc->link].lname[next_to_last] = '\0'; } } label_columns = 9; WriteInternalTitle(fp0, SHOWINFO_TITLE); fprintf(fp0, "<h1>%s %s (%s) (<a href=\"%s\">%s</a>)", LYNX_NAME, LYNX_VERSION, LYVersionDate(), (LYVersionIsRelease()? LYNX_WWW_HOME : LYNX_WWW_DIST), LYVersionStatus()); fprintf(fp0, "</h1>\n"); /* don't forget to close <h1> */ #ifdef DIRED_SUPPORT if (lynx_edit_mode && nlinks > 0) { BEGIN_DL(gettext("Directory that you are currently viewing")); temp = HTfullURL_toFile(doc->address); ADD_SS(gettext("Name:"), temp); FREE(temp); dt_URL(fp0, doc->address); END_DL(); temp = HTfullURL_toFile(links[doc->link].lname); if (lstat(temp, &dir_info) == -1) { CTRACE((tfp, "lstat(%s) failed, errno=%d\n", temp, errno)); HTAlert(CURRENT_LINK_STATUS_FAILED); } else { char modes[80]; label_columns = 16; if (S_ISDIR(dir_info.st_mode)) { BEGIN_DL(gettext("Directory that you have currently selected")); } else if (S_ISREG(dir_info.st_mode)) { BEGIN_DL(gettext("File that you have currently selected")); #ifdef S_IFLNK } else if (S_ISLNK(dir_info.st_mode)) { BEGIN_DL(gettext("Symbolic link that you have currently selected")); #endif } else { BEGIN_DL(gettext("Item that you have currently selected")); } ADD_SS(gettext("Full name:"), temp); #ifdef S_IFLNK if (S_ISLNK(dir_info.st_mode)) { char buf[MAX_LINE]; int buf_size; size_t limit = sizeof(buf) - 1; if ((buf_size = (int) readlink(temp, buf, limit)) != -1) { if (buf_size > (int) limit) buf_size = (int) limit; buf[buf_size] = '\0'; } else { sprintf(buf, "%.*s", (int) limit, gettext("Unable to follow link")); } ADD_SS(gettext("Points to file:"), buf); } #endif name = HTAA_UidToName((int) dir_info.st_uid); if (*name) ADD_SS(gettext("Name of owner:"), name); name = HTAA_GidToName((int) dir_info.st_gid); if (*name) ADD_SS(gettext("Group name:"), name); if (S_ISREG(dir_info.st_mode)) { ADD_NN(gettext("File size:"), (long) dir_info.st_size, gettext("(bytes)")); } /* * Include date and time information. */ ADD_SS(gettext("Creation date:"), ctime(&dir_info.st_ctime)); ADD_SS(gettext("Last modified:"), ctime(&dir_info.st_mtime)); ADD_SS(gettext("Last accessed:"), ctime(&dir_info.st_atime)); END_DL(); label_columns = 9; BEGIN_DL(gettext("Access Permissions")); modes[0] = '\0'; modes[1] = '\0'; /* In case there are no permissions */ modes[2] = '\0'; if ((dir_info.st_mode & S_IRUSR)) strcat(modes, ", read"); if ((dir_info.st_mode & S_IWUSR)) strcat(modes, ", write"); if ((dir_info.st_mode & S_IXUSR)) { if (S_ISDIR(dir_info.st_mode)) strcat(modes, ", search"); else { strcat(modes, ", execute"); if ((dir_info.st_mode & S_ISUID)) strcat(modes, ", setuid"); } } ADD_SS(gettext("Owner:"), &modes[2]); modes[0] = '\0'; modes[1] = '\0'; /* In case there are no permissions */ modes[2] = '\0'; if ((dir_info.st_mode & S_IRGRP)) strcat(modes, ", read"); if ((dir_info.st_mode & S_IWGRP)) strcat(modes, ", write"); if ((dir_info.st_mode & S_IXGRP)) { if (S_ISDIR(dir_info.st_mode)) strcat(modes, ", search"); else { strcat(modes, ", execute"); if ((dir_info.st_mode & S_ISGID)) strcat(modes, ", setgid"); } } ADD_SS(gettext("Group:"), &modes[2]); modes[0] = '\0'; modes[1] = '\0'; /* In case there are no permissions */ modes[2] = '\0'; if ((dir_info.st_mode & S_IROTH)) strcat(modes, ", read"); if ((dir_info.st_mode & S_IWOTH)) strcat(modes, ", write"); if ((dir_info.st_mode & S_IXOTH)) { if (S_ISDIR(dir_info.st_mode)) strcat(modes, ", search"); else { strcat(modes, ", execute"); #ifdef S_ISVTX if ((dir_info.st_mode & S_ISVTX)) strcat(modes, ", sticky"); #endif } } ADD_SS(gettext("World:"), &modes[2]); END_DL(); } FREE(temp); } else { #endif /* DIRED_SUPPORT */ BEGIN_DL(gettext("File that you are currently viewing")); LYformTitle(&Title, doc->title); HTSprintf(&temp, "%s%s", LYEntifyTitle(&buffer, Title), ((doc->isHEAD && !strstr(Title, " (HEAD)") && !strstr(Title, " - HEAD")) ? " (HEAD)" : "")); ADD_SS(gettext("Linkname:"), temp); FREE(temp); dt_URL(fp0, doc->address); if (HTLoadedDocumentCharset()) { ADD_SS(gettext("Charset:"), HTLoadedDocumentCharset()); } else { LYUCcharset *p_in = HTAnchor_getUCInfoStage(HTMainAnchor, UCT_STAGE_PARSER); if (!p_in || isEmpty(p_in->MIMEname) || HTAnchor_getUCLYhndl(HTMainAnchor, UCT_STAGE_PARSER) < 0) { p_in = HTAnchor_getUCInfoStage(HTMainAnchor, UCT_STAGE_MIME); } if (p_in && non_empty(p_in->MIMEname) && HTAnchor_getUCLYhndl(HTMainAnchor, UCT_STAGE_MIME) >= 0) { HTSprintf(&temp, "%s %s", LYEntifyTitle(&buffer, p_in->MIMEname), gettext("(assumed)")); ADD_SS(gettext("Charset:"), p_in->MIMEname); FREE(temp); } } if ((cp = HText_getServer()) != NULL && *cp != '\0') ADD_SS(gettext("Server:"), cp); if ((cp = HText_getDate()) != NULL && *cp != '\0') ADD_SS(gettext("Date:"), cp); if ((cp = HText_getLastModified()) != NULL && *cp != '\0') ADD_SS(gettext("Last Mod:"), cp); if (LYInfoAdvanced) { if (HTMainAnchor && HTMainAnchor->expires) { ADD_SS(gettext("Expires:"), HTMainAnchor->expires); } if (HTMainAnchor && HTMainAnchor->cache_control) { ADD_SS(gettext("Cache-Control:"), HTMainAnchor->cache_control); } if (HTMainAnchor && HTMainAnchor->content_length > 0) { ADD_NN(gettext("Content-Length:"), HTMainAnchor->content_length, gettext("bytes")); } else { ADD_NN(gettext("Length:"), HText_getNumOfBytes(), gettext("bytes")); } if (HTMainAnchor && HTMainAnchor->content_language) { ADD_SS(gettext("Language:"), HTMainAnchor->content_language); } } if (doc->post_data) { fprintf(fp0, "<dt><em>%s</em> <xmp>%.*s</xmp>\n", LYEntifyTitle(&buffer, gettext("Post Data:")), BStrLen(doc->post_data), BStrData(doc->post_data)); ADD_SS(gettext("Post Content Type:"), doc->post_content_type); } ADD_SS(gettext("Owner(s):"), (owner_address ? owner_address : NO_NOTHING)); ADD_NN(gettext("size:"), HText_getNumOfLines(), gettext("lines")); StrAllocCopy(temp, ((lynx_mode == FORMS_LYNX_MODE) ? gettext("forms mode") : (HTisDocumentSource() ? gettext("source") : gettext("normal")))); if (doc->safe) StrAllocCat(temp, gettext(", safe")); if (doc->internal_link) StrAllocCat(temp, gettext(", via internal link")); if (LYInfoAdvanced) { if (HText_hasNoCacheSet(HTMainText)) StrAllocCat(temp, gettext(", no-cache")); if (HTAnchor_isISMAPScript((HTAnchor *) HTMainAnchor)) StrAllocCat(temp, gettext(", ISMAP script")); if (doc->bookmark) StrAllocCat(temp, gettext(", bookmark file")); } ADD_SS(gettext("mode:"), temp); FREE(temp); END_DL(); if (nlinks > 0) { BEGIN_DL(gettext("Link that you currently have selected")); ADD_SS(gettext("Linkname:"), LYGetHiliteStr(doc->link, 0)); if (lynx_mode == FORMS_LYNX_MODE && links[doc->link].type == WWW_FORM_LINK_TYPE) { if (links[doc->link].l_form->submit_method) { int method = links[doc->link].l_form->submit_method; char *enctype = links[doc->link].l_form->submit_enctype; ADD_SS(gettext("Method:"), ((method == URL_POST_METHOD) ? "POST" : ((method == URL_MAIL_METHOD) ? "(email)" : "GET"))); ADD_SS(gettext("Enctype:"), (non_empty(enctype) ? enctype : "application/x-www-form-urlencoded")); } if (links[doc->link].l_form->submit_action) { ADD_SS(gettext("Action:"), links[doc->link].l_form->submit_action); } if (!(links[doc->link].l_form->submit_method && links[doc->link].l_form->submit_action)) { fprintf(fp0, "<dt> %s\n", LYEntifyTitle(&buffer, gettext("(Form field)"))); } } else { dt_URL(fp0, NonNull(links[doc->link].lname)); } END_DL(); } else { fprintf(fp0, "<h2>%s</h2>", LYEntifyTitle(&buffer, gettext("No Links on the current page"))); } if ((cp = HText_getHttpHeaders()) != 0) { fprintf(fp0, "<h2>%s</h2>", LYEntifyTitle(&buffer, gettext("Server Headers:"))); fprintf(fp0, "<pre>%s</pre>", LYEntifyTitle(&buffer, cp)); } #ifdef DIRED_SUPPORT } #endif /* DIRED_SUPPORT */ EndInternalPage(fp0); LYrefresh(); LYCloseTemp(tempfile); FREE(Title); FREE(buffer); return (0); }
/* Create or find a child anchor with a possible link ** -------------------------------------------------- ** ** Create new anchor with a given parent and possibly ** a name, and possibly a link to a _relatively_ named anchor. ** (Code originally in ParseHTML.h) */ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4( HTParentAnchor *, parent, /* May not be 0 */ CONST char *, tag, /* May be "" or 0 */ CONST char *, href, /* May be "" or 0 */ HTLinkType *, ltype) /* May be 0 */ { HTChildAnchor * child; CTRACE((tfp,"Entered HTAnchor_findChildAndLink: tag=`%s',%s href=`%s'\n", NonNull(tag), (ltype == HTInternalLink) ? " (internal link)" : "", NonNull(href) )); if (tag && *tag) { child = HTAnchor_findNamedChild(parent->parent, tag); } else { child = HTAnchor_addChild(parent); } if (href && *href) { CONST char *fragment = NULL; HTParentAnchor0 * dest; if (ltype == HTInternalLink && *href == '#') { dest = parent->parent; } else { CONST char *relative_to = (parent->inBASE && *href != '#') ? parent->content_base : parent->address; DocAddress parsed_doc; parsed_doc.address = HTParse(href, relative_to, PARSE_ALL_WITHOUT_ANCHOR); parsed_doc.post_data = NULL; parsed_doc.post_content_type = NULL; if (ltype && parent->post_data && ltype == HTInternalLink) { /* for internal links, find a destination with the same post data if the source of the link has post data. - kw Example: LYNXIMGMAP: */ parsed_doc.post_data = parent->post_data; parsed_doc.post_content_type = parent->post_content_type; } parsed_doc.bookmark = NULL; parsed_doc.isHEAD = FALSE; parsed_doc.safe = FALSE; dest = HTAnchor_findAddress_in_adult_table(&parsed_doc); FREE(parsed_doc.address); } /* ** [from HTAnchor_findAddress()] ** If the address represents a sub-anchor, we load its parent (above), ** then we create a named child anchor within that parent. */ fragment = (*href == '#') ? href+1 : HTParseAnchor(href); if (*fragment) dest = (HTParentAnchor0 *)HTAnchor_findNamedChild(dest, fragment); if (tag && *tag) { if (child->dest) { /* DUPLICATE_ANCHOR_NAME_WORKAROUND - kw */ CTRACE((tfp, "*** Duplicate ChildAnchor %p named `%s'", child, tag)); if ((HTAnchor *)dest != child->dest || ltype != child->type) { CTRACE((tfp, ", different dest %p or type, creating unnamed child\n", child->dest)); child = HTAnchor_addChild(parent); } } } HTAnchor_link(child, (HTAnchor *)dest, ltype); } return child; }