/* Zoekt HTML-bestanden door op markeringen van markante passages. Deze worden geplaatst in werkbestanden per taal, waaruit dstqview een random selectie maakt. Dit dstqview is bedoeld om vaak, op verzoek via de website te kunnen draaien, terwijl destaq bijvoorbeeld eens per etmaal draait. Destaq komt van Portugees 'em destaque' = op de voorpagina, highlighted, prominent aanwezig. Bloemlezing, selectie, anthology, featured articles, dat idee. Invoer (stdin): de output van find (relatief vanuit current dir). Uitvoer: bestanden in ~/homepage/../cgi-bin/lstviewd/destaq/destaqll.htm waarin ll een taalcode is, zoals nl = Nederlands, en = Engels. 7 - 9, 12 - 13, 20 februari, 16 maart 2013 1 feb 2014: - added rel="nofollow" to generated links, so Google etc won't index these pages, which makes no sense anyway. - If no

tag is present in the file, used the instead, and if even that one isn't found or empty, use a default string, so the generated links always text. */ #include <stdio.h> #include <stdlib.h> #define _GNU_SOURCE /* See feature_test_macros(7) */ #define __USE_GNU /* Manpage says _GN_SOURCE, but what is tested is __USE_GNU */ #include <string.h> #include <errno.h> #include <ctype.h> #include <time.h> #include <sys/stat.h> #include "../../cgi-src/fstrfind/fstrfind.h" #define EMERGENCY_BRAKE 45 static int DoHtmlFile (char *htmlpath); static void BlankOutTags (char *s, int len); static void CorrHyprlink (char *s, int len, char *htmlpath); static void CorrImaglink (char *s, int len, char *htmlpath); static char *DeleteCommand = "rm /var/www/cgi-bin/dstqview/destaq??.htm 2> /dev/null"; static char *DestaqFilesPath = "/var/www/cgi-bin/dstqview/destaq%2.2s.htm"; static char *MarkeringStart = "<!-- Start Destaque Rudhar.com -->"; static char *MarkeringStop = "<!-- Stop Destaque Rudhar.com -->"; static char *Href = " href="; int main (int argc, char **argv) { static char buf[1024]; FILE *fpi = stdin; char *p; struct stat st; system(DeleteCommand); while (fgets(buf, sizeof buf, fpi)) { p = strrchr(buf, '\n'); if (p) *p = '\0'; /* Accept only files, skip directories. */ stat(buf, &st); if (!(st.st_mode & S_IFREG)) continue; DoHtmlFile(buf); } return 0; } #define DFLTTITLE "«TITLE»" static int DoHtmlFile (char *htmlpath) { FILE *hfp = NULL; static char buffr[4096]; static char LangCode[2+1]; static char h1[256]; static char title[256]; char *p; long cc, pp, qq; int DestaqueLines = 0; int LineCount = 0; FILE *fpo = NULL; if ((hfp = fopen(htmlpath, "rt")) == NULL) { fprintf(stderr, "Cannot open input file %s for reading\n", htmlpath); return 1; } memset(LangCode, '\0', sizeof LangCode); memset(h1, '\0', sizeof h1); memset(title, '\0', sizeof title); strcpy(title, DFLTTITLE); while (cc = ftell(hfp), fgets(buffr, sizeof buffr, hfp) != NULL) { if (!LangCode[0] && (p = strcasestr(buffr, "<html lang=")) != NULL) { p += strlen("<html lang="); if (*p == '\"') p++; strncpy(LangCode, p, sizeof LangCode - 1); } if (!h1[0] && (p = strcasestr(buffr, "<h1>")) != NULL) { pp = cc + (p - buffr) + strlen("<h1>"); fseek(hfp, cc, SEEK_SET); qq = fstrfindex(hfp, "</h1>", 1, 1, 1); if (qq > pp) { if (qq - pp > sizeof h1 - 1) qq = pp + sizeof h1 - 1; memset(h1, '\0', sizeof h1); fseek(hfp, pp, SEEK_SET); fread(h1, qq - pp, 1, hfp); } /* Remove tags from the h1/title, because the title is later used to build a <A HREF tag. If the title itself has tags of its own, especially <A NAME or <A HREF, this will interfere with it. */ BlankOutTags(h1, sizeof h1); } if (strcmp(title, DFLTTITLE) == 0 && (p = strcasestr(buffr, "<title>")) != NULL) { pp = cc + (p - buffr) + strlen("<title>"); fseek(hfp, cc, SEEK_SET); qq = fstrfindex(hfp, "", 1, 1, 1); if (qq > pp) { if (qq - pp > sizeof title - 1) qq = pp + sizeof title - 1; memset(title, '\0', sizeof title); fseek(hfp, pp, SEEK_SET); fread(h1, qq - pp, 1, hfp); } /* Remove tags from the h1/title, because the title is later used to build a EMERGENCY_BRAKE) { DestaqueLines = LineCount = 0; if (fpo) { fprintf(fpo, "%s\n", MarkeringStop); fprintf(fpo, "

%s

\n\n
\n\n", htmlpath, h1); fclose(fpo); fpo = NULL; } } else if (DestaqueLines) { char *p; if (LineCount <= 0) { char OutPath[256]; sprintf(OutPath, DestaqFilesPath, LangCode); fpo = fopen(OutPath, "at"); if (!fpo) { fprintf(stderr, "Could not open output file %s, errno=%d\n", OutPath, errno); perror(NULL); DestaqueLines = LineCount = 0; continue; } } p = buffr; while (1) { CorrHyprlink(p, (sizeof buffr) - (p - buffr), htmlpath); p = strcasestr(p, Href); if (!p) { break; } else { p++; } } CorrImaglink(buffr, (sizeof buffr), htmlpath); LineCount++; fprintf(fpo, "%s", buffr); } if ((p = strstr(buffr, MarkeringStop)) != NULL) { DestaqueLines = 0; if (fpo) { fprintf(fpo, "

%s

\n\n
\n\n", htmlpath, h1[0] ? h1 : title); fclose(fpo); fpo = NULL; } } } if (DestaqueLines) { /* This means an end-of-file was encountered in an HTML file, although the current block of featured text had not been terminated yet. In an output file that causes two
's with just one MarkeringStart in between. Signal that situation to stderr so it can be detected and corrected. */ fprintf(stderr, "Unterminated feature block in file %s\n", htmlpath); } if (hfp) fclose (hfp); if (fpo) fclose(fpo); return 0; } /* Remove any tags from the string, overwriting them with spaces */ static void BlankOutTags (char *s, int len) { char *p; int intag = 0; for (p = s; p < s + len && *p; p++) { if (*p == '<') intag = 1; else if (*p == '>') { /* Wipe last */ *p = ' '; intag = 0; } if (intag) *p = ' '; } } static void CorrHyprlink (char *s, int len, char *htmlpath) { char *p, *q; int l; char *TargetTop = " target=_top "; /* Leave lines without a hyperlink untouched */ if ((p = strcasestr(s, Href)) == NULL) return; /* Add target=_top, so the resulting link will also work properly in a framed environment */ /* 22 July 2025: disabled this, as most links now have a target already, and duplicate targets are incorrect. */ #if 0 l = strlen(TargetTop); memmove(p + l, p, s + len - p - l); memcpy(p, TargetTop, l); #endif /* If the hyperlink is absolute (i.e., to an external site) no further action is necessary */ p = strcasestr(s, Href); if ((q = strstr(p, "://")) != NULL && q - p < 13) { return; } /* Expand file local hyperlinks */ p += strlen(Href) + 1; if (*p == '#') { l = strlen(htmlpath); memmove(p + l + 1, p, s + len - p - l - 1); memcpy(p + 1, htmlpath, l); memcpy(p, ".", 1); return; } /* Add a prefix to the path, so it works also from a different directory level. */ p = strcasestr(s, Href); p += strlen(Href) + 1; q = strrchr(htmlpath, '/'); if (!p || !q) return; l = q + 1 - htmlpath; memmove(p + l + 1, p, s + len - p - l - 1); memcpy(p + 1, htmlpath, l); memcpy(p, ".", 1); } /* The following function added 20 February 2013 */ static void CorrImaglink (char *s, int len, char *htmlpath) { char *p, *q; int l; char *Imag = "