?? htbrowse.c
字號:
#ifdef CATCH_SIG#include <signal.h>/* SetSignal** This function sets up signal handlers. This might not be necessary to** call if the application has its own handlers.*/PRIVATE void SetSignal (void){ /* On some systems (SYSV) it is necessary to catch the SIGPIPE signal ** when attemting to connect to a remote host where you normally should ** get `connection refused' back */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { HTTRACE(APP_TRACE, "HTSignal.... Can't catch SIGPIPE\n"); } else { HTTRACE(APP_TRACE, "HTSignal.... Ignoring SIGPIPE\n"); }#ifdef HT_MEMLOG HTMemLog_flush();#endif}#endif /* CATCH_SIG *//* Print version information** -------------------------*/PRIVATE void VersionInfo (LineMode * lm){ HTView * pView = lm ? lm->pView : NULL; OutputData(pView, "\n\nW3C Reference Software\n\n"); OutputData(pView, "\tW3C Line Mode Browser version %s.\n", APP_VERSION); OutputData(pView, "\tW3C Reference Library version %s.\n\n",HTLib_version()); OutputData(pView, "Please send feedback to <libwww@w3.org>\n");}/* Reference_List** --------------** Print out a list of HyperText References from current document*/PRIVATE void Reference_List (LineMode * lm, BOOL titles){ int refs = HText_sourceAnchors(HTMainText); if (refs <= 0) { OutputData(lm->pView, "\n\nThere are no references from this document.\n\n"); } else { int cnt; OutputData(lm->pView, "\n*** References from this document ***\n"); for (cnt=1; cnt<=refs; cnt++) { HTLink * link = HTAnchor_mainLink((HTAnchor*)HText_childNumber(HTMainText,cnt)); HTAnchor * dest = HTLink_destination(link); HTParentAnchor * parent = HTAnchor_parent(dest); char * address = HTAnchor_address(dest); const char * title = titles ? HTAnchor_title(parent) : NULL; OutputData(lm->pView, reference_mark, cnt); OutputData(lm->pView, "%s%s\n", ((HTAnchor*)parent!=dest) && title ? "in " : "", (char *)(title ? title : address)); HT_FREE(address); }#ifndef WWW_WIN_WINDOW fflush(OUTPUT);#endif }} /* History_List** ------------** Display a history list of nodes visited during the session.*/PRIVATE void History_List (LineMode * lm){ int current = HTHistory_position(lm->history); int max = HTHistory_count(lm->history); int cnt; OutputData(lm->pView, "\n Documents you have visited: "); if (max > MAX_HISTORY) { max = MAX_HISTORY; OutputData(lm->pView, "(truncated)\n"); } else OutputData(lm->pView, "\n"); for (cnt=1; cnt<=max; cnt++) { HTAnchor *anchor = HTHistory_list(lm->history, cnt); char *address = HTAnchor_address(anchor); HTParentAnchor *parent = HTAnchor_parent(anchor); const char *title = HTAnchor_title(parent); OutputData(lm->pView, "%s R %d\t%s%s\n", (cnt==current) ? "*" : " ", cnt, ((HTAnchor*)parent!=anchor) && title ? "in " : "", title ? title : address); HT_FREE(address); } OutputData(lm->pView, "\n");}/* Prompt for answer and get text back. Reply text is either NULL on** error or a dynamic string which the caller must HT_FREE.*/PRIVATE char * AskUser (HTRequest * request, const char * Msg, const char * deflt){ char buffer[200]; char *reply = NULL; HTPrint("%s ", Msg ? Msg : "UNKNOWN"); if (deflt) HTPrint("(RETURN for [%s]) ", deflt);#ifndef NO_STDIO if (!fgets(buffer, 200, stdin)) return NULL; /* NULL string on error, Henrik */ buffer[strlen(buffer)-1] = '\0'; /* Overwrite newline */ if (*buffer) StrAllocCopy(reply, buffer); else if (deflt) StrAllocCopy(reply, deflt);#endif return reply;}PRIVATE BOOL confirm (HTRequest * request, const char * Msg){ char response[4]; HTPrint("%s (y/n) ", Msg ? Msg : "UNKNOWN");#ifndef NO_STDIO if (fgets(response, 4, stdin)) /* get reply, max 3 chars */#endif { char *ptr = response; while (*ptr) { if (*ptr == '\n') { *ptr = '\0'; break; } *ptr = TOUPPER(*ptr); ptr++; } return (!strcmp(response, "YES") || !strcmp(response, "Y")) ? YES : NO; } return NO;}/* MakeCommandLine** ---------------** Generate the Prompt line and flush it to the user*/PRIVATE void MakeCommandLine (LineMode * lm, BOOL is_index){ /* First Line */ if (HTAnchor_hasChildren(HTMainAnchor)) { int refs = HText_sourceAnchors(HTMainText); if (refs>1) OutputData(lm->pView, "1-%d, ", refs); else OutputData(lm->pView, "1, "); } if (HText_canScrollUp(HTMainText)) { OutputData(lm->pView, "Top, "); OutputData(lm->pView, "Up, "); } if (HText_canScrollDown(HTMainText)) { OutputData(lm->pView, "BOttom, "); OutputData(lm->pView, "Down or <RETURN> for more,"); } /* Second Line */ OutputData(lm->pView, "\n"); if (HTHistory_canBacktrack(lm->history)) OutputData(lm->pView, "Back, "); if (HTHistory_canForward(lm->history)) OutputData(lm->pView, "Forward, "); if (is_index) OutputData(lm->pView, "FIND <keywords>, "); OutputData(lm->pView, "Quit, or Help: "); fflush(stdout); /* For use to flush out the prompt */ return;}/*** PUT the current document to the destination specified by the user** Returns the result of the load function.*/PRIVATE int PutAnchor (LineMode * lm, HTRequest * request){ char * dest = AskUser(request, "Destination: ", NULL); /* ** If user has typed a destination then create a new request object and ** start the PUT operation. The destination is taken relative to the ** current location. */ if (dest) { HTRequest * new_request = Thread_new(lm, YES, LM_UPDATE); HTPutDocumentRelative(HTMainAnchor, dest, HTMainAnchor, new_request); HT_FREE(dest); } return YES;}/*** Delete the current document.*/PRIVATE int DeleteAnchor (LineMode * lm, HTRequest * request){ int status = HT_INTERNAL; BOOL doit = confirm(request, "Delete the current document?"); if (doit) { HTRequest * new_request = Thread_new(lm, YES, LM_UPDATE); status = HTDeleteAnchor((HTAnchor *) HTMainAnchor, new_request); } return status;}/*** This function puts up a stream to a file in order to save a document. This** is activated by '>', '>>' or '>!' from the prompt line.*/PRIVATE BOOL SaveOutputStream (HTRequest * req, char * This, char * Next){ FILE *fp; char *fname; char *fmode; /* Checks if file exists. Can be overruled by using '>!' */ if (*(This+1) == '>') { /* Append to file */ fmode = "ab"; fname = *(This+2) ? (This+2) : Next; } else if (*(This+1) == '!') { fmode = "wb"; /* Overwrite file */ fname = *(This+2) ? (This+2) : Next; } else { /* File name follows */ fmode = "wb"; fname = *(This+1) ? (This+1) : Next; if (fname) { /* See if file exists */ if ((fp = fopen(fname, "r")) != NULL) { fclose(fp); if (!confirm(req, "File exists - overwrite?")) return NO; } } } if (!fname) /* No file name given */ return NO; if ((fp = fopen(fname, fmode)) == NULL) { if (SHOW_MSG) HTPrint("Can't access file (%s)\n", fname); return NO; } HTRequest_setOutputStream(req, HTFWriter_new(req, fp, NO)); if (SHOW_MSG) HTPrint("Saving to file `%s\'\n", fname); return (HTLoadAnchor((HTAnchor*) HTMainAnchor, req) != HT_WOULD_BLOCK);}CSError_t LoadedUsersCallback(CSUser_t * pCSUser, int index, void * pVoid){ LineMode * lm = (LineMode *)pVoid; OutputData(lm->pView, "%d: %s\n", index, CSUser_name(pCSUser)); return CSError_OK;}CSError_t UserListCallback(char * username, char * url, int index, void * pVoid){ LineMode * lm = (LineMode *)pVoid; OutputData(lm->pView, "%d: %s %s\n", index, username, url); return CSError_OK;}PRIVATE BOOL ShowPICSUsers(LineMode * lm){ OutputData(lm->pView, "Loaded users:\n"); CSLoadedUser_enum(&LoadedUsersCallback, (void *)lm); OutputData(lm->pView, "Listed users:\n"); CSUserList_enum(&UserListCallback, (void *)lm); return YES;}PRIVATE int PICS_userCallback(CSUser_t * pCSUser, void * pVoid){ LineMode * lm = (LineMode *)pVoid; char * userName; char * password = NULL; HTAlertCallback *cbf; int ret; HTAlertPar * reply; if (lm->noPICSPasswords) { lm->pCSUser = pCSUser; return 0; } if (!(cbf = HTAlert_find(HT_A_USER_PW))) return -1; reply = HTAlert_newReply(); userName = CSUser_name(pCSUser); if ((ret = (*cbf)(lm->console, HT_A_USER_PW, HT_MSG_NULL, userName, NULL, reply))) { userName = HTAlert_replyMessage(reply); password = HTAlert_replySecret(reply); } HTAlert_deleteReply(reply); if (!ret) { HTPrint("PICS set user *canceled*.\n"); return -1; } ret = -1; if (!userName) HTPrint("PICS cannot set to no name.\n"); else if (CSUser_checkPassword(pCSUser, password) == NO) HTPrint("PICS password was not valid.\n"); else { ret = 0; lm->pCSUser = pCSUser; } HT_FREE(userName); HT_FREE(password); return ret;}PRIVATE BOOL SetPICSUser(LineMode * lm, char * userName){ char * password = NULL; HTAlertCallback *cbf; BOOL ret; HTAlertPar * reply; if (!(cbf = HTAlert_find(HT_A_USER_PW))) return NO; reply = HTAlert_newReply(); if ((ret = (*cbf)(lm->console, HT_A_USER_PW, HT_MSG_NULL, userName, NULL, reply))) { userName = HTAlert_replyMessage(reply); password = HTAlert_replySecret(reply); } HTAlert_deleteReply(reply); if (!ret) { HTPrint("PICS set user *canceled*.\n"); return NO; } ret = NO; if (!userName) HTPrint("Canceled.\n"); else if (!(lm->pCSUser = CSApp_registerUserByName(userName, password))) { char * url; if ((url = CSUserList_findURL(userName)) == NULL) HTPrint("PICS user \"%s\" is unknown.\n", userName); else if (!CSLoadedUser_load(url, lm->cwd)) HTPrint("Can't load PICS user \"%s\".\n", userName); else if ((CSLoadedUser_find(userName)) == NO) HTPrint("PICS user \"%s\" not found in \"%s\".\n", userName, url); else if (!(lm->pCSUser = CSApp_registerUserByName(userName, password))) HTPrint("Failed to set PICS user to \"%s\".\n", userName); ret = YES; HT_FREE(url); } HT_FREE(userName); HT_FREE(password); return ret;}PRIVATE BOOL LoadPICSUser(LineMode * lm, char * url){ CSUser_t * pCSUser; if (!(pCSUser = CSLoadedUser_load(url, lm->cwd))) return NO; lm->pCSUser = pCSUser; return YES;}CSError_t PICSCallback(HTRequest* pReq, CSLabel_t * pCSLabel, CSUser_t * pCSUser, CSError_t disposition, void * pVoid){ LineMode * lm = (LineMode *)pVoid; char * mesg; switch (disposition) { case CSError_RATING_RANGE: { char * labelStr = CSLabel_getRatingStr(pCSLabel); char * userStr = CSUser_getRatingStr(pCSUser); char * anchorStr = HTAnchor_address((HTAnchor*)HTRequest_anchor(pReq)); OutputData(lm->pView, "PICS user %s is not allowed to see document: %s\n", CSUser_name(pCSUser), anchorStr); OutputData(lm->pView, " %s's \"%s\" rating for service %s (%s) did not include %s\n", CSUser_name(pCSUser), CSLabel_getRatingName(pCSLabel), CSLabel_getServiceName(pCSLabel), userStr, labelStr); HT_FREE(userStr); HT_FREE(labelStr); HT_FREE(anchorStr); } return disposition; case CSError_BUREAU_NONE: mesg="label bureau was not contacted"; break; case CSError_RATING_VALUE: mesg="value"; break; case CSError_RATING_MISSING: mesg="rating not found"; break; case CSError_SINGLELABEL_MISSING: mesg="no single-labels found"; break; case CSError_SERVICE_MISSING: mesg="service not available";break; case CSError_SERVICE_NONE: mesg="no services available for document"; break; case CSError_RATING_NONE: mesg="no ratings in a service"; break; case CSError_BAD_DATE: mesg="labels were out of date"; break; default:HTPrint("PICSCallback: odd error code: %d\n", disposition); return disposition; } OutputData(lm->pView, "PICS disallowed document: %s\n", mesg); return disposition;}/* ------------------------------------------------------------------------- *//* EVENT FUNCTIONS *//* ------------------------------------------------------------------------- *//* parse_command** ------------** Given the user's input, deal with it as necessary.** Any Command which works returns from the routine. If nothing** works then a search or error message down at the bottom.**** Returns HT_ERROR Error has occured or we quit** HT_OK Call back was OK*/PRIVATE int parse_command (char* choice, SOCKET s, HTRequest *req, HTEventType type)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -