GRASS Programmer's Manual
6.4.2(2012)
|
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 }