summaryrefslogtreecommitdiff
path: root/fsstnd/dhelp_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'fsstnd/dhelp_parse.c')
-rw-r--r--fsstnd/dhelp_parse.c808
1 files changed, 808 insertions, 0 deletions
diff --git a/fsstnd/dhelp_parse.c b/fsstnd/dhelp_parse.c
new file mode 100644
index 0000000..8bb57e0
--- /dev/null
+++ b/fsstnd/dhelp_parse.c
@@ -0,0 +1,808 @@
+/* ********************************************************************
+ *** dhelp ***
+ *** Debian online help system ***
+ ********************************************************************
+ *** Copyright (c) 1997-99 by Marco Budde (Budde@tu-harburg.de) ***
+ *** GNU GPL license ***
+ ******************************************************************** */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
+ #include <db1/db.h>
+#else
+ #include <db.h>
+#endif
+
+
+#define DOCDIR "/usr/doc"
+#define INDEXROOT "/usr/doc/HTML2"
+#define DBNAME "/var/lib/dhelp/dbase_fsstnd"
+#define DBTITLE_NAME "/var/lib/dhelp/titles_fsstnd"
+
+
+typedef struct
+{
+ char dir[100]; /* section name */
+ char dtitle[100]; /* description of a section */
+ char name[50]; /* linkname */
+ char file[100]; /* name of a HTML file */
+ char descrip[1000]; /* description of item */
+} tItem;
+
+
+/* ************************************
+ * Eingabe: String *
+ * Ausgabe: Anzahl von / im String *
+ ************************************ */
+
+int strcnt (const char *s)
+{
+ int i=0;
+
+ for ( ; *s!='\0'; s++)
+ if (*s == '/')
+ i++;
+ return i;
+}
+
+
+/* *******************************
+ * strdel: Ersetzt \n durch \0 *
+ ******************************* */
+
+void strdel (char *s)
+{
+ for ( ; *s!='\n'; s++);
+ *s = '\0';
+}
+
+
+/* ************************************
+ * strpart: liefert Teilpfad aus in *
+ ************************************ */
+
+void strpart (const char *in, char *out)
+{
+ for ( ; (*in!='\0')&&(*in!='/'); in++, out++)
+ *out = *in;
+ if (*in == '/')
+ *out++ = *in++;
+ *out++='\0'; /* richtig ? */
+}
+
+
+/* ------------------------------------------------------------- */
+
+char *path_index_cwd (char *buf)
+{
+ char cwd[MAXPATHLEN];
+ char *cwd_ptr;
+ char resolv_name[MAXPATHLEN];
+
+ realpath (INDEXROOT, resolv_name);
+ cwd_ptr = getcwd (cwd, sizeof (cwd)) + strlen (resolv_name);
+ if (strlen (cwd_ptr) > 0)
+ cwd_ptr++;
+ strcpy (buf, cwd_ptr);
+
+ return (buf);
+}
+
+
+char *path_relative (char *buf)
+{
+ char cwd[MAXPATHLEN];
+ int i;
+
+ path_index_cwd (cwd);
+ buf[0] = '\0';
+ if (strlen (cwd) != 0)
+ for (i = 1; i < (strcnt (cwd) + 3); i++)
+ strcat (buf, "../");
+ else
+ strcpy (buf, "../");
+ return (buf);
+}
+
+
+void rm_r (char *dirname)
+{
+ DIR *dir;
+ struct dirent *dir_entry;
+ struct stat buf;
+ char zw[MAXPATHLEN];
+
+ if ((dir = opendir (dirname)) == NULL)
+ return;
+
+ while ((dir_entry = readdir (dir)) != NULL)
+ {
+ if (strcmp (dir_entry->d_name, ".") != 0
+ && (strcmp (dir_entry->d_name, "..") != 0))
+ {
+ strcpy (zw, dirname);
+ strcat (zw, "/");
+ strcat (zw, dir_entry->d_name);
+ stat (zw, &buf);
+ if (S_ISDIR (buf.st_mode))
+ {
+ rm_r (zw); /* Unterverzeichnisse loeschen */
+ rmdir (zw);
+ }
+ else
+ remove (zw);
+ }
+ }
+
+ closedir (dir);
+}
+
+/* --------------------------------------------------------------- */
+
+
+DB *db_title_open (int flags)
+{
+ HASHINFO hash;
+
+ #ifdef __alpha__
+ hash.bsize = 512;
+ #else
+ hash.bsize = 256;
+ #endif
+ hash.ffactor = 8;
+ hash.nelem = 1;
+ hash.cachesize = 5000;
+ hash.hash = NULL;
+ hash.lorder = 0;
+
+ return (dbopen (DBTITLE_NAME, flags, 0644, DB_HASH, &hash));
+}
+
+int db_title_write (DB *db, tItem *item)
+{
+ DBT key, data;
+
+ key.data = item->dir;
+ key.size = strlen (item->dir) + 1;
+ data.data = item->dtitle;
+ data.size = strlen (item->dtitle) + 1;
+
+ return ((db->put)(db, &key, &data, 0));
+}
+
+int db_title_read (DB *db, char *dir, char *title, int size)
+{
+ DBT key, data;
+ int i;
+
+ key.data = dir;
+ key.size = strlen (dir) + 1;
+
+ i = ((db->get)(db, &key, &data, 0));
+
+ switch (i)
+ {
+ case 0 : strncpy (title, data.data, size);
+ break;
+ case 1 : strcpy (title, "");
+ }
+
+ return (i);
+}
+
+
+/* ---------------------------------------------------------------- */
+
+typedef struct
+{
+ char file[100];
+ char dir[100];
+ char name[50];
+} tkey_data;
+
+int db_compare (const DBT *key1, const DBT *key2)
+{
+ /* Ueberprueft, ob key1 groesser, kleiner oder gleich key2 ist */
+
+ /* muss wahrscheinlich geaendert werden! fidogate/ entfernen vor
+ Vergleich */
+
+ tkey_data *data1, *data2;
+ int i;
+
+ data1 = key1->data;
+ data2 = key2->data;
+
+ i = strcmp (data1->dir, data2->dir); /* sortieren nach dir */
+ if (i == 0)
+ return (strcmp (data1->name, data2->name)); /* sortieren nach name */
+ else
+ return (i);
+}
+
+DB* db_open (int flags)
+{
+ /* Oeffnet die Datenbank */
+
+ BTREEINFO btree;
+
+ btree.flags = 0;
+ btree.cachesize = 10000;
+ btree.minkeypage = 0;
+ btree.psize = 0;
+ btree.compare = (int (*)(const DBT *, const DBT *))(db_compare);
+ /* aendern!!! */
+ btree.prefix = NULL;
+ btree.lorder = 0;
+
+ return (dbopen (DBNAME, flags, 0644, DB_BTREE, &btree));
+}
+
+int db_write (DB *db, tItem *item)
+{
+ /* speichert einen dhelp Eintrag (item) in die Datenbank */
+
+ DBT key, data;
+ tkey_data key_data;
+
+ strcpy (key_data.file, item->file);
+ strcpy (key_data.dir, item->dir);
+ strcpy (key_data.name, item->name);
+
+ key.data = &key_data;
+ key.size = sizeof (key_data);
+ data.data = item->descrip; /* ohne & richtig? */
+ data.size = sizeof (item->descrip);
+ return ((db->put)(db, &key, &data, 0));
+}
+
+
+int db_read (DB *db, tItem *item)
+{
+ /* holt einen dhelp Eintrag aus der Datenbank */
+
+ DBT key, data;
+ tkey_data *key_data;
+ int i;
+
+ i = (db->seq)(db, &key, &data, R_NEXT);
+
+ if (i == 0)
+ {
+ key_data = key.data;
+ strcpy (item->file, key_data->file);
+ strcpy (item->dir, key_data->dir);
+ strcpy (item->name, key_data->name);
+ strcpy (item->descrip, data.data);
+ }
+
+ return (i);
+}
+
+int db_del (DB *db, tItem *item)
+{
+ DBT key;
+ tkey_data key_data;
+
+ strcpy (key_data.file, item->file);
+ strcpy (key_data.dir, item->dir);
+ strcpy (key_data.name, item->name);
+
+ key.data = &key_data;
+ key.size = sizeof (key_data);
+
+ return ((db->del)(db, &key, 0));
+}
+
+/* --------------------------------------------------------------- */
+
+void html_error (FILE *out)
+{
+ if (ferror (out) != 0)
+ {
+ fprintf (stderr, "dhelp_parse: can't write index.html\n");
+ exit (1);
+ }
+}
+
+
+void html_w_head (FILE *out, DB *tdb)
+{
+ char zw[MAXPATHLEN], zw2[100];
+ char cwd[MAXPATHLEN];
+
+ clearerr (out);
+
+ path_index_cwd (cwd);
+ db_title_read (tdb, cwd, zw2, sizeof (zw));
+ fprintf (out, "<HTML>\n\n<HEAD>\n<TITLE>%s</TITLE>\n"
+ "<LINK REV=made HREF=\"mailto:Budde@tu-harburg.de\">\n"
+ "</HEAD>\n\n", zw2);
+ fprintf (out, "<BODY BGCOLOR=#FFFFFF>\n");
+
+ path_relative (zw);
+ strcat (zw, "dhelp/debian.jpg");
+ fprintf (out, "<IMG SRC=\"%s\" ALT=\"Debian GNU/Linux\"> \n", zw);
+ fprintf (out, "<H1>%s</H1>\n<P>\n", zw2);
+ fprintf (out, "<DL>\n");
+
+ html_error (out);
+}
+
+
+void html_w_tail (FILE *out)
+{
+ char cwd[MAXPATHLEN];
+ int lang = 5;
+ char *language[] = { "", "de/", "da/", "it/", "es/", "fr/" };
+ char *search[] = { "Search", "Suche", "Søg", "Ricerca", "Buscar",
+ "Rechercher" };
+ char *info[] = { "info documents", "info Dokumente", "info dokumenter",
+ "documenti info", "documentos info", "Pages info" };
+ char *man[] = { "man pages", "Handbücher", "manual", "pagine di manuale",
+ "páginas de manual", "Pages de manuel" };
+ char *other[] = { "other documents", "andere Dokumente", "andre dokumenter",
+ "altri documenti", "Otros documentos",
+ "Autres documents" };
+ int i;
+
+ clearerr (out);
+
+ path_index_cwd (cwd); /* get language */
+ strcat (cwd, "/");
+ for (i=0; i <= lang; i++)
+ if (!strncmp (cwd, language[i], 3))
+ break;
+ if (i > lang)
+ i = 0;
+
+ fprintf (out, "</DL>\n");
+ fprintf (out, "<P>\n<CENTER>\n"
+ "<FORM ACTION=\"/cgi-bin/dsearch\">\n"
+ "<INPUT TYPE=\"text\" NAME=\"search\">\n"
+ "<INPUT TYPE=\"submit\" VALUE=\"%s\">\n"
+ "</FORM><BR>\n"
+ "[ <A HREF=\"/cgi-bin/info2www\">%s</A> | \n"
+ "<A HREF=\"/cgi-bin/man2html\">%s</A> | \n"
+ "<A HREF=\"/doc/\">%s</A> ]\n</CENTER>\n",
+ search[i], info[i], man[i], other[i]);
+ fprintf (out, "</BODY></HTML>\n");
+
+ html_error (out);
+}
+
+
+void html_w_item (tItem *item, FILE *out)
+{
+ char zw[MAXPATHLEN];
+
+ clearerr (out);
+
+ path_relative (zw);
+ fprintf (out, "<DT><IMG SRC=\"%sdhelp/text.gif\">"
+ " <A HREF=\"%s%s\"><FONT FACE=\"Helvetica, Arial\">"
+ "<B>%s</B></FONT></A><P></DT>\n"
+ " <DD>%s</DD>\n\n",
+ zw, zw, item->file, item->name, item->descrip);
+
+ html_error (out);
+}
+
+
+int html_w_item_links (DB *db, DB *tdb, tItem *item)
+{
+ char cwd[MAXPATHLEN];
+ char dir[MAXPATHLEN], *dir_ptr;
+ FILE *out;
+
+ path_index_cwd (cwd);
+ dir_ptr = item->dir; /* richtig ? */
+ while (strcmp (cwd, item->dir))
+ {
+ strpart (dir_ptr, dir);
+ dir_ptr += strlen (dir);
+ mkdir (dir, 0755);
+ chdir (dir);
+ path_index_cwd (cwd);
+ }
+
+ if ((out = fopen ("index.html", "w")) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open index.html\n\n");
+ exit (1);
+ }
+
+ html_w_head (out, tdb);
+ do
+ {
+ strcpy (dir, item->dir);
+ html_w_item (item, out);
+ if ((db_read (db, item)) != 0)
+ {
+ fclose (out);
+ return (1);
+ }
+ }
+ while (!strcmp (dir, item->dir));
+ fclose (out);
+
+ return (0);
+}
+
+
+int html_w_dir_links (char *dirname, DB *tdb)
+{
+ DIR *dir;
+ FILE *out;
+ struct dirent *dir_entry;
+ struct stat buf;
+ char zw[MAXPATHLEN];
+ char relpath[MAXPATHLEN];
+
+ strcpy (zw, dirname);
+ strcat (zw, "/index.html");
+
+ chdir (dirname); /* ??? */
+
+ if ((out = fopen (zw, "r")) == NULL) /* existiert index.html bereits? */
+ {
+ if ((out = fopen (zw, "w")) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open %s\n", zw);
+ return (1);
+ }
+ html_w_head (out, tdb);
+ }
+ else
+ {
+ fclose (out);
+ if ((out = fopen (zw, "a")) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open %s\n", zw);
+ return (1);
+ }
+ }
+ dir = opendir (dirname);
+
+ while ((dir_entry = readdir (dir)) != NULL)
+ {
+ if (strcmp (dir_entry->d_name, ".") != 0
+ && strcmp (dir_entry->d_name, "..") != 0)
+ {
+ strcpy (zw, dirname);
+ strcat (zw, "/");
+ strcat (zw, dir_entry->d_name);
+ stat (zw, &buf);
+ if (S_ISDIR (buf.st_mode))
+ {
+ path_relative (relpath);
+ fprintf (out, "<DT><IMG SRC=\"%sdhelp/folder.gif\">"
+ " <A HREF=\"%s/index.html\">"
+ "<FONT FACE=\"Helvetica, Arial\"><B>%s/</B></FONT>"
+ "</A></DT>\n"
+ " <DD></DD>\n\n",
+ relpath, dir_entry->d_name, dir_entry->d_name);
+ if (html_w_dir_links (zw, tdb))
+ {
+ fclose (out);
+ return (1);
+ }
+ chdir (".."); /* ??? */
+ }
+ }
+ }
+ html_w_tail (out);
+
+ fclose (out);
+ closedir (dir);
+ return (0);
+}
+
+
+void html_write (void)
+{
+ tItem item;
+ DB *db, *tdb;
+ int i;
+ FILE *out;
+
+ if ((db = db_open (O_RDONLY)) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open %s\n\n", DBNAME);
+ exit (0);
+ }
+ if ((tdb = db_title_open (O_RDONLY)) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open %s\n\n", DBTITLE_NAME);
+ exit (0);
+ }
+
+ rm_r (INDEXROOT);
+ mkdir (INDEXROOT, 0755);
+ chdir (INDEXROOT); /* usr/doc/HTML */
+
+ if ((out = fopen ("README", "w")) != NULL)
+ {
+ fprintf (out, "\nDon't put files in this directory!\n"
+ "dhelp will delete *all* files in this directory "
+ "when creating a new index.\n\n"
+ "Marco Budde (budde@debian.org)\n\n");
+ fclose (out);
+ }
+
+ db_read (db, &item);
+ do
+ {
+ i = html_w_item_links (db, tdb, &item);
+ chdir (INDEXROOT);
+ }
+ while (i == 0);
+
+ if (html_w_dir_links (INDEXROOT, tdb))
+ {
+ fprintf (stderr, "dhelp_parse: can't write index\n");
+ exit (1);
+ }
+
+ db->close (db); /* ??? */
+ tdb->close (tdb); /* ??? */
+}
+
+
+/* --------------------------------------------------------------- */
+
+
+
+int get_item (FILE *fd, char *filename, tItem *item)
+{
+ char zw[200];
+ int cnt = 0;
+
+ item->descrip[0]='\0';
+ item->dtitle[0]='\0';
+ item->file[0]='\0';
+
+ /* <item> == Start suchen */
+ do
+ if ((fgets (zw, sizeof(zw), fd)) == NULL)
+ return 1;
+ while (strncmp ("<item>", zw, 6) != 0);
+
+ /* Daten eines <item> parsen */
+ do
+ {
+ if ((fgets (zw, sizeof(zw), fd)) == NULL)
+ return 1;
+ if (strncmp ("<directory>", zw, 11) == 0)
+ {
+ strncpy (item->dir, zw+11, sizeof (item->dir));
+ item->dir[sizeof(item->dir)-1] = '\0';
+ strdel (item->dir);
+ }
+ if (strncmp ("<dirtitle>", zw, 10) == 0)
+ {
+ strncpy (item->dtitle, zw+10, sizeof (item->dtitle));
+ item->dtitle[sizeof(item->dtitle)-1] = '\0';
+ strdel (item->dtitle);
+ }
+ if (strncmp ("<linkname>", zw, 10) == 0)
+ {
+ strncpy (item->name, zw+10, sizeof (item->name));
+ item->name[sizeof(item->name)-1] = '\0';
+ strdel (item->name);
+ }
+ if (strncmp ("<filename>", zw, 10) == 0)
+ {
+ strcpy (item->file, filename); /* Verzeichnisname */
+ strncat (item->file, zw+10, sizeof (item->file) - strlen (filename));
+ item->file[sizeof(item->file)-1] = '\0';
+ strdel (item->file);
+ }
+ if (strncmp ("<description>", zw, 13) == 0)
+ {
+ fgets (zw, sizeof(zw), fd);
+ while (strncmp ("</description>", zw, 14) != 0)
+ {
+ cnt = cnt + strlen (zw);
+ if (cnt < sizeof (item->descrip))
+ {
+ strcat (item->descrip, zw);
+ item->descrip[sizeof(item->descrip)-1] = '\0';
+ }
+ if ((fgets (zw, sizeof(zw), fd)) == NULL)
+ return 1;
+ }
+ }
+ }
+ while (strncmp ("</item>", zw, 7) != 0);
+
+ return 0;
+}
+
+
+int dhelp_add (char *name)
+{
+ FILE *in;
+ tItem item;
+ DB *db, *db_title;
+ char *file_ptr;
+ char resolv_docdir[MAXPATHLEN];
+
+ if ((in = fopen (name, "r")) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open %s\n\n", name);
+ return (1);
+ }
+ if ((db = db_open (O_RDWR|O_CREAT)) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open %s\n\n", DBNAME);
+ return (1);
+ }
+ if ((db_title = db_title_open (O_RDWR|O_CREAT)) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open %s\n\n", DBTITLE_NAME);
+ return (1);
+ }
+
+ /* relativen Pfad zum Dokument erzeugen */
+
+ realpath (DOCDIR, resolv_docdir);
+ file_ptr = name;
+ file_ptr += strlen (resolv_docdir);
+ file_ptr++;
+ file_ptr [strlen(file_ptr)-6] = '\0';
+
+ while (!(get_item (in, file_ptr, &item)))
+ {
+ if (item.file[0] != '\0')
+ db_write (db, &item);
+ if (item.dtitle[0] != '\0')
+ db_title_write (db_title, &item);
+ }
+
+ fclose (in);
+ db->close (db);
+ db_title->close (db_title);
+
+ return (0);
+}
+
+
+int dhelp_del (char *name)
+{
+ FILE *in;
+ tItem item;
+ DB *db;
+ char *file_ptr;
+ char resolv_docdir[MAXPATHLEN];
+
+ if ((in = fopen (name, "r")) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open %s\n\n", name);
+ return (1);
+ }
+ if ((db = db_open (O_RDWR|O_CREAT)) == NULL)
+ {
+ fprintf (stderr, "dhelp_parse: can't open %s\n\n", DBNAME);
+ return (1);
+ }
+
+ /* relativen Pfad zum Dokument erzeugen */
+
+ realpath (DOCDIR, resolv_docdir);
+ file_ptr = name;
+ file_ptr += strlen (resolv_docdir);
+ file_ptr++;
+ file_ptr [strlen(file_ptr)-6] = '\0';
+
+ while (!(get_item (in, file_ptr, &item)))
+ db_del (db, &item);
+
+ fclose (in);
+ db->close (db);
+
+ return (0);
+}
+
+
+void dhelp_add_rec (char *dirname)
+{
+ DIR *dir;
+ struct dirent *dir_entry;
+ struct stat buf;
+ char zw[MAXPATHLEN];
+
+ dir = opendir (dirname);
+
+ while ((dir_entry = readdir (dir)) != NULL)
+ {
+ if ((strcmp (dir_entry->d_name, ".") != 0)
+ && (strcmp (dir_entry->d_name, "..") != 0))
+ {
+ strcpy (zw, dirname);
+ strcat (zw, "/");
+ strcat (zw, dir_entry->d_name);
+ lstat (zw, &buf);
+ if (S_ISDIR (buf.st_mode))
+ dhelp_add_rec (zw);
+ else
+ if (!strcmp (dir_entry->d_name, ".dhelp"))
+ dhelp_add (zw);
+ }
+ }
+
+ closedir (dir);
+}
+
+/* -------------------------------------------------------------- */
+
+void help (void)
+{
+ printf ("\nUsage: dhelp_parse <option> <directories>\n\n");
+ printf ("-a add dhelp file in <directories>\n");
+ printf ("-d del dhelp file in <directories>\n");
+ printf ("-r index all dhelp files in %s\n\n", DOCDIR);
+}
+
+
+int main (int argc, char *argv[])
+{
+ int i;
+ char zw[MAXPATHLEN];
+ char resolv_name[MAXPATHLEN];
+
+ if ((argc < 2) || (strlen (argv[1]) != 2) || (argv[1][0] != '-'))
+ {
+ help();
+ return (1);
+ }
+
+ if (!strcmp (argv[1], "-r"))
+ {
+ remove (DBNAME); /* loesche db, um alte/falsche Eintraege
+ zu loeschen */
+ realpath (DOCDIR, resolv_name);
+ dhelp_add_rec (resolv_name);
+ }
+ else
+ {
+ mkdir ("/var/lib/dhelp/", 0755);
+ for (i=2; i < argc; i++)
+ {
+ if (!strncmp (argv[i], DOCDIR, strlen (DOCDIR)))
+ {
+ strcpy (zw, argv[i]);
+ strcat (zw, "/.dhelp");
+ realpath (zw, resolv_name);
+ switch (argv[1][1])
+ {
+ case 'a': dhelp_add (resolv_name);
+ break;
+ case 'd': dhelp_del (resolv_name);
+ break;
+ default: help ();
+ }
+ }
+ else
+ {
+ fprintf (stderr, "dhelp_parse: You can add only directories "
+ "under %s!\n\n", DOCDIR);
+ return (1);
+ }
+ }
+ }
+
+ html_write ();
+
+ return (0);
+}