GRASS Programmer's Manual  6.4.2(2012)
reg_html.c
Go to the documentation of this file.
00001 
00002 /***************************************************************************
00003  *            reg_html.c
00004  *
00005  *  Fri May 20 18:14:32 2005
00006  *  Copyright  2005  User
00007  *  Email
00008  ****************************************************************************/
00009 
00010 /*
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program; if not, write to the Free Software
00023  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00024  */
00025 
00026 
00027 #include "globals.h"
00028 
00029 void new_ext_html(char *ext, char *gisbase, char **html, int major, int minor,
00030                   int revision)
00031 {
00032     int pos1, pos2, pos3;
00033     int start, end;
00034     int insert_here;
00035     char *first_char;
00036     char *last_char;
00037     char item[MAXSTR];
00038     int len;
00039 
00040     pos1 = find_pos("<b>Drivers sections:</b>", html, 0);       /* first go to section on "Drivers" */
00041     if (pos1 < 0) {
00042         /* we have a new version of the HTML docs that does not have a "Drivers" section anymore */
00043         /* let's check for the special GEM comment */
00044         pos1 =
00045             find_pos
00046             ("<!-- GEM Extensions StartHTML. Do not delete or change this comment! -->",
00047              html, 0);
00048         if (pos1 < 0) {
00049             /* sorry, I can't handle these HTML docs */
00050             print_warning
00051                 ("Unknown format of index.html. Unable to register HTML man pages.\n");
00052             return;
00053         }
00054     }
00055     pos2 = find_pos("<hr>", html, pos1);        /* the horizontal ruler marks the end of the HTML text */
00056     if (find_pos("<h3>Installed extensions:</h3>", html, pos1) == -1) {
00057         /* Extensions section does not yet exist: create it now */
00058         insert_str("<h3>Installed extensions:</h3>\n", pos2, html);
00059         insert_str("<ul>\n", pos2 + 1, html);
00060         insert_str("</ul>\n", pos2 + 2, html);
00061         insert_str("<p>\n", pos2 + 3, html);
00062     }
00063 
00064     start = find_pos("<h3>Installed extensions:</h3>", html, pos1);
00065     end = find_pos("</ul>", html, start);
00066     insert_here = start + 2;
00067     /* check if this entry already exists and if so: bail out or overwrite, if force mode */
00068     sprintf(item, "\">%s", ext);
00069     pos3 = find_pos(item, html, insert_here);
00070     if (pos3 != -1) {
00071         /* exists:  */
00072         print_warning("list item '%s' exists in index.html.\n", ext);
00073         if ((FORCE) && (UPGRADE)) {
00074             sprintf(item,
00075                     "<li><a href=\"../extensions/%s/index.html\">%s (%i.%i.%i)</a>\n",
00076                     ext, ext, major, minor, revision);
00077             strcpy(html[pos3], item);
00078         }
00079         return;
00080     }
00081 
00082     /* now go through all links in the Extensions section and insert this one in the right
00083        alphabetical position */
00084     pos3 = find_pos("<li><a href=", html, start);
00085     while ((pos3 != -1) && (pos3 < end)) {
00086         /* extract name of extension at this position */
00087         first_char = strrchr(html[pos3], '"');
00088         last_char = strrchr(html[pos3], '<');
00089         len = (last_char - first_char) / sizeof(char);
00090         strncpy(item, first_char + 2 * sizeof(char), len);
00091         item[len - 1] = '\0';   /* get rid of '<' */
00092         if (strcmp(ext, item) < 0) {
00093             insert_here = pos3;
00094             break;              /* found our position: let's quit this! */
00095         }
00096         /* look for next item */
00097         start++;
00098         pos3 = find_pos("<li><a href=", html, start);
00099     }
00100 
00101     /* now insert new entry for this extension */
00102     sprintf(item,
00103             "<li><a href=\"../extensions/%s/index.html\">%s (%i.%i.%i)</a>\n",
00104             ext, ext, major, minor, revision);
00105     insert_str(item, insert_here, html);
00106 
00107 }
00108 
00109 
00110 void delete_ext_html(char *ext, char *gisbase, char **html)
00111 {
00112     int pos1, pos2, pos3;
00113     int start, end;
00114     char item[MAXSTR];
00115     int found;
00116     int i;
00117 
00118     pos1 = find_pos("<b>Drivers sections:</b>", html, 0);       /* first go to section on "Drivers" */
00119     if (pos1 < 0) {
00120         /* we have a new version of the HTML docs that does not have a "Drivers" section anymore */
00121         /* let's check for the special GEM comment */
00122         pos1 =
00123             find_pos
00124             ("<!-- GEM Extensions StartHTML. Do not delete or change this comment! -->",
00125              html, 0);
00126         if (pos1 < 0) {
00127             /* sorry, I can't handle these HTML docs */
00128             print_warning
00129                 ("Unknown format of index.html. Unable to de-register HTML man pages.\n");
00130             return;
00131         }
00132     }
00133 
00134     pos2 = find_pos("<hr>", html, pos1);        /* the horizontal ruler marks the end of the HTML text */
00135     if (find_pos("<h3>Installed extensions:</h3>", html, pos1) == -1) {
00136         /* Extensions section does not exist: bail out! */
00137         print_warning("no extensions section found in index.html.\n");
00138         return;
00139     }
00140 
00141     start = find_pos("<h3>Installed extensions:</h3>", html, pos1);
00142     end = find_pos("</ul>", html, start);
00143     /* check if the entry exists and if so delete */
00144     found = 0;
00145     sprintf(item, "\">%s", ext);
00146     pos3 = find_pos(item, html, start);
00147     if (pos3 == -1) {
00148         /* does not exist: */
00149         print_warning("extension '%s' not listed in index.html.\n", ext);
00150         return;
00151     }
00152 
00153     /* delete item, if it was found in the extensions section */
00154     if (pos3 < end) {
00155         delete_str(pos3, html);
00156     }
00157     end--;                      /* end of extensions section is no one up! */
00158 
00159     /* if no more entries left in the extensions list: delete the entire section */
00160     pos3 = find_pos("<ul>", html, start);
00161     if ((pos3 != -1) && (end > pos3) && (end - pos3 < 2)) {
00162         for (i = 0; i < 4; i++) {
00163             delete_str(pos3 - 1, html);
00164         }
00165     }
00166 }
00167 
00168 
00169 void register_html(char *pkg_short_name, char *gisbase, int major, int minor,
00170                    int revision)
00171 {
00172 
00173     char file[MAXSTR];
00174     char str[MAXSTR];
00175     char **line;
00176     int n_lines, i;
00177     FILE *f_in, *f_out;
00178 
00179     /* check if index.html exists and is readable */
00180     sprintf(file, "%s/docs/html/index.html", gisbase);
00181     f_in = fopen(file, "r");
00182     if (f_in == NULL) {
00183         if (errno == ENOENT) {
00184             /* file does not exist */
00185             return;
00186         }
00187         else {
00188             /* sth. strange happened */
00189             fclose(f_in);
00190             print_error(ERR_REGISTER_HTML, "checking for file '%s': %s\n",
00191                         file, strerror(errno));
00192         }
00193     }
00194 
00195     /* create a temporary index.html copy for write access */
00196     /* TODO: Do not hardcode temp paths */
00197     strcpy(TMP_HTML, "/tmp/grass.extensions.db.XXXXXX");        /* TMP_HTML is a global variable */
00198     mkstemp(TMP_HTML);
00199 
00200     f_out = fopen(TMP_HTML, "w+");
00201     if (f_out == NULL) {
00202         print_error(ERR_REGISTER_HTML,
00203                     "could not create temp file '%s': %s\n \
00204                 Make sure that directory /tmp exists on your system and you have write permission.\n", TMP_HTML, strerror(errno));
00205     }
00206 
00207     atexit(&exit_db);           /* now need to register an at exit func to remove tmpdb automatically! */
00208 
00209     /* everything fine: create a shell command to install HTML stuff */
00210     if (VERBOSE) {
00211         sprintf(str,
00212                 "cp -vf %s %s/docs/html/index.html ; chmod -v a+r %s/docs/html/index.html ;",
00213                 TMP_HTML, gisbase, gisbase);
00214     }
00215     else {
00216         sprintf(str,
00217                 "cp -f %s %s/docs/html/index.html &>%s ; chmod a+r %s/docs/html/index.html &>%s ;",
00218                 TMP_HTML, gisbase, TMP_NULL, gisbase, TMP_NULL);
00219     }
00220     strcpy(HTML_CMD, str);
00221 
00222     /* count number of lines in index.html */
00223     n_lines = 0;
00224     while (fgets(str, MAXSTR, f_in) != NULL) {
00225         n_lines++;
00226     }
00227     if (n_lines == 0) {
00228         return;
00229     }
00230     rewind(f_in);
00231 
00232     /* create an array large enough to hold all lines in index.html */
00233     /* plus the entries that are to be added for the extension */
00234     /* plus one NULL terminator */
00235     /* and copy all lines from index.html into this */
00236     line = (char **)calloc(n_lines + 10, sizeof(char *));
00237     for (i = 0; i < (n_lines + 10); i++) {
00238         line[i] = NULL;
00239     }
00240     i = 0;
00241     while (fgets(str, MAXSTR, f_in) != NULL) {
00242         line[i] = (char *)malloc((1 + strlen(str)) * sizeof(char));
00243         strcpy(line[i], str);
00244         i++;
00245     }
00246 
00247     /* create "Extensions" entry in html document if necessary and add a link to */
00248     /* this extension's HTML man index */
00249     new_ext_html(pkg_short_name, gisbase, line, major, minor, revision);
00250 
00251     /* write output to tmpfile */
00252     i = 0;
00253     while (line[i] != NULL) {
00254         fprintf(f_out, line[i]);
00255         i++;
00256     }
00257     fflush(f_out);
00258 
00259     /* close files */
00260     fclose(f_in);
00261     fclose(f_out);
00262 
00263     /* free memory */
00264     for (i = 0; i < (n_lines + 10); i++) {
00265         free(line[i]);
00266     }
00267     free(line);
00268 }
00269 
00270 
00271 void deregister_html(char *pkg_short_name, char *gisbase)
00272 {
00273 
00274     char file[MAXSTR];
00275     char str[MAXSTR];
00276     char **line;
00277     int n_lines, i;
00278     FILE *f_in, *f_out;
00279 
00280     /* check if index.html exists and is readable */
00281     sprintf(file, "%s/docs/html/index.html", gisbase);
00282     f_in = fopen(file, "r");
00283     if (f_in == NULL) {
00284         if (errno == ENOENT) {
00285             /* file does not exist */
00286             return;
00287         }
00288         else {
00289             /* sth. strange happened */
00290             fclose(f_in);
00291             print_error(ERR_REGISTER_HTML, "checking for file '%s': %s\n",
00292                         file, strerror(errno));
00293         }
00294     }
00295 
00296     /* create a temporary index.html copy for write access */
00297     /* TODO: Do not hardcode temp paths */
00298     strcpy(TMP_HTML, "/tmp/grass.extensions.db.XXXXXX");        /* TMP_HTML is a global variable */
00299     mkstemp(TMP_HTML);
00300 
00301     f_out = fopen(TMP_HTML, "w+");
00302     if (f_out == NULL) {
00303         print_error(ERR_REGISTER_HTML,
00304                     "could not create temp file '%s': %s\n \
00305                 Make sure that directory /tmp exists on your system and you have write permission.\n", TMP_HTML, strerror(errno));
00306     }
00307 
00308     atexit(&exit_db);           /* now need to register an at exit func to remove tmpdb automatically! */
00309 
00310     /* everything fine: create a shell command to copy modified HTML stuff on uninstall */
00311     if (VERBOSE) {
00312         sprintf(str,
00313                 "cp -vf %s %s/docs/html/index.html ; chmod -v a+r %s/docs/html/index.html ;",
00314                 TMP_HTML, gisbase, gisbase);
00315     }
00316     else {
00317         sprintf(str,
00318                 "cp -f %s %s/docs/html/index.html &>%s ; chmod a+r %s/docs/html/index.html &>%s ;",
00319                 TMP_HTML, gisbase, TMP_NULL, gisbase, TMP_NULL);
00320     }
00321     strcpy(HTML_CMD, str);
00322 
00323 
00324     /* count number of lines in index.html */
00325     n_lines = 0;
00326     while (fgets(str, MAXSTR, f_in) != NULL) {
00327         n_lines++;
00328     }
00329     if (n_lines == 0) {
00330         return;
00331     }
00332     rewind(f_in);
00333 
00334     /* create an array large enough to hold all lines in index.html */
00335     /* plus one NULL terminator */
00336     /* and copy all lines from index.html into this */
00337     line = (char **)calloc(n_lines + 1, sizeof(char *));
00338     for (i = 0; i < (n_lines + 1); i++) {
00339         line[i] = NULL;
00340     }
00341     i = 0;
00342     while (fgets(str, MAXSTR, f_in) != NULL) {
00343         line[i] = (char *)malloc((1 + strlen(str)) * sizeof(char));
00344         strcpy(line[i], str);
00345         i++;
00346     }
00347 
00348     /* delete link to this extension's HTML manual from index.html */
00349     delete_ext_html(pkg_short_name, gisbase, line);
00350 
00351     /* write output to tmpfile */
00352     i = 0;
00353     while (line[i] != NULL) {
00354         fprintf(f_out, line[i]);
00355         i++;
00356     }
00357     fflush(f_out);
00358 
00359     /* close files */
00360     fclose(f_in);
00361     fclose(f_out);
00362 
00363     /* free memory */
00364     for (i = 0; i < (n_lines + 1); i++) {
00365         free(line[i]);
00366     }
00367     free(line);
00368 }
00369 
00370 
00371 /*
00372    Returns number of restored entries 
00373  */
00374 int restore_html(char *gisbase)
00375 {
00376     char str[MAXSTR];
00377     char idx[MAXSTR];
00378     char ext_idx[MAXSTR];
00379     char dir[MAXSTR];
00380     char subdir[MAXSTR];
00381     char **line;
00382     int n_entries, n_lines, i;
00383     FILE *f_in, *f_out, *f_ext;
00384     DIR *dirp;
00385     DIR *subdirp;
00386     struct dirent *ep;
00387     int num_restored;
00388     int n_subdirs;
00389     int major, minor, revision;
00390 
00391 
00392     /* check if index.html exists and is readable */
00393     sprintf(idx, "%s/docs/html/index.html", gisbase);
00394     f_in = fopen(idx, "r");
00395     if (f_in == NULL) {
00396         if (errno == ENOENT) {
00397             /* file does not exist */
00398             return (0);
00399         }
00400         else {
00401             /* sth. strange happened */
00402             fclose(f_in);
00403             print_error(ERR_REGISTER_HTML, "checking for file '%s': %s\n",
00404                         idx, strerror(errno));
00405         }
00406     }
00407 
00408     /* create a temporary index.html copy for write access */
00409     /* TODO: Do not hardcode temp paths */
00410     strcpy(TMP_HTML, "/tmp/grass.extensions.db.XXXXXX");        /* TMP_HTML is a global variable */
00411     mkstemp(TMP_HTML);
00412 
00413     f_out = fopen(TMP_HTML, "w+");
00414     if (f_out == NULL) {
00415         print_error(ERR_REGISTER_HTML,
00416                     "could not create temp file '%s': %s\n \
00417                 Make sure that directory /tmp exists on your system and you have write permission.\n", TMP_HTML, strerror(errno));
00418     }
00419 
00420     /* everything fine: create a shell command to install HTML stuff */
00421     if (VERBOSE) {
00422         sprintf(str,
00423                 "cp -vf %s %s/docs/html/index.html ; chmod -v a+r %s/docs/html/index.html ;",
00424                 TMP_HTML, gisbase, gisbase);
00425     }
00426     else {
00427         sprintf(str,
00428                 "cp -f %s %s/docs/html/index.html &>%s ; chmod a+r %s/docs/html/index.html &>%s ;",
00429                 TMP_HTML, gisbase, TMP_NULL, gisbase, TMP_NULL);
00430     }
00431     strcpy(HTML_CMD, str);
00432 
00433     atexit(&exit_db);           /* now need to register an at exit func to remove tmpdb automatically! */
00434 
00435     /* allocate a pointer to the directory structure */
00436     sprintf(dir, "%s/docs/extensions", gisbase);
00437     dirp = opendir(dir);
00438     if (dirp == NULL) {
00439         /* directory does not exist or is not accessible */
00440         return (0);
00441     }
00442 
00443     /* PASS 1 */
00444     /* count number of subdirs in docs/extensions/ each new link will require one entry in index.html */
00445     n_entries = 0;
00446     n_subdirs = 0;
00447     while ((ep = readdir(dirp))) {
00448         sprintf(subdir, "%s/%s", dir, ep->d_name);
00449         if ((!strcmp(ep->d_name, ".")) || (!strcmp(ep->d_name, ".."))) {
00450             continue;
00451         }
00452         subdirp = opendir(subdir);
00453         if (subdirp == NULL) {
00454             continue;
00455         }
00456         n_subdirs++;
00457         closedir(subdirp);
00458     }
00459     closedir(dirp);
00460 
00461     /* count number of lines in menu.tcl */
00462     n_lines = 0;
00463     while (fgets(str, MAXSTR, f_in) != NULL) {
00464         n_lines++;
00465     }
00466     if (n_lines == 0) {
00467         return (0);
00468     }
00469     rewind(f_in);
00470 
00471     /* create an array large enough to hold all lines in index.html */
00472     /* plus one new entry to make a link for each extension */
00473     /* plus space for the new Extensions section */
00474     /* plus one NULL terminator */
00475     /* and copy all lines from menu.tcl into this */
00476     line = (char **)calloc(n_lines + n_subdirs + 10, sizeof(char *));
00477     for (i = 0; i < (n_lines + n_subdirs + 10); i++) {
00478         line[i] = NULL;
00479     }
00480     i = 0;
00481     while (fgets(str, MAXSTR, f_in) != NULL) {
00482         line[i] = (char *)malloc((1 + strlen(str)) * sizeof(char));
00483         strcpy(line[i], str);
00484         i++;
00485     }
00486     line[i] = NULL;             /* add NULL terminator */
00487 
00488     /* PASS 2: re-create links if necessary */
00489     dirp = opendir(dir);
00490     num_restored = 0;
00491     while ((ep = readdir(dirp))) {
00492         sprintf(subdir, "%s/%s", dir, ep->d_name);
00493         if ((!strcmp(ep->d_name, ".")) || (!strcmp(ep->d_name, ".."))) {
00494             continue;
00495         }
00496         subdirp = opendir(subdir);
00497         if (subdirp == NULL) {
00498             continue;
00499         }
00500         closedir(subdirp);
00501 
00502         /* try to open extension's index.html file */
00503         sprintf(ext_idx, "%s/index.html", subdir);
00504         f_ext = fopen(ext_idx, "r");
00505         if (f_ext == NULL) {
00506             continue;           /* cannot access index.html: skip to next extension */
00507         }
00508         major = 0;
00509         minor = 0;
00510         revision = 0;
00511         /* retrieve version information from extension's index.html */
00512         i = 0;
00513         while (fgets(str, MAXSTR, f_ext) != NULL) {
00514             if (strstr(str, "<title>") != NULL) {
00515                 i = 1;
00516                 break;          /* this is the title line: that's all we need */
00517             }
00518         }
00519         if (i == 0) {
00520             continue;           /* not a valid index.html: skip to next extension */
00521         }
00522         sscanf(strchr(str, '(') + sizeof(char), "%i.%i.%i", &major, &minor,
00523                &revision);
00524         new_ext_html(ep->d_name, gisbase, line, major, minor, revision);
00525         num_restored++;
00526         fclose(f_ext);
00527     }
00528     closedir(dirp);
00529 
00530     /* write output to tmpfile */
00531     i = 0;
00532     while (line[i] != NULL) {
00533         fprintf(f_out, line[i]);
00534         i++;
00535     }
00536     fflush(f_out);
00537 
00538     /* close remaining files */
00539     fclose(f_in);
00540     fclose(f_out);
00541 
00542     /* free memory */
00543     for (i = 0; i < (n_lines + n_subdirs + 10); i++) {
00544         free(line[i]);
00545     }
00546     free(line);
00547 
00548     return (num_restored);
00549 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines