diff options
Diffstat (limited to 'fsstnd/dhelp_parse.c')
-rw-r--r-- | fsstnd/dhelp_parse.c | 808 |
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); +} |