GRASS Programmer's Manual  6.4.2(2012)
tools.c
Go to the documentation of this file.
00001 
00002 /***************************************************************************
00003  *            tools.c
00004  *
00005  *  Mon Apr 18 15:00:13 2005
00006  *  Copyright  2005  Benjamin Ducke
00007  ****************************************************************************/
00008 
00009 /*
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00023  */
00024 
00025 #include "globals.h"
00026 
00027 
00028 /* the following are for cross-platform compatibility. They may already exist
00029    on a Linux or BSD system, but maybe absent e.g. in Win32, so we will define
00030    them here. */
00031 
00032 
00033 char *basename(char *path)
00034 {
00035     char *copy;
00036     char *element;
00037     char *backup;
00038 
00039     copy = strdup(path);
00040 
00041     backup = NULL;
00042     element = strtok(copy, "/");
00043     if (element == NULL) {
00044         if (copy != NULL) {
00045             free(copy);
00046         }
00047         return (NULL);
00048     }
00049 
00050     backup = strdup(element);
00051     while (element != NULL) {
00052         element = strtok(NULL, "/");
00053         if ((backup != NULL) && (element != NULL)) {
00054             free(backup);
00055         }
00056         if ((element != NULL) && (*element != '\0')) {
00057             backup = strdup(element);
00058         }
00059     }
00060 
00061     if (copy != NULL) {
00062         free(copy);
00063     }
00064 
00065     return (backup);
00066 }
00067 
00068 
00069 /*      A shell version of mkdir () 
00070    needed because the MINGW one does no accept unix style MOD specifications.
00071    THIS DOES NOT CHECK FOR ERRORS !
00072  */
00073 void mkdir_s(char *pathname, char *mode)
00074 {
00075     char tmp[5000];
00076 
00077     sprintf(tmp, "mkdir %s --mode=%s -p", pathname, mode);
00078     system(tmp);
00079 
00080 }
00081 
00082 /* 
00083    Removes all dangling white-spaces and EOL chars from the end of a string.
00084    Returns total number of chopped-off characters.
00085  */
00086 int chop(char *string)
00087 {
00088     int i;
00089     int chopped;
00090     int stop = 0;
00091 
00092     chopped = 0;
00093     i = strlen(string) - 1;
00094     while (i >= 0) {
00095         stop = 1;
00096         if ((string[i] == '\n') || (string[i] == '\t') ||
00097             (string[i] == ' ') || (string[i] == '\f') ||
00098             (string[i] == '\r')) {
00099             chopped++;
00100             stop = 0;
00101         }
00102         if (stop == 1) {
00103             /* got a non white-space char: stop chopping! */
00104             break;
00105         }
00106         i--;
00107     }
00108 
00109     /* chop string */
00110     string[strlen(string) - chopped] = '\0';
00111 
00112     return (chopped);
00113 }
00114 
00115 
00116 /* 
00117    Inserts a string into an array of n strings; positions start at 0
00118    The size of the array will be increased by one char*. 
00119    Returns new size of array.
00120    String array must be NULL-terminated.
00121    There must be at least one slots left after the NULL-terminator to
00122    hold the new string! This function will not resize the string
00123    array to accomodate the new string!
00124  */
00125 int insert_str(char *str, int pos, char **strarr)
00126 {
00127     char save[MAXSTR];
00128     char insert[MAXSTR];
00129     char last[MAXSTR];
00130     int n, j;
00131     int len;
00132 
00133     /* check for valid pos */
00134     n = 0;
00135     while (strarr[n] != NULL) {
00136         n++;
00137     }
00138 
00139     if ((pos < 0) || (pos > (n))) {
00140         print_error(ERR_REGISTER_ENTRIES_GISMAN,
00141                     "insert: invalid line number %i.\n", pos);
00142     }
00143 
00144     /* if a new string is to be added to the end of the array: */
00145     if (pos == n) {
00146         len = (1 + strlen(str)) * sizeof(char);
00147         strarr[n] = malloc(len);
00148         strcpy(strarr[n], str);
00149         n = n + 2;
00150         strarr[n - 1] = NULL;
00151         return (n);
00152     }
00153 
00154     strcpy(last, strarr[n - 1]);
00155     strcpy(insert, strarr[pos]);
00156     free(strarr[pos]);
00157     strarr[pos] = malloc((1 + strlen(str)) * sizeof(char));
00158     strcpy(strarr[pos], str);
00159     /* now move all strings > pos up one */
00160     for (j = pos; j < n - 1; j++) {
00161         strcpy(save, strarr[j + 1]);    /* save string to be overwritten */
00162         free(strarr[j + 1]);    /* overwrite string */
00163         len = (1 + strlen(insert)) * sizeof(char);      /* make room for string to be inserted */
00164         strarr[j + 1] = malloc(len);
00165         strcpy(strarr[j + 1], insert);  /* insert string */
00166 
00167         strcpy(insert, save);   /* set saved string to next to be inserted */
00168 
00169     }
00170 
00171     /* overwrite NULL terminator with last item */
00172     strarr[n] = malloc((1 + strlen(last)) * sizeof(char));
00173     strcpy(strarr[n], last);
00174 
00175     /* increase size of array by one */
00176     n = n + 2;
00177     strarr[n - 1] = NULL;       /* set last element of array to NULL */
00178 
00179     return (n);
00180 }
00181 
00182 
00183 /* 
00184    Delete a string at position pos (o to n) from an array of n strings; 
00185    positions start at 0
00186    The size of the array will be decreased by one char*.
00187    Returns new size of array.
00188    String array must be NULL-terminated.
00189  */
00190 int delete_str(int pos, char **strarr)
00191 {
00192     int i;
00193 
00194     /* check for valid pos */
00195     i = 0;
00196     while (strarr[i] != NULL) {
00197         i++;
00198     }
00199 
00200     if ((pos < 0) || (pos > (i))) {
00201         print_error(ERR_REGISTER_ENTRIES_GISMAN,
00202                     "delete: invalid line number %i.\n", pos);
00203     }
00204 
00205     /* now move all strings > pos down one */
00206     i = pos;
00207     while (strarr[i] != NULL) {
00208         free(strarr[i]);
00209         if (strarr[i + 1] != NULL) {
00210             strarr[i] = malloc((1 + (strlen(strarr[i + 1]))) * sizeof(char));
00211             strcpy(strarr[i], strarr[i + 1]);
00212         }
00213         i++;
00214     }
00215 
00216     /* decrease size of array by one */
00217     i = i - 1;
00218     strarr[i] = NULL;           /* set last element of array to NULL */
00219 
00220     return (i);
00221 }
00222 
00223 
00224  /*
00225     Returns the first line number in which *str is found.
00226     Search starts after line number 'start'.
00227     Returns -1 if string not found.
00228     String array must be NULL-terminated.
00229   */
00230 int find_pos(char *str, char **strarr, int start)
00231 {
00232     int i, j;
00233 
00234     /* check for valid pos */
00235     i = 0;
00236     while (strarr[i] != NULL) {
00237         i++;
00238     }
00239 
00240     if ((start < 0) || (start > (i))) {
00241         exit(ERR_REGISTER_ENTRIES_GISMAN);
00242     }
00243 
00244     for (j = start; j < (i); j++) {
00245         if (strstr(strarr[j], str) != NULL) {
00246             return (j);
00247         }
00248     }
00249 
00250     return (-1);
00251 }
00252 
00253 
00254  /*
00255     Dumps an array of strings to a file.
00256     String array must be NULL-terminated.
00257   */
00258 void dump_str(FILE * f, char **strarr)
00259 {
00260     int i;
00261 
00262     i = 0;
00263     while (strarr[i] != NULL) {
00264         fprintf(f, "%i: %s", i, strarr[i]);
00265         i++;
00266     }
00267 }
00268 
00269 /*
00270    Get package name. Copies the package name as found in
00271    the 'name' info file into the char array *name.
00272  */
00273 void get_package_name(char *path, char *name)
00274 {
00275     FILE *f;
00276     char file[MAXSTR];
00277     char tmp[MAXSTR];
00278 
00279     sprintf(file, "%s/%s", path, "name");
00280 
00281     /* get extension name */
00282     f = fopen(file, "r");
00283     if (f == NULL) {
00284         print_error(ERR_INVALID_EXT, "'name' file not readable.\n");
00285     }
00286     else {
00287         if (nc_fgets_nb(tmp, MAXSTR, f) == NULL) {
00288             fclose(f);
00289             print_error(ERR_INVALID_EXT,
00290                         "invalid or missing extension name.\n");
00291         }
00292         else {
00293             chop(tmp);
00294             strcpy(name, tmp);
00295         }
00296     }
00297     fclose(f);
00298 }
00299 
00300 /*
00301    A replacement function for fgets to filter out comments and blank lines.
00302    Useful for parsing settings files.
00303    Returns a line from a file only if it does not start with '#'.
00304    Returns only the part of the line left of '#'.
00305    Otherwise, tries to read the next line from the file or returns NULL on EOF.
00306  */
00307 char *nc_fgets(char *s, int size, FILE * stream)
00308 {
00309     char *hashmark;
00310     char *tmp;
00311 
00312     if (fgets(s, size, stream) == NULL) {
00313         return (NULL);
00314     }
00315 
00316     hashmark = strchr(s, '#');
00317 
00318     if (hashmark != NULL) {
00319         if (s - hashmark == 0) {
00320             /* line starts with a hashmark: recursively call nc_fgets() */
00321             return (nc_fgets(s, size, stream));
00322         }
00323         else {
00324             /* return only the part before '#' */
00325             tmp = malloc(sizeof(char) * MAXSTR);
00326             strcpy(tmp, s);
00327             tmp = strtok(tmp, "#");
00328             sprintf(s, "%s\n", tmp);
00329             free(tmp);
00330         }
00331     }
00332     return (s);
00333 }
00334 
00335 
00336 /*
00337    Same as nc_fgets (). Additionally, this filters for HTML tags.
00338  */
00339 char *nc_fgets_html(char *s, int size, FILE * stream)
00340 {
00341     char *hashmark;
00342     char *tmp;
00343     char *tag;
00344     char *tag_2;
00345     char *tag_insert;
00346     char *tag_content;
00347     char *pos;
00348     char *insert;
00349     int space;
00350 
00351     if (fgets(s, size, stream) == NULL) {
00352         return (NULL);
00353     }
00354 
00355     /* look for HTML tags: this discards all text inside the tags except for:
00356        <br> becomes \n
00357        <p> becomes \n\n
00358      */
00359     tmp = malloc(sizeof(char) * (strlen(s) + 1));
00360     tag_content = malloc(sizeof(char) * (strlen(s) + 1));
00361 
00362     insert = tmp;
00363     pos = s;
00364 
00365     while (*pos != '\0') {
00366         if (*pos == '<') {      /* possibly an html open tag */
00367             tag = pos;
00368             tag_insert = tag_content;
00369             pos--;
00370             if (pos >= s) {
00371                 if (*pos == 32) {
00372                     space = 1;
00373                 }
00374                 else {
00375                     space = 0;
00376                 }
00377             }
00378             while (*tag != '\0') {
00379                 *tag_insert = *tag;
00380                 (*tag_insert)++;
00381                 if (*tag == '>') {      /* OK, we got a tag */
00382                     *tag_insert = '\0';
00383 
00384                     /* only add additional newlines, if this is not the end of the line already! */
00385                     tag_2 = tag;
00386                     tag_2++;
00387                     if (*tag_2 != '\n') {
00388                         if (strstr(tag_content, "<br>") != NULL) {
00389                             /* a <br> at the start of a line produce no additional linefeed! */
00390                             if (insert > tmp) {
00391                                 *insert = '\n';
00392                                 (*insert)++;
00393                             }
00394                         }
00395                         if (strstr(tag_content, "<BR>") != NULL) {
00396                             if (insert > tmp) {
00397                                 *insert = '\n';
00398                                 (*insert)++;
00399                             }
00400                         }
00401                         if (strstr(tag_content, "<p>") != NULL) {
00402                             if (insert > tmp) {
00403                                 *insert = '\n';
00404                                 (*insert)++;
00405                             }
00406                             *insert = '\n';
00407                             (*insert)++;
00408                         }
00409                         if (strstr(tag_content, "<P>") != NULL) {
00410                             if (insert > tmp) {
00411                                 *insert = '\n';
00412                                 (*insert)++;
00413                             }
00414                             *insert = '\n';
00415                             (*insert)++;
00416                         }
00417                     }
00418 
00419                     pos = tag;  /* skip this */
00420 
00421                     /* if the next character is a space and there was none
00422                        before the tag: skip that, too 
00423                      */
00424                     if (*pos == 32) {
00425                         if (space == 1) {
00426                             pos++;
00427                             space = 0;
00428                         }
00429                     }
00430                     break;
00431                 }
00432                 tag++;
00433             }
00434         }
00435         if (*pos != '>') {
00436             *insert = *pos;
00437             insert++;
00438         }
00439         pos++;
00440     }
00441 
00442     *insert = '\0';
00443 
00444     strcpy(s, tmp);
00445 
00446     free(tmp);
00447     free(tag_content);
00448 
00449     hashmark = strchr(s, '#');
00450 
00451     if (hashmark != NULL) {
00452         if (s - hashmark == 0) {
00453             /* line starts with a hashmark: recursively call nc_fgets_html() */
00454             return (nc_fgets_html(s, size, stream));
00455         }
00456         else {
00457             /* return only the part before '#' */
00458             tmp = malloc(sizeof(char) * MAXSTR);
00459             strcpy(tmp, s);
00460             tmp = strtok(tmp, "#");
00461             sprintf(s, "%s\n", tmp);
00462             free(tmp);
00463         }
00464     }
00465 
00466     return (s);
00467 }
00468 
00469 
00470 /*
00471    Checks whether a string actually contains text or is a blank line/whitespace only.
00472    Returns 1 if text , 0 if only blank/whitespace.
00473  */
00474 int is_text(char *s)
00475 {
00476     int i;
00477     int nonws;
00478 
00479     /* check for a blank or white-space only line */
00480     nonws = 0;
00481     for (i = strlen(s) - 1; i >= 0; i--) {
00482         if ((s[i] == ' ') || (s[i] == '\t') || (s[i] == '\n') ||
00483             (s[i] == '\f') || (s[i] == '\r')) {
00484             nonws = 0;
00485         }
00486         else {
00487             nonws = 1;
00488             break;              /* break at first non-ws char! */
00489         }
00490     }
00491 
00492     return (nonws);
00493 }
00494 
00495 
00496 /*
00497    Same as nc_fgets() but also skips over blank lines and those that contain only 
00498    whitespace chars.
00499  */
00500 char *nc_fgets_nb(char *s, int size, FILE * stream)
00501 {
00502     char *hashmark;
00503     char *tmp;
00504 
00505     if (fgets(s, size, stream) == NULL) {
00506         return (NULL);
00507     }
00508 
00509 
00510     if (is_text(s) == 0) {
00511         /* line is ws only: recursively call nc_fgets() to get next line */
00512         return (nc_fgets_nb(s, size, stream));
00513     }
00514 
00515     hashmark = strchr(s, '#');
00516 
00517     if (hashmark != NULL) {
00518         if (s - hashmark == 0) {
00519             /* line starts with a hashmark: recursively call nc_fgets() */
00520             return (nc_fgets_nb(s, size, stream));
00521         }
00522         else {
00523             /* return only the part before '#' */
00524             tmp = malloc(sizeof(char) * MAXSTR);
00525             strcpy(tmp, s);
00526             tmp = strtok(tmp, "#");
00527             sprintf(s, "%s\n", tmp);
00528             free(tmp);
00529         }
00530     }
00531     return (s);
00532 }
00533 
00534 
00535 /*
00536    This just dumps an ASCII file to stdout, line by line, but
00537    skips over comments.
00538  */
00539 void dump_ascii(char *file, char *heading)
00540 {
00541     char tmp[MAXSTR];
00542     FILE *f;
00543 
00544     fprintf(stdout, "%s\n", heading);
00545     f = fopen(file, "r");
00546     if (f == NULL) {
00547         fprintf(stdout, "  No information available.\n");
00548     }
00549     else {
00550         while (nc_fgets_html(tmp, MAXSTR, f) != NULL) {
00551             fprintf(stdout, "  %s", tmp);
00552         }
00553         fprintf(stdout, "\n");
00554         fclose(f);
00555     }
00556 }
00557 
00558 
00559 /* 
00560    Dumps the contents of an ASCII file without comment lines but with blank lines
00561    to a temporary file.
00562  */
00563 void dump_plain(char *file, char *tmpfile)
00564 {
00565     char tmp[MAXSTR];
00566     FILE *f_in;
00567     FILE *f_out;
00568 
00569     /* create a temporary menu.tcl file for write access */
00570     /* TODO: Do not hardcode temp path */
00571     strcpy(tmpfile, "/tmp/grass.extensions.db.XXXXXX"); /* TMP_GISMAN is a global variable */
00572     mkstemp(tmpfile);
00573 
00574     f_out = fopen(tmpfile, "w+");
00575     if (f_out == NULL) {
00576         print_error(ERR_DUMP_PLAIN_TXT,
00577                     "could not create temp file '%s': %s\n \
00578                 Make sure that directory /tmp exists on your system and you have write permission.\n", tmpfile, strerror(errno));
00579     }
00580 
00581     atexit(&exit_db);           /* now need to register an at exit func to remove tmpfile automatically! */
00582 
00583     f_in = fopen(file, "r");
00584     while (nc_fgets(tmp, MAXSTR, f_in) != NULL) {
00585         fprintf(f_out, tmp);
00586     }
00587 
00588     fclose(f_in);
00589     fclose(f_out);
00590 }
00591 
00592 
00593 /* 
00594    Same as dump_plain() but adds a <br> after each newline in the stream.
00595    Also replaces blank lines with a <p>.
00596  */
00597 void dump_html(char *file, char *tmpfile)
00598 {
00599     char tmp[MAXSTR];
00600     char line[MAXSTR];
00601     FILE *f_in;
00602     FILE *f_out;
00603     int fd;
00604 
00605     /* create a temporary menu.tcl file for write access */
00606     /* TODO: Do not hardcode temp path */
00607     strcpy(tmpfile, "/tmp/grass.extensions.db.XXXXXX"); /* TMP_GISMAN is a global variable */
00608     mkstemp(tmpfile);
00609 
00610     f_out = fopen(tmpfile, "w+");
00611     if (f_out == NULL) {
00612         print_error(ERR_DUMP_PLAIN_TXT,
00613                     "could not create temp file '%s': %s\n \
00614                 Make sure that directory /tmp exists on your system and you have write permission.\n", tmpfile, strerror(errno));
00615     }
00616 
00617     atexit(&exit_db);           /* now need to register an at exit func to remove tmpfile automatically! */
00618 
00619     f_in = fopen(file, "r");
00620     while (nc_fgets(line, MAXSTR, f_in) != NULL) {
00621         chop(line);
00622         if (!is_text(line)) {   /* replace blank lines with a <p> */
00623             fprintf(f_out, "<p>\n");
00624         }
00625         else {
00626             sprintf(tmp, "%s <br>\n", line);
00627             fprintf(f_out, tmp);
00628         }
00629     }
00630 
00631     fclose(f_in);
00632     fclose(f_out);
00633     close(fd);
00634 }
00635 
00636 
00637 /* 
00638    A pretty dumb function: this just lists all directories which are directly below
00639    top level and not called "src". It is assumed that these contain binary distributions
00640    which can be installed by just doing a "make install" in the respective directory.
00641  */
00642 void list_binaries(char *package)
00643 {
00644     char tmp[MAXSTR];
00645     struct stat buf;
00646     DIR *dir;
00647     struct dirent *dir_entry;
00648     int n_dirs = 0;
00649 
00650     fprintf(stdout, "Binary installation files\n");
00651 
00652     dir = opendir(package);
00653     if (dir == NULL) {
00654         fprintf(stdout, "  None.\n\n");
00655         return;
00656     }
00657 
00658     dir_entry = readdir(dir);
00659     while (dir_entry != NULL) {
00660         if ((strcmp(dir_entry->d_name, ".")) &&
00661             (strcmp(dir_entry->d_name, "..")) &&
00662             (strcmp(dir_entry->d_name, "src"))
00663             ) {
00664             /* check if it is a directory */
00665             sprintf(tmp, "%s/%s", package, dir_entry->d_name);
00666             stat(tmp, &buf);
00667             if (S_ISDIR(buf.st_mode)) {
00668                 if (n_dirs == 0) {
00669                     fprintf(stdout, "  %s", dir_entry->d_name);
00670                 }
00671                 else {
00672                     fprintf(stdout, ", %s", dir_entry->d_name);
00673                 }
00674                 n_dirs++;
00675             }
00676         }
00677         dir_entry = readdir(dir);
00678     }
00679     if (n_dirs == 0) {
00680         fprintf(stdout, "  None.");
00681     }
00682     fprintf(stdout, "\n\n");
00683 }
00684 
00685 
00686 /* 
00687    Just as dumb: checks, if a specified directory 'binaries' exists in addition to 'src'
00688    Returns 1 if so, 0 otherwise 
00689  */
00690 int binaries_exist(char *package, char *binaries)
00691 {
00692     char tmp[MAXSTR];
00693     struct stat buf;
00694     DIR *dir;
00695     struct dirent *dir_entry;
00696 
00697     dir = opendir(package);
00698     if (dir == NULL) {
00699         return (0);
00700     }
00701 
00702     dir_entry = readdir(dir);
00703     while (dir_entry != NULL) {
00704         if ((strcmp(dir_entry->d_name, ".")) &&
00705             (strcmp(dir_entry->d_name, "..")) &&
00706             (strcmp(dir_entry->d_name, "src"))
00707             ) {
00708             /* check if it is a directory */
00709             sprintf(tmp, "%s/%s", package, dir_entry->d_name);
00710             stat(tmp, &buf);
00711             if (S_ISDIR(buf.st_mode)) {
00712                 if (!strcmp(dir_entry->d_name, binaries)) {
00713                     return (1); /* found it */
00714                 }
00715             }
00716         }
00717         dir_entry = readdir(dir);
00718     }
00719     return (0);
00720 }
00721 
00722 
00723 /* 
00724    Tests for a known file-extension:
00725    .tar.gz, .tgz
00726    .tar.bz2, .tbz
00727    .zip
00728    Returns:
00729    0 = unknown (TYPE_UNKNOWN)
00730    1 = tar file with gzip compression (TAR_GZIP)
00731    2 = tar file with bzip2 compression (TAR_BZIP2)
00732    3 = zip archive (ZIP)
00733    4 = plain tar archive, uncompressed (TAR)
00734 
00735    VERY primitive!
00736  */
00737 int check_filetype(char *myfile)
00738 {
00739 
00740     if (strstr(myfile, ".tar.gz") != NULL) {
00741         return (1);
00742     }
00743     if (strstr(myfile, ".tgz") != NULL) {
00744         return (1);
00745     }
00746     if (strstr(myfile, ".tar.bz2") != NULL) {
00747         return (2);
00748     }
00749     if (strstr(myfile, ".tbz") != NULL) {
00750         return (2);
00751     }
00752     if (strstr(myfile, ".zip") != NULL) {
00753         return (3);
00754     }
00755     if (strstr(myfile, ".tar") != NULL) {
00756         return (4);
00757     }
00758 
00759     return (0);
00760 }
00761 
00762 /*
00763    Retrieves an extension from the WWW using wget and
00764    stores the file in the current directory.
00765  */
00766 void wget_extension(char *url)
00767 {
00768     char str[MAXSTR];
00769     int error;
00770 
00771     fprintf(stdout, "Downloading...");
00772 
00773     if (VERBOSE) {
00774         sprintf(str, "wget -N %s", url);
00775     }
00776     else {
00777         sprintf(str, "wget -N -q %s", url);
00778     }
00779     error = system(str);
00780     if (error == -1) {
00781         print_error(ERR_DOWNLOAD,
00782                     "could not run 'wget' to download extension. Is it installed?\n");
00783     }
00784     if (error > 0) {
00785         print_error(ERR_DOWNLOAD, "running command '%s'.\n", str);
00786     }
00787 
00788     print_done();
00789 }
00790 
00791 /*
00792    This function checks if there is write access to the GRASS directory.
00793    If not, it aborts with an error message.
00794    Otherwise, 'cmd' is simply executed as currently running user.
00795  */
00796 void su(char *gisbase, char *cmd)
00797 {
00798     char tmpfile[MAXSTR];
00799     int error;
00800     static unsigned long next;
00801     FILE *f;
00802 
00803     /* check for permission  */
00804     next = next * 1103515245 + 54321;   /* generate a random file name */
00805     next = (next / 65536) % 32768;
00806     srand(next);
00807     sprintf(tmpfile, "%s/gem.test.%i", gisbase, rand());
00808 
00809     f = fopen(tmpfile, "w+");
00810 
00811     if (errno == EACCES) {      /* permission denied */
00812         print_error(ERR_INSTALL_EXT,
00813                     "You don't have write access to your local GRASS installation.\nPlease consult your system administrator.\n");
00814     }
00815     else {
00816         remove(tmpfile);
00817         fclose(f);
00818         error = system(cmd);
00819         if (error != 0) {
00820             print_error(ERR_MISSING_CMD, "could not run '%s'.\n", cmd);
00821         }
00822     }
00823 }
00824 
00825 
00826 /*
00827    Compares two version descriptions consisting of three ints each
00828    returns: -1, if major.minor.revision < major2.minor2.revision2,
00829    0, if equal
00830    1, if major.minor.revision > major2.minor2.revision2,
00831  */
00832 int vercmp(int major, int minor, int revision, int major2, int minor2,
00833            int revision2)
00834 {
00835     if ((major == major2) && (minor == minor2) && (revision == revision2)) {
00836         return (0);
00837     }
00838     if (major2 > major) {
00839         return (-1);
00840     }
00841     if (major2 < major) {
00842         return (1);
00843     }
00844     if (minor2 > minor) {
00845         return (-1);
00846     }
00847     if (minor2 < minor) {
00848         return (1);
00849     }
00850     if (revision2 > revision) {
00851         return (-1);
00852     }
00853     if (revision2 < revision) {
00854         return (1);
00855     }
00856 
00857     return (0);
00858 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines