Hi devs, I have re-run the coverity scan on master, results below.
There is also the option of Travis integration which might be a good idea. Anyone to support this? Markus ---------- Forwarded message --------- From: <scan-ad...@coverity.com> Date: Mon, Feb 3, 2020 at 6:58 PM Subject: New Defects reported by Coverity Scan for grass To: <nete...@gmail.com> Hi, Please find the latest report on new defect(s) introduced to grass found with Coverity Scan. 600 new defect(s) introduced to grass found with Coverity Scan. 1 defect(s), reported by Coverity Scan earlier, were marked fixed in the recent build analyzed by Coverity Scan. New defect(s) Reported-by: Coverity Scan Showing 20 of 600 defect(s) ** CID 1415720: Uninitialized variables (UNINIT) /raster/r.geomorphon/pattern.c: 128 in calc_pattern() ________________________________________________________________________________________________________ *** CID 1415720: Uninitialized variables (UNINIT) /raster/r.geomorphon/pattern.c: 128 in calc_pattern() 122 pattern->negatives += i; 123 124 if (fabs(zenith_angle) > zenith_threshold || 125 fabs(nadir_angle) > nadir_threshold) { 126 if (fabs(nadir_angle) < fabs(zenith_angle)) { 127 pattern->pattern[i] = 1; >>> CID 1415720: Uninitialized variables (UNINIT) >>> Using uninitialized value "zenith_height". 128 pattern->elevation[i] = zenith_height; /* ZMIANA! */ 129 pattern->distance[i] = zenith_distance; 130 pattern->num_positives++; 131 } 132 if (fabs(nadir_angle) > fabs(zenith_angle)) { 133 pattern->pattern[i] = -1; ** CID 1415719: Resource leaks (RESOURCE_LEAK) /vector/v.info/level1.c: 29 in level_one_info() ________________________________________________________________________________________________________ *** CID 1415719: Resource leaks (RESOURCE_LEAK) /vector/v.info/level1.c: 29 in level_one_info() 23 n_faces = n_kernels = 0; 24 25 Points = Vect_new_line_struct(); 26 Cats = Vect_new_cats_struct(); 27 28 Vect_rewind(Map); >>> CID 1415719: Resource leaks (RESOURCE_LEAK) >>> Failing to save or free storage allocated by "Vect_get_full_name(Map)" >>> leaks it. 29 G_message(_("Topology not available for vector map <%s>. " 30 "Registering primitives..."), Vect_get_full_name(Map)); 31 while (TRUE) { 32 /* register line */ 33 type = Vect_read_next_line(Map, Points, Cats); 34 ** CID 1415718: Resource leaks (RESOURCE_LEAK) /display/d.barscale/draw_scale.c: 637 in draw_scale() ________________________________________________________________________________________________________ *** CID 1415718: Resource leaks (RESOURCE_LEAK) /display/d.barscale/draw_scale.c: 637 in draw_scale() 631 D_end(); /* no-op? */ 632 } 633 D_stroke(); 634 635 636 if (fontsize < 0) >>> CID 1415718: Resource leaks (RESOURCE_LEAK) >>> Variable "label" going out of scope leaks the storage it points to. 637 return 0; 638 639 /* draw the distance + units text */ 640 641 D_get_text_box(label, &tt, &tb, &tl, &tr); 642 ** CID 1415717: Resource leaks (RESOURCE_LEAK) /vector/v.overlay/area_area.c: 493 in area_area() ________________________________________________________________________________________________________ *** CID 1415717: Resource leaks (RESOURCE_LEAK) /vector/v.overlay/area_area.c: 493 in area_area() 487 } 488 489 if (centr[0] || centr[1]) 490 Vect_write_line(Out, GV_BOUNDARY, Points, Cats); 491 } 492 >>> CID 1415717: Resource leaks (RESOURCE_LEAK) >>> Variable "APoints" going out of scope leaks the storage it points to. 493 return 0; ** CID 1415716: (STRING_OVERFLOW) /raster/r.geomorphon/main.c: 504 in main() /raster/r.geomorphon/main.c: 307 in main() ________________________________________________________________________________________________________ *** CID 1415716: (STRING_OVERFLOW) /raster/r.geomorphon/main.c: 504 in main() 498 num_of_steps = 5; 499 multi_patterns = G_malloc(num_of_steps * sizeof(PATTERN)); 500 /* prepare outputs */ 501 for (i = 0; i < 5; ++i) { 502 multiple_output[i].forms_buffer = Rast_allocate_buf(CELL_TYPE); 503 strcpy(multiple_output[i].name, prefix); >>> CID 1415716: (STRING_OVERFLOW) >>> You might overrun the 100-character fixed-size string >>> "multiple_output[i].name" by copying "postfixes[i]" without checking the >>> length. 504 strcat(multiple_output[i].name, postfixes[i]); 505 multiple_output[i].fd = 506 Rast_open_new(multiple_output[i].name, CELL_TYPE); 507 } 508 509 /* main loop */ /raster/r.geomorphon/main.c: 307 in main() 301 302 /* generate global ternary codes */ 303 for (i = 0; i < 6561; ++i) 304 global_ternary_codes[i] = ternary_rotate(i); 305 306 /* open DEM */ >>> CID 1415716: (STRING_OVERFLOW) >>> You might overrun the 150-character fixed-size string >>> "elevation.elevname" by copying "opt_input->answer" without checking the >>> length. 307 strcpy(elevation.elevname, opt_input->answer); 308 open_map(&elevation); 309 310 if (!multires) { 311 PATTERN *pattern; 312 PATTERN patterns[4]; ** CID 1415715: Memory - illegal accesses (UNINIT) /raster/r.fill.stats/main.c: 1111 in main() ________________________________________________________________________________________________________ *** CID 1415715: Memory - illegal accesses (UNINIT) /raster/r.fill.stats/main.c: 1111 in main() 1105 data_type_string_out = "double"; 1106 } 1107 1108 /* initialize data type dependent cell handling functions */ 1109 init_cell_funcs(); 1110 >>> CID 1415715: Memory - illegal accesses (UNINIT) >>> Using uninitialized value "data_type_string_in" when calling >>> "G_message". 1111 G_message(_("Input data type is '%s' (%i bytes) and output data type is '%s' (%i bytes)."), 1112 data_type_string_in, CELL_IN_SIZE, data_type_string_out, 1113 CELL_OUT_SIZE); 1114 1115 /* just print projected mem usage if user wants it so */ 1116 G_message("Minimal estimated memory usage is %.3f MB.", ** CID 1415714: (TAINTED_SCALAR) /raster/r.clump/clump.c: 105 in do_renumber() /raster/r.clump/clump.c: 157 in do_renumber() ________________________________________________________________________________________________________ *** CID 1415714: (TAINTED_SCALAR) /raster/r.clump/clump.c: 105 in do_renumber() 99 G_fatal_error(_("Unable to read from temp file")); 100 101 temp_clump = cur_clump; 102 103 do_write = 0; 104 for (col = 0; col < ncols; col++) { >>> CID 1415714: (TAINTED_SCALAR) >>> Using tainted variable "*temp_clump" as an index to pointer "index". 105 new_clump = clumpid[index[*temp_clump]]; 106 if (*temp_clump != new_clump) { 107 *temp_clump = new_clump; 108 do_write = 1; 109 } 110 temp_clump++; /raster/r.clump/clump.c: 157 in do_renumber() 151 G_fatal_error(_("Unable to read from temp file")); 152 153 temp_clump = cur_clump; 154 temp_cell = out_cell; 155 156 for (col = 0; col < ncols; col++) { >>> CID 1415714: (TAINTED_SCALAR) >>> Using tainted variable "*temp_clump" as an index to pointer "index". 157 *temp_cell = clumpid[index[*temp_clump]]; 158 if (*temp_cell == 0) { 159 Rast_set_c_null_value(temp_cell, 1); 160 } 161 temp_clump++; 162 temp_cell++; ** CID 1415713: Insecure data handling (TAINTED_SCALAR) ________________________________________________________________________________________________________ *** CID 1415713: Insecure data handling (TAINTED_SCALAR) /lib/vector/Vlib/read_nat.c: 226 in V2_read_next_line_nat() 220 if (!Vect_box_overlap(&lbox, &mbox)) 221 continue; 222 } 223 224 if (line_c && Map->constraint.field_flag) { 225 /* skip feature by field */ >>> CID 1415713: Insecure data handling (TAINTED_SCALAR) >>> Passing tainted variable "line_c->n_cats" to a tainted sink. 226 if (Vect_cat_get(line_c, Map->constraint.field, NULL) == 0) 227 continue; 228 } 229 230 return ret; 231 } ** CID 1415712: API usage errors (PRINTF_ARGS) ________________________________________________________________________________________________________ *** CID 1415712: API usage errors (PRINTF_ARGS) /lib/psdriver/erase.c: 6 in PS_Erase() 0 } 1 #include "psdriver.h" 2 3 void PS_Erase(void) 4 { 5 if (ps.encapsulated) >>> CID 1415712: API usage errors (PRINTF_ARGS) >>> Argument "ps.bot" to format specifier "%d" was expected to have type >>> "int" but has type "double". 6 output("%d %d %d %d BOX\n", ps.left, ps.top, ps.right, ps.bot); 7 else 8 output("ERASE\n"); ** CID 1415711: (UNINIT) /raster/r.geomorphon/pattern.c: 129 in calc_pattern() /raster/r.geomorphon/pattern.c: 108 in calc_pattern() ________________________________________________________________________________________________________ *** CID 1415711: (UNINIT) /raster/r.geomorphon/pattern.c: 129 in calc_pattern() 123 124 if (fabs(zenith_angle) > zenith_threshold || 125 fabs(nadir_angle) > nadir_threshold) { 126 if (fabs(nadir_angle) < fabs(zenith_angle)) { 127 pattern->pattern[i] = 1; 128 pattern->elevation[i] = zenith_height; /* ZMIANA! */ >>> CID 1415711: (UNINIT) >>> Using uninitialized value "zenith_distance". 129 pattern->distance[i] = zenith_distance; 130 pattern->num_positives++; 131 } 132 if (fabs(nadir_angle) > fabs(zenith_angle)) { 133 pattern->pattern[i] = -1; 134 pattern->elevation[i] = nadir_height; /* ZMIANA! */ /raster/r.geomorphon/pattern.c: 108 in calc_pattern() 102 } 103 } else { 104 patterns->distance[i]=search_distance; 105 } 106 */ 107 /* this is used to lower flat threshold if distance exceed flat_distance parameter */ >>> CID 1415711: (UNINIT) >>> Using uninitialized value "zenith_distance". 108 zenith_threshold = (flat_distance > 0 && 109 flat_distance < 110 zenith_distance) ? atan2(flat_threshold_height, 111 zenith_distance) : 112 flat_threshold; 113 nadir_threshold = (flat_distance > 0 && ** CID 1415710: Incorrect expression (SIZEOF_MISMATCH) /imagery/i.segment/write_output.c: 229 in write_bands_ms() ________________________________________________________________________________________________________ *** CID 1415710: Incorrect expression (SIZEOF_MISMATCH) /imagery/i.segment/write_output.c: 229 in write_bands_ms() 223 struct Colors colors; 224 struct History hist; 225 struct ngbr_stats Rout; 226 227 out_fd = G_malloc(sizeof(int) * globals->nbands); 228 name = G_malloc(sizeof(char *) * globals->nbands); >>> CID 1415710: Incorrect expression (SIZEOF_MISMATCH) >>> Passing argument "8UL /* sizeof (DCELL) */ * globals->nbands" to >>> function "G__malloc" and then casting the return value to "DCELL **" is >>> suspicious. 229 outbuf = G_malloc(sizeof(DCELL) * globals->nbands); 230 for (n = 0; n < globals->nbands; n++) { 231 outbuf[n] = Rast_allocate_d_buf(); 232 G_asprintf(&name[n], "%s%s", globals->Ref.file[n].name, globals->bsuf); 233 out_fd[n] = Rast_open_new(name[n], DCELL_TYPE); 234 } ** CID 1415709: (CHECKED_RETURN) /raster/r.clump/clump.c: 113 in do_renumber() /raster/r.clump/clump.c: 97 in do_renumber() ________________________________________________________________________________________________________ *** CID 1415709: (CHECKED_RETURN) /raster/r.clump/clump.c: 113 in do_renumber() 107 *temp_clump = new_clump; 108 do_write = 1; 109 } 110 temp_clump++; 111 } 112 if (do_write) { >>> CID 1415709: (CHECKED_RETURN) >>> Calling "lseek(cfd, coffset, 0)" without checking return value. This >>> library function may fail and return an error code. 113 lseek(cfd, coffset, SEEK_SET); 114 if (write(cfd, cur_clump, csize) != csize) 115 G_fatal_error(_("Unable to write to temp file")); 116 } 117 } 118 G_percent(1, 1, 1); /raster/r.clump/clump.c: 97 in do_renumber() 91 92 for (row = 0; row < nrows; row++) { 93 94 G_percent(row, nrows, 2); 95 96 coffset = (off_t)row * csize; >>> CID 1415709: (CHECKED_RETURN) >>> Calling "lseek(cfd, coffset, 0)" without checking return value. This >>> library function may fail and return an error code. 97 lseek(cfd, coffset, SEEK_SET); 98 if (read(cfd, cur_clump, csize) != csize) 99 G_fatal_error(_("Unable to read from temp file")); 100 101 temp_clump = cur_clump; 102 ** CID 1415708: Insecure data handling (TAINTED_SCALAR) ________________________________________________________________________________________________________ *** CID 1415708: Insecure data handling (TAINTED_SCALAR) /raster/r.statistics/o_adev.c: 51 in o_adev() 45 catb = basecat; 46 catc = covercat; 47 count = 0; 48 } 49 50 if (usecats) >>> CID 1415708: Insecure data handling (TAINTED_SCALAR) >>> Passing tainted variable "*((CELL *)&covercat)" to a tainted sink. 51 sscanf(Rast_get_c_cat((CELL *) &covercat, cats), "%lf", &x); 52 else 53 x = covercat; 54 55 for (i = 0; i < value; i++) { 56 if (count * sizeof(double) >= mem) { ** CID 1415707: (TAINTED_SCALAR) /lib/vector/diglib/plus.c: 235 in dig_load_plus() /lib/vector/diglib/plus.c: 225 in dig_load_plus() /lib/vector/diglib/plus.c: 255 in dig_load_plus() /lib/vector/diglib/plus.c: 245 in dig_load_plus() ________________________________________________________________________________________________________ *** CID 1415707: (TAINTED_SCALAR) /lib/vector/diglib/plus.c: 235 in dig_load_plus() 229 230 /* Lines */ 231 if (dig_fseek(plus, Plus->Line_offset, 0) == -1) 232 G_fatal_error(_("Unable read topology for lines")); 233 234 dig_alloc_lines(Plus, Plus->n_lines); >>> CID 1415707: (TAINTED_SCALAR) >>> Using tainted variable "Plus->n_lines" as a loop boundary. 235 for (i = 1; i <= Plus->n_lines; i++) { 236 if (dig_Rd_P_line(Plus, i, plus) == -1) 237 G_fatal_error(_("Unable to read topology for line %d"), i); 238 } 239 240 /* Areas */ /lib/vector/diglib/plus.c: 225 in dig_load_plus() 219 220 /* Nodes */ 221 if (dig_fseek(plus, Plus->Node_offset, 0) == -1) 222 G_fatal_error(_("Unable read topology for nodes")); 223 224 dig_alloc_nodes(Plus, Plus->n_nodes); >>> CID 1415707: (TAINTED_SCALAR) >>> Using tainted variable "Plus->n_nodes" as a loop boundary. 225 for (i = 1; i <= Plus->n_nodes; i++) { 226 if (dig_Rd_P_node(Plus, i, plus) == -1) 227 G_fatal_error(_("Unable to read topology for node %d"), i); 228 } 229 230 /* Lines */ /lib/vector/diglib/plus.c: 255 in dig_load_plus() 249 250 /* Isles */ 251 if (dig_fseek(plus, Plus->Isle_offset, 0) == -1) 252 G_fatal_error(_("Unable to read topology for isles")); 253 254 dig_alloc_isles(Plus, Plus->n_isles); >>> CID 1415707: (TAINTED_SCALAR) >>> Using tainted variable "Plus->n_isles" as a loop boundary. 255 for (i = 1; i <= Plus->n_isles; i++) { 256 if (dig_Rd_P_isle(Plus, i, plus) == -1) 257 G_fatal_error(_("Unable to read topology for isle %d"), i); 258 } 259 260 return (1); /lib/vector/diglib/plus.c: 245 in dig_load_plus() 239 240 /* Areas */ 241 if (dig_fseek(plus, Plus->Area_offset, 0) == -1) 242 G_fatal_error(_("Unable to read topo for areas")); 243 244 dig_alloc_areas(Plus, Plus->n_areas); >>> CID 1415707: (TAINTED_SCALAR) >>> Using tainted variable "Plus->n_areas" as a loop boundary. 245 for (i = 1; i <= Plus->n_areas; i++) { 246 if (dig_Rd_P_area(Plus, i, plus) == -1) 247 G_fatal_error(_("Unable read topology for area %d"), i); 248 } 249 250 /* Isles */ ** CID 1415706: Resource leaks (RESOURCE_LEAK) /lib/rst/interp_float/segmen2d_parallel.c: 418 in IL_interp_segments_2d_parallel() ________________________________________________________________________________________________________ *** CID 1415706: Resource leaks (RESOURCE_LEAK) /lib/rst/interp_float/segmen2d_parallel.c: 418 in IL_interp_segments_2d_parallel() 412 G_free_ivector(indx); 413 G_free_vector(b); 414 */ 415 G_free(data_local[tid]->points); 416 G_free(data_local[tid]); 417 } >>> CID 1415706: Resource leaks (RESOURCE_LEAK) >>> Variable "point" going out of scope leaks the storage it points to. 418 } 419 } /* All threads join master thread and terminate */ 420 421 for (i_cnt = 0; i_cnt < threads; i_cnt++) { 422 G_free(matrix[i_cnt]); 423 G_free(indx[i_cnt]); ** CID 1415705: Resource leaks (RESOURCE_LEAK) /vector/v.external/list.c: 353 in list_layers_ogr() ________________________________________________________________________________________________________ *** CID 1415705: Resource leaks (RESOURCE_LEAK) /vector/v.external/list.c: 353 in list_layers_ogr() 347 ret = i; 348 } 349 } 350 351 OGR_DS_Destroy(Ogr_ds); 352 >>> CID 1415705: Resource leaks (RESOURCE_LEAK) >>> Variable "loc_proj_units" going out of scope leaks the storage it >>> points to. 353 return ret; 354 } ** CID 1415704: API usage errors (PW.TOO_FEW_PRINTF_ARGS) /vector/v.in.ascii/points.c: 151 in () ________________________________________________________________________________________________________ *** CID 1415704: API usage errors (PW.TOO_FEW_PRINTF_ARGS) /vector/v.in.ascii/points.c: 151 in () 145 catcol >= ntokens) { 146 if (ignore_flag) { 147 G_debug(3, "Skipping broken row %d: '%s'", row, buf); 148 continue; 149 } 150 else { >>> CID 1415704: API usage errors (PW.TOO_FEW_PRINTF_ARGS) >>> the format string requires additional arguments 151 G_warning(_("ntokens: %d, xcol: %d, ycol: %d, zcol: %d"), xcol, ycol, zcol); 152 G_fatal_error(_("Broken row %d: '%s'"), row, buf); 153 } 154 } 155 156 len = strlen(buf) + 1; ** CID 1415703: Resource leaks (RESOURCE_LEAK) /vector/v.label.sa/labels.c: 723 in label_line_candidates() ________________________________________________________________________________________________________ *** CID 1415703: Resource leaks (RESOURCE_LEAK) /vector/v.label.sa/labels.c: 723 in label_line_candidates() 717 tmp_shape = label->shape; 718 label->shape = tmp; 719 720 label_point_candidates(label); 721 label->shape = tmp_shape; 722 Vect_destroy_line_struct(tmp); >>> CID 1415703: Resource leaks (RESOURCE_LEAK) >>> Variable "below_candidates" going out of scope leaks the storage it >>> points to. 723 return; 724 } 725 726 candidates = G_calloc(n * 2, sizeof(label_candidate_t)); 727 for (i = 0; i < n; i++) { 728 memcpy(&candidates[i * 2], &above_candidates[i], ** CID 1415702: (DC.WEAK_CRYPTO) /vector/v.label.sa/annealing.c: 82 in simulate_annealing() /vector/v.label.sa/annealing.c: 72 in simulate_annealing() /vector/v.label.sa/annealing.c: 107 in simulate_annealing() ________________________________________________________________________________________________________ *** CID 1415702: (DC.WEAK_CRYPTO) /vector/v.label.sa/annealing.c: 82 in simulate_annealing() 76 if (lp->n_candidates < 2) 77 continue; 78 79 cc = lp->current_candidate; 80 /*and a random new candidate place */ 81 c = (int)((double)(lp->n_candidates) * >>> CID 1415702: (DC.WEAK_CRYPTO) >>> "rand" should not be used for security-related applications, because >>> linear congruential algorithms are too easy to break. 82 (rand() / (RAND_MAX + 1.0))); 83 if (c == cc) { 84 if (c == 0) 85 c++; 86 else 87 c--; /vector/v.label.sa/annealing.c: 72 in simulate_annealing() 66 67 for (i = 0; i < (n_labels * 30); i++) { 68 int l, c, cc, r; 69 label_t *lp; 70 71 /* pick a random label */ >>> CID 1415702: (DC.WEAK_CRYPTO) >>> "rand" should not be used for security-related applications, because >>> linear congruential algorithms are too easy to break. 72 r = rand(); 73 l = (int)((double)(n_labels) * (r / (RAND_MAX + 1.0))); 74 lp = &labels[l]; 75 /* skip labels without sufficient number of candidates */ 76 if (lp->n_candidates < 2) 77 continue; /vector/v.label.sa/annealing.c: 107 in simulate_annealing() 101 } 102 /* else apply with probability p=e^(-dE/T) */ 103 else { 104 double dp, dr; 105 106 dp = pow(M_E, -dE / T); >>> CID 1415702: (DC.WEAK_CRYPTO) >>> "rand" should not be used for security-related applications, because >>> linear congruential algorithms are too easy to break. 107 dr = (double)rand() / RAND_MAX; 108 if (dr <= dp) { 109 do_label_overlap(lp, cc, c); 110 lp->current_score += lp->candidates[c].score; 111 lp->current_candidate = c; 112 successes++; ** CID 1415701: Resource leaks (RESOURCE_LEAK) /vector/v.overlay/area_area.c: 493 in area_area() ________________________________________________________________________________________________________ *** CID 1415701: Resource leaks (RESOURCE_LEAK) /vector/v.overlay/area_area.c: 493 in area_area() 487 } 488 489 if (centr[0] || centr[1]) 490 Vect_write_line(Out, GV_BOUNDARY, Points, Cats); 491 } 492 >>> CID 1415701: Resource leaks (RESOURCE_LEAK) >>> Variable "Points" going out of scope leaks the storage it points to. 493 return 0; ________________________________________________________________________________________________________ To view the defects in Coverity Scan visit, https://u2389337.ct.sendgrid.net/ls/click?upn=nJaKvJSIH-2FPAfmty-2BK5tYpPklAc1eEA-2F1zfUjH6teExWYffAcTwo3Zs4Osg-2B-2F92CCWuAyO4ddCCiK6Lyu3Zo2A-3D-3DM68e_1fJmB2fTvLSRHaGG3R4Zs7PAImoD8NTRTiIHP0uw7V4OY0ITb54-2FoE1ZzXl37C1QCKUPbsY34wCDK65aEx6vK3rwfOAPPiZ22QlP53dsUyuhk8T-2F-2B5-2FY6fc6E0Zo2gA1EEKnReg6AGCxVLgvwUzLMKyj-2B86WRglCwV3iupUDJ63lyUwXtEMk4ZtrkmS-2BBpiVnA-2FyNWIdmftZLIRf4xNI5VJcGzuY0X5rTm-2Fl67voPtI-3D To manage Coverity Scan email notifications for "nete...@gmail.com", click https://u2389337.ct.sendgrid.net/ls/click?upn=nJaKvJSIH-2FPAfmty-2BK5tYpPklAc1eEA-2F1zfUjH6teEwKPNNrzEFiIgTetQBd7l2XshiJhkGRbbOKBdDwUVNeC5t3zZR9Cyp5DqHjaG-2B2Fd9-2B2JCJhGaf6K8XfKew1sOxms9SIUe7-2Bu1Q4p5KMnAibl5CD-2FGd8dRn7wJzLDcFswk-3DfOpQ_1fJmB2fTvLSRHaGG3R4Zs7PAImoD8NTRTiIHP0uw7V4OY0ITb54-2FoE1ZzXl37C1QetqwsKw5oa-2Bohu8YHnVupsXsOHyTm3xCAJN4wr0BebnWmOvOMCMuuPJzjeDcmxVbSLm-2BAVDnge6-2B7HLvui4acX96HYYG8kikpsex4yZ8vHzYmMm4TSxFfm-2B5IhDPh6QdhdxeCRWObiokr-2FKPshnPYZXXz2amJevsDn58R7Lx-2FK8-3D -- Markus Neteler, PhD https://www.mundialis.de - free data with free software https://grass.osgeo.org https://courses.neteler.org/blog _______________________________________________ grass-dev mailing list grass-dev@lists.osgeo.org https://lists.osgeo.org/mailman/listinfo/grass-dev