/* ** Output an element in HTML ** Returns YES if OK, else NO */ PRIVATE BOOL HTNewsNode_print (HTNewsDir * dir, HTNewsNode * node) { if (node && node->show) { HTStructured *target = dir->target; char * escaped; HTNewsDir_addLevelTags (dir, node->refLevel); /* Added by MP. */ START(HTML_LI); /* Start the anchor and put the subject as anchor text */ /* Changed by MP to allow nodes without names */ if (!node->fake && node->name && node->subject) { escaped = HTEscape(node->name, URL_XPALPHAS); HTStartAnchor(target, NULL, escaped); } if (node->subject) PUTS(node->subject); if (!node->fake && node->name && node->subject) { END(HTML_A); HT_FREE(escaped); } /* From field */ if (node->from) { PUTS (" by "); /* Changed by MP. */ PUTS(node->from); } /* In group listing, put number of groups in the set; added by MP. */ if (node->name && strrchr(node->name, '*')) { char buf[16]; sprintf (buf, " (%d groups)", node->refChildren); PUTS (buf); } } return YES; }
/* Generate Outout ** =============== */ PRIVATE void WSRC_gen_html (HTStream * me, BOOL source_file) { if (me->par_value[PAR_DATABASE_NAME]) { char * shortname = NULL; int l; StrAllocCopy(shortname, me->par_value[PAR_DATABASE_NAME]); l = strlen(shortname); if ( l > 4 && !strcasecomp(shortname + l -4, ".src")) { shortname[l-4] = 0; /* Chop of .src -- boring! */ } START(HTML_TITLE); PUTS(shortname); PUTS(source_file ? " WAIS source file" : " index"); END(HTML_TITLE); START(HTML_H1); PUTS(shortname); PUTS(source_file ? " description" : " index"); END(HTML_H1); HT_FREE(shortname); /* memleak, henrik */ } START(HTML_DL); /* Definition list of details */ if (source_file) { START(HTML_DT); PUTS("Access link"); START(HTML_DD); if (me->par_value[PAR_IP_NAME] && me->par_value[PAR_DATABASE_NAME]) { char WSRC_address[256]; char *addr = HTAnchor_address((HTAnchor*) me->request->anchor); char *gate = HTGateway_find(addr); char *www_database = HTEscape(me->par_value[PAR_DATABASE_NAME], URL_XALPHAS); if (!gate) { sprintf(WSRC_address, "wais://%s%s%s/%s", me->par_value[PAR_IP_NAME], me->par_value[PAR_TCP_PORT] ? ":" : "", me->par_value[PAR_TCP_PORT] ? me->par_value[PAR_TCP_PORT] :"", www_database); HTStartAnchor(me->target, NULL, WSRC_address); PUTS("Direct access"); END(HTML_A); } else { sprintf(WSRC_address, "%s%s%s%s/%s", gate, me->par_value[PAR_IP_NAME], me->par_value[PAR_TCP_PORT] ? ":" : "", me->par_value[PAR_TCP_PORT] ? me->par_value[PAR_TCP_PORT] : "", www_database); HTStartAnchor(me->target, NULL, WSRC_address); PUTS("Through a gateway"); END(HTML_A); } HT_FREE(gate); HT_FREE(addr); HT_FREE(www_database); } else { give_parameter(me, PAR_IP_NAME); give_parameter(me, PAR_DATABASE_NAME); } } /* end if source_file */ if (me->par_value[PAR_MAINTAINER]) { START(HTML_DT); PUTS("Maintainer"); START(HTML_DD); PUTS(me->par_value[PAR_MAINTAINER]); } if (me->par_value[PAR_IP_NAME]) { START(HTML_DT); PUTS("Host"); START(HTML_DD); PUTS(me->par_value[PAR_IP_NAME]); } END(HTML_DL); if (me->par_value[PAR_DESCRIPTION]) { START(HTML_PRE); /* Preformatted description */ PUTS(me->par_value[PAR_DESCRIPTION]); END(HTML_PRE); } (*me->target->isa->_free)(me->target); return; } /* generate html */
/* ** Output an element in HTML ** Returns YES if OK, else NO */ PRIVATE BOOL HTDirNode_print (HTDir *dir, HTDirNode *node) { char *tp = NULL; HTStructured *target = dir->target; if (dir->show & HT_DS_ICON) { HTFormat format = NULL; HTEncoding encoding = NULL; double q=1.0; HTIconNode * icon; if (node->mode == HT_IS_FILE) HTBind_getFormat(node->fname, &format, &encoding, NULL, NULL, &q); icon = HTIcon_find(node->mode, format, encoding); /* Are we having a hot or a cold icon? */ if (!(dir->show & HT_DS_HOTI)) { if (icon) { char * alt = HTIcon_alternative(icon, YES); HTMLPutImg(target, HTIcon_url(icon), alt, NULL); HT_FREE(alt); PUTC(' '); } } /* Start the anchor element */ if (dir->base) { char *escaped = expand_name(node->fname, node->mode); char *full; if ((full = (char *) HT_MALLOC(strlen(escaped)+strlen(dir->base)+1)) == NULL) HT_OUTOFMEM("HTDirNode_print"); strcpy(full, dir->base); strcat(full, escaped); HTStartAnchor(target, NULL, full); HT_FREE(escaped); HT_FREE(full); } else { char *escaped = expand_name(node->fname, node->mode); HTStartAnchor(target, NULL, escaped); HT_FREE(escaped); } if (dir->show & HT_DS_HOTI) { char * alt = HTIcon_alternative(icon, YES); HTMLPutImg(target, HTIcon_url(icon), alt, NULL); PUTC(' '); } } else { if (dir->base) { char *escaped = expand_name(node->fname, node->mode); char *full; if ((full = (char *) HT_MALLOC(strlen(escaped)+strlen(dir->base)+1)) == NULL) HT_OUTOFMEM("HTDirNode_print"); strcpy(full, dir->base); strcat(full, escaped); HTStartAnchor(target, NULL, escaped); HT_FREE(escaped); HT_FREE(full); } else { char *escaped = HTEscape(node->fname, URL_XPALPHAS); HTStartAnchor(target, NULL, escaped); HT_FREE(escaped); } } /* Insert the anchor text and end anchor */ { char *in = node->fname; char *out = dir->fnbuf; int l = dir->curfw; while (l-- > 0 && *in && (*out++ = *in++)); if (*in) *(out-1) = '>'; else if (node->mode == HT_IS_DIR) { *out++ = '/'; l--; } *out = '\0'; PUTS(dir->fnbuf); END(HTML_A); out = dir->fnbuf; while (l-- >= 0) *out++ = ' '; LeftStr(&out, " ", HT_DLEN_SPACE); *out = '\0'; PUTS(dir->fnbuf); } /* Print the rest of it */ tp = dir->lnbuf; if (node->date) { RightStr(&tp, node->date, HT_DLEN_DATE); LeftStr(&tp, " ", HT_DLEN_SPACE); } if (node->size) { RightStr(&tp, node->size, HT_DLEN_SIZE); LeftStr(&tp, " ", HT_DLEN_SPACE); } if (node->note) { LeftStr(&tp, node->note, HT_DLEN_DES); LeftStr(&tp, " ", HT_DLEN_SPACE); } *tp = '\0'; PUTS(dir->lnbuf); PUTC('\n'); return YES; }
/* HTVMSBrowseDir() ** ** This function generates a directory listing as an HTML-object ** for local file URL's. It assumes the first two elements of ** of the path are a device followed by a directory: ** ** file://localhost/device/directory[/[foo]] ** ** Will not accept 000000 as a directory name. ** Will offer links to parent through the top directory, unless ** a terminal slash was included in the calling URL. ** ** Returns HT_LOADED on success, HTLoadError() messages on error. ** ** Developed for Lynx by Foteos Macrides ([email protected]). */ PUBLIC int HTVMSBrowseDir ARGS4( CONST char *, address, HTParentAnchor *, anchor, HTFormat, format_out, HTStream *, sink ) { HTStructured* target; HTStructuredClass targetClass; char *pathname = HTParse(address, "", PARSE_PATH + PARSE_PUNCTUATION); char *tail = NULL; char *title = NULL; char *header = NULL; char *parent = NULL; char *relative = NULL; char *cp, *cp1; int pathend, len; DIR *dp; struct stat file_info; time_t NowTime; static char ThisYear[8]; VMSEntryInfo *entry_info = 0; char string_buffer[64]; HTUnEscape(pathname); CTRACE((tfp,"HTVMSBrowseDir: Browsing `%s\'\n", pathname)); /* * Require at least two elements (presumably a device and directory) * and disallow the device root (000000 directory). Symbolic paths * (e.g., sys$help) should have been translated and expanded (e.g., * to /sys$sysroot/syshlp) before calling this routine. */ if (((*pathname != '/') || (cp = strchr(pathname+1, '/')) == NULL || *(cp + 1) == '\0' || 0 == strncmp((cp + 1), "000000", 6)) || (dp = HTVMSopendir(pathname)) == NULL) { FREE(pathname); return HTLoadError(sink, 403, COULD_NOT_ACCESS_DIR); } /* * Set up the output stream. */ _HTProgress (BUILDING_DIR_LIST); if (UCLYhndl_HTFile_for_unspec >= 0) { HTAnchor_setUCInfoStage(anchor, UCLYhndl_HTFile_for_unspec, UCT_STAGE_PARSER, UCT_SETBY_DEFAULT); } target = HTML_new(anchor, format_out, sink); targetClass = *(target->isa); /* * Set up the offset string of the anchor reference, * and strings for the title and header. */ cp = strrchr(pathname, '/'); /* find lastslash */ StrAllocCopy(tail, (cp+1)); /* take slash off the beginning */ if (*tail != '\0') { StrAllocCopy(title, tail); *cp = '\0'; if ((cp1=strrchr(pathname, '/')) != NULL && cp1 != pathname && strncmp((cp1+1), "000000", 6)) StrAllocCopy(parent, (cp1+1)); *cp = '/'; } else { pathname[strlen(pathname)-1] = '\0'; cp = strrchr(pathname, '/'); StrAllocCopy(title, (cp+1)); pathname[strlen(pathname)] = '/'; } StrAllocCopy(header, pathname); /* * Initialize path name for HTStat(). */ pathend = strlen(pathname); if (*(pathname+pathend-1) != '/') { StrAllocCat(pathname, "/"); pathend++; } /* * Output the title and header. */ START(HTML_HTML); PUTC('\n'); START(HTML_HEAD); PUTC('\n'); HTUnEscape(title); START(HTML_TITLE); PUTS(title); PUTS(" directory"); END(HTML_TITLE); PUTC('\n'); FREE(title); END(HTML_HEAD); PUTC('\n'); START(HTML_BODY); PUTC('\n'); HTUnEscape(header); START(HTML_H1); PUTS(header); END(HTML_H1); PUTC('\n'); if (HTDirReadme == HT_DIR_README_TOP) { FILE * fp; if (header[strlen(header)-1] != '/') StrAllocCat(header, "/"); StrAllocCat(header, HT_DIR_README_FILE); if ((fp = fopen(header, "r")) != NULL) { START(HTML_PRE); for(;;) { char c = fgetc(fp); if (c == (char)EOF) break; #ifdef NOTDEFINED switch (c) { case '&': case '<': case '>': PUTC('&'); PUTC('#'); PUTC((char)(c / 10)); PUTC((char) (c % 10)); PUTC(';'); break; default: PUTC(c); } #else PUTC(c); #endif /* NOTDEFINED */ } END(HTML_PRE); fclose(fp); } } FREE(header); if (parent) { HTSprintf0(&relative, "%s/..", tail); HTStartAnchor(target, "", relative); PUTS("Up to "); HTUnEscape(parent); PUTS(parent); END(HTML_A); START(HTML_P); PUTC('\n'); FREE(relative); FREE(parent); } /* * Set up the date comparison. */ NowTime = time(NULL); strcpy(ThisYear, (char *)ctime(&NowTime)+20); ThisYear[4] = '\0'; /* * Now, generate the Btree and put it out to the output stream. */ { char dottest = 2; /* To avoid two strcmp() each time */ STRUCT_DIRENT *dirbuf; HTBTree *bt; /* Set up sort key and initialize BTree */ bt = HTBTree_new((HTComparer) compare_VMSEntryInfo_structs); /* Build tree */ while ((dirbuf = HTVMSreaddir(dp))) { HTAtom *encoding = NULL; HTFormat format; /* Skip if not used */ if (!dirbuf->d_ino) { continue; } /* Current and parent directories are never shown in list */ if (dottest && (!strcmp(dirbuf->d_name, ".") || !strcmp(dirbuf->d_name, ".."))) { dottest--; continue; } /* Don't show the selective enabling file * unless version numbers are included */ if (!strcasecomp(dirbuf->d_name, HT_DIR_ENABLE_FILE)) { continue; } /* Skip files beginning with a dot? */ if ((no_dotfiles || !show_dotfiles) && *dirbuf->d_name == '.') { continue; } /* OK, make an lstat() and get a key ready. */ *(pathname+pathend) = '\0'; StrAllocCat(pathname, dirbuf->d_name); if (HTStat(pathname, &file_info)) { /* for VMS the failure here means the file is not readable... we however continue to browse through the directory... */ continue; } entry_info = (VMSEntryInfo *)malloc(sizeof(VMSEntryInfo)); if (entry_info == NULL) outofmem(__FILE__, "HTVMSBrowseDir"); entry_info->type = 0; entry_info->size = 0; entry_info->date = 0; entry_info->filename = 0; entry_info->display = TRUE; /* Get the type */ format = HTFileFormat(dirbuf->d_name, &encoding, (CONST char **)&cp); if (!cp) { if(!strncmp(HTAtom_name(format), "application",11)) { cp = HTAtom_name(format) + 12; if(!strncmp(cp,"x-", 2)) cp += 2; } else cp = HTAtom_name(format); } StrAllocCopy(entry_info->type, cp); StrAllocCopy(entry_info->filename, dirbuf->d_name); if (S_ISDIR(file_info.st_mode)) { /* strip .DIR part... */ char *dot; dot = strstr(entry_info->filename, ".DIR"); if (dot) *dot = '\0'; LYLowerCase(entry_info->filename); StrAllocCopy(entry_info->type, "Directory"); } else { if ((cp = strstr(entry_info->filename, "READ")) == NULL) { cp = entry_info->filename; } else { cp += 4; if (!strncmp(cp, "ME", 2)) { cp += 2; while (cp && *cp && *cp != '.') { cp++; } } else if (!strncmp(cp, ".ME", 3)) { cp = (entry_info->filename + strlen(entry_info->filename)); } else { cp = entry_info->filename; } } LYLowerCase(cp); if (((len = strlen(entry_info->filename)) > 2) && entry_info->filename[len-1] == 'z') { if (entry_info->filename[len-2] == '.' || entry_info->filename[len-2] == '_') entry_info->filename[len-1] = 'Z'; } } /* Get the date */ { char *t = (char *)ctime((CONST time_t *)&file_info.st_ctime); *(t+24) = '\0'; StrAllocCopy(entry_info->date, (t+4)); *((entry_info->date)+7) = '\0'; if ((atoi((t+19))) < atoi(ThisYear)) StrAllocCat(entry_info->date, (t+19)); else { StrAllocCat(entry_info->date, (t+11)); *((entry_info->date)+12) = '\0'; } } /* Get the size */ if (!S_ISDIR(file_info.st_mode)) entry_info->size = (unsigned int)file_info.st_size; else entry_info->size = 0; /* Now, update the BTree etc. */ if(entry_info->display) { CTRACE((tfp,"Adding file to BTree: %s\n", entry_info->filename)); HTBTree_add(bt, entry_info); } } /* End while HTVMSreaddir() */ FREE(pathname); HTVMSclosedir(dp); START(HTML_PRE); /* * Run through the BTree printing out in order */ { HTBTElement * ele; int i; for (ele = HTBTree_next(bt, NULL); ele != NULL; ele = HTBTree_next(bt, ele)) { entry_info = (VMSEntryInfo *)HTBTree_object(ele); /* Output the date */ if(entry_info->date) { PUTS(entry_info->date); PUTS(" "); } else PUTS(" * "); /* Output the type */ if(entry_info->type) { for(i = 0; entry_info->type[i] != '\0' && i < 15; i++) PUTC(entry_info->type[i]); for(; i < 17; i++) PUTC(' '); } /* Output the link for the name */ HTDirEntry(target, tail, entry_info->filename); PUTS(entry_info->filename); END(HTML_A); /* Output the size */ if(entry_info->size) { if(entry_info->size < 1024) sprintf(string_buffer," %d bytes", entry_info->size); else sprintf(string_buffer," %dKb", entry_info->size/1024); PUTS(string_buffer); } PUTC('\n'); /* end of this entry */ free_VMSEntryInfo_contents(entry_info); } } HTBTreeAndObject_free(bt); } /* End of both BTree loops */ /* * Complete the output stream. */ END(HTML_PRE); PUTC('\n'); END(HTML_BODY); PUTC('\n'); END(HTML_HTML); PUTC('\n'); FREE(tail); FREE_TARGET; return HT_LOADED; } /* End of directory reading section */
/* Generate Outout ** =============== */ PRIVATE void WSRC_gen_html ARGS2(HTStream *, me, BOOL, source_file) { if (me->par_value[PAR_DATABASE_NAME]) { char * shortname = 0; int l; StrAllocCopy(shortname, me->par_value[PAR_DATABASE_NAME]); l = strlen(shortname); if ( l > 4 && !strcasecomp(shortname + l -4, ".src")) { shortname[l-4] = 0; /* Chop of .src -- boring! */ } START(HTML_HEAD); PUTC('\n'); START(HTML_TITLE); PUTS(shortname); PUTS(source_file ? gettext(" WAIS source file") : INDEX_SEGMENT); END(HTML_TITLE); PUTC('\n'); END(HTML_HEAD); START(HTML_H1); PUTS(shortname); PUTS(source_file ? gettext(" description") : INDEX_SEGMENT); END(HTML_H1); PUTC('\n'); FREE(shortname); } START(HTML_DL); /* Definition list of details */ if (source_file) { START(HTML_DT); PUTS(gettext("Access links")); MAYBE_END(HTML_DT); START(HTML_DD); if (me->par_value[PAR_IP_NAME] && me->par_value[PAR_DATABASE_NAME]) { char * WSRC_address = NULL; char * www_database; www_database = HTEscape(me->par_value[PAR_DATABASE_NAME], URL_XALPHAS); HTSprintf0(&WSRC_address, "%s//%s%s%s/%s", STR_WAIS_URL, me->par_value[PAR_IP_NAME], me->par_value[PAR_TCP_PORT] ? ":" : "", me->par_value[PAR_TCP_PORT] ? me->par_value[PAR_TCP_PORT] :"", www_database); HTStartAnchor(me->target, NULL, WSRC_address); PUTS(gettext("Direct access")); END(HTML_A); /** Proxy will be used if defined, so let user know that - FM **/ PUTS(gettext(" (or via proxy server, if defined)")); FREE(www_database); FREE(WSRC_address); } else { give_parameter(me, PAR_IP_NAME); give_parameter(me, PAR_DATABASE_NAME); } MAYBE_END(HTML_DD); } /* end if source_file */ if (me->par_value[PAR_MAINTAINER]) { START(HTML_DT); PUTS(gettext("Maintainer")); MAYBE_END(HTML_DT); START(HTML_DD); PUTS(me->par_value[PAR_MAINTAINER]); MAYBE_END(HTML_DD); } if (me->par_value[PAR_IP_NAME]) { START(HTML_DT); PUTS(gettext("Host")); MAYBE_END(HTML_DT); START(HTML_DD); PUTS(me->par_value[PAR_IP_NAME]); MAYBE_END(HTML_DD); } END(HTML_DL); if (me->par_value[PAR_DESCRIPTION]) { START(HTML_PRE); /* Preformatted description */ PUTS(me->par_value[PAR_DESCRIPTION]); END(HTML_PRE); } (*me->target->isa->_free)(me->target); return; } /* generate html */