123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874 |
- /***************************************************************************
- * reg_entries.c
- *
- * Fri May 13 11:35:33 2005
- * Copyright 2005 User
- * Email
- ****************************************************************************/
- /*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- #include <dirent.h>
- #include "globals.h"
- int menu_created;
- /*
- Returns 1, if the string is a submenu item, 0 otherwise.
- Very primitive
- */
- int is_submenu(char *item)
- {
- if (strchr(item, '[') == NULL) {
- return (0);
- }
- if (strrchr(item, ']') == NULL) {
- return (0);
- }
- if (strchr(item, '[') > strrchr(item, ']')) {
- return (0);
- }
- return (1);
- }
- /*
- If "Extensions" menu does not yet exist, it will be created immediately
- to the left of the "Help" menu in GIS Manager's main menu bar.
- Returns the line nr after which the "Extension" menu entries should be
- inserted.
- */
- int check_ext_menu(char **tcl_lines)
- {
- int idx;
- /* check if "Extensions" menu exists */
- idx = find_pos("\"&Xtns\" all options 1", tcl_lines, 0);
- if (idx == -1) { /* does not exist: create a new one */
- idx = find_pos("\"&Help\" all options", tcl_lines, 0);
- if (idx == -1) { /* Help menu does not exist: place at far right */
- idx = find_pos("}]", tcl_lines, 0);
- if (idx == -1) {
- print_error(ERR_REGISTER_ENTRIES_GISMAN,
- "could not parse 'menu.tcl'.\n");
- }
- insert_str(" \"&Xtns\" all options 1 {\n", idx, tcl_lines);
- idx++;
- insert_str(" }\n", idx, tcl_lines);
- return (idx);
- }
- insert_str(" \"&Xtns\" all options 1 {\n", idx, tcl_lines);
- idx++;
- insert_str(" }\n", idx, tcl_lines);
- }
- return (idx);
- }
- /*
- Creates a new submenu for this extension under "Extensions" in GIS Managers
- main menu bar.
- Returns line no. of submenu, after which additional entries should be appended
- to menu.tcl.
- */
- int new_submenu(char *pkg_short_name, char *menu, char **tcl_lines)
- {
- char tmp[MAXSTR];
- char tmp2[MAXSTR];
- char searchstr[MAXSTR];
- int idx, idx2;
- int insert_here;
- int last;
- char *first_quote;
- char *second_quote;
- int len;
- int terminator;
- /* Store the position of the "Extensions" entry and start looking for submenu from there */
- idx = find_pos("\"&Xtns\" all options", tcl_lines, 0);
- last = find_pos("\" all options", tcl_lines, idx + 1) - 1; /* find end of "Extensions" menu */
- if (last == -1) {
- last = find_pos("}]", tcl_lines, 0); /* end of menu.tcl */
- }
- /* check if the line is a valid submenu specifier */
- if (!is_submenu(menu)) {
- print_warning
- ("first line not a submenu specifier in 'entries-gisman'.\n");
- return (-1);
- }
- else {
- /* check if a submenu with this name does already exist */
- len = (strrchr(menu, ']') - strchr(menu, '[')) / sizeof(char);
- strncpy(tmp, strchr(menu, '[') + sizeof(char), len);
- tmp[len - 1] = '\0'; /* get rid of [] */
- sprintf(searchstr, "{cascad \"%s\"", tmp); /* this is what we need to look for */
- idx2 = find_pos(searchstr, tcl_lines, idx);
- if ((idx2 != -1) && (idx2 < last)) {
- print_warning("submenu '%s' exists in GIS Manager's Xtns menu.\n",
- tmp);
- return (-1);
- }
- /* ELSE: create a new submenu in the right place */
- insert_here = idx + 1; /* by default: place submenu in first line after "Extensions" menu */
- idx2 = find_pos("{cascad ", tcl_lines, idx); /* go through all submenus in "Extensions" */
- while ((idx2 != -1) && (idx2 < last)) {
- /* check for alphabetical order */
- first_quote = strchr(tcl_lines[idx2], '\"'); /* get name of submenu w/o quotation marks */
- second_quote = strchr(first_quote + sizeof(char), '\"');
- len = (second_quote - first_quote) / sizeof(char);
- strncpy(tmp2, first_quote + sizeof(char), len);
- tmp2[len - 1] = '\0'; /* get rid of "" */
- if (strcmp(tmp, tmp2) < 0) {
- insert_here = idx2;
- break;
- }
- idx++;
- idx2 = find_pos("{cascad ", tcl_lines, idx);
- }
- /* create new submenu and return line no in menu.tcl for insertion of entries */
- sprintf(tmp, " \t\t\t%s {} \"\" 1 {\n", searchstr);
- insert_str(tmp, insert_here, tcl_lines);
- insert_str(" \t\t\t}}\n", insert_here + 1, tcl_lines);
- /* create an uninstall entry in menu.tcl */
- terminator = find_pos("}]", tcl_lines, 0);
- /* this is just a comment that tells the uninstall function which submenu to remove */
- sprintf(tmp, "#(DO_NOT_REMOVE_THIS_COMMENT) <%s> %s {} \"\" 1 {\n",
- pkg_short_name, searchstr);
- insert_str(tmp, terminator + 1, tcl_lines);
- /* return next line for insertion of menu entries and commands! */
- return (insert_here + 1);
- }
- return (-1);
- }
- /*
- Inserts a new menu entry into the extension's own submenu under "Extensions".
- Returns the line number in menu.tcl after which the next entry should be
- inserted.
- */
- int new_item(char *item, char *menu, char **tcl_lines, int line_no)
- {
- char *token;
- int num_tokens;
- char entry[MAXSTR];
- char command[MAXSTR];
- char tmp[MAXSTR];
- /* remove dangling white spaces and EOL chars */
- chop(item);
- token = strtok(item, ";");
- if (token == NULL) {
- print_warning("invalid token in 'entries-gisman'.\n");
- return (-1);
- }
- strcpy(entry, token); /* get menu entry string */
- num_tokens = 0;
- while (token != NULL) {
- token = strtok(NULL, ";");
- if (token != NULL) {
- strcpy(command, token); /* get command string */
- }
- num_tokens++;
- }
- if (num_tokens > 2) {
- print_warning("invalid number of tokens (%i) in 'entries-gisman'.\n",
- num_tokens);
- return (-1);
- }
- /* just a separator or a 'real' menu entry? */
- if ((!strcmp(entry, "-")) && (!strcmp(entry, "-"))) {
- sprintf(tmp, " \t\t\t {separator}\n");
- }
- else {
- sprintf(tmp, " \t\t\t {command \"%s\" {} \"%s\" {} -command {%s }}\n",
- entry, command, command);
- }
- insert_str(tmp, line_no, tcl_lines);
- /* return line no. for next entry */
- line_no++;
- return (line_no);
- }
- /*
- Checks if there are any entries in entries-gisman.
- Reads GISBASE/etc/dm/menu.tcl into an array of strings.
- Adds a new item "Extensions" to the menu bar, if it is missing.
- Adds new submenus and menu items to the GIS manager, as stated in entries-gisman
- Writes the new menu structure to a temporary file which will then be installed
- using the 'su' function.
- */
- void register_entries_gisman(char *pkg_short_name, char *gisbase)
- {
- char file[MAXSTR];
- char str[MAXSTR];
- char menu[MAXSTR];
- int len;
- char **line;
- int n_entries, n_lines, i;
- int n_lines_org, n_lines_new;
- int line_no;
- FILE *f_gisman, *f_in, *f_out;
- /* check if entries-gisman exists and is readable */
- sprintf(file, "../entries-gisman");
- f_gisman = fopen(file, "r");
- if (f_gisman == NULL) {
- if (errno == ENOENT) {
- /* file does not exist */
- return;
- }
- else {
- /* sth. strange happened */
- fclose(f_gisman);
- print_error(ERR_REGISTER_ENTRIES_GISMAN,
- "checking for file '%s': %s\n", file,
- strerror(errno));
- }
- }
- /* check if menu.tcl exists and is readable */
- sprintf(file, "%s/etc/dm/menu.tcl", gisbase);
- f_in = fopen(file, "r");
- if (f_in == NULL) {
- if (errno == ENOENT) {
- /* file does not exist */
- return;
- }
- else {
- /* sth. strange happened */
- fclose(f_in);
- print_error(ERR_REGISTER_ENTRIES_GISMAN,
- "checking for file '%s': %s\n", file,
- strerror(errno));
- }
- }
- /* create a temporary menu.tcl file for write access */
- /* TODO: Do not hardcode temp paths */
- strcpy(TMP_GISMAN, "/tmp/grass.extensions.db.XXXXXX"); /* TMP_GISMAN is a global variable */
- mkstemp(TMP_GISMAN);
- f_out = fopen(TMP_GISMAN, "w+");
- if (f_out == NULL) {
- print_error(ERR_REGISTER_ENTRIES_GISMAN,
- "could not create temp file '%s': %s\n \
- Make sure that directory /tmp exists on your system and you have write permission.\n", TMP_GISMAN, strerror(errno));
- }
- atexit(&exit_db); /* now need to register an at exit func to remove tmpdb automatically! */
- /* everything fine: create a shell command to install gisman-entries and modified menu.tcl */
- /* this also creates a backup-copy of menu.tcl */
- if (VERBOSE) {
- sprintf(str,
- "mkdir --verbose %s/etc/dm/gem-entries ; cp -vf ../entries-gisman %s/etc/dm/gem-entries/%s ; \
- cp -vf %s/etc/dm/menu.tcl %s/etc/dm/menu.tcl.gem.bak ; \
- cp -vf %s %s/etc/dm/menu.tcl ; chmod -v a+r %s/etc/dm/menu.tcl ;",
- gisbase, gisbase, pkg_short_name, gisbase, gisbase, TMP_GISMAN, gisbase, gisbase);
- }
- else {
- sprintf(str,
- "mkdir %s/etc/dm/gem-entries &> %s ; cp -f ../entries-gisman %s/etc/dm/gem-entries/%s &> %s ; \
- cp -f %s/etc/dm/menu.tcl %s/etc/dm/menu.tcl.gem.bak &> %s ; \
- cp -f %s %s/etc/dm/menu.tcl &> %s ; chmod a+r %s/etc/dm/menu.tcl &> %s ;",
- gisbase, TMP_NULL, gisbase, pkg_short_name, TMP_NULL, gisbase, gisbase, TMP_NULL, TMP_GISMAN, gisbase, TMP_NULL, gisbase, TMP_NULL);
- }
- strcpy(GISMAN_CMD, str);
- /* count number of lines in entries-gisman */
- n_entries = 0;
- while (fgets(str, MAXSTR, f_gisman) != NULL) {
- n_entries++;
- }
- if (n_entries == 0) {
- return;
- }
- rewind(f_gisman);
- /* count number of lines in menu.tcl */
- n_lines = 0;
- while (fgets(str, MAXSTR, f_in) != NULL) {
- n_lines++;
- }
- if (n_lines == 0) {
- return;
- }
- n_lines_org = n_lines;
- rewind(f_in);
- /* create an array large enough to hold all lines in menu.tcl */
- /* plus the entries that are to be added from entries-gisman */
- /* plus one NULL terminator */
- /* and copy all lines from menu.tcl into this */
- line = (char **)calloc(n_lines + (n_entries * 2) + 6, sizeof(char *));
- for (i = 0; i < (n_lines + (n_entries * 2) + 6); i++) {
- line[i] = NULL;
- }
- i = 0;
- while (fgets(str, MAXSTR, f_in) != NULL) {
- line[i] = (char *)malloc((1 + strlen(str)) * sizeof(char));
- strcpy(line[i], str);
- i++;
- }
- check_ext_menu(line); /* create "Extensions" menu if necessary */
- /* read all lines from entries-gisman and add to menus */
- i = 1;
- while (nc_fgets_nb(str, MAXSTR, f_gisman) != NULL) {
- if (i == 1) {
- /* store name of menu item */
- len = (strrchr(str, ']') - strchr(str, '[')) / sizeof(char);
- strncpy(menu, strchr(str, '[') + sizeof(char), len);
- menu[len - 1] = '\0'; /* get rid of [] */
- line_no = new_submenu(pkg_short_name, str, line);
- if (line_no < 0) {
- print_warning("no GIS Manager menu entries created.\n");
- break;
- }
- i++;
- }
- else {
- line_no = new_item(str, menu, line, line_no);
- if (line_no < 0) {
- print_warning("error creating GIS Manager menu entries.\n");
- break;
- }
- i++;
- }
- }
- /* write output to tmpfile */
- i = 0;
- while (line[i] != NULL) {
- fprintf(f_out, line[i]);
- i++;
- }
- fflush(f_out);
- /* check for accidental corruption of menu.tcl: if tmpfile has less lines than installed
- menu.tcl, we did sth. wrong and should leave the orginal file untouched! */
- rewind(f_out);
- n_lines_new = 0;
- while (fgets(str, MAXSTR, f_out) != NULL) {
- n_lines_new++;
- }
- if ((n_lines_new == 0) || (n_lines_new < n_lines_org)) {
- print_warning
- ("file truncation detected. Retaining orginal file 'menu.tcl'.\n");
- strcpy(GISMAN_CMD, "");
- }
- /* close files */
- fclose(f_in);
- fclose(f_gisman);
- fclose(f_out);
- /* free memory */
- for (i = 0; i < (n_lines + (n_entries * 2) + 6); i++) {
- free(line[i]);
- }
- free(line);
- }
- /*
- This version is for Michael Barton's new version of the GIS Manager (gis.m)
- It is much simpler and more flexible, because gis.m can build menus
- from files at runtime.
- All we have to do is make sure there is a folder 'Xtns' in $GISBASE/etc/gm
- and we copy 'entries-gisman2' (if provided) into that folder using a
- filename 'extension name'.gem!
- */
- void register_entries_gisman2(char *pkg_short_name, char *gisbase)
- {
- char file[MAXSTR];
- FILE *f_gisman2;
- char str[MAXSTR];
- /* check if entries-gisman2 exists and is readable */
- sprintf(file, "../entries-gisman2");
- f_gisman2 = fopen(file, "r");
- if (f_gisman2 == NULL) {
- if (errno == ENOENT) {
- /* file does not exist */
- return;
- }
- else {
- /* sth. strange happened */
- fclose(f_gisman2);
- print_error(ERR_REGISTER_ENTRIES_GISMAN2,
- "checking for file '%s': %s\n", file,
- strerror(errno));
- }
- }
- /* let's just blindly create an 'Xtns' dir: if it exists already: no problem */
- /* and then copy file into it! */
- if (VERBOSE) {
- sprintf(str,
- "mkdir --verbose -p %s/etc/gm/Xtns ; cp -fv ../entries-gisman2 %s/etc/gm/Xtns/%s.gem ; ",
- gisbase, gisbase, pkg_short_name);
- }
- else {
- sprintf(str,
- "mkdir -p %s/etc/gm/Xtns ; cp -f ../entries-gisman2 %s/etc/gm/Xtns/%s.gem ; ",
- gisbase, gisbase, pkg_short_name);
- }
- strcpy(GISMAN2_CMD, str);
- }
- /*
- Checks for a comment left by the new_submenu () function in menu.tcl.
- If it exists, the submenu specified in that comment will be removed along
- with all its entries.
- Returns -1 on failure, number of removed entries otherwise.
- If no more submenu entries exist, this will also remove the "Xtns" menu.
- */
- int deregister_entries_gisman(char *pkg_short_name, char *gisbase)
- {
- char file[MAXSTR];
- char str[MAXSTR];
- char tmp[MAXSTR];
- char **line;
- int n_lines, i;
- int n_lines_org, n_lines_new;
- FILE *f_in, *f_out;
- int pos;
- int start, end;
- int start_sub, end_sub;
- char *lq, *rq;
- int num_removed;
- /* check if menu.tcl exists and is readable */
- sprintf(file, "%s/etc/dm/menu.tcl", gisbase);
- f_in = fopen(file, "r");
- if (f_in == NULL) {
- if (errno == ENOENT) {
- /* file does not exist */
- return (0);
- }
- else {
- /* sth. strange happened */
- fclose(f_in);
- print_error(ERR_DEREGISTER_ENTRIES_GISMAN,
- "checking for file '%s': %s\n", file,
- strerror(errno));
- }
- }
- /* create a temporary menu.tcl file for write access */
- /* TODO: Do not hardcode temp paths */
- strcpy(TMP_GISMAN, "/tmp/grass.extensions.db.XXXXXX"); /* TMP_GISMAN is a global variable */
- mkstemp(TMP_GISMAN);
- f_out = fopen(TMP_GISMAN, "w+");
- if (f_out == NULL) {
- print_error(ERR_REGISTER_ENTRIES_GISMAN,
- "could not create temp file '%s': %s\n \
- Make sure that directory /tmp exists on your system and you have write permission.\n", TMP_GISMAN, strerror(errno));
- }
- atexit(&exit_db); /* now need to register an at exit func to remove tmpdb automatically! */
- /* everything fine: create a shell command to copy modified menu.tcl on uninstall */
- if (VERBOSE) {
- sprintf(str, "cp -vf %s/etc/dm/menu.tcl %s/etc/dm/menu.tcl.gem.bak ; \
- cp -vf %s %s/etc/dm/menu.tcl ; chmod -v a+r %s/etc/dm/menu.tcl ;", gisbase, gisbase, TMP_GISMAN, gisbase, gisbase);
- }
- else {
- sprintf(str,
- "cp -f %s/etc/dm/menu.tcl %s/etc/dm/menu.tcl.gem.bak &> %s ; \
- cp -f %s %s/etc/dm/menu.tcl &> %s ; chmod a+r %s/etc/dm/menu.tcl &> %s ;", gisbase, gisbase, TMP_NULL, TMP_GISMAN, gisbase, TMP_NULL, gisbase, TMP_NULL);
- }
- strcpy(GISMAN_CMD, str);
- /* count number of lines in menu.tcl */
- n_lines = 0;
- while (fgets(str, MAXSTR, f_in) != NULL) {
- n_lines++;
- }
- if (n_lines == 0) {
- return (-1);
- }
- rewind(f_in);
- n_lines_org = n_lines;
- /* create an array large enough to hold all lines in menu.tcl */
- /* plus one NULL terminator */
- /* and copy all lines from menu.tcl into this */
- line = (char **)calloc(n_lines + 1, sizeof(char *));
- for (i = 0; i < n_lines + 1; i++) {
- line[i] = NULL;
- }
- i = 0;
- while (fgets(str, MAXSTR, f_in) != NULL) {
- line[i] = (char *)malloc((1 + strlen(str)) * sizeof(char));
- strcpy(line[i], str);
- i++;
- }
- /* search for uninstall comment */
- sprintf(str, "#(DO_NOT_REMOVE_THIS_COMMENT) <%s> {cascad",
- pkg_short_name);
- pos = find_pos(str, line, 0);
- if (pos == -1) {
- print_warning
- ("could not find uninstall information in 'menu.tcl'.\n");
- return (-1);
- }
- /* copy name of submenu to search for */
- lq = strchr(line[pos], '\"');
- lq++;
- rq = strchr(lq, '\"');
- strcpy(tmp, lq);
- tmp[(rq - lq) / sizeof(char)] = '\0';
- /* now find "Xtns" menu start and end */
- start = find_pos("\"&Xtns\" all options 1", line, 0);
- end = find_pos("\" all options", line, start + 1) - 1;
- if (end == -1) {
- end = find_pos("}]", line, 0); /* end of menu.tcl */
- }
- if (start == -1) {
- print_warning("menu 'Xtns' does not exist.\n");
- return (-1);
- }
- /* now find our submenu and set the search range to it */
- sprintf(str, "{cascad \"%s\"", tmp);
- start_sub = find_pos(str, line, start);
- if ((start_sub == -1) || (start_sub > end)) {
- print_warning("could not find submenu entry '%s' in 'menu.tcl'.\n",
- tmp);
- return (-1);
- }
- end_sub = find_pos(" \t\t\t}}", line, start_sub);
- if ((end_sub == -1) || (end_sub > end)) {
- print_warning
- ("could not find end of submenu entry '%s' in 'menu.tcl'.\n",
- tmp);
- return (-1);
- }
- num_removed = 0;
- /* now kill every line in between start and end! */
- for (i = 0; i < ((end_sub - start_sub) + 1); i++) {
- delete_str(start_sub, line);
- num_removed++;
- }
- /* now kill the uninstall comment */
- sprintf(str, "#(DO_NOT_REMOVE_THIS_COMMENT) <%s> {cascad",
- pkg_short_name);
- pos = find_pos(str, line, 0);
- delete_str(pos, line);
- num_removed++;
- /* check if there are any submenus left in "Xtns" and if not: remove Xtns menu */
- start = find_pos("\"&Xtns\" all options 1", line, 0);
- end = find_pos("\" all options", line, start + 1) - 1;
- if (end - start < 3) {
- for (i = 0; i < ((end - start) + 1); i++) {
- delete_str(start, line);
- num_removed++;
- }
- }
- /* write output to tmpfile */
- i = 0;
- while (line[i] != NULL) {
- fprintf(f_out, line[i]);
- i++;
- }
- fflush(f_out);
- /* check for accidental corruption of menu.tcl: if tmpfile is empty (=0 lines),
- we did sth. wrong and should leave the orginal file untouched! */
- rewind(f_out);
- n_lines_new = 0;
- while (fgets(str, MAXSTR, f_out) != NULL) {
- n_lines_new++;
- }
- if ((n_lines_new == 0)) {
- print_warning
- ("file truncation detected. Retaining orginal file 'menu.tcl'.\n");
- strcpy(GISMAN_CMD, "");
- }
- /* close files */
- fclose(f_in);
- fclose(f_out);
- /* free memory */
- for (i = 0; i < n_lines + 1; i++) {
- free(line[i]);
- }
- free(line);
- return (num_removed);
- }
- /*
- This version is for Michael Barton's new GIS Manager.
- In this case, all we have to do is delete the .gem file!
- */
- void deregister_entries_gisman2(char *pkg_short_name, char *gisbase)
- {
- char file[MAXSTR];
- FILE *f_gisman2;
- char str[MAXSTR];
- /* check if entries-gisman2 exists and is readable */
- sprintf(file, "%s/etc/gm/Xtns/%s.gem", gisbase, pkg_short_name);
- f_gisman2 = fopen(file, "r");
- if (f_gisman2 == NULL) {
- if (errno == ENOENT) {
- /* file does not exist */
- return;
- }
- else {
- /* sth. strange happened */
- fclose(f_gisman2);
- print_error(ERR_DEREGISTER_ENTRIES_GISMAN2,
- "checking for file '%s': %s\n", file,
- strerror(errno));
- }
- }
- if (VERBOSE) {
- sprintf(str, "rm -vf %s/etc/gm/Xtns/%s.gem ; ",
- gisbase, pkg_short_name);
- }
- else {
- sprintf(str, "rm -f %s/etc/gm/Xtns/%s.gem ; ",
- gisbase, pkg_short_name);
- }
- strcpy(GISMAN_CMD, str);
- }
- /*
- Returns number of restored entries
- */
- int restore_entries_gisman(char *gisbase)
- {
- char str[MAXSTR];
- char menu[MAXSTR];
- char file[MAXSTR];
- char dir[MAXSTR];
- char pkg_short_name[MAXSTR];
- int len;
- char **line;
- int n_entries, n_lines, i;
- int line_no;
- FILE *f_gisman, *f_in, *f_out;
- DIR *dirp;
- struct dirent *ep;
- int num_restored;
- int n_files;
- /* check if menu.tcl exists and is readable */
- sprintf(file, "%s/etc/dm/menu.tcl", gisbase);
- f_in = fopen(file, "r");
- if (f_in == NULL) {
- if (errno == ENOENT) {
- /* file does not exist */
- return (0);
- }
- else {
- /* sth. strange happened */
- fclose(f_in);
- print_error(ERR_REGISTER_ENTRIES_GISMAN,
- "checking for file '%s': %s\n", file,
- strerror(errno));
- }
- }
- /* create a temporary menu.tcl file for write access */
- /* TODO: Do not hardcode temp paths */
- strcpy(TMP_GISMAN, "/tmp/grass.extensions.db.XXXXXX"); /* TMP_GISMAN is a global variable */
- mkstemp(TMP_GISMAN);
- f_out = fopen(TMP_GISMAN, "w+");
- if (f_out == NULL) {
- print_error(ERR_REGISTER_ENTRIES_GISMAN,
- "could not create temp file '%s': %s\n \
- Make sure that directory /tmp exists on your system and you have write permission.\n", TMP_GISMAN, strerror(errno));
- }
- atexit(&exit_db); /* now need to register an at exit func to remove tmpdb automatically! */
- /* everything fine: create a shell command to copy modified menu.tcl on uninstall */
- if (VERBOSE) {
- sprintf(str, "cp -vf %s/etc/dm/menu.tcl %s/etc/dm/menu.tcl.gem.bak ; \
- cp -vf %s %s/etc/dm/menu.tcl ; chmod -v a+r %s/etc/dm/menu.tcl ;", gisbase, gisbase, TMP_GISMAN, gisbase, gisbase);
- }
- else {
- sprintf(str,
- "cp -f %s/etc/dm/menu.tcl %s/etc/dm/menu.tcl.gem.bak &> %s ; \
- cp -f %s %s/etc/dm/menu.tcl &> %s ; chmod a+r %s/etc/dm/menu.tcl &> %s ;", gisbase, gisbase, TMP_NULL, TMP_GISMAN, gisbase, TMP_NULL, gisbase, TMP_NULL);
- }
- strcpy(GISMAN_CMD, str);
- /* allocate a pointer to the directory structure */
- sprintf(dir, "%s/etc/dm/gem-entries", gisbase);
- dirp = opendir(dir);
- if (dirp == NULL) {
- /* directory does not exist or is not accessible */
- return (0);
- }
- /* PASS 1 */
- /* open all files in gem-entries and count the number of lines each has */
- n_entries = 0;
- n_files = 0;
- while ((ep = readdir(dirp))) {
- sprintf(file, "%s/%s", dir, ep->d_name);
- f_gisman = fopen(file, "r");
- if ((!strcmp(ep->d_name, ".")) || (!strcmp(ep->d_name, ".."))) {
- fclose(f_gisman);
- continue;
- }
- if (f_gisman == NULL) {
- fclose(f_gisman);
- continue;
- }
- /* count number of lines in file */
- while (fgets(str, MAXSTR, f_gisman) != NULL) {
- n_entries++;
- }
- n_files++;
- fclose(f_gisman);
- }
- closedir(dirp);
- /* count number of lines in menu.tcl */
- n_lines = 0;
- while (fgets(str, MAXSTR, f_in) != NULL) {
- n_lines++;
- }
- if (n_lines == 0) {
- return (0);
- }
- rewind(f_in);
- /* create an array large enough to hold all lines in menu.tcl */
- /* plus the entries that are to be added from the files in gem-entries/ */
- /* plus space for uninstall comments */
- /* plus one NULL terminator */
- /* and copy all lines from menu.tcl into this */
- line =
- (char **)calloc(n_lines + (n_entries * 2) + (n_files * 5) + 1,
- sizeof(char *));
- for (i = 0; i < (n_lines + (n_entries * 2) + (n_files * 5) + 1); i++) {
- line[i] = NULL;
- }
- i = 0;
- while (fgets(str, MAXSTR, f_in) != NULL) {
- line[i] = (char *)malloc((1 + strlen(str)) * sizeof(char));
- strcpy(line[i], str);
- i++;
- }
- line[i] = NULL; /* add NULL terminator */
- check_ext_menu(line); /* create "Extensions" menu if necessary */
- /* PASS 2: re-create submenus and all menu items if necessary */
- dirp = opendir(dir);
- num_restored = 0;
- while ((ep = readdir(dirp))) {
- sprintf(file, "%s/%s", dir, ep->d_name);
- if ((!strcmp(ep->d_name, ".")) || (!strcmp(ep->d_name, ".."))) {
- continue;
- }
- f_gisman = fopen(file, "r");
- if (f_gisman == NULL) {
- continue;
- }
- /* read all lines from entries-gisman and add to menus */
- i = 1;
- while (nc_fgets_nb(str, MAXSTR, f_gisman) != NULL) {
- if (i == 1) {
- /* store name of menu item */
- len = (strrchr(str, ']') - strchr(str, '[')) / sizeof(char);
- strncpy(menu, strchr(str, '[') + sizeof(char), len);
- menu[len - 1] = '\0'; /* get rid of [] */
- line_no = new_submenu(pkg_short_name, str, line);
- if (line_no < 0) {
- break;
- }
- i++;
- num_restored++;
- }
- else {
- line_no = new_item(str, menu, line, line_no);
- if (line_no < 0) {
- break;
- }
- i++;
- num_restored++;
- }
- }
- fclose(f_gisman);
- }
- closedir(dirp);
- /* write output to tmpfile */
- i = 0;
- while (line[i] != NULL) {
- fprintf(f_out, line[i]);
- i++;
- }
- fflush(f_out);
- /* close remaining files */
- fclose(f_in);
- fclose(f_out);
- /* free memory */
- for (i = 0; i < (n_lines + (n_entries * 2) + (n_files * 5) + 1); i++) {
- free(line[i]);
- }
- free(line);
- return (num_restored);
- }
|