Browse Source

welcome to GRASS 7.0.svn

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@31142 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Neteler 16 years ago
commit
db49180dd7
100 changed files with 33186 additions and 0 deletions
  1. 327 0
      AUTHORS
  2. 58 0
      CHANGES
  3. 40 0
      COPYING
  4. 339 0
      GPL.TXT
  5. 309 0
      INSTALL
  6. 441 0
      Makefile
  7. 51 0
      README
  8. 192 0
      REQUIREMENTS.html
  9. 444 0
      SUBMITTING
  10. 77 0
      SUBMITTING_DOCS
  11. 109 0
      SUBMITTING_PYTHON
  12. 247 0
      SUBMITTING_SCRIPTS
  13. 281 0
      SUBMITTING_TCLTK
  14. 64 0
      TODO
  15. 1531 0
      aclocal.m4
  16. 360 0
      binaryInstall.src
  17. 1466 0
      config.guess
  18. 1579 0
      config.sub
  19. 16123 0
      configure
  20. 1814 0
      configure.in
  21. 45 0
      contributors.csv
  22. 40 0
      contributors_extra.csv
  23. 17 0
      db/Makefile
  24. 50 0
      db/base/Makefile
  25. 100 0
      db/base/columns.c
  26. 170 0
      db/base/connect.c
  27. 132 0
      db/base/copy.c
  28. 79 0
      db/base/createdb.c
  29. 97 0
      db/base/databases.c
  30. 47 0
      db/base/db.columns.html
  31. 126 0
      db/base/db.connect.html
  32. 75 0
      db/base/db.copy.html
  33. 39 0
      db/base/db.createdb.html
  34. 20 0
      db/base/db.databases.html
  35. 58 0
      db/base/db.describe.html
  36. 19 0
      db/base/db.drivers.html
  37. 23 0
      db/base/db.dropdb.html
  38. 39 0
      db/base/db.droptable.html
  39. 109 0
      db/base/db.execute.html
  40. 69 0
      db/base/db.select.html
  41. 35 0
      db/base/db.tables.html
  42. 136 0
      db/base/describe.c
  43. 80 0
      db/base/drivers.c
  44. 79 0
      db/base/dropdb.c
  45. 87 0
      db/base/droptable.c
  46. 176 0
      db/base/execute.c
  47. 8 0
      db/base/local_proto.h
  48. 79 0
      db/base/printtab.c
  49. 294 0
      db/base/select.c
  50. 104 0
      db/base/tables.c
  51. 119 0
      db/databaseintro.html
  52. 10 0
      db/db.login/Makefile
  53. 46 0
      db/db.login/description.html
  54. 107 0
      db/db.login/main.c
  55. 40 0
      db/drivers/Makefile
  56. 28 0
      db/drivers/README
  57. 41 0
      db/drivers/dbf/Makefile
  58. 125 0
      db/drivers/dbf/column.c
  59. 28 0
      db/drivers/dbf/create_table.c
  60. 71 0
      db/drivers/dbf/cursor.c
  61. 127 0
      db/drivers/dbf/db.c
  62. 34 0
      db/drivers/dbf/dbdriver.h
  63. BIN
      db/drivers/dbf/dbf_catalog/datetime.dbf
  64. BIN
      db/drivers/dbf/dbf_catalog/river.dbf
  65. 1075 0
      db/drivers/dbf/dbfexe.c
  66. 141 0
      db/drivers/dbf/describe.c
  67. 31 0
      db/drivers/dbf/driver.c
  68. 49 0
      db/drivers/dbf/error.c
  69. 41 0
      db/drivers/dbf/execute.c
  70. 125 0
      db/drivers/dbf/fetch.c
  71. 82 0
      db/drivers/dbf/globals.h
  72. 109 0
      db/drivers/dbf/grass-dbf.html
  73. 48 0
      db/drivers/dbf/listtab.c
  74. 48 0
      db/drivers/dbf/main.c
  75. 113 0
      db/drivers/dbf/main_debug.c
  76. 25 0
      db/drivers/dbf/proto.h
  77. 61 0
      db/drivers/dbf/select.c
  78. 35 0
      db/drivers/dbf/str.c
  79. 341 0
      db/drivers/dbf/table.c
  80. 30 0
      db/drivers/mk_dbdriver_h.sh
  81. 67 0
      db/drivers/mysql/Makefile
  82. 149 0
      db/drivers/mysql/create_table.c
  83. 77 0
      db/drivers/mysql/cursor.c
  84. 194 0
      db/drivers/mysql/db.c
  85. 40 0
      db/drivers/mysql/dbdriver.h
  86. 243 0
      db/drivers/mysql/describe.c
  87. 31 0
      db/drivers/mysql/driver.c
  88. 45 0
      db/drivers/mysql/error.c
  89. 90 0
      db/drivers/mysql/execute.c
  90. 270 0
      db/drivers/mysql/fetch.c
  91. 27 0
      db/drivers/mysql/globals.h
  92. 74 0
      db/drivers/mysql/grass-mesql.html
  93. 125 0
      db/drivers/mysql/grass-mysql.html
  94. 68 0
      db/drivers/mysql/index.c
  95. 59 0
      db/drivers/mysql/listtab.c
  96. 24 0
      db/drivers/mysql/main.c
  97. 94 0
      db/drivers/mysql/parse.c
  98. 15 0
      db/drivers/mysql/proto.h
  99. 80 0
      db/drivers/mysql/select.c
  100. 0 0
      db/drivers/odbc/INSTALL

+ 327 - 0
AUTHORS

@@ -0,0 +1,327 @@
+GRASS GIS 6 List of Authors
+===========================
+
+$Date$
+
+
+Many people have contributed to GRASS GIS. Without any one of them the
+project would not exist in its current form.
+
+The authors of the individual programs are listed at the end of their 
+manual page in the GRASS users manuals or in the source code. However, 
+numerous authors of bug fixes and enhancements as well as people who 
+have been working on coordination, integration, translation, 
+documentation and testing are not mentioned. Therefore, this 
+page is an attempt to acknowledge those who contributed to GRASS 
+development.
+
+Please allow us to extend our most cordial thanks to all of you. If you 
+contributed to GRASS at any point during its existence, please let us 
+know your name and e-mail address so we can add your name.
+
+Active parts of the program have authors dating back to GRASS's 
+inception in 1982. Please check the GRASS 1.x - 5.0 credits list at:
+ http://www.grass-gis.org/devel/grasscredits.html
+
+
+GRASS 6.0 was made up of entirely new code for much of the vector and 
+database management subsystems. The raster, display, and projection 
+subsystems are largely directly inherited from GRASS 5.4 without change. 
+The core GIS, GUI, and build subsystems are a hybrid of old and new code.
+
+Thus we must also thank and credit the members of the 5.0 core
+development team, listed below, as many are still active in the 
+project and GRASS 6 owes much of itself to the generosity of 
+their bright minds.
+
+
+Email addresses below have been spam-proofed to protect the innocent;
+add "@" and "." as needed.
+
+A list of contributors with write access is available in
+./contributors.csv
+
+A list of contributors without write access is available in
+./contributors_extra.csv
+
+A list of translators is available in
+./translators.csv
+
+
+New contributions specific to GRASS 6.1 - 6.3:
+-------------------------------------------------
+(work in progress: please complete and correct, this list may be incomplete)
+
+Additional authors:
+NVIZ
+ - ACS - Massimo Cuomo <m.cuomo at acsys.it>: New flythrough navigation
+
+gis.m/tcltk module GUI:
+ - Cedrik Shock <cedricpublic at shockfamily.net>
+
+Source code Quality assessment system
+ - SOCCER Labs at Ecole Polytechnique de Montreal, Canada
+   http://web.soccerlab.polymtl.ca/grass-evolution/grass-browsers/grass-index-en.html
+   http://www.grass-gis.org/mailman/listinfo/grass-qa
+
+Bugtracker maintainer:
+   Maciej "Maciek" Sieczka <werchowyna at epf.pl>
+
+Power user tester:
+   Maciej "Maciek" Sieczka <werchowyna at epf.pl>
+
+
+
+GRASS 5.7/6.0: Primary authors of new source code
+-------------------------------------------------
+
+Institutions:
+ ITC-IRST, Trento, Italy   Providing web structure and various mailing lists
+ Intevation GmbH, Germany  Providing CVS and Request Tracker
+ Baylor University, USA    Providing user mailing list 1998-5/2006
+
+VECTOR
+ - Radim Blazek <blazek itc it>: vector engine core developer
+ - David D Gray: vector engine contributions
+ - modules: see individual authors and ./contributors.csv
+ 
+DBMI
+ - based on original code from GRASS 5.0 (developer unknown, CERL?)
+ - Radim Blazek <blazek itc it>: core developer of 5.7 enhancements
+ - Alexander Shevlakov: drivers and sqlp contributions
+ - modules: see individual authors and ./contributors.csv
+
+DGLib: vector networking
+ - Roberto Micarelli <mi ro iol it>: LIBDGL - graph library for vector
+     network analysis
+
+FORMS library
+ - Radim Blazek <blazek itc it>: core developer 
+
+RASTER
+ - Modules: see 5.4 authors below + individual modules
+ - Integration of raster modules: Markus Neteler <neteler itc it>
+ - Large file support (LFS): Glynn Clements  <glynn gclements.plus.com>
+ - modules: see individual authors and ./contributors.csv
+
+3D RASTER
+ - Grid3D library by CERL and GMSL/University of Illinois
+ - Jaro Hofierka <hofierka geomodel sk>
+ - Helena Mitasova <hmitaso unity ncsu edu>
+ - Alfonso Vitti <alfonso vitti ing unitn it>: important bugfixes
+ - Soeren Gebbert <soeren.gebbert gmx de>: important bugfixes
+ - modules: see individual authors and ./contributors.csv
+
+PROJ
+ - Integrated by Paul Kelly <paul-grass stjohnspoint co uk>
+
+NEW DOCUMENTATION:
+ - existing documentation: see 5.4 authors below + individual modules
+ - Markus Neteler <neteler itc it>
+ - Otto Dassau <dassau gdf-hannover de>
+ - M. Hamish Bowman <hamish.bowman otago ac nz>
+ - Radim Blazek <blazek itc it>
+
+WEB SITE
+ - Markus Neteler <neteler itc it>: setup and maintenance since 1998,
+     cron jobs for auto-update, PHP migration, mailing lists, etc
+ - Scott Mitchell <smitch mac com>: contributions
+ - M. Hamish Bowman <hamish.bowman otago ac nz>: contributions
+
+
+GRASS 6.0 - 6.2 major project contributers
+------------------------------------------
+
+PROJECT INTEGRATION
+ - Markus Neteler <neteler itc it>: GRASS project coordination
+ - Radim Blazek <blazek itc it>: driving force for vector enhancements
+ - M. Hamish Bowman <hamish.bowman otago ac nz>: General sanitation
+ - Bernhard Reiter <bernhard intevation de>: Maintain CVS, Bug-tracker
+
+BUILD SYSTEM
+ - Eric Mitchell: core development
+ - Paul Kelly <paul-grass stjohnspoint co uk>: Fine tuning
+ - Glynn Clements <glynn gclements plus com>: Assistance and advice
+
+DOCUMENTATION
+ - New docs engine: Markus Neteler <neteler itc it>
+ - Programming docs/doxygen: Markus Neteler <neteler itc it>, Paolo Armani
+
+GUI
+ - Radim Blazek <blazek itc it>: primary author of d.m and v.digit
+ - Michael Barton <michael.barton asu edu>: tcltkgrass menu system 
+   partial rewrite and integration into d.m
+ - Multibyte FreeType Font Support: www.FOSS4G.org team
+
+CODE PORTABILITY
+ - Brad Douglas <rez at touchofmadness.com>: various libs
+
+INTERNATIONALIZATION
+ - Integration: Markus Neteler <neteler itc it>, based on www.FOSS4G.org initiative:
+    (S. Masumoto, V. Raghavan, S. Nonogaki, M. Neteler, T. Nemoto, T. Mori, M. Niwa,
+     A. Hagiwara, and N. Hattori)
+ - Multi-byte text support: FOSS4G members, see http://www.foss4g.org
+ - Translators: There are as many to thank as there are languages to speak
+    - Arabic: Dr. Alaa Masoud
+    - Chinese: Zhang Jun
+    - Czech: Martin Landa, Jachym Cepicky, Michal Bil, Radim Blazek
+    - German: Stephan Holl 
+    - French: Emmanuel Saracco, Daniel Calvelo, Laurent Courty
+    - Italian: Maurizio Napolitano, Luciano Montanaro, Lorenzo Moretti
+    - Japanese: Susumu Nonogaki
+    - Polish: Artur Niecior
+    - Russian: Alexander Shevlakov
+    - Slovenia: Miha Staut
+    - Spanish: el bueno (manzano_jm), Luis Izquierdo, Daniel Calvelo
+    - Turkish: Aras.Gor.O Yalcin Yilmaz
+    - Vietnamese: Tran Van Anh, Bui Huu Manh (Mystus vittatus)
+
+NVIZ
+ - Radim Blazek <blazek itc it>: updated vector and 3D vector support
+ - Bob Covill <bcovill tekmap ns ca>: Core enhancements
+ - Helena Mitasova <hmitaso unity ncsu edu>: 3D volume support supervision
+ - Jaro Hofierka <hofierka geomodel sk>: 3D volume support supervision
+ - Tomas Paudits: 3D volume support implementation
+
+SPECIAL THANKS:
+ - Frank Warmerdam <warmerdam pobox com>: for writing and maintaining the
+    essential GDAL and OGR libraries as well as PROJ4, GeoTIFF, etc etc.
+    He plays a key role in (Free) GIS interoperability.
+
+
+In addition, we must thank those that have packaged GRASS 6 into the
+easy to install binary packages which are at the forefront of the users'
+software experience.
+
+Linux (generic): Markus Neteler <neteler itc it>
+Linux (Debian):  DebianGIS Project <pkg-grass-devel lists.alioth.debian.org>
+Linux (SuSE):    GDF Hannover bR, see http://www.gdf-hannover.de
+Mac OS/X:        Lorenzo Moretti <lorenzo.moretti bologna enea it>
+                 Jeshua Lacock <jeshua OpenOSX com>
+MS-Windows/Cygwin:  Huidae Cho <grass4u gmail com>
+
+
+GRASS GIS 5.4 Author List
+-------------------------
+
+Please check additionally the GRASS 1.x-5.0 credits list at:
+ http://www.grass-gis.org/devel/grasscredits.html
+
+While it is impossible for us to give credit to everyone (past 
+and present) who has contributed to GRASS, the following is the 
+incomplete official list for GRASS 5.0-5.4:
+
+Institutions:
+ ITC-IRST, Trento, Italy   Providing web structure and various mailing lists
+ Intevation GmbH, Germany  Providing CVS and Request Tracker
+ Baylor University, USA    Providing user mailing list 1998-5/2006
+
+
+GRASS 5 Core Team (most have CVS write access):
+ Michael Barton  <michael.barton asu edu>      (tcltkgrass menus)
+ Roger Bivand    <Roger.Bivand nhh.no>         ("R" statistical language 
+                                                support)
+ Radim Blazek    <blazek itc.it>               (DBMS support, ps.map, d.dm)
+ Hamish Bowman   <hamish.bowman otago.ac.nz>   (ps.map,display,rasters, ...)
+ Huidae Cho      <grass4u gmail.com>           (FreeType,r.topmodel,r.topidx, ..)
+ Glynn Clements  <glynn gclements.plus.com>    (Code portability, ...)
+ Bob Covill      <bcovill tekmap.ns.ca>        (NVIZ export formats, 
+                                                r.in|out.bin)
+ Jaro Hofierka   <hofierka geomodel.sk>        (NVIZ port, grid3D and related)
+ Paul Kelly      <paul-grass stjohnspoint.co.uk> (PROJ4, datum trafo, IRIX ...)
+ Lubos Mitas     <lmitas ncsa.uiuc.edu>        (multivariate spline
+                                                interpolation (RST) 
+                                                and erosion modeling)
+ Helena Mitasova <hmitaso unity.ncsu.edu>      (interpolation modules, NVIZ,
+                                                G3D, erosion modelling)
+ Eric G. Miller  <egm2 jps.net>                (sites format, new autoconf 
+                                                system, bugfixes etc.)
+ Roger S. Miller <rgrmill rt66.com>            (raster modules, r.drain etc.)
+ Markus Neteler  <neteler itc.it>              (GRASS 5 coordination, this&that ...)
+ Bernhard Reiter <bernhard intevation.de>      (License, CVS, Bugfixes, RT)
+ Alexander Shevlakov <sixote yahoo.com>        (PostgreSQL/GRASS interface)
+ Mike Thomas <miketh brisbane.paradigmgeo.com> (generic Windows driver)
+ Jan-Oliver Wagner   <jan intevation.de>       (XML-support, 
+                                                Module descriptions)
+ Frank Warmerdam     <warmerdam pobox.com>     (GDAL, SHAPE implementation, 
+                                                new GRASS I/O library)
+ Michel Wurtz        <mw teledetection.fr>     (ESRI E00 support)
+
+
+Former programmers (GRASS 5.0):
+ Andrea Aime         <aaime comune.modena.it>    (raster/vector modules)
+ Carl Anderson       <candrsn mindspring.com>    (XDRIVER support)
+ Malcolm Blue        <mblue nb.sympatico.ca>     (Windows NT/Cygnus port)
+ Jacques Bouchard    <bouchard onera.fr>         (tcltkgrass, bugfixes)
+ David D. Gray       <ddgray armadce.demon.co.uk>(Vector, SQL support)
+ Justin Hickey       <jhickey hpcc.nectec.or.th> (GRASS initialization, 
+						  new env var handling, SGI)
+ John Huddleston     <jhudd lamar.colostate.edu> (Windows NT/Cygnus port)
+ Bill Hughes         <bhughes grasshoppernet.com> (64bit compliance)
+ Andreas Lange       <Andreas.Lange Rhein-Main.de> (SGI/Irix compliance, 
+						   Proj/Datum support)
+ Brook Milligan      <brook trillium.NMSU.Edu>    (initial autoconf implementation)
+ Phisan Santitamnont <fsvpss eng.chula.ac.th>     (initial Linux compilation
+                                                   of 4.2.1, bugfixes)
+
+Significant contributions (very incomplete, please add):
+ Angus Carr      <apcarr flash.lakeheadu.ca> (ERDAS LAN)
+ Eric Mitchell   <emitchell altaira com>     (new 5.1 Makefile system)
+ Pierre de Mouveaux <pierre polaris-technologies.com>  (NVIZ, d.layers)
+ Job Spijker     <spijker geo uu.nl>         (v.bubble)
+ Laura Toma      <ltoma bowdoin edu>         (r.terraflow)
+ Philip Warner   <pjw rhyme com.au>          (NVIZ code cleanup)
+ David B. Satnik and Ali R. Vali             (i.fft)
+
+Additional project contributions (very incomplete, please add):
+ Florian Goessmann <florian wallweg39 de>
+ Scott Mitchell    <smitch mac com>
+ Martin Wegmann    <wegmann biozentrum uni-wuerzburg.de>
+
+Former User support (GRASS 5.0):
+ Edward Zarecky  <Edward_Zarecky baylor.edu> (user support)
+ Lisa Zygo       <Lisa_Zygo baylor.edu>      (user support, GRASS manuals)
+
+Former GRASS 4.2.1 development:
+   University of Hannover/Physical Geography and Landscape Ecology
+   Markus Neteler <neteler geog.uni-hannover.de> (GRASS 4.2.1 coordination)
+
+Former GRASS 4.2.0 development:
+   Center for Applied Geographic and Spatial Research
+   Bruce Byars <Bruce_Byars baylor.edu> (GRASS 4.2.0 coordination)
+
+Former GRASS 4 development (1984 to 1995):
+   U.S. Army Construction Engineering Research Laboratories  (CERL)
+   Jim Westervelt, Michael Shapiro, Chris Rewerts, Robert Lozar, David Gerdes, ...
+   See: http://www.grass-gis.org/devel/grasscredits.html
+
+Former Institutions
+ - University of Illinois at Urbana-Champaign, USA
+   Helena Mitasova <hmitaso unity.ncsu.edu> (interpolation modules, NVIZ, G3D)
+   William Brown   <brown gis.uiuc.edu>     (libraries, interpolation modules, 
+					     NVIZ, G3D)
+
+ - National Center for Supercomputing Applications, USA
+   Lubos Mitas (multivariate spline interpolation (RST) and erosion modeling)
+ 
+ - High Performance Computing Center, Thailand
+   National Electronics and Computer Technology Center
+   Bangkok, Thailand
+
+ - Baylor University: Hosting the user mailing list, 1998-5/2006
+
+
+Contact:
+
+ GRASS Development Team
+ c/o M. Neteler
+ Fondazione Mach - Centre for Alpine Ecology
+ 38100 Viote del Monte Bondone (Trento)
+ Italy
+ email: neteler AT cealp.it
+
+Internet:  http://www.grass-gis.org/ (main site)
+           http://grass.ibiblio.org/ (mirror)
+           http://www.grass-gis.org/mirrors.php (list of mirrors)
+
+with a worldwide distribution network.

+ 58 - 0
CHANGES

@@ -0,0 +1,58 @@
+CHANGES IN GRASS 6 compared to GRASS 5
+
+    * New Vector Engine (geometry):
+          o Support for 2D/3D vectors (see screenshot) (CAD drawings,
+            TINs), visualization supported in NVIZ
+          o multiformat - also virtual map supported from external
+            data sources (SHAPE-file, PostGIS) without the need of data
+            conversion (through OGR library with 'v.external');
+            Export/Import to PostGIS;
+          o spatial index build on the fly - 'v.build' (was:
+            v.support) significantly accelerated;
+          o category index to accelerate attribute queries;
+
+    * Database Management Interface (attributes):
+          o Attribute storage in DBMS for compatibility with industry
+            standards (SQL based interface for PostgreSQL, mySQL, ODBC, dBase)
+          o multiattribute - attributes saved in dBase files (default)
+            or saved in external DBMS
+          o multilayer - features in one vector may represent one or
+            several layers and may be linked to one or many external
+            tables
+          o forms library implemented for user friendly query dialogs
+          o Linear reference systems supported (LRS, yet to integrate)
+
+    * Applications/Misc:
+          o SQL queries/selects/extractions supported by vector modules
+          o interactive attributes updating is supported through the
+            forms library (d.what.vect lets you modify directly the
+            attached attributes)
+          o Vector network analysis: Shortest path, Traveling salesman
+            (round trip), Allocation of sources (subnetworks), Minimum
+            Steiner trees (starlike connections), and isodistances (from
+            centers) (e.g. shortest path, see screenshot) - based on
+            DGLIB (Directed Graph Library), costs may be assigned both
+            to nodes and arcs (and also different in both directions of
+            a vector line)
+          o new v.digit with GUI (screenshot)
+          o import and export of any OGR supported vector format
+            (Shapefile, TIGER, MapInfo and GML2, PostGIS and DGN)
+          o GUI generated on runtime and display manager (screenshots)
+          o i18n: support for multiple languages (messages partially
+            indicated and translated)
+          o multiple GRASS sessions: a user can start more than one session at the time
+
+    * Interoperability
+          o Raster and vector data interoperability is granted through
+            the GDAL/OGR libraries which implement interfaces to OGC
+            standards and common GIS data formats
+
+    * Volume visualization
+          o NVIZ now supports volume (voxel) visualization
+          o VTK export
+
+    * Large File Support for raster maps (Experimental!)
+          o GRASS 6.0 experimentally supports reading and writing
+            large files (> 2GB, LFS support)
+
+    * Programmer's manual integrated into source code (doxygen)

+ 40 - 0
COPYING

@@ -0,0 +1,40 @@
+Copyright and License Statement
+
+The Geographic Resources Analysis and Support System (GRASS)
+Geographic Information System (GIS) is Copyright by members
+of the GRASS Development Team.
+
+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.
+
+Parts of GRASS are not copyright by the GRASS development team.
+The original authors hold the copyrights and you have to abide
+to their licensing terms where noted.
+(Keep in mind that code linking into GRASS can only be distributed
+if compatible with the GPL.)
+
+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 General Public License (GPL) 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.
+
+Questions regarding GRASS GIS should be directed to the
+GRASS Development Team at the following address:
+
+ GRASS Development Team
+ c/o M. Neteler
+ Fondazione Mach - Centre for Alpine Ecology
+ 38100 Viote del Monte Bondone (Trento)
+ Italy
+ neteler AT cealp.it
+
+Internet:  http://grass.osgeo.org
+           http://www.grass-gis.org

+ 339 - 0
GPL.TXT

@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 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.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.

+ 309 - 0
INSTALL

@@ -0,0 +1,309 @@
+                   INSTALL GRASS from source code
+		   ------------------------------
+
+Please read *all* text below.
+
+Note: During the development stages, this version of GRASS was
+      previously called GRASS 5.1 and 5.7.
+
+
+Table of contents
+PREREQUISITES
+(A) SOURCE CODE DISTRIBUTION
+(B) COMPILATION
+(C) COMPILATION NOTES for 64bit platforms
+(D) INSTALLATION (first time)
+(E) INSTALLATION ON MACOSX
+(F) RUNNING GRASS
+(G) UPDATE OF SOURCE CODE (CVS or CVS snapshot only)
+(H) COMPILING INDIVIDUAL MODULES - OWN MODULES
+(I) CODE OPTIMIZATION
+(J) DEBUGGING OPTIONS
+(K) LARGE FILE SUPPORT (for raster maps)
+(L) SUPPORT
+(M) GRASS PROGRAMMER'S MANUAL
+(N) CONTRIBUTING CODE AND PATCHES
+(O) DRAFT TUTORIAL
+
+
+PREREQUISITES
+
+The install order matters. GRASS needs at least two libraries
+which have to be installed before installing/compiling GRASS:
+For links to the software, see ./REQUIREMENTS.html in this
+directory:
+
+Installation order:
+	1. PROJ4
+	2. GDAL-OGR  (compiled without GRASS support)
+        3. optionally: databases such as PostgreSQL, MySQL, sqlite
+	4. GRASS
+        5. optionally: GDAL-OGR-GRASS plugin
+
+(A) SOURCE CODE DISTRIBUTION
+
+GRASS source code is currently distributed in 2 forms:
+
+1) Officially released source code (e.g. grass-6.0.0.tar.gz or later)
+
+  The Full source code version contains all the GRASS source code
+  required for compilation. It is distributed as one file (*.tar.gz
+  package) and the version is composed of 3 numbers, e.g. 6.0.0, 6.0.1
+  etc.
+
+2) SVN or SVN Snapshots of source code (SVN or SVN snapshot)
+
+  This version of the source code can be acquired either from the SVN
+  repository (http://svn.osgeo.org/grass/) or as a snapshot
+  (*.tar.gz package) of that SVN repository. The SVN snapshot name
+  contains the date when the snapshot was created (checked out from
+  the SVN repository), e.g. grass-6.3.svn_src_snapshot_2008_01_19.tar.gz
+
+
+(B) COMPILATION
+
+IMPORTANT: All unix distributions are different.
+           For Solaris, see hint below.
+
+The command,
+
+   ./configure --help 
+
+explains the options used to disable the compilation of non-mandatory
+GRASS modules. See REQUIREMENTS.html for details.
+  
+First step of the compilation:
+
+    CFLAGS="-g -Wall" ./configure
+
+
+Explanation of make targets: 
+
+    make install       - installs the binary
+
+    make bindist       - make a binary package with install script
+
+    make srcdist       - make a source package for distribution
+    make srclibsdist   - make a source package for library distribution
+
+    make libs          - make libraries only
+
+    make clean         - delete all files created by 'make' 
+    make distclean     - 'make clean' + delete all files created by './configure'
+    make libsclean     - clean libraries compiled by 'make libs'
+
+    make htmldocs      - generate programmer's documentation in HTML
+    make packagehtmldocs - package programmer's documentation in HTML
+    make pdfdocs       - generate programmer's documentation as PDF files
+
+
+Next step is the compilation itself:
+
+    make       
+
+
+Note for Solaris users:
+
+To configure GRASS correctly on a system which doesn't have a suitable
+install program (AC_PROG_INSTALL ignores versions which are known to
+have problems), you need to ensure that $srcdir is an absolute path,
+by using e.g.:
+
+	`pwd`/configure ...
+or:
+	./configure --srcdir=`pwd` ...
+
+Then proceed as described above.
+
+
+Note for using a different compiler:
+
+By setting environment variables, the compiler
+names can be defined (C and C++):
+
+	CC=cc CPP=cpp ./configure ...
+
+
+(C) COMPILATION NOTES for 64bit platforms
+
+To successfully compile GRASS on 64bit platforms, the required
+FFTW2 library has to be compiled with -fPIC flag:
+
+    #this applies to FFTW2, not GRASS:
+    cd fftw-2.1.5/
+    CFLAGS="-fPIC" ./configure
+    make
+    make install
+
+To fully enable 64bit library usage for GRASS on 64bit platforms, 
+the following additional parameters are recommended/required:
+
+    ./configure \
+       --enable-64bit \
+       --with-libs=/usr/lib64 \
+       ...
+
+See also CODE OPTIMIZATION below.
+
+
+(D) INSTALLATION (first time)
+
+After compilation, the resulting code is stored in the directory
+    ./dist.$ARCH
+and the scripts (grass6, ...) in
+    ./bin.$ARCH
+
+To run GRASS, simply start
+    ./bin.$ARCH/grass6
+
+or run
+
+    make install
+    grass6
+
+
+(E) INSTALLATION ON MACOSX
+
+See the ReadMe.rtf in the ./macosx/ folder.
+
+
+(F) RUNNING GRASS
+
+Download a sample data package from the GRASS web site, for example the
+Spearfish60 data set. Extract the data set and point "database" in the
+GRASS startup menu to the directory.
+
+Enjoy.
+
+
+(G) UPDATE OF SOURCE CODE (SVN or SVN snapshot only)
+
+Assuming that you want to update your current installation from
+SVN, you have to perform a few steps. In general:
+
+- update from SVN
+- configure, compile
+
+In detail:
+
+    cd /where/your/grass6sourcecode/lives/
+    svn update
+    ./configure ...
+    make
+    make install
+
+
+(H) COMPILING INDIVIDUAL MODULES - OWN MODULES
+
+To compile (self-made) GRASS modules or to compile modified modules
+at least the GRASS libraries have to be compiled locally. This is
+done by launching:
+
+    make libs
+
+Then change into the module's directory and launch the "make" 
+command. The installation can be either done with "make install" from
+the main source code directory or locally with 
+    "INST_NOW=y make"
+
+You may want to define an alias for this:
+    alias gmake6='INST_NOW=y make'
+Then simply compile/install the current module with
+    gmake6
+
+Note: If you keep your module source code outside the standard GRASS
+source code directory structure, you will have to change the relative
+path(s) in the Makefile to absolute path(s).
+
+
+(I) CODE OPTIMIZATION
+
+If you would like to set compiler optimisations, for a possibly faster
+binary, type (don't enter a ";" anywhere):
+
+	CFLAGS=-O ./configure
+or,
+	setenv CFLAGS -O
+	./configure
+
+whichever works on your shell. Use -O2 instead of -O if your compiler
+supports this (note: O is the letter, not zero). Using the "gcc" compiler,
+you can also specify processor specific flags (examples, please suggest
+better settings to us):
+
+  CFLAGS="-mcpu=athlon -O2" # AMD Athlon processor with code optimisations
+  CFLAGS="-mcpu=pentium"    # Intel Pentium processor
+  CFLAGS="-mcpu=pentium4"   # Intel Pentium4 processor
+  CFLAGS="-O2 -msse -msse2 -mfpmath=sse -minline-all-stringops" # Intel XEON 64bit processor
+  CFLAGS="-mtune=nocona -m64 -minline-all-stringops"            # Intel Pentium 64bit processor
+
+To find out optional CFLAGS for your platform, enter:
+  gcc -dumpspecs
+
+See also: http://gcc.gnu.org/
+
+A real fast GRASS version (and small binaries) will be created with
+LDFLAGS set to "stripping" (but this disables debugging):
+
+  CFLAGS="-O2 -mcpu=<cpu_see_above> -Wall" LDFLAGS="-s" ./configure
+
+
+(J) DEBUGGING OPTIONS
+
+The LDFLAGS="" part must be undefined as "-s" will strip the debugging 
+information.
+
+Don't use -O for CFLAGS if you want to be able to step through function
+bodies. When optimisation is enabled, the compiler will re-order statements
+and re-arrange expressions, resulting in object code which barely resembles
+the source code.
+
+The -g and -Wall compiler flags are often useful for assisting debugging:
+
+  CFLAGS="-g -Wall" ./configure
+
+See also the file
+./doc/debugging.txt
+
+
+(K) LARGE FILE SUPPORT (for raster maps)
+
+GRASS >= 6.0 includes experimental support for reading and writing large files
+(> 2GB) if it is possible in your operating system. If you compile with
+  configure [...] --enable-largefile
+you should be able to have raster maps which are larger than 2GB.
+
+Note that the support currently only applies to the core raster I/O code.
+Individual programs may or may not work with large files - please report.
+
+
+(L) SUPPORT
+
+Note that this code is still actively being developed and errors inevitably
+turn up. If you find a bug, please report it to the GRASS bug tracking system
+so we can fix it. See http://grass.osgeo.org/bugtracking/index.php
+
+If you are interested in helping to develop GRASS, please join the GRASS
+developers mailing list. See http://grass.osgeo.org/devel/index.php
+
+
+(M) GRASS PROGRAMMER'S MANUAL
+
+The Programmer's manual is generated with doxygen from the source code.
+Please see the README file and the files at:
+http://grass.osgeo.org/devel/index.php#prog
+
+
+(N) CONTRIBUTING CODE AND PATCHES
+
+Please see ./SUBMITTING, ./SUBMITTING_DOCS, ./SUBMITTING_TCLTK
+./SUBMITTING_PYTHON and ./SUBMITTING_SCRIPTS in this directory.
+
+
+(O) DRAFT TUTORIAL
+
+http://grass.gdf-hannover.de/twiki/bin/view/GRASS/GrassSixTutorial
+
+------------------
+(C) 1999-2008 by The GRASS Development Team
+$Date$

+ 441 - 0
Makefile

@@ -0,0 +1,441 @@
+#############################################################################
+#
+# MODULE:   	GRASS Compilation
+# AUTHOR(S):	Original author unknown - probably CERL
+#   	    	Justin Hickey - Thailand - jhickey AT hpcc.nectec.or.th
+#		Markus Neteler - Germany - neteler AT itc.it
+#		Andreas Lange - Germany - Andreas.Lange AT Rhein-Main.de
+#		Radim Blazek - Italy - blazek AT itc.it
+# PURPOSE:  	It provides the commands necessary to compile, install,
+#		clean, and uninstall GRASS
+#		See INSTALL file for explanations.
+# COPYRIGHT:    (C) 2002,2004 by the GRASS Development Team
+#
+#               This program is free software under the GNU General Public
+#   	    	License (>=v2). Read the file COPYING that comes with GRASS
+#   	    	for details.
+#
+#############################################################################
+
+MODULE_TOPDIR = .
+
+include $(MODULE_TOPDIR)/include/Make/Platform.make
+include $(MODULE_TOPDIR)/include/Make/Grass.make
+
+# Install directories
+exec_prefix=            ${prefix}
+BINDIR=			${UNIX_BIN}
+
+# Shell commands
+MAKE_DIR_CMD=		mkdir -p -m 755
+
+# Extra commands
+HTML2PDF=		htmldoc --footer d.1
+GRASS_PDFDIR=		$(GISBASE)/docs/pdf
+
+
+DIRS = \
+	lib \
+	db \
+	display \
+	doc \
+	gem \
+	general \
+	gui \
+	imagery \
+	misc \
+	ps \
+	raster \
+	raster3d \
+	scripts \
+	sites \
+	tools \
+	vector \
+	visualization \
+	man \
+	macosx
+
+SUBDIRS = $(DIRS)
+
+ifneq ($(strip $(HAVE_NLS)),)
+	LOCALE=1
+else
+	LOCALE=0
+endif
+
+FILES = AUTHORS COPYING CHANGES REQUIREMENTS.html GPL.TXT
+
+BIN_DIST_FILES = $(FILES) \
+	grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}.tmp \
+	bin \
+	bwidget \
+	docs \
+	driver \
+	etc \
+	fonts \
+	include \
+	lib \
+	man \
+	scripts
+
+default: builddemolocation
+	@echo "GRASS GIS compilation log"     > $(ERRORLOG)
+	@echo "-------------------------"    >> $(ERRORLOG)
+	@echo "Started compilation: `date`"  >> $(ERRORLOG)
+	@echo "--"                           >> $(ERRORLOG)
+	@echo "Errors in:"                   >> $(ERRORLOG)
+	chmod 744 install-sh
+	@list='$(SUBDIRS)'; \
+	for subdir in $$list; do \
+		$(MAKE) -C $$subdir; \
+	done
+	if [ ${LOCALE} -eq 1 ] ; then $(MAKE) -C locale; fi
+	-cp -f $(FILES) ${ARCH_DISTDIR}/
+	-cp -f ${ARCH_BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR} ${ARCH_DISTDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}.tmp
+	@(cd tools ; sh -c "./build_html_index.sh")
+	@if [ `cat "$(ERRORLOG)" | wc -l` -gt 5 ] ; then \
+		echo "--"     >> $(ERRORLOG) ; \
+		echo "In case of errors please change into the directory with error and run 'make'." >> $(ERRORLOG) ; \
+		echo "If you get multiple errors, you need to deal with them in the order they"      >> $(ERRORLOG) ; \
+		echo "appear in the error log. If you get an error building a library, you will"     >> $(ERRORLOG) ; \
+		echo "also get errors from anything which uses the library."  >> $(ERRORLOG) ; \
+	else \
+		echo "No errors detected." >> $(ERRORLOG) ; \
+	fi
+	@echo "--"  >> $(ERRORLOG)
+	@echo "Finished compilation: `date`" >> $(ERRORLOG)
+	@cat $(ERRORLOG)
+	@if [ `cat "$(ERRORLOG)" | wc -l` -gt 8 ] ; then false ; else true ; fi
+
+LIBDIRS = \
+	lib/external/shapelib \
+	lib/datetime \
+	lib/gis \
+	lib/linkm \
+	lib/db \
+	lib/form \
+	lib/vector \
+	db/drivers
+
+# Compile libraries only
+libs:
+	make -C lib/ headers
+	@list='$(LIBDIRS)'; \
+	for subdir in $$list; do \
+		$(MAKE) -C $$subdir; \
+	done
+	-cp -f $(FILES) ${ARCH_DISTDIR}/
+	-cp -fr --parents include ${ARCH_DISTDIR}/
+
+#we leave this target for a while so that people can easily upgrade (11/2004):
+mix:
+	@echo "NOTE: 'make mix' is no longer needed (changed 9 Nov 2004)"
+
+mixclean:
+	list='$(SUBDIRS)'; \
+	find include -type l -exec rm {} \; 2>/dev/null; \
+	for subdir in $$list; do \
+		find $$subdir -type l -exec rm {} \; 2>/dev/null; \
+	done
+	-rm -f MIX 
+
+# Any target that has a dependency on this target will be forced to be made.
+# If we switch to GNU Make then this feature can be replaced with .PHONY
+FORCE:
+
+cleandistdirs: 
+	-rm -rf ${ARCH_DISTDIR}/bin/         2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/bwidget/     2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/docs/        2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/driver/      2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/etc/         2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/fonts/       2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/include/     2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/lib/         2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/locale/      2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/man/         2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/scripts/     2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/demolocation/ 2>/dev/null
+	-rm -rf ${ARCH_DISTDIR}/tcltkgrass/ 2>/dev/null
+	-rm -f ${ARCH_DISTDIR}/AUTHORS ${ARCH_DISTDIR}/CHANGES ${ARCH_DISTDIR}/REQUIREMENTS.html ${ARCH_DISTDIR}/COPYING ${ARCH_DISTDIR}/GPL.TXT ${ARCH_DISTDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}.tmp 2>/dev/null
+	-rmdir ${ARCH_DISTDIR}
+	-rm -f ${ARCH_BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR} 2>/dev/null
+	-rm -f ${ARCH_BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}.bat 2>/dev/null
+	-rmdir ${ARCH_BINDIR}
+
+# Clean out the strings extracted from scripts for translation
+cleanscriptstrings:
+	rm -f locale/scriptstrings/*.c 2>/dev/null
+
+clean: cleandistdirs cleanscriptstrings
+	@list='$(SUBDIRS)'; \
+	for subdir in $$list; do \
+		$(MAKE) -C $$subdir clean; \
+	done
+
+libsclean: cleandistdirs
+	@list='$(LIBDIRS)'; \
+	for subdir in $$list; do \
+		$(MAKE) -C $$subdir clean; \
+	done
+
+distclean: clean
+	-rm -f config.cache config.log config.status config.status.${ARCH} 2>/dev/null
+	-rm -f ChangeLog ChangeLog.bak $(ERRORLOG) grass.pc
+	-rm -f include/config.h include/version.h include/winname.h include/Make/Grass.make include/Make/Platform.make 2>/dev/null
+	-rm -f swig/perl/Makefile.PL swig/perl2/make.pl swig/python/Makefile 2>/dev/null
+
+strip: FORCE
+	@ if [ ! -f ${ARCH_BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR} ] ; then \
+		echo "ERROR: GRASS has not been compiled. Try \"make\" first."; \
+		echo "  Strip aborted, exiting Make."; \
+		exit; \
+	fi; \
+	cd ${ARCH_DISTDIR} ; find . -type f -perm +111 -exec strip {} \;
+
+install: FORCE
+	@ # The following action MUST be a single action. That is, all lines
+	@ # except the last line must have a backslash (\) at the end to
+	@ # continue the statement. The reason for this is that Make does not
+	@ # have an exit command thus, exit terminates the shell. However, 
+	@ # Make creates a new shell for each action listed for a target.
+	@ # Therefore, the only way exit will quit Make is if there is only
+	@ # a single action for the target.
+	@ # Check if grass has been compiled, if INST_DIR is writable, and if
+	@ # grass is part of INST_DIR
+	echo ${ARCH_BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}
+	@ if [ ! -f ${ARCH_BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR} ] ; then \
+		echo "ERROR: GRASS has not been compiled. Try \"make\" first."; \
+		echo "  Installation aborted, exiting Make."; \
+		exit; \
+	fi; \
+	if [ "${MACOSX_APP}" = "1" ] ; then \
+		${MAKE} install-macosx; \
+		exit; \
+	fi; \
+	INST_PATH=`dirname ${INST_DIR}`; \
+	while [ ! -d $$INST_PATH ]; do \
+		INST_PATH=`dirname $$INST_PATH`; \
+	done; \
+	if [ ! -d "${INST_DIR}" -a ! -w "$$INST_PATH" ] ; then \
+		echo "ERROR: Directory $$INST_PATH is a parent directory of your"; \
+		echo "  install directory ${INST_DIR} and is not writable."; \
+		echo "  Perhaps you need root access."; \
+		echo "  Installation aborted, exiting Make."; \
+		exit; \
+	fi; \
+	if [ -d ${INST_DIR} -a ! -w "${INST_DIR}" ] ; then \
+		echo "ERROR: Your install directory ${INST_DIR} is not writable."; \
+		echo "  Perhaps you need root access."; \
+		echo "  Installation aborted, exiting Make."; \
+		exit; \
+	fi; \
+	result=`echo "${INST_DIR}" | awk '{ if ($$1 ~ /grass/) print $$1 }'`; \
+	if [ "$$result" = "" ] ; then \
+		echo "WARNING: Your install directory ${INST_DIR}"; \
+		echo "  does not contain the word 'grass'."; \
+		echo "  It is highly recommended that the word 'grass' be part"; \
+		echo "  of your install directory to avoid conflicts."; \
+		echo "  Do you want to continue? [y/n]"; \
+		read ans; \
+		ans=`echo "$$ans" | tr A-Z a-z`; \
+		if [ "$$ans" != "y" ] ; then \
+			echo "Installation aborted, exiting Make."; \
+			exit; \
+		fi; \
+	fi; \
+	${MAKE} real-install
+
+real-install: FORCE
+	test -d ${INST_DIR} || ${MAKE_DIR_CMD} ${INST_DIR}
+	@##### test -d ${INST_DIR}/dev || ${MAKE_DIR_CMD} ${INST_DIR}/dev
+	test -d ${BINDIR} || ${MAKE_DIR_CMD} ${BINDIR}
+	-sed -e "s#^GISBASE.*#GISBASE=${INST_DIR}#" ${ARCH_BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR} > ${BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}
+	-chmod a+x ${BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}
+ifneq ($(strip $(MINGW)),)
+	-sed -e "s#WINGISBASE=.*#WINGISBASE=${INST_DIR}#" ${ARCH_BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}.bat > ${BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}.bat
+	-chmod a+x ${BINDIR}/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}.bat
+endif
+	-cd ${GISBASE} ; tar cBf - $(FILES) | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - bin | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - bwidget | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - docs | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - driver | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - etc | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - fonts | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - man | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - scripts | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	if [ ${LOCALE} -eq 1 ] ; then cd ${GISBASE} ; tar cBf - locale | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null ; fi
+	@ # The man, include, and lib could go to ${PREFIX}/ BUT if this is
+	@ # done, then the corresponding uninstall instructions must delete
+	@ # the grass files BY FILENAME NOT DIRECTORY!! Otherwise there is a
+	@ # high risk of deleteing system files since PREFIX is defined by
+	@ # default to be /usr/local
+	@##### -cd ${GISBASE} ; tar cBf - man | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - include | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-cd ${GISBASE} ; tar cBf - lib | (cd ${INST_DIR} ; tar xBf - ) 2>/dev/null
+	-sed 's#'${GISBASE}'#'${INST_DIR}'#g' ${GISBASE}/etc/monitorcap > ${INST_DIR}/etc/monitorcap
+	-sed 's#'${GISBASE}'#'${INST_DIR}'#g' ${GISBASE}/etc/fontcap > ${INST_DIR}/etc/fontcap
+	@##### -chmod -R 1777 ${INST_DIR}/locks 2>/dev/null
+	-chmod -R a+rX ${INST_DIR} 2>/dev/null
+	@#GEM installation
+	-tar cBf - gem/skeleton | (cd ${INST_DIR}/etc ; tar xBf - ) 2>/dev/null
+	-${INSTALL} gem/gem6 ${BINDIR} 2>/dev/null
+	@# enable OSX Help Viewer
+	@if [ "`cat include/Make/Platform.make | grep -i '^ARCH.*darwin'`" ] ; then /bin/ln -sfh "${INST_DIR}/docs/html" /Library/Documentation/Help/GRASS-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR} ; fi
+
+
+install-strip: FORCE
+	${MAKE} strip
+	${MAKE} install
+
+install-macosx: FORCE
+	${MAKE} -C macosx install-macosx
+
+bindist:  
+	if [ "${MACOSX_APP}" = "1" ] ; then \
+		${MAKE} bindist-macosx; \
+		exit; \
+	fi; \
+	${MAKE} real-bindist
+
+real-bindist:
+	mkdir -p ${ARCH_DISTDIR}/etc/nad/src ; \
+	    cp -f ${MODULE_TOPDIR}/lib/proj/*.lla ${ARCH_DISTDIR}/etc/nad/src ; true
+	( date=`date '+%d_%m_%Y'`; cd ${ARCH_DISTDIR}; tar cBf - ${BIN_DIST_FILES} | gzip -fc > ../grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}-${ARCH}-$$date.tar.gz)
+	-date=`date '+%d_%m_%Y'`; name=grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}-${ARCH}-$$date.tar.gz; \
+            size=`ls -l $$name | awk '{print $$5}'`; \
+	    sed -e "s/BIN_DIST_VERSION/${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}-${ARCH}-$$date/" \
+	    -e "s/GRASSPRG_NAME/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}/" \
+	    -e "s/SIZE_TAR_FILE/$$size/" -e "s#BIN_DIST_DIR#'${INST_DIR}'#" \
+	    -e "s/ARCHITECTURE/${ARCH}/" \
+	    -e "s/LD_LIBRARY_PATH_VAR/${LD_LIBRARY_PATH_VAR}/" \
+	    -e "s/TEST_STR=/TEST_STR=executable/" \
+	    -e "s#IMPORTANT.*#Generated from the binaryInstall.src file using the command make bindist#" \
+	    -e "s/# executable shell.*//" -e "s/# make bindist.*//" \
+	    binaryInstall.src > grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}-${ARCH}-$$date-install.sh ; \
+	    chmod a+x grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}-${ARCH}-$$date-install.sh 2>/dev/null
+
+bindist-macosx:
+	${MAKE} -C macosx bindist-macosx
+
+# make a source package for distribution:
+srcdist: FORCE distclean
+	-${MAKE_DIR_CMD} ./grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+
+	@ # needed to store code in package with grass-version path:
+	-mv * ./grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	@ # do not include the debian control files:
+	-mv ./grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}/debian .
+	@ #we use -h to get the linked files into as real files:
+	tar cvfzh grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}.tar.gz ./grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}/* --exclude=CVS
+	@ # restore src code location:
+	-mv ./grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}/* .
+	-rmdir ./grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	@ echo "Distribution source package: grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}.tar.gz ready. Calculating MD5 sum..."
+	md5sum grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}.tar.gz > grass-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}.md5sum
+
+# make a source package for library distribution:
+srclibsdist: FORCE distclean
+	-${MAKE_DIR_CMD} ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+
+	@ # needed to store code in package with grass-version path:
+	-cp -L * ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	-cp -rL tools ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	-cp -rL include ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	-cp -rL --parents lib/external/shapelib ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	-cp -rL --parents lib/datetime ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	-cp -rL --parents lib/db ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	-cp -rL --parents lib/gis ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	-cp -rL --parents lib/linkm ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	-cp -rL --parents lib/form ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	-cp -rL --parents lib/vector ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+
+	-cp -rL --parents db/drivers ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+
+	tar chvfz grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}.tar.gz ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}/* --exclude=CVS
+	-rm -r ./grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}
+	@ echo "Distribution source package: grass-lib-${GRASS_VERSION_MAJOR}.${GRASS_VERSION_MINOR}.${GRASS_VERSION_RELEASE}.tar.gz ready."
+
+# generate docs as single HTML document:
+htmldocs-single:
+	(cd lib/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs-single)
+	(cd rfc/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs-single)
+	(cd swig/; $(MAKE) cleandocs ; $(MAKE) htmldocs-single)
+
+# generate docs as multiple HTML documents:
+htmldocs:
+	(cd lib/db/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd lib/g3d/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd lib/gis/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd lib/gmath/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd lib/gpde/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd lib/ogsf/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd lib/proj/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd lib/segment/; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd lib/vector/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd lib/vector/dglib/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd rfc/ ; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+	(cd swig/; $(MAKE) cleandocs ; $(MAKE) htmldocs)
+
+packagehtmldocs: htmldocs
+	tar chvfz grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}refman_`date '+%Y_%m_%d'`_html.tar.gz lib/db/html lib/g3d/html lib/gis/html lib/gmath/html lib/gpde/html lib/proj/html lib/ogsf/html lib/segment/html lib/vector/html lib/vector/dglib/html rfc/html swig/html
+
+#alternatively, the docs can be generated as single PDF document (see doxygen FAQ for 'TeX capacity exceeded'):
+#  (cd lib/ ; make pdfdocs)
+
+pdfdocs:
+	(cd lib/db/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd lib/g3d/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd lib/gis/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd lib/gmath/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd lib/gpde/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd lib/ogsf/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd lib/proj/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd lib/segment/; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd lib/vector/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd lib/vector/dglib/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd rfc/ ; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	(cd swig/; $(MAKE) cleandocs ; $(MAKE) pdfdocs)
+	@echo "Written PDF docs in: lib/db/latex/, lib/g3d/latex/, lib/gis/latex/, lib/gmath/latex/ lib/gpde/latex/ lib/ogsf/latex/, lib/proj//latex/, lib/segment/latex/, lib/vector/latex/ lib/vector/dglib/latex/ rfc/latex/ swig/latex/"
+
+html2pdfdoc:
+	@ echo "Light PDF document from modules' HTML documentation"
+	@ # http://www.htmldoc.org
+	@test -d $(GRASS_PDFDIR) || mkdir -p $(GRASS_PDFDIR)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage --no-links database.html display.html general.html imagery.html misc.html photo.html postscript.html raster.html raster3D.html vector.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}commands.pdf)
+
+html2pdfdoccomplete:
+	@ echo "Complete PDF document from modules' HTML documentation"
+	@ # http://www.htmldoc.org
+	@test -d $(GRASS_PDFDIR) || mkdir -p $(GRASS_PDFDIR)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage database.html db.*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}database.pdf)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage display.html d.*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}display.pdf)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage general.html g.*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}general.pdf)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage imagery.html i.*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}imagery.pdf)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage misc.html m.*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}misc.pdf)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage photo.html i.ortho*.html photo*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}photo.pdf)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage postscript.html ps.*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}postscript.pdf)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage raster.html r.*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}raster.pdf)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage raster3D.html r3.*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}raster3d.pdf)
+	(cd ${ARCH_DISTDIR}/docs/html ; $(HTML2PDF) --webpage vector.html v*.html -f $(GRASS_PDFDIR)/grass${GRASS_VERSION_MAJOR}${GRASS_VERSION_MINOR}vector.pdf)
+
+changelog:
+	@ echo "creating ChangeLog file (following 'trunk' only)..."
+	@ # svn2cl creates a GNU style ChangeLog file:
+	@ # http://ch.tudelft.nl/~arthur/svn2cl/
+	@if [ ! -x "`which svn2cl`" ] ; then \
+		echo "\"svn2cl\" is required, please install first from http://ch.tudelft.nl/~arthur/svn2cl/" ;	exit 1 ; \
+	fi
+	sh svn2cl ./ChangeLog
+
+
+builddemolocation:
+	test -d ${ARCH_DISTDIR} || ${MAKE_DIR_CMD} ${ARCH_DISTDIR}
+	-tar cBf - demolocation | (cd ${ARCH_DISTDIR}/ ; tar xBfo - ) 2>/dev/null
+	@ echo "GISDBASE: ${RUN_GISBASE}" > ${RUN_GISRC}
+	@ echo "LOCATION_NAME: demolocation" >> ${RUN_GISRC}
+	@ echo "MAPSET: PERMANENT" >> ${RUN_GISRC}
+	@ echo "GRASS_DB_ENCODING: utf-8" >> ${RUN_GISRC}
+	@ echo "DEBUG: 0" >> ${RUN_GISRC}
+	@ echo "GRASS_GUI: text" >> ${RUN_GISRC}

+ 51 - 0
README

@@ -0,0 +1,51 @@
+GRASS Development Subversion repository
+
+##########################################################
+How to get write access here?
+
+Write access is only granted to developers who agree to abide by
+RFC2 - Legal aspects of code contributions
+http://download.osgeo.org/grass/grass6_progman/rfc/rfc2_psc.html
+and the code submission guidelines (file SUBMITTING in this 
+directory).
+
+This needs to be communicated to a GRASS developer. S/he will 
+then possibly propose you to the GRASS Project Steering committee
+after a period of evaluation. For details, see
+http://download.osgeo.org/grass/grass6_progman/rfc/main.html
+
+Once write access is granted, you, the new developer need to
+obtain an "osgeo_id" at http://www.osgeo.org/osgeo_userid
+If you already have an "osgeo_id" but forgot it, search for it at
+Search at http://www.osgeo.org/cgi-bin/ldap_web_search.py
+
+##########################################################
+How to compile GRASS:
+   See INSTALL file.
+
+Yes, you should really read INSTALL.
+
+##########################################################################
+How to generate the 'Programmer's Manual':
+
+This needs doxygen (http://www.doxygen.org) and optionally
+Graphviz dot (http://www.research.att.com/sw/tools/graphviz/).
+
+To build the GRASS programmer's documentation, run
+   make htmldocs
+here. This takes quite some time. The result is in doxygenhtml/index.html
+which refers to further document repositories in
+   lib/vector/html/index.html
+   lib/db/html/index.html
+   lib/gis/html/index.html
+
+The master file is: ./grassrefman.dox where all sub-documents have to
+be linked into.
+
+To generate the documents in PDF format, run
+   make pdfdocs
+
+An online version is available at:
+http://download.osgeo.org/grass/grass6_progman/
+http://download.osgeo.org/grass/grass6_progman_pdf/
+

+ 192 - 0
REQUIREMENTS.html

@@ -0,0 +1,192 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>REQUIREMENTS to compile GRASS GIS 6</title>
+</head>
+<body bgcolor="#FFFFFF">
+
+<h2>REQUIREMENTS to compile GRASS GIS 6</h2>
+
+A workstation running some flavor of UNIX like Solaris, IRIX, Linux, BSD,
+Mac OS X or cygwin (on Win32). Ideally, you should have at least 500 Mb for data
+and 32 Mb RAM. The source code package needs around 50 MB uncompressed.
+The resulting binaries may need between 20 MB and 180 MB depending on your
+platform. During a full compilation you may need temporarily up to 550MB including
+the source code.
+<p>
+To disable features please read the <a href="INSTALL">INSTALL</a> file.
+
+<h3>General requirements:</h3>
+
+(most tools are standard tools on Linux, for other platforms you may have
+to install some of them.)
+
+<ul>
+<li><B>C-compiler</B> (cc, gcc, egcs, ...)
+<br>gcc: <a href="http://www.gnu.org/software/gcc/gcc.html">http://www.gnu.org/software/gcc/gcc.html</a>
+<br>
+
+<li><B>GNU make</B> is recommended
+<br><a href="http://www.gnu.org/software/make/make.html">http://www.gnu.org/software/make/make.html</a>
+<br>
+
+<li><B>zlib</B> compression library (already installed on most modern systems)
+<br>It is used to internally compress GRASS raster maps:
+<br>libz: <a href="http://www.gzip.org/zlib/">http://www.gzip.org/zlib</a>
+<!-- freesoftware.com is broken! <br><a href="ftp://ftp.freesoftware.com/pub/infozip/zlib/">ftp://ftp.freesoftware.com/pub/infozip/zlib</a> -->
+<br>
+
+<li><B>flex</B> lexical analyzer generator (flex) - note: lex is no longer supported, please use flex instead:
+<br>flex: <a href="http://www.gnu.org/software/flex/flex.html">http://www.gnu.org/software/flex/flex.html</a>
+<br>
+
+<li><B>parser generator</B> (yacc, bison)
+<br>bison: <a href="http://www.gnu.org/software/bison/bison.html">http://www.gnu.org/software/bison/bison.html</a>
+<br>
+
+<li><B>libncurses4.x/5.x</B> (already installed on modern systems)
+<br><a href="http://www.gnu.org/software/ncurses/ncurses.html">http://www.gnu.org/software/ncurses/ncurses.html</a>
+<br><a href="ftp://ftp.gnu.org/pub/gnu/ncurses/">ftp://ftp.gnu.org/pub/gnu/ncurses</a>
+<br>
+
+<li><B>X Window</B>  system for graphical output, development libraries (X development
+libraries, in some linux distributions they are separate packages, e.g. xlibs-dev)
+<br><a href="http://www.xfree.org">http://www.xfree.org</a>
+<br><a href="http://www.x.org">http://www.x.org</a>
+<br>winGRASS note: As alternative a generic MS-Windows driver is under
+construction which does not require X11
+<br>
+
+<li><B>PROJ4</B> - Projection Library<br>
+<a href="http://proj.maptools.org">http://proj.maptools.org</a>
+<br>
+
+<li><B>GDAL and OGR</B> for import and export of most external raster and vector
+map formats<br>
+<a href="http://www.gdal.org">http://www.gdal.org</a>
+
+</ul>
+
+<h3>
+Optional requirements:</h3>
+
+<ul>
+<li><B>Tcl/Tk 8.x libraries</B> (including the 'wish' program) to use the GRASS GUI
+menu system and the NVIZ visualization suite<br>
+Some features of the new <em>gis.m</em> GIS manager may depend on version 8.4 or newer.
+<br>
+<!--
+On some platforms (e.g. Debian) GRASS 6.0.2 and earlier needed to be compiled
+against the Tcl/Tk 8.3 development packages in order to get NVIZ working correctly.
+This has been fixed in newer versions of GRASS.<br>
+-->
+see <a href="http://tcl.sourceforge.net">http://tcl.sourceforge.net</a>
+
+
+<li>If hardware openGL support is missing in the X Server, <B>Mesa-3.x</B>
+(openGL clone) may be required for NVIZ<br>
+<a href="http://mesa3d.sourceforge.net">http://mesa3d.sourceforge.net</a>
+
+
+<li><B>C++ Compiler</B> (required for the r.terraflow module)<br>
+gcc: <a href="http://www.gnu.org/software/gcc/gcc.html">http://www.gnu.org/software/gcc/gcc.html</a>
+
+
+<li><B>FFTW 2.x or 3.x</B> (library for computing the Discrete Fourier Transform), required
+for i.fft and i.ifft and other modules<br>
+<a href="http://www.fftw.org">http://www.fftw.org</a>
+
+
+<li><B>LAPACK / BLAS</B> (libraries for numerical computing) for GMATH library (GRASS numerical lib)<br>
+[<a href="http://www.netlib.org/lapack/">http://www.netlib.org/lapack</a>] (usually available on Linux distros)
+<br>
+<I>Note: LAPACK/BLAS support is intended for future module implementations, no need to
+use it at time!</I>
+
+
+<li><B>libpng</B> (for r.out.png and the PNG driver), usually already installed.<br>
+<a href="http://www.libpng.org/pub/png/libpng.html">http://www.libpng.org/pub/png/libpng.html</a>
+
+
+<li><B>libjpeg</B> (for r.out.tiff), usually already installed.<br>
+<a href="http://www.ijg.org">http://www.ijg.org</a><br>
+<a href="ftp://ftp.uu.net/graphics/jpeg/">ftp://ftp.uu.net/graphics/jpeg</a>
+
+
+<li><B>libtiff</B> (for r.out.tiff), usually already installed.<br>
+<a href="http://www.libtiff.org">http://www.libtiff.org</a>
+
+<li><B>readline</B> for extra command prompt functionality
+<br><a href="http://tiswww.case.edu/~chet/readline/rltop.html">http://tiswww.case.edu/~chet/readline/rltop.html</a>
+<br><a href="ftp://ftp.gnu.org/gnu/readline/">ftp://ftp.gnu.org/gnu/readline/</a>
+
+<li><B>PostgreSQL libraries</B> (for the PostgreSQL database interface)<br>
+<a href="http://www.postgresql.org">http://www.postgresql.org</a>
+
+
+<li><B>mySQL libraries</B> (for the mySQL database interface)<br>
+<a href="http://www.mysql.org">http://www.mysql.org</a>
+
+
+<li><B>sqlite libraries</B> (for the sqlite database interface)<br>
+<a href="http://www.sqlite.org">http://www.sqlite.org</a>
+
+
+<li><B>unixODBC</B> (for the ODBC database interface)<br>
+<a href="http://www.unixodbc.org">http://www.unixodbc.org</a>
+
+
+<li><B>Motif or Lesstif libraries</B> (for the "xanim" <!-- and ogl3d -->
+module)<br>
+<a href="http://www.lesstif.org">http://www.lesstif.org</a>
+
+
+<li><B>R language</B> (for the R statistical language interface)<br>
+<a href="http://cran.r-project.org">http://cran.r-project.org</a>
+
+
+<li><B>FreeType2</B> (for TrueType font support and d.text.freetype)<br>
+<a href="http://www.freetype.org">http://www.freetype.org</a>
+
+<li><B>Python</B> (for new wxPython GUI and SWIG interface)<br>
+<a href="http://www.python.org">http://www.python.org</a>
+
+<li><B>wxPython >= 2.8.1.1</B> for wxPython-based GUI (see file
+gui/wxpython/README)<br>
+<a href="http://www.wxpython.org">http://www.wxpython.org</a>
+
+<li><B>FFMPEG</B> (for direct rendering of animations from NVIZ),
+    including libavcodec, libavformat, libswscale <BR>
+<a href="http://ffmpeg.mplayerhq.hu/">http://ffmpeg.mplayerhq.hu</a><BR>
+
+<li><B>Cairo</B> (Cairo graphics library, Version &gt;= XX)<BR>
+<a href="http://cairographics.org">http://cairographics.org</a><BR>
+</ul>
+
+
+<h3>Note:</h3>
+
+SUN Solaris users may go here to download precompiled libraries etc.:
+<br><a href="http://www.sunfreeware.com">http://www.sunfreeware.com</a>
+
+<p>
+SGI IRIX users may go here to download precompiled libraries etc.:
+<br><a href="http://freeware.sgi.com">http://freeware.sgi.com</a>
+
+<p>
+MacOSX users may go here to download precompiled libraries etc.:
+<br><a href="http://fink.sourceforge.net">http://fink.sourceforge.net</a>
+
+<p>
+
+<hr WIDTH="100%">
+<br><i>&copy; GRASS Development Team 2001-2006</i>
+<p>Please report bugs here:
+<br><a href="http://www.grass-gis.org/bugtracking/bugreport.html">http://www.grass-gis.org/bugtracking/bugreport.html</a>
+
+<p>
+<i>$Id$</i>
+</p>
+</body>
+</html>

+ 444 - 0
SUBMITTING

@@ -0,0 +1,444 @@
+$Date$
+
+NOTE: Please improve this list!
+
+Dear (new) GRASS Developer,
+
+When submitting C code to GRASS SVN repository, please take care of
+following rules:
+
+[ see SUBMITTING_SCRIPTS for shell script hints ]
+[ see SUBMITTING_TCLTK for tcl and tk hints ]
+[ see SUBMITTING_DOCS for documentation ]
+[ see SUBMITTING_PYTHON for Python code hints ]
+
+
+1.  Get and read the GRASS 6 Programmer's Manual here:
+    http://download.osgeo.org/grass/grass6_progman/
+
+    or generate it from this source code (the programmer's manual is
+    integrated in the source code in doxygen style):
+      make htmldocs
+      make pdfdocs
+
+
+2.  Use the directory structure to place your module appropriately into
+    the source tree
+    	- libes go into lib/
+    	- raster goes into raster/
+    	- vector goes into vector/
+    	- ...
+
+    Consider to take a look at "GNU Coding Standards"
+    http://www.gnu.org/prep/standards.html
+
+    In future, there will be a centralized contribution directory.
+
+
+3.  Add a header section to each file you submit and make sure you include
+    the copyright. The purpose section is meant to contain a general
+    overview of the code in the file to assist other programmers that will
+    need to make changes to your code.
+
+    Example (ficticious header for a file called color.c) :
+
+/****************************************************************************
+ *
+ * MODULE:       d.rast (or new higher level module name (eg GRASS core) 
+ *               for 6.1)
+ * AUTHOR(S):    Original author unknown - probably CERL
+ *               John Doe - jdoe@some.where.org
+ * PURPOSE:      To provide storage and manipulation of colors used for 
+ *               rendering the raster. The colors are stored in a doubly linked
+ *               list which must be initialized with InitColors() before it can
+ *               be used. Note that most linked list functionality (add,
+ *               remove, get) is supported, but their is no sorting
+ *               functionality.
+ * COPYRIGHT:    (C) 2005 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+    The copyright protects your rights according to GNU General Public
+    License (www.gnu.org).
+
+
+4.  - deleted.
+    We don't want the $ ID $ in source code any more as it causes problems
+    for the SVN branches.
+
+
+5.  To ensure that the software system continues to work, please include
+
+	#include <grass/config.h>
+
+    in your files and make use of the various system dependencies
+    contained therein.  As one example of this, see lib/gmath/fft.c.
+    Please refrain from declaring system functions within the
+    software; include the proper header files (conditionally dependent
+    on config.h macros if necessary) instead.
+
+
+6. Order of include headers
+
+    In general, headers should be included in the order:
+ 
+    1. Core system headers (stdio.h, ctype.h, ...)
+    2. Headers for non-core system components (X11, libraries).
+    3. Headers for core systems of the package being compiled (grass/gis.h, grass/glocale.h, ...)
+    4. Headers for the specific library/program being compiled (geodesic.h, ...)
+ 
+    Each class of header has an obligation to be compatible with those
+    above it in the list, but not those below it.
+
+
+7.  Always specify the return type for ALL functions including those that
+    return type "void", and insert return statements for ALL functions.
+    Also, use ANSI C prototypes to declare your functions. 
+    For module return values, see "Exit status" below.
+
+    Examples:
+    
+    void G_something(void);
+    int G_something_else(int, int);
+    
+    void G_something(void)
+    {
+    	/* Snipped out code */
+	
+	return;
+    }
+    
+    int G_something_else(int x, int y)
+    {
+    	/* Snipped out code */
+	
+	return(0);
+    }
+
+
+8.  Module exit status is defined as EXIT_SUCCESS or EXIT_FAILURE, e.g.
+
+    {
+      ...
+      if (G_parser (argc, argv))
+          exit (EXIT_FAILURE);
+
+      ...
+      exit (EXIT_SUCCESS);
+    }
+
+
+9.  Use fprintf instead of printf. But:
+    
+    For errors and warnings please use the G_fatal_error() and
+    G_warning() functions. General messages for the user should use
+    G_message() while debug messages should use G_debug() whenever
+    possible. There are two variants to G_message(): G_verbose_message()
+    which will only display the message if in verbose mode, and
+    G_important_message() which will always show the message unless
+    the module is running in --quiet mode. G_fatal_error() and
+    G_warning() will always be displayed regardless of verbosity setting.
+    Messages sent to any of these functions will be printed to stderr.
+
+    G_message() output is not expected to be sent to pipe or file.
+
+    Always use the gettext macros with _("") for user messages,
+    example:
+      G_fatal_error (_("Vector map <%s> not found"), name); 
+
+
+    Pipe/file data output:
+    For data output redirected to pipe or file, please use fprintf() and 
+    specify the stdout stream as follows:
+
+      fprintf(stdout, ...);
+      fflush(stdout);
+
+      fflush(stdout) always required when using fprintf(stdout, ...).
+
+
+10. Use the GRASS library function G_asprintf() instead of the
+    standard C functions asprintf(), vsnprintf() and snprintf(). These
+    functions are not portable or have other issues.  Example:
+
+    char *msg;
+
+    G_asprintf(&msg, "%s", parameters);
+    do_something_with_msg();
+    G_free(msg);
+
+    Note that you should free memory when G_asprintf() is used.
+
+
+11. Use the following GRASS library functions instead of the standard C
+    functions. The reason for this is that the following functions ensure
+    good programming practice (e.g. always checking if memory was allocated)
+    and/or improves portability. PLEASE refer to the programmers manual
+    for the proper use (e.g. determining if any casts are needed for arguments
+    or return values) of these library functions. They may perform a task
+    slightly different from their corresponding C library function, and thus,
+    their use may not be the same.
+    
+    	G_malloc() instead of malloc()
+	G_calloc() instead of calloc()
+	G_realloc() instead of realloc()
+	G_free() instead of free()
+	G_getenv() instead of getenv()
+	G_setenv() instead of setenv()
+	G_unsetenv() instead of unsetenv()
+	G_sleep() instead of sleep()
+
+	Could somebody please add others (please verify that they are
+	useful and safe first)
+
+
+12. Use function names which fulfil the official GNU naming convention.
+    http://www.gnu.org/prep/standards/html_node/Names.html#Names
+
+    Instead of naming a function like: MyNewFunction() use underscores
+    for seperation and lower case letters: my_new_function().
+
+
+13. Don't use the C++ comment style! This confuses several compilers.
+    Use instead:
+       /* C-comments */
+
+    If you want to comment code portions, use
+       #ifdef notdef 
+            portion_to_be_commented;
+       #endif
+    This is safe comparing to nested /* comments */
+
+    Functions in the library must be documented in doxygen style to
+    get them into the programmer's manual (generate with 
+      make pdfdocs  or
+      make htmldocs
+    ). See lib/gis/*.c for examples.
+
+
+14. PLEASE take the time to add comments throughout your code explaining what
+    the code is doing. It will save a HUGE amount of time and frustration for
+    other programmers that may have to change your code in the future.
+
+
+15. To promote a consistent coding style, please use the "indent" program
+    on all new C modules using the following switches:
+    
+     $ indent -nbad -bap -bbb -nbbo -nbc -br -bli1 -bls -cbi0 -ncdb -nce \
+        -ci4 -cli0 -ncs -d0 -di0 -fc1 -nfca -hnl -i4 -ip4 -l80 -lc80 -lp \
+	-npcs -pi4 -nprs -npsl -sbi0 -sc -nsob -ss -ts8  main.c
+
+    Existing code should not be re-indented except in extreme cases, as this
+    will make "diff" comparisons with older versions impossible. If indent is 
+    needed, do not check in any changes other than the indentation in the same 
+    commit! Do add the indent switches and any indent warning messages to the 
+    SVN log. Any change or fix mixed in with an indent is very hard to track 
+    making it hard for others to follow the change or fix any new bugs.
+
+
+16. Platform dependent code:
+    Do not remove #ifdef __CYGWIN__ and/or #ifndef __CYGWIN__ lines and 
+    their encapsulated lines from source code (one example was that someone
+    removed drand48 definition.)
+
+
+17. Suggested compiler flags:
+    We suggest to use very strict compiler flags to capture errors
+    at the very beginning. Here our list of flags, please use them
+    to configure you development version of GRASS:
+
+    GNU/Linux:
+
+       MYCFLAGS="-g -Wall -Werror-implicit-function-declaration -fno-common"
+       MYCXXFLAGS="-g -Wall"
+       
+       CFLAGS="$MYCFLAGS" CXXFLAGS="$MYCXXFLAGS" ./configure ... 
+
+    MacOSX:     [to be suggested]
+
+    MS-Windows: [to be suggested]
+
+
+18. Make sure a new line is at the end of each file.
+
+
+19. When writing Makefiles, use the current standard.
+
+    If you have to use commands, please check for:
+    
+            avoid     | use instead
+    ------------------+---------------
+    make target       | $(MAKE) target
+    mkdir target      | $(MKDIR) target
+    cp  (executable)  | $(INSTALL) -m 755 file target
+    cp  (normal file) | $(INSTALL) -m 644 file target
+    ar                | $(AR)
+
+    rm: be VERY careful with recursive remove.
+
+    Examples: see below examples or others
+              raster/r.info/Makefile
+              vector/v.digit/Makefile
+
+    If you are unsure, please ask on the GRASS Developers list.
+
+    
+20. Have a look at ./INSTALL
+
+
+21. Have a function included in your module which writes to the history
+    file of the map (e.g. command line, parameters etc.). See e.g.
+    raster/r.patch/main.c
+
+    (the same applies to vector and g3d modules!)
+
+
+22. Standard parser options: use G_define_standard_option() whenever possible
+    to define standard module command line options. This will save you time,
+    create fewer bugs, and make things easier on the translators.
+    See lib/gis/parser.c for details of the function definition.
+
+
+23. Add/update, if required the related GUI menus:
+     gui/tcltk/gis.m/gmmenu.tcl
+
+
+24. For consistency, use README rather than README.txt for any README files.
+
+
+25. GRASS/Environment variables:
+    If you add a new variable, please follow the naming convention.
+    All variables are described in
+    lib/init/variables.html
+
+
+26. Be sure to develop on top of the LATEST GRASS code (which is in SVN repository).
+    You can re-check before submission with 'svn diff':
+
+    Be sure to create unified ("diff -u") format. "Plain" diffs (the default
+    format) are risky, because they will apply without warning to code which
+    has been substantially changed; they are also harder to read than unified.
+
+    Such diffs should be made from the top-level directory, e.g.
+    "svn diff display/d.vect/main.c"; that way, the diff will
+    include the pathname rather than just "main.c".
+
+
+27. Try to use module names which describe shortly the intended purpose of the module.
+
+    The first letters for module name should be:
+	d. 	- display commands
+	db. 	- database commands
+	g. 	- general GIS management commands
+	i. 	- imagery commands
+	m.	- miscellaneous tool commands
+	ps. 	- postscript commands
+	r. 	- raster commands
+	r3. 	- raster3D commands
+	v. 	- vector commands
+
+    Some additional naming conventions
+    * export modules:     (type).out.(format) eg: r.out.arc,  v.out.ascii
+    * import module:      (type).in.(format)  eg: r.in.arc, v.in.ascii
+    * conversion modules: (type).to.(type)    eg: r.to.vect, v.to.rast, r3.to.rast
+
+    Avoid module names with more than two dots in the name. 
+    Example:
+       instead of r.to.rast3.elev use r.to.rast3elev    
+
+
+28. Use the grass test suite to test your modules.
+
+    http://www-pool.math.tu-berlin.de/~soeren/grass/GRASS_TestSuite
+
+    You can easily write specific tests for your modules.
+
+    If your module is part of GRASS and you created some standard test
+    cases, please contact the developers to add your tests to the
+    default test suite.  This will automatize complex test scenarios
+    and assure to find bugs much faster, if changes were made to your
+    modules or to the grass library.
+
+    Consider to subscribe to the GRASS Quality Assessment System to
+    get immediate notification about the code quality:
+
+    http://www.grass-gis.org/mailman/listinfo/grass-qa
+
+
+29. When submitting new files to the repository set SVN properties,
+    usually for directory
+
+      svn:ignore : *.tmp.html
+      		   *OBJ*
+
+    or e.g. for C-file
+    
+      svn:mime-type : text/x-csrc
+      svn:keywords : Author Date Id
+      svn:eol-style : native
+
+    See
+    http://svnbook.red-bean.com/en/1.4/svn.advanced.props.html
+
+
+30. Use doxygen style for source code documentation. It is required
+    for GRASS libraries, but also recommended for GRASS modules.
+
+    Do not use structural command inside documentation block since it
+    leads to some duplication of information (e.g. do not use \fn
+    command in comment blocks). The exception is \file command for
+    documenting a file, in this case structural command is required.
+
+    For files
+
+    /**
+       \file snap.c
+   
+       \brief Vector library - Clean vector map (snap lines)
+
+       (C) 2001-2008 by the GRASS Development Team
+   
+       This program is free software under the 
+       GNU General Public License (>=v2). 
+       Read the file COPYING that comes with GRASS
+       for details.
+   
+       \author Radim Blazek
+   
+       \date 2001-2008
+    */
+
+    For functions
+
+    /**
+       \brief Snap lines in vector map to existing vertex in threshold
+
+       For details see Vect_snap_lines_list()
+
+       \param[in] Map input vector map 
+       \param[in] type type of lines to be snap
+       \param[in] thresh threshold value for snapping
+       \param[out] Err vector map where lines representing snap are written or NULL
+       \param[out] msgout file pointer where messages will be written or NULL
+       
+       \return	   
+    */
+
+
+31. Tell the other developers about the new code using the following e-mail:
+    grass-dev@lists.osgeo.org
+ 
+    To subscribe to this mailing list, see
+    http://lists.osgeo.org/mailman/listinfo/grass-dev
+
+
+32. In case of questions feel free to contact the developers at the above
+    mailing list.
+    http://www.grass-gis.org/devel/index.php#submission
+
+...
+[please add further hints if required]

+ 77 - 0
SUBMITTING_DOCS

@@ -0,0 +1,77 @@
+$Date$
+
+NOTE: Please improve this list!
+
+Dear (new) GRASS Developer,
+
+When submitting documentation to GRASS SVN repository, please take
+care of following rules:
+
+[ see SUBMITTING for C hints ]
+[ see SUBMITTING_SCRIPTS for shell script hints ]
+[ see SUBMITTING_TCLTK for tcl and tk hints ]
+[ see SUBMITTING_PYTHON for Python code hints ]
+
+
+1. Editing of HTML pages
+   To avoid insertion of too complicated HTML tags (see also below),
+   we strongly suggest to use a plain text editor rather than a
+   HTML editor for editing.
+
+
+2. Module manual page:
+   Place the documentation in HTML format into 'description.html'.
+   The easiest way to do this is to study an existing HTML page
+   (to get the page style, e.g. vector/v.to.db/description.html).
+   With a few exceptions header and footer are NOT allowed.
+   You can add figures (PNG format), the figure name prefix should be the 
+   module name. See raster/r.terraflow/description.html for an example.
+
+   Note that the parameter information is auto-generated upon
+   compilation. This is done by running module in a virtual session
+   after compilation (see the output of 'make'). To subsequently
+   verify the final HTML page, check the resulting HTML pages which
+   will be stored with the name of the module.
+
+   Examples (please add some) should be coded like this:
+
+   <div class="code"><pre>
+   v.to.db map=soils type=area option=area col=area_size unit=h
+   </pre></div>
+ 
+   The online WWW man pages is updated every Saturday (from SVN
+   repository).
+
+
+3. Usage of limited HTML tags
+   Since the MAN conversion of g.html2man is limited, please use
+   no other HTML tags than:
+   <A> <B> <BLINK> <BODY> <BR> <CODE> <DD> <DL> <DT> <EM> 
+   <H2> <H3> <H4>  <HEAD> <HEADER> <HR> <I> <IMG> <LI> <OL> <P>
+   <PRE> <SUP> <TABLE> <TD> <TH> <TITLE> <TR> <UL>
+
+
+4. Suggested HTML markup protocol:
+   Module names (i.e., v.category) should be emphsized with <em>,
+   and boldface <b> for flags and parameter names. Shell commands, 
+   names, values, etc. should use <tt>. Empahsized phrases should use 
+   italics <i>. The SEE ALSO section of each page should also be 
+   alphabetized. 	  		
+
+
+5. When submitting new files to the repository set SVN properties,
+   e.g. for HTML file
+    
+       svn:mime-type : text/html
+       svn:keywords : Author Date Id
+       svn:eol-style : native
+
+   See
+   http://svnbook.red-bean.com/en/1.4/svn.advanced.props.html
+
+
+6. See also
+   http://grass.gdf-hannover.de/wiki/Updating_GRASS_Documentation
+
+...
+[please add further hints if required]

+ 109 - 0
SUBMITTING_PYTHON

@@ -0,0 +1,109 @@
+$Date$
+
+NOTE: Please improve this list!
+
+Dear (new) GRASS Developer,
+
+When submitting Python code to GRASS SVN repository, please take
+care of following rules:
+
+[ see SUBMITTING for C hints ]
+[ see SUBMITTING_SCRIPTS for shell script hints ]
+[ see SUBMITTING_TCLTK for tcl and tk hints ]
+[ see SUBMITTING_DOCS for documentation ]
+
+
+1.  Indentation
+
+    As Python determines nesting based upon indentation, it
+    isn't just a stylistic issue.
+
+    Please use 4-space indentation (GNU Emacs python-mode default).
+
+    See also "Python Style Guide" by Guido van Rossum
+    http://www.python.org/doc/essays/styleguide.html
+
+
+2.  Add a header section to the script you submit and make sure you
+    include the copyright. The purpose section is meant to contain a
+    general over view of the code in the file to assist other
+    programmers that will need to make changes to your code. For this
+    purpose use Python Docstring, see
+    http://epydoc.sourceforge.net/docstrings.html
+
+    Example (fictitious header for a script called r.myscript):
+
+"""
+MODULE:    r.myscript
+
+AUTHOR(S): Me <email AT some domain>
+
+PURPOSE:   Calculates univariate statistics from a GRASS raster map
+
+COPYRIGHT: (C) 2007 by the GRASS Development Team
+
+           This program is free software under the GNU General Public
+           License (>=v2). Read the file COPYING that comes with GRASS
+           for details.
+"""
+
+   The copyright protects your rights according to GNU General Public
+   License (www.gnu.org).
+
+
+3.  - deleted.
+    We don't want the $ ID $ in source code any more as it causes problems
+    for the branches.
+
+
+4. PLEASE take the time to add comments throughout your code explaining what
+    the code is doing. It will save a HUGE amount of time and frustration for
+    other programmers that may have to change your code in the future.
+
+
+5. Make sure a new line is at the end of each file.
+
+
+6. For consistency, use README rather than README.txt for any README files.
+
+
+7. Be sure to develop on top of the LATEST GRASS code (which is in SVN repository).
+   You can re-check before submission with 'svn diff':
+
+   Be sure to create unified ("diff -u") format. "Plain" diffs (the default
+   format) are risky, because they will apply without warning to code which
+   has been substantially changed; they are also harder to read than unified.
+
+   Such diffs should be made from the top-level directory, e.g.
+   "svn diff gui/wxpython/wxgui.py"; that way, the diff will
+   include the pathname rather than just "wxgui.py".
+
+
+8. When submitting new files to the repository set SVN properties,
+   usually for directory
+
+      svn:ignore : *.pyc
+
+   or e.g. for Python file
+    
+      svn:mime-type : text/python
+      svn:keywords : Author Date Id
+      svn:eol-style : native
+
+   See
+   http://svnbook.red-bean.com/en/1.4/svn.advanced.props.html
+
+
+8. Tell the other developers about the new code using the following e-mail:
+   grass-dev@lists.osgeo.org
+ 
+   To subscribe to this mailing list, see
+   http://lists.osgeo.org/mailman/listinfo/grass-dev
+
+
+9. In case of questions feel free to contact the developers at the above
+   mailing list.
+   http://www.grass-gis.org/devel/index.php#submission
+
+...
+[please add further hints if required]

+ 247 - 0
SUBMITTING_SCRIPTS

@@ -0,0 +1,247 @@
+$Date$
+
+NOTE: Please improve this list!
+
+Dear (new) GRASS Developer,
+
+When submitting SHELL scripts to GRASS SVN repositiory,
+please take care of following rules:
+
+[ see SUBMITTING for C code hints ]
+[ see SUBMITTING_TCLTK for tcl and tk hints ]
+[ see SUBMITTING_DOCS for documentation ]
+[ see SUBMITTING_PYTHON for Python code hints ]
+
+
+0.  Instructions for the GRASS script parser can be found in the g.parser 
+    module's help page.
+    http://grass.osgeo.org/grass63/manuals/html63_user/g.parser.html
+
+
+1.  Use the directory structure to place your script appropriately into
+    the source tree
+    	- scripts go into scripts/
+
+    Consider to take a look at [please suggest Shell tutorial].
+ 
+    Also add a Makefile and a description.html file into this directory.
+    See existing scripts for examples.
+
+
+2.  Add a header section to the script you submit and make sure you include
+    the copyright. The purpose section is meant to contain a general
+    overview of the code in the file to assist other programmers that will
+    need to make changes to your code.
+
+    Example (ficticious header for a script called r.myscript) :
+
+#!/bin/sh
+
+############################################################################
+#
+# MODULE:       r.myscript
+# AUTHOR(S):    Me <email AT some domain>
+# PURPOSE:      Calculates univariate statistics from a GRASS raster map
+# COPYRIGHT:    (C) 2005 by the GRASS Development Team
+#
+#               This program is free software under the GNU General Public
+#               License (>=v2). Read the file COPYING that comes with GRASS
+#               for details.
+#
+#############################################################################
+
+    The copyright protects your rights according to GNU General Public
+    License (www.gnu.org).
+    You can easily autogenerate the header and parameters from an existing
+    module using the --script flag. Example:
+
+     d.rast --script
+
+    Just select an existing module which is close to your application to save
+    efforts.
+
+
+3.  - deleted.
+    We don't want the $ ID $ in scripts any more as it
+    causes problems for the SVN branches.
+
+
+4.  As a general principle, shell variables should almost always be quoted.
+    Use only secure temp files, see g.tempfile and scripts/* for examples.
+
+
+5.  [This rule is currently under review]  If you search for a command in $PATH, do NOT
+    use the "which" command or the "type -p" command. Both commands are not
+    supported on all platforms, thus causing problems for some people. As an
+    alternative, please use code similar to the following shell script snippet
+    which will perform the same function. In this case, the path of the grass60
+    command is saved if grass60 is found in $PATH. This won't recognize aliased
+    command name.
+
+	# Search for grass5 command in user's path
+	for i in `echo $PATH | sed 's/^:/.:/
+    	    	    		    s/::/:.:/g
+				    s/:$/:./
+				    s/:/ /g'`
+	do
+	    if [ -f $i/grass5 ] ; then
+    		
+		# Save the path of the grass60 command
+		GRASS_PATH=$i/grass60
+		# Use the first one in user's path
+		break
+	    fi
+	done
+
+<?>
+    If you must use "which", use as follows:
+
+	# check if we have awk
+	if [ ! -x "`which awk`" ] ; then
+	    g.message -e "awk required, please install awk or gawk first" 
+	    exit 1
+	fi
+</?>
+
+
+6.  Add a test to check if the user is in GRASS before starting main part 
+    of script. Result of running the script is unpredicable otherwise.
+
+	if [ -z "$GISBASE" ] ; then
+	    echo "You must be in GRASS GIS to run this program." 1>&2
+	    exit 1
+	fi
+
+    This is the only case, where g.message module (see below) can not be used.
+    In all other cases, you should prefer it's usage over the 'echo' command.
+
+
+7.  Create and use secure temporary files and directories. Use the g.tempfile
+    module to do this. e.g.
+
+	# setup temporary file
+	TMP="`g.tempfile pid=$$`"
+	if [ $? -ne 0 ] || [ -z "$TMP" ] ; then
+	    g.message -e "unable to create temporary files"
+	    exit 1
+	fi
+
+    For temportary directories remove the newly created file and mkdir using 
+    the same name. Beware of commands like "rm -f ${TMP}*" as this becomes
+    "rm -f *" if $TMP is unset (hence the test above).
+
+
+8.  Testing the existence of variables. For portability, use
+	if [ -z "$VARIABLE" ] ; then
+    instead of
+	if [ "$VARIABLE" == "" ] ; then
+
+    and
+
+	if [ -n "$VARIABLE" ] ; then
+    instead of
+	if [ "$VARIABLE" != "" ] ; then
+
+
+9.  Internationalization proofing Awk: In some areas (e.g. some European
+    countries) the decimal place is held with a comma instead of a dot.
+    When scanning variables awk doesn't understand this, so scripts need to 
+    temporarily discard locale settings before calling awk.
+
+	# set environment so that awk works properly in all languages
+	unset LC_ALL
+	LC_NUMERIC=C
+        export LC_NUMERIC
+
+	awk '{print $1}'
+
+
+10. Use g.findfile when there is a need to test if a map exists.
+
+	# test for input raster map
+	g.findfile element=cell file="$INPUT" > /dev/null
+	if [ $? -eq 0 ] ; then
+	  g.message -e "Raster map <$GIS_OPT_MAP> not found in mapset search path"
+	  exit 1
+	fi
+
+	# test for input vector map
+	eval `g.findfile element=vector file=$GIS_OPT_MAP`
+	if [ ! "$file" ] ; then
+	   g.message -e "Vector map <$GIS_OPT_MAP> not found in mapset search path"
+	   exit 1
+	fi
+
+    ... and so forth. See 'g.manual g.findfile' for details.
+
+
+11. For any informational output, use the g.message modul. This module should
+    be also used for error messages and warnings. You can also use it for
+    debugging purposes. 
+
+	#normal message:
+	g.message "Done"
+
+	# warning:
+        g.message -w "No input values found, using default values"
+
+	# error:
+        g.message -e "No map found, exiting."
+
+	# debug output (use g.gisenv to enable/disable)
+        g.message -d "Our calculated value is: $value"
+
+    Try to omit any usage of the 'echo' command for informational output.
+
+
+12. For consistency, use README rather than README.txt for any README files.
+
+
+13. Be sure to develop on top of the LATEST GRASS code (which is in SVN).
+    You can re-check before submission with 'cvs diff':
+
+    Be sure to create unified ("diff -u") format. "Plain"
+    diffs (the default format) are risky, because they will apply without
+    warning to code which has been substantially changed; they are also
+    harder to read than unified.
+
+    Such diffs should be made from the top-level directory, e.g.
+    "cvs diff display/d.vect/main.c"; that way, the diff will
+    include the pathname rather than just "main.c".
+
+
+14. For portability, scripts must work on any POSIX compliant shell, and
+    therefore may not include any Bashisms. Test with ash for errors:
+
+	ash -n scriptname
+
+
+15. When submitting new files to the repository set SVN properties,
+    usually for directory
+
+      svn:ignore : *.tmp.html
+
+    or e.g. for script file
+    
+      svn:executable : *
+      svn:mime-type : text/x-sh
+      svn:keywords : Author Date Id
+      svn:eol-style : native
+
+    See
+    http://svnbook.red-bean.com/en/1.4/svn.advanced.props.html
+
+
+16. Tell the other developers about the new code using the following e-mail:
+    grass-dev@lists.osgeo.org
+ 
+    To subscribe to this mailing list, see
+    http://lists.osgeo.org/mailman/listinfo/grass-dev
+
+
+17. In case of questions feel free to contact the developers at the above
+    mailing list.
+    http://www.grass-gis.org/devel/index.php#submission
+
+...
+[please add further hints if required]

+ 281 - 0
SUBMITTING_TCLTK

@@ -0,0 +1,281 @@
+$Date$
+
+NOTE: Please improve this list!
+
+Dear (new) GRASS Developer,
+
+When submitting TCL and TK SCRIPTS to GRASS SVN repository,
+please take care of following rules:
+
+[ see SUBMITTING for C code hints ]
+[ see SUBMITTING_SCRIPTS for shell script hints ]
+[ see SUBMITTING_DOCS for documentation ]
+[ see SUBMITTING_PYTHON for Python code hints ]
+
+
+1.  Use the directory structure to place your program appropriately into
+    the source tree
+        - general grass tcl/tk libraries and reusable code go into lib/gtcltk
+        - user interfaces go in gui/tcltk
+        - scripts go in scripts/
+            Programs here must have a proper Makefile and description.html
+
+ 
+2.  Add a header section to the script you submit and make sure you include
+    the copyright. The purpose section is meant to contain a general
+    overview of the code in the file to assist other programmers that will
+    need to make changes to your code.
+
+    Example (fictitious header for a script called r.myscript) :
+
+############################################################################
+#
+# MODULE:       r.myscript
+# AUTHOR(S):    Me <email AT some domain>
+# PURPOSE:      Calculates univariate statistics from a GRASS raster map
+# COPYRIGHT:    (C) 2005 by the GRASS Development Team
+#
+#               This program is free software under the GNU General Public
+#               License (>=v2). Read the file COPYING that comes with GRASS
+#               for details.
+#
+#############################################################################
+
+    The copyright protects your rights according to GNU General Public
+    License (www.gnu.org).
+
+
+3.  PLEASE take the time to add comments throughout your code explaining what
+    the code is doing. It will save a HUGE amount of time and frustration for
+    other programmers that need to change or understand your code in the future.
+    Many of the programmers working on grass are not heavily invested in tcl
+    and tk, so extra documentation and explanation are greatly appreciated.
+
+
+4.  Test your program with both tcl/tk 8.3 and tcl/tk 8.4.
+
+
+5.  Always use the gettext macros with [G_msg "..."] for user messages.
+    The string must be quoted using quotation marks, not braces, for
+    xgettext to find it. The string cannot include variable ($) or
+    command ([...]) substitutions. If you need substitutions use
+    [format ...].
+
+    Examples:
+    button .ok -text [G_msg "Ok"]
+
+    set statusbartext [format [G_msg "Monitor %d running"] $monitor_number]]
+
+    Use positional parameters if substitutions might be rearranged in another language:
+
+    format [G_msg "We produced %1\$d units in location %2\$s"] $num $city
+    format [G_msg "In location %2\$s we produced %1\$d units"] $num $city
+
+
+6.  Use "GRASS_TCLSH" and "GRASS_WISH" environment variables instead of
+    "tclsh" and "wish" at the start of Tcl/Tk scripts. This allows users to
+    override the default names, so that developers don't need worry about the
+    shell names.
+
+    Tcl script:
+
+    	#!/bin/sh
+	# the next line restarts using tclsh. Note the backslash: \
+	exec $GRASS_TCLSH "$0" "$@"
+
+
+    Tk script:
+
+    	#!/bin/sh
+	# the next line restarts using wish. Note the backslash: \
+	exec $GRASS_WISH "$0" "$@"
+
+
+7.  Do not source files that have already been sourced.
+
+        gui.tcl sources:
+            options.tcl 
+            select.tcl
+            gronsole.tcl
+
+    If your code requires something to be sourced before it note so
+    in a comment at the top of the file.
+
+
+8.  Set tabstops in your editor to 8 spaces.
+    When modifying files use the indentation style that is already present.
+    Please use consistent indentation style in your new code. Whether you use
+    tabs or spaces to indent please be consistent. Where tabs and spaces are
+    mixed please remember that a tab is 8 spaces.
+
+
+9.  Use the tk options database to control the appearance of your user interface.
+    In general do not set options on tk widgets unless that option is truly
+    specific to that widget. It makes them harder to customize.
+
+    Example: Don't set options like -foreground or -background or -font
+    when creating widgets, unless there's a really _really_ specific reason to
+    have it that color (like it's demonstrating that color).
+
+    If you want something like a label to look different than everything else
+    of that class (other labels) give it a distinctive name, like
+    .moduletitlelabel . If you have a bunch of them give them all the same 
+    distinctive name. This allows them to have their options controlled by the 
+    options database.
+
+    You can put your options at the start of your script (before creating any
+    widgets) like this:
+    option add *modultitlelabel.background red
+    More examples are in lib/gtcltk/options.tcl
+
+    Many common options, like font, background and foreground colors,
+    highlighting, scrollbar colors, and help bubble appearance are controlled
+    by options.tcl. You can include it at the start of your script with:
+    source $env(GISBASE)/etc/gtcltk/options.tcl
+
+
+10. Avoid using global variables. Thay are a frequent source of bugs, make code
+    harder to understand, and make your program difficult to reuse. Additionally,
+    putting code into procs usually makes it run faster (it gets compiled).
+
+
+11. For consistency, use README rather than README.txt for any README files.
+
+
+12. Use of GRASS commands in shell wrapper.
+
+    Any GRASS program run in an xterm (those which do interactive query) needs
+    to use grass-run.sh, e.g.:
+
+    exec -- $env(GISBASE)/etc/grass-xterm-wrapper -e $env(GISBASE)/etc/grass-run.sh g.proj ...
+
+    You should probably also use "-T g.proj -n g.proj" to set the title
+    back (otherwise it will be "grass-run.sh", which isn't particularly
+    informative).
+
+    The xterm will close as soon as the command completes (whether it
+    succeeds or fails). You can use the -hold switch to retain the xterm
+    window after the command completes, but you should only do that for
+    debugging; having to manually close the xterm window each time would
+    be annoying in normal use. Alternatively, redirect stdout/stderr to a
+    file, to catch any error messages.
+
+
+13. Be sure to develop on top of the LATEST GRASS code (which is in
+    SVN repository). You can re-check before submission with 'svn
+    diff':
+
+    Be sure to create unified ("diff -u") format. "Plain"
+    diffs (the default format) are risky, because they will apply without
+    warning to code which has been substantially changed; they are also
+    harder to read than unified.
+
+    Such diffs should be made from the top-level directory, e.g.
+    "cvs diff display/d.vect/main.c"; that way, the diff will
+    include the pathname rather than just "main.c".
+
+
+14. Tell the other developers about the new code using the following e-mail:
+    grass-dev@lists.osgeo.org
+ 
+    To subscribe to this mailing list, see
+    http://lists.osgeo.org/mailman/listinfo/grass-dev
+
+
+15. In case of questions feel free to contact the developers at the above
+    mailing list.
+    http://www.grass-gis.org/devel/index.php#submission
+
+
+16. Try to evaluate things only once. Tcl compiles the program to bytecode which
+    can be interpreted fairly quickly. If there are strings that must still be
+    evaluated tcl must parse and either compile or interpret them
+    each time they are encountered. In general this means put braces around
+    expressions and especially regular expressions (Tcl also compiles regular
+    expressions). Multiple evaluation can also lead to bugs.
+
+    Expressions via expr command:
+    Slow:
+        set y [expr $a * $x + $b]
+    Fast:
+        set y [expr {$a * $x + $b}]
+
+    Expressions in conditions:
+    Slow:
+        if [...] {...
+    Fast:
+        if {[...]} {...
+
+    Regular expressions:
+    Very slow:
+        regex "x(\[0-9\]+).*not" $string trash number
+    Fast:
+        regex {x([0-9]+).*not} $string trash number
+
+    If you really want speed:
+    If a regular expression needs to be constructed from variables but used
+    multiple times store it in a variable that will not be destroyed or
+    changed between reuse. Tcl stores the compiled regex with the variable.
+
+
+17. You might want to decompose lists in a somewhat easy way:
+
+    Difficult and slow:
+    # Make x1 y1 x2 y2 the first four things in the list
+    set list [commandMakesList]
+    set x1 [lindex $list 0]
+    set y1 [lindex $list 1]
+    set x2 [lindex $list 2]
+    set y2 [lindex $list 3]
+
+    Easier and faster:
+    # Make x1 y1 x2 y2 the first four things in the list
+    foreach {x1 y1 x2 y2} [commandMakesList] {break}
+
+    Be sure to include a comment as to what you are doing.
+
+
+18. Use the Tcl list functions (list, lappend etc) for manipulating lists.
+
+    For example, use:
+
+        set vals [list $foo $bar]
+
+    rather than:
+
+        set vals "$foo $bar"
+
+    The former will always create a list with two elements, adding braces
+    if necessary, while the latter will split $foo and $bar into multiple
+    elements if they contain spaces. Additionally the first is faster
+    because tcl is not internally converting between strings and lists.
+
+    A related issue is to remember that command lines (as used by exec and
+    open "|...") are lists. exec behaves like execl(), spawnl() etc, and
+    not like system().
+
+    Overlooking either of these points is likely to result in code which
+    fails when a command argument contains a space.
+
+
+19. Tcl C library:
+    Memory allocated with Tcl_Alloc (such as the result of Tcl_Merge)
+    must be freed with Tcl_Free. This means that the ->freeProc of
+    an interpreter when returning a string using Tcl_Merge should be
+    TCL_DYNAMIC. Incorrectly freeing memory with glibc free will
+    cause segfaults in Tcl 8.4 and later.
+
+
+20. When submitting new files to the repository set SVN properties,
+    e.g.
+
+      svn:executable : *
+      svn:mime-type : text/x-tcl
+      svn:keywords : Author Date Id
+      svn:eol-style : native
+
+    See
+    http://svnbook.red-bean.com/en/1.4/svn.advanced.props.html
+
+...
+[please add further hints if required]

+ 64 - 0
TODO

@@ -0,0 +1,64 @@
+
+                TODO
+               ------
+
+6.0.0 (can be done, but cannot stop 6.0.0 release)
+-----------------------------------------------------------------
+- Cygwin/Windows and other (Non-Linux) platform specific problems
+- i18n translations
+
+
+> 6.1.0 
+-------
+
+Vector TODO: see doc/vector/TODO
+
+Missing modules:
+- write Vect_map_exists() and implement in g.remove and v.digit -n (radim)
+
+- add '-d' dissolve to v.reclass
+- add 'where=' to v.to.rast
+- add '-3' for 3D distance calculation in v.distance
+
+- change default color white to black:
+   (better define DEFAULT_FG_COLOR, DEFAULT_BG_COLOR in gis.h, update in 5.0 and 5.7)
+display/d.erase/main.c:	color->answer = "white";	/* set default color! */
+display/d.path/main.c:    bgcolor_opt->answer     = "white" ;
+display/d.barscale/main.c:	opt2->answer     = "white" ;
+display/d.legend/main.c:	opt2->answer     = "white" ;
+display/d.colortable/main.c:	opt2->answer     = "white" ;
+display/d.geodesic/main.c:    parm.lcolor->answer     = "white";
+display/d.geodesic/main.c:	line_color = D_translate_color (parm.lcolor->answer = "white");
+display/d.geodesic/main.c:    if(strcmp (parm.lcolor->answer, "white") == 0)
+display/d.graph/main.c:	opt2->answer     = "white" ;
+display/d.histogram/main.c:	opt2->answer     = "white" ;
+display/d.mapgraph/main.c:	opt2->answer     = "white" ;
+display/d.measure/main.c:	parm.c2->answer = "white";
+display/d.rast.arrow/arrow.c:    opt5->answer     = "white" ;
+display/d.rhumbline/main.c:	parm.lcolor->answer     = "white";
+display/d.rhumbline/main.c:		line_color = D_translate_color (parm.lcolor->answer = "white");
+display/d.rhumbline/main.c:	if(strcmp (parm.lcolor->answer, "white") == 0)
+display/d.scale/main.c:	opt2->answer     = "white" ;
+display/d.title/main.c:	opt2->answer     = "white" ;
+display/d.linegraph/linegraph.c:    t_color_opt->answer     = "white" ;
+
+- merge of image libraries:
+  A)
+    - lib/imagery/: standard lib, in use (i.* except for i.points3, i.rectify3)
+    - imagery/i.ortho.photo/libes/: standard lib, in use (i.ortho.photo, photo.*)
+  B)
+    - lib/image3/: never finished improvement which integrated the standard lib and
+                   the ortho lib. Seems to provide also ortho rectification for
+                   satellite data (i.points3, i.rectify3)
+  C) 
+    - merge of i.points, i.vpoints, i.points3
+    - merge of i.rectify and i.rectify3
+    - addition of new resampling algorithms such as bilinear, cubic convolution
+      (take from r.proj?)
+    - add other warping methods (maybe thin splines from GDAL?)
+    - implement/finish linewise ortho-rectification of satellite data
+    - Add support for > 8bit colors (only 0-255 supported currently)
+
+- Depreciate tape functions in next major revision of GRASS and create a
+  tape module that accomplishes tape access.
+

File diff suppressed because it is too large
+ 1531 - 0
aclocal.m4


+ 360 - 0
binaryInstall.src

@@ -0,0 +1,360 @@
+#!/bin/sh
+
+##########################################################################
+#
+# IMPORTANT: The binaryInstall.src file is a source file, NOT an
+# executable shell script!! Used to generate grass-MAJ.MIN.VER-ARCH-DD_MM_YYYY-install.sh by
+# make bindist
+#  
+# GRASS binary package installation tool
+# platform independent
+#
+# $Id$
+# 1999-2000 by Markus Neteler, neteler@itc.it
+#
+##########################################################################
+
+# Set a zero size variable for testing if this file is a source file. Note
+# that the make bindist command will change this line to TEST_STR = executable
+# without the spaces surrounding the equal sign
+TEST_STR=
+
+# Use a text string for sed to recognize to insert the proper version
+NAME_VER=BIN_DIST_VERSION
+TAR_FILE_SIZE=SIZE_TAR_FILE
+ARCH=ARCHITECTURE
+
+GRASSPRG=GRASSPRG_NAME
+
+# Set the default BINDIR and DESTDIR directories
+BINDIR=/usr/local/bin
+DESTDIR=/usr/local/grass$NAME_VER
+UNINSTALL=grass${NAME_VER}uninstall.sh
+
+# Check if this is a source file or not
+if [ -z "$TEST_STR" ] ; then
+    echo "This is a source script, not an executable script which can be run."
+    exit
+fi
+
+# Check for first parameter:
+if [ $# -lt 1 -o "$1" = "-h" -o "$1" = "-help" -o "$1" = "--help"  ] ; then
+    echo "
+
+GRASS GIS $NAME_VER binary package installation tool
+
+Usage:	grass-$NAME_VER-install.sh grass-$NAME_VER.tar.gz [dest_dir] [bin_dir]
+
+      with:
+        [dest_dir] - optional: FULL path name to the installation directory
+                     (default: /usr/local/grass$NAME_VER/)
+        [bin_dir] - optional: FULL path name to the grass binary directory
+                     (default: /usr/local/bin/)
+		     Notes: 1) Only the grass executable file is stored here
+		     	    2) If you want to change the binary directory only
+			       then you need to specify the destination
+			       directory as well
+
+You may need login as root for installation.
+"
+    exit
+fi
+
+# Check for second parameter:
+if [ "$2" ] ; then
+    DESTDIR=$2
+fi
+
+# Check for third parameter:
+if [ "$3" ] ; then
+    BINDIR=$3
+fi
+
+# Print out script identification message
+echo ""
+echo "GRASS GIS $NAME_VER binary package installation tool"
+echo ""
+
+# Check for correct package name:
+if [ ! -f $1 ] ; then 
+    echo "ERROR: Wrong package name $1. File does not exists."
+    echo ""
+    exit
+fi
+
+# Obtain the package name and path
+CURR_DIR=`pwd`
+PACKAGE_NAME=`basename $1`
+PACKAGE_DIR=`dirname $1`
+
+# the dirname command uses . and .. if found so we need the absolute path
+cd $PACKAGE_DIR
+PACKAGE_DIR=`pwd`
+
+# Check if package is first parameter and in gz or bz2 compression:
+# is package in .tar.gz format?
+echo $PACKAGE_NAME | grep "\.tar\.gz" > /dev/null
+if [ $? -eq 0 ] ; then
+    UNPACK=gunzip
+    	
+    # Is gunzip there?
+    IFSSAVE="$IFS"
+    IFS=":"
+    GUNZIP=""
+    for TEST in $PATH ; do
+        if [ -x $TEST/gunzip ] ; then
+	    GUNZIP="$TEST/gunzip"
+	fi
+    done
+    # which gunzip | grep -v no > /dev/null
+    IFS="$IFSSAVE"
+    if [ ! "$GUNZIP" ] ; then
+        echo "No gunzip installed. Please get from:"
+        echo "   http://www.gnu.org/software/gzip/gzip.html"
+        exit
+    fi
+else
+    # not in .tar.gz format, perhaps in .tar.bz2 format?
+    echo $PACKAGE_NAME | grep "\.tar\.bz2" > /dev/null
+    if [ $? -eq 0 ] ; then
+        UNPACK=bunzip2
+    
+        # Is bunzip2 there?
+        IFSSAVE="$IFS"
+        IFS=":"
+        BUNZIP2=""
+        for TEST in $PATH ; do
+            if [ -x $TEST/bunzip2 ] ; then
+	        BUNZIP2="$TEST/bunzip2"
+	    fi
+        done
+        IFS="$IFSSAVE"
+        # which bunzip2 | grep -v no > /dev/null
+        if [ ! "$BUNZIP2" ] ; then
+    	    echo "No bunzip2 installed. Please get from:"
+    	    echo "   http://sources.redhat.com/bzip2/index.html"
+    	    exit
+        fi
+    else
+        # not in .tar.gz or .tar.bz2 format, completely wrong!
+        echo "ERROR: You need the GRASS binary package in .tar.gz compression "
+        echo "or .tar.bz2."
+        echo ""
+        exit
+    fi
+fi
+
+# Check if the size of the tar gzip file is the same as what was on the server
+SIZE=`ls -l $PACKAGE_NAME | tr -s " " | cut -d" " -f5`
+if [ $? -ne 0 ] ; then
+    echo "ERROR while installing binaries!"
+    echo "Exiting."
+    exit
+fi
+
+if [ $SIZE -ne $TAR_FILE_SIZE ] ; then
+    echo "ERROR: The size of the binary package is not correct."
+    echo "  Perhaps there was a transmission error. Please download"
+    echo "  the package again"
+    echo ""
+    exit
+fi
+
+echo "Using $UNPACK decompressor..."
+
+echo "The package $PACKAGE_NAME seems to be o.k."
+echo " Proceeding..."
+echo ""
+
+# Check if the paths for the binary and the destination are the same
+BIN_PATH1=$BINDIR/grass-$NAME_VER
+BIN_PATH2=$BIN_PATH1/
+
+if [ $BIN_PATH1 = $DESTDIR -o $BIN_PATH2 = $DESTDIR ] ; then
+    echo "ERROR:"
+    echo "It appears that the destination directory path is the same as the"
+    echo "path for the grass binary executable. This results in a name"
+    echo "conflict between the destination directory and the executable."
+    echo "Please run this script again with a different path name for the"
+    echo "destination directory."
+    exit
+fi
+
+# Check if BINDIR is a directory
+if [ ! -d "$BINDIR" ] ; then
+    
+    # Check if BINDIR is a file
+    if [ -f "$BINDIR" ] ; then
+    	echo ""
+	echo "ERROR: $BINDIR is a file not a directory."
+	echo "Please specify a directory for the binary executable directory."
+	exit
+    fi
+   
+    mkdir -p $BINDIR
+    
+    if [ $? -ne 0 ] ; then
+	echo "An error occured trying to create $BINDIR ! Exiting."
+	exit
+    fi
+fi
+
+# Check if DESTDIR is appropriate
+echo "Checking and creating installation directory..."
+
+if [ ! -d "$DESTDIR" ] ; then
+
+    # Check if a word "grass" is in string $DESTDIR
+    echo $DESTDIR | grep "grass" > /dev/null
+    
+    if [ $? -eq 1 ] ; then
+    	echo "WARNING: Your destination path $DESTDIR does not contain the word 'grass'"
+        echo "Continue (y/n)?"
+        read ans         
+        
+	if [ "$ans" = "n" -o "$ans" = "N" ] ; then
+            exit
+        fi
+    fi
+    
+    # Check if DESTDIR is a file
+    if [ -f "$DESTDIR" ] ; then
+    	echo ""
+	echo "ERROR: $DESTDIR is a file not a directory."
+	echo "Please specify a directory for the destination directory"
+	exit
+    fi
+
+    mkdir -p $DESTDIR
+    
+    if [ $? -ne 0 ] ; then
+    	echo "An error occured trying to create $DESTDIR! Exiting."
+    	exit
+    fi
+else
+    if [ -d $DESTDIR/bin ] ; then
+    	echo ""
+        echo "ERROR: Old GRASS distribution existing in $DESTDIR!"
+        echo "Remove first!"
+        exit
+    else
+
+    	# Check if a word "grass" is in string $DESTDIR
+        echo $DESTDIR | grep "grass" > /dev/null
+        
+	if [ $? -eq 1 ] ; then
+            echo "WARNING: Your destination path $DESTDIR does not contain the word 'grass'"
+            echo "Continue (y/n)?"
+            read ans         
+            
+	    if [ "$ans" = "n" -o "$ans" = "N" ] ; then
+            	exit
+            fi
+        fi
+
+	# Check if DESTDIR is writable
+	touch $DESTDIR/test$$ > /dev/null
+	if [ $? -ne 0 ] ; then
+	    echo "ERROR: Destination directory $DESTDIR is not"
+	    echo "writable, try installing as root!"
+	    echo "Exiting."    
+	    exit 1
+        fi
+	rm -f $DESTDIR/test$$ > /dev/null
+
+    fi        
+fi
+
+
+# Start the installation job...
+echo "Installing GRASS binaries into $DESTDIR"
+echo ""
+
+echo "Uncompressing the package and extracting to target directory..."
+PACK_FILE=`echo $PACKAGE_DIR/$PACKAGE_NAME | sed 's+^//+/+g'`
+cd $DESTDIR; $UNPACK -c $PACK_FILE | tar -xf -
+if [ $? -eq 1 ] ; then
+    echo "An error occured or user break while installing binaries! Exiting."
+    exit
+fi
+
+# Get rid of any CVS directories
+find . -name CVS -exec rm -rf {} \; 2>/dev/null ; true
+cd $CURR_DIR
+
+# Creating start script
+echo "Creating start script:"
+echo "$BINDIR/$GRASSPRG -> $BINDIR/grass-$NAME_VER"
+
+STRING="s|^GISBASE.*|GISBASE\=\'$DESTDIR\'|g"
+
+sed -e $STRING $DESTDIR/$GRASSPRG.tmp > $BINDIR/grass-$NAME_VER
+if [ $? -eq 1 ] ; then
+  echo "An error occured trying to create the grass start script! Exiting."
+  echo "You probably do not have permission to install into $BINDIR."
+  echo "You may need to be the root user to install in that directory."
+  exit
+fi
+
+ln -sf $BINDIR/grass-$NAME_VER $BINDIR/$GRASSPRG
+chmod ugo+x $BINDIR/grass-$NAME_VER
+
+if [ $? -eq 1 ] ; then
+    echo "An error occured trying to create the grass start script! Exiting."
+    echo "You probably do not have permission to install into $BINDIR."
+    echo "You may need to be the root user to install in that directory."
+    exit
+fi
+
+echo "Creating the locks directory for monitors..."
+SERVERNAME=`uname -n | sed -e "s/\..*//"`
+
+if [ ! -d $DESTDIR/locks ] ; then
+    mkdir $DESTDIR/locks
+fi
+
+rm -rf $DESTDIR/locks/*
+mkdir $DESTDIR/locks/$SERVERNAME
+chmod -R 1777 $DESTDIR/locks
+
+echo""
+
+echo "Creating datum transformation gridshift files..."
+
+if test -x "${DESTDIR}/etc/nad2bin" ; then
+    NAD2BIN="${DESTDIR}/etc/nad2bin"
+else
+    # Use version installed with PROJ.4 (should be in path)
+    NAD2BIN=nad2bin
+fi
+
+for i in "${DESTDIR}"/etc/nad/src/*.lla
+do 
+    "${NAD2BIN}" < $i \
+    "${DESTDIR}"/etc/nad/`echo \`basename "$i"\` | sed 's/.lla//'` && rm -f "$i"
+done
+
+if test -z "`ls \"${DESTDIR}/etc/nad/src\"`" ; then
+    rmdir "${DESTDIR}/etc/nad/src"
+fi
+
+echo""
+
+echo "Generating display font configuration file..."
+
+GISBASE="$DESTDIR" GISRC=junk LD_LIBRARY_PATH_VAR="${DESTDIR}/lib:$LD_LIBRARY_PATH_VAR" "${DESTDIR}/bin/g.mkfontcap" -o
+
+echo""
+
+# Print out some messages
+echo "Installation finished. Start GRASS $NAME_VER with"
+echo "    $BINDIR/$GRASSPRG"
+echo ""
+#echo "The graphical user interface can be started within GRASS GIS."
+#echo ""
+#echo "You can uninstall grass by typing"
+#echo "    sh $UNINSTALL"
+#echo "in the directory $BINDIR"
+echo ""
+echo "Welcome to GRASS GIS. Enjoy this open source GRASS GIS!"
+echo ""

File diff suppressed because it is too large
+ 1466 - 0
config.guess


File diff suppressed because it is too large
+ 1579 - 0
config.sub


File diff suppressed because it is too large
+ 16123 - 0
configure


File diff suppressed because it is too large
+ 1814 - 0
configure.in


+ 45 - 0
contributors.csv

@@ -0,0 +1,45 @@
+cvs_id,name,email,osgeo_id,rfc2_agreed
+-,Ivan Shmakov,<ivan theory.asu.ru>,1gray,yes
+-,Eric Patton,<epatton nrcan.gc.ca>,epatton,yes
+-,Maris Nartiss,<maris.gis@gmail.com>,marisn,yes
+alex,Alex Shevlakov,<sixote yahoo.com>,,-
+andreas,Andreas Lange,<andreas.c.lange gmx.de>,,-
+benjamin,Benjamin Ducke,<benjamin.ducke ufg.uni-kiel.de>,benducke,yes
+bernhard,Bernhard Reiter,<bernhard intevation.de>,,-
+bob,Bob Covill,<bcovill tekmap.ns.ca>,,-
+brad,Brad Douglas,<rez touchofmadness.com>,bdouglas,yes
+carlos,Carlos Davila,<cdavilam jemila.jazztel.es>,cdavilam,yes
+cedric,Cedric Shock,<cedricgrass shockfamily.net>,,-
+cho,Huidae Cho,<grass4u gmail.com>,hcho,yes
+danielc,Daniel Calvelo Aros,<dca.gis gmail.com>,dcalvelo,yes
+david,David D. Gray,<ddgray armadce.demon.co.uk>,,-
+eric,Eric G. Miller,<egm2 jps.net>,,-
+florian,Florian Goessmann,<florian wallweg39.de>,,-
+frankw,Frank Warmerdam,<warmerdam pobox.com>,warmerdam,-
+glynn,Glynn Clements,<glynn gclements.plus.com>,glynn,yes
+hamish,Hamish Bowman,<hamish_b yahoo.com>,hamish,yes
+helena,Helena Mitasova,<hmitaso unity.ncsu.edu>,helena,yes
+jachym,Jachym Cepicky,<jachym.cepicky gmail.com>,jachym,yes
+jan,Jan-Oliver Wagner,<jan intevation.de>,,-
+john,John Huddleston,<jhudd.lamar colostate.edu>,,-
+justin,Justin Hickey,<jhickey hpcc.nectec.or.th>,,-
+markus,Markus Neteler,<neteler cealp.it>,neteler,yes
+martin,Martin Wegmann,<wegmann biozentrum.uni-wuerzburg.de>,wegmann,-
+martinl,Martin Landa,<landa.martin gmail.com>,martinl,yes
+massimo,Massimo Cuomo,<m.cuomo acsys.it>,,-
+michael,Michael Barton,<michael.barton asu.edu>,cmbarton,yes
+mike,Mike Thomas,<miketh brisbane.paradigmgeo.com>,,-
+moritz,Moritz Lennert,<mlennert club.worldonline.be>,mlennert,yes
+msieczka,Maciek Sieczka,<tutey o2.pl>,msieczka,yes
+paul,Paul Kelly,<paul-grass stjohnspoint.co.uk>,pkelly,yes
+paulo,Paulo Marcondes,<pmarc.debian gmail.com>,pmarcondes,-
+pallech,Serena Pallecchi,<pallecch cli.di.unipi.it>,,-
+radim,Radim Blazek,<radim.blazek gmail.com>,rblazek,-
+roberto,Roberto Micarelli,<miro iol.it>,,-
+robertoa,Roberto Antolin,<roberto geomatica.como.polimi.it>,rantolin,yes
+roger,Roger S. Miller,<rgrmill rt66.com>,,-
+scott,Scott Mitchell,<smitch mac.com>,smitch,yes
+soeren,Soeren Gebbert,<soerengebbert googlemail.com>,,-
+stephan,Stephan Holl,<stephan.holl intevation.de>,sholl,yes
+william,William Kyngesburye,<kyngchaos kyngchaos.com>,kyngchaos,yes
+wolf,Wolf Bergenheim,<wolf+grass bergenheim.net>,wolf,yes

+ 40 - 0
contributors_extra.csv

@@ -0,0 +1,40 @@
+name,email,rfc2_agreed
+Andrea Aime,<aaime openplans.org>,-
+Lars Ahlzen,<lars ahlzen.com>,-
+Carl Anderson,<candrsn mindspring.com>,-
+Dylan Beaudette,<dylan.beaudette gmail.com>,yes
+Roger Bivand,<Roger Bivand nhh.no>,-
+Malcolm Blue,<mblue nb sympatico.ca>,-
+Jacques Bouchard,<bouchard onera.fr>,-
+Maria Brovelli,<maria.brovelli polimi.it>,-
+William Brown,<brown gis.uiuc.edu>,-
+Bruce Byars,<Bruce_Byars baylor.edu>,-
+Angus Carr,<apcarr flash lakeheadu.ca>,-
+Otto Dassau,<otto.dassau gmx de>,-
+Charles Ehlschlaeger,<cre111 wiu.edu>,-
+Pierre de Mouveaux,<pierre polaris-technologies.com>,-
+Roberto Flor,<flor fbk.eu>,-
+Antonio Galea,<ant9000 netwise.it>,-
+Ralf Gerlich,<ralf gerlich at bsse.biz>,-
+Jaro Hofierka,<hofierka geomodel.sk>,-
+Stephan Holl,<stephan holl-land.de>,-
+Bill Hughes,<bhughes grasshoppernet.com>,-
+Ari Jolma,<ari jolma tkk fi>,-
+Jeshua Lacock,<jeshua OpenOSX.com>,-
+Roger Miller,<rgrmill rt66.com>,-
+Brook Milligan,<brook trillium nmsu.edu>,-
+Lubos Mitas,<lmitas ncsa uiuc.edu>,-
+Eric Mitchell,<emitchell altaira.com>,-
+Scott Mitchell,<smitch mac.com>,-
+Lorenzo Moretti,<lorenzo moretti bologna.enea.it>,-
+Maris Nartiss,<maris nartiss gmail.com>,-
+Tomas Paudits,<tpaudits mailbox.sk>,-
+Francesco Pirotti,<francesco.pirotti unipd.it>,-
+Phisan Santitamnont,<fsvpss eng.chula.ac.th>,-
+Christoph Simon,<ciccio kiosknet.com.br>,-
+Job Spijker,<spijker geo.uu.nl>,-
+Laura Toma,<ltoma bowdoin.edu>,-
+Alfonso Vitti,<alfonso vitti ing.unitn.it>,-
+Philip Warner,<pjw rhyme com.au>,-
+Trevor Wiens,<twiens interbaun.com>,-
+Michel Wurtz,<mw teledetection.fr>,-

+ 17 - 0
db/Makefile

@@ -0,0 +1,17 @@
+
+MODULE_TOPDIR = ..
+
+SUBDIRS = \
+	drivers \
+	base \
+	db.login
+
+PGM = databaseintro
+
+include $(MODULE_TOPDIR)/include/Make/Dir.make
+
+default: htmldir
+
+htmldir: parsubdirs
+
+clean: cleansubdirs

+ 50 - 0
db/base/Makefile

@@ -0,0 +1,50 @@
+
+MODULE_TOPDIR = ../..
+
+LIBES = $(DBMILIB) $(GISLIB) $(DATETIMELIB)
+DEPENDENCIES = $(GISDEP) $(DBMIDEP)
+
+#not used: db.createdb db.dropdb db.databases db.droptable
+PROGRAMS = db.columns db.copy db.describe db.drivers db.execute db.select db.tables db.connect
+
+include $(MODULE_TOPDIR)/include/Make/Multi.make
+
+default: $(patsubst %,$(BIN)/%$(EXE),$(PROGRAMS))
+	$(MAKE) htmlmulti
+
+$(BIN)/db.columns$(EXE): $(OBJDIR)/columns.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.copy$(EXE): $(OBJDIR)/copy.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.createdb$(EXE): $(OBJDIR)/createdb.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.dropdb$(EXE): $(OBJDIR)/dropdb.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.droptable$(EXE): $(OBJDIR)/droptable.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.databases$(EXE): $(OBJDIR)/databases.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.describe$(EXE): $(OBJDIR)/describe.o $(OBJDIR)/printtab.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.drivers$(EXE): $(OBJDIR)/drivers.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.execute$(EXE): $(OBJDIR)/execute.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.select$(EXE): $(OBJDIR)/select.o $(OBJDIR)/printtab.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.tables$(EXE): $(OBJDIR)/tables.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+
+$(BIN)/db.connect$(EXE): $(OBJDIR)/connect.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+

+ 100 - 0
db/base/columns.c

@@ -0,0 +1,100 @@
+/****************************************************************************
+ *
+ * MODULE:       db.columns
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>, Markus Neteler <neteler itc.it>
+ * PURPOSE:      list the column names for a table
+ * COPYRIGHT:    (C) 2002-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/codes.h>
+#include <stdlib.h>
+#include <grass/glocale.h>
+
+
+struct {
+	char *driver, *database, *table;
+} parms;
+
+
+/* function prototypes */
+static void parse_command_line (int, char **);
+
+
+int
+main (int argc, char **argv)
+{
+    dbDriver *driver;
+    dbHandle handle;
+    dbTable *table;
+    dbString table_name;
+    int col, ncols;
+
+    parse_command_line (argc, argv);
+
+    driver = db_start_driver(parms.driver);
+    if (driver == NULL)
+        G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
+       
+    db_init_handle (&handle);
+    db_set_handle (&handle, parms.database, NULL);
+    if (db_open_database(driver, &handle) != DB_OK)
+        exit (EXIT_FAILURE);
+
+    db_init_string(&table_name);
+    db_set_string(&table_name, parms.table);
+    if(db_describe_table (driver, &table_name, &table) != DB_OK)
+        exit (EXIT_FAILURE);
+
+    db_close_database(driver);
+    db_shutdown_driver(driver);
+
+    ncols = db_get_table_number_of_columns(table);
+    for (col = 0; col < ncols; col++)
+	fprintf(stdout, "%s\n", db_get_column_name(db_get_table_column(table, col)));
+
+    exit (EXIT_SUCCESS);
+}
+
+
+static void
+parse_command_line (int argc, char **argv)
+{
+    struct Option *driver, *database, *table;
+    struct GModule *module;
+    char *drv, *db;
+
+    /* Initialize the GIS calls */
+        G_gisinit(argv[0]) ;
+
+    table 		= G_define_standard_option(G_OPT_TABLE);
+    table->required 	= YES;
+
+    driver 		= G_define_standard_option(G_OPT_DRIVER);
+    driver->options     = db_list_drivers();
+    if ( (drv=db_get_default_driver_name()) )
+        driver->answer = drv;
+
+    database 		= G_define_standard_option(G_OPT_DATABASE);
+    if ( (db=db_get_default_database_name()) )
+         database->answer = db;
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("List all columns for a given table.");
+
+    if(G_parser(argc, argv))
+        exit (EXIT_FAILURE);
+
+    parms.driver	= driver->answer;
+    parms.database	= database->answer;
+    parms.table		= table->answer;
+}

+ 170 - 0
db/base/connect.c

@@ -0,0 +1,170 @@
+/****************************************************************************
+ *
+ * MODULE:       db.connect
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Alex Shevlakov <sixote yahoo.com>, 
+ *               Glynn Clements <glynn gclements.plus.com>,
+ *               Markus Neteler <neteler itc.it>,
+ *               Hamish Bowman <hamish_b yahoo com>
+ * PURPOSE:      set parameters for connection to database
+ * COPYRIGHT:    (C) 2002-2008 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+
+/* database for DBF can be written with variables:
+ *   database=$GISDBASE/$LOCATION_NAME/$MAPSET/dbf
+ */
+
+int
+main(int argc, char *argv[])
+{
+    dbConnection conn;
+    struct Flag *print, *check_set_default;
+/*    struct Option *driver, *database, *user, *password, *keycol;*/
+    struct Option *driver, *database, *schema, *group;
+    struct GModule *module;
+
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords    = _("database, SQL");
+    module->description =
+	_("Prints/sets general DB connection for current mapset and exits.");
+
+
+    print = G_define_flag();
+    print->key               = 'p';
+    print->description       = _("Print current connection parameters and exit");
+
+    check_set_default = G_define_flag();
+    check_set_default->key         = 'c';
+    check_set_default->description =
+	_("Check connection parameters, set if uninitialized, and exit");
+
+    driver = G_define_standard_option(G_OPT_DRIVER);
+    driver->options    = db_list_drivers();
+    driver->answer = db_get_default_driver_name();
+
+    database = G_define_standard_option(G_OPT_DATABASE);
+    database->answer = db_get_default_database_name();
+
+    schema = G_define_option() ;
+    schema->key        = "schema" ;
+    schema->type       = TYPE_STRING ;
+    schema->required   = NO  ;
+    schema->multiple   = NO ;
+    schema->answer     = db_get_default_schema_name();
+    schema->label      = _("Database schema");
+    schema->description = _("Do not use this option if schemas "
+			    "are not supported by driver/database server");
+
+    group = G_define_option() ;
+    group->key        = "group" ;
+    group->type       = TYPE_STRING ;
+    group->required   = NO  ;
+    group->multiple   = NO ;
+    group->answer     = db_get_default_group_name();
+    group->description = _("Default group of database users to which "
+			   "select privilege is granted");
+
+/* commented due to new mechanism:
+    user = G_define_option() ;
+    user->key        = "user" ;
+    user->type       = TYPE_STRING ;
+    user->required   = NO  ;
+    user->multiple   = NO ;
+    user->description= "User:" ;    
+
+    password = G_define_option() ;
+    password->key        = "password" ;
+    password->type       = TYPE_STRING ;
+    password->required   = NO  ;
+    password->multiple   = NO ;
+    password->description= "Password:" ;
+*/
+
+    if(G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+
+    if(print->answer) {
+	/* get and print connection */
+	if (db_get_connection( &conn ) == DB_OK) {
+	    fprintf(stdout, "driver:%s\n", conn.driverName ? conn.driverName : "");
+	    fprintf(stdout, "database:%s\n", conn.databaseName ? conn.databaseName : "");    
+	    fprintf(stdout, "schema:%s\n", conn.schemaName ? conn.schemaName : "");    
+	    fprintf(stdout, "group:%s\n", conn.group ? conn.group : "");    
+	}
+	else
+	    G_fatal_error(_("Database connection not defined. "
+			    "Run db.connect."));
+
+	exit(EXIT_SUCCESS);
+    }
+
+
+    if(check_set_default->answer) {
+    	/* check connection and set to system-wide default in required */
+/*
+ * TODO: improve db_{get,set}_connection() to not return DB_OK on error
+ *	 (thus currently there is no point in checking for that here)
+ */
+	db_get_connection(&conn);
+
+	if ( !conn.driverName && !conn.databaseName ) {
+
+	    db_set_default_connection();
+	    db_get_connection(&conn);
+
+	    G_message(_("Default driver / database set to:\n"
+		"driver: %s\ndatabase: %s"), conn.driverName, conn.databaseName);
+	}
+	/* they must be a matched pair, so if one is set but not the other
+	    then give up and let the user figure it out */
+	else if ( !conn.driverName ) {
+	    G_fatal_error( _("Default driver is not set") ); 
+	}
+	else if ( !conn.databaseName ) {
+	    G_fatal_error( _("Default database is not set") ); 
+	}
+
+	/* connection either already existed or now exists */
+	exit(EXIT_SUCCESS);
+    }
+
+
+    /* set connection*/
+    db_get_connection( &conn );  /* read current */
+
+    if ( driver->answer )
+    	conn.driverName = driver->answer;
+    		
+    if ( database->answer )
+    	conn.databaseName = database->answer;
+
+    if ( schema->answer )
+    	conn.schemaName = schema->answer;
+
+    if ( group->answer )
+    	conn.group = group->answer;
+
+    db_set_connection( &conn );    
+
+
+    exit(EXIT_SUCCESS);
+}
+

+ 132 - 0
db/base/copy.c

@@ -0,0 +1,132 @@
+/****************************************************************************
+ *
+ * MODULE:       db.copy
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>, Markus Neteler <neteler itc.it>
+ * PURPOSE:      copy a table
+ * COPYRIGHT:    (C) 2003-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+
+
+int
+main (int argc, char **argv)
+{
+    int    ret;
+    struct Option *from_driver, *from_database, *from_table;
+    struct Option *to_driver, *to_database, *to_table;
+    struct Option *where, *select;
+    struct GModule *module;
+    char   *drv, *db;
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("Copy a table. Either 'from_table' (optionaly with 'where') can be used "
+			"or 'select' option, but not 'from_table' and 'select' at the same time.");
+
+    from_driver		     = G_define_option();
+    from_driver->key 	     = "from_driver";
+    from_driver->type 	     = TYPE_STRING;
+    from_driver->options     = db_list_drivers();
+    from_driver->required    = NO;
+    from_driver->description = _("Input driver name");
+    if ( (drv=db_get_default_driver_name()) )
+         from_driver->answer = drv;
+
+    from_database 	       = G_define_option();
+    from_database->key 	       = "from_database";
+    from_database->type        = TYPE_STRING;
+    from_database->required    = NO;
+    from_database->description = _("Input database name");
+    if ( (db=db_get_default_database_name()) )
+	from_database->answer = db;
+
+    from_table 		    = G_define_option();
+    from_table->key 	    = "from_table";
+    from_table->type 	    = TYPE_STRING;
+    from_table->required    = NO;
+    from_table->description = _("Input table name (only, if 'select' is not used)");
+
+    to_driver		   = G_define_option();
+    to_driver->key 	   = "to_driver";
+    to_driver->type 	   = TYPE_STRING;
+    to_driver->options     = db_list_drivers();
+    to_driver->required    = NO;
+    to_driver->description = _("Output driver name");
+    if ( (drv=db_get_default_driver_name()) )
+         to_driver->answer = drv;
+
+    to_database 	     = G_define_option();
+    to_database->key 	     = "to_database";
+    to_database->type        = TYPE_STRING;
+    to_database->required    = NO;
+    to_database->description = _("Output database name");
+    if ( (db=db_get_default_database_name()) )
+	to_database->answer = db;
+
+    to_table 		  = G_define_option();
+    to_table->key 	  = "to_table";
+    to_table->type 	  = TYPE_STRING;
+    to_table->required    = YES;
+    to_table->description = _("Output table name");
+
+    where 		= G_define_option();
+    where->key 	    	= "where";
+    where->type 	= TYPE_STRING;
+    where->required	= NO;
+    where->description	= _("Optional where condition (without WHERE key word), e.g.:\n"
+			  "\t\tobec = 'Liptakov'");
+
+    select 		= G_define_option();
+    select->key 	= "select";
+    select->type 	= TYPE_STRING;
+    select->required	= NO;
+    select->description	= _("Full select statement (only, if 'from_table' and 'where' is not used), e.g.:\n"
+			  "\t\tSELECT dedek FROM starobince WHERE obec = 'Frimburg'");
+
+    if (G_parser(argc, argv))
+        exit (EXIT_FAILURE);
+
+    /* Check options and copy tables */
+    if ( from_table->answer ) {
+	if ( select->answer )
+	    G_fatal_error ( _("Cannot combine 'from_table' and 'select' options") );
+
+	if ( where->answer ) {
+	    ret = db_copy_table_where ( from_driver->answer, from_database->answer, from_table->answer,
+				        to_driver->answer, to_database->answer, to_table->answer,
+		   			where->answer );
+	} else { 
+	    ret = db_copy_table ( from_driver->answer, from_database->answer, from_table->answer,
+				  to_driver->answer, to_database->answer, to_table->answer );
+	}
+    } else {
+       	if ( !select->answer )	
+	    G_fatal_error ( _("Either 'from_table' or 'select' option must be given.") );
+
+       	if ( where->answer )
+	    G_fatal_error ( _("Cannot combine 'select' and 'where' options") );
+
+	ret = db_copy_table_select ( from_driver->answer, from_database->answer, from_table->answer,
+			             to_driver->answer, to_database->answer, to_table->answer,
+	       			     select->answer );
+    }
+
+    if ( ret == DB_FAILED ) {
+	G_warning ( _("Copy table failed") );
+	exit (EXIT_FAILURE);
+    }
+
+    exit (EXIT_SUCCESS);
+}

+ 79 - 0
db/base/createdb.c

@@ -0,0 +1,79 @@
+/****************************************************************************
+ *
+ * MODULE:       db.createdb
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>, Markus Neteler <neteler itc.it>
+ * PURPOSE:      create a new empty database
+ * COPYRIGHT:    (C) 2002-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+
+
+struct {
+	char *driver, *database;
+} parms;
+
+
+/* function prototypes */
+static void parse_command_line (int, char **);
+
+
+int
+main (int argc, char **argv)
+{
+    dbDriver *driver;
+    dbHandle handle;
+    int stat;
+
+    parse_command_line (argc, argv);
+
+    driver = db_start_driver (parms.driver);
+    if (driver == NULL)
+        G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
+
+    db_init_handle (&handle);
+    db_set_handle (&handle, parms.database, NULL);
+    stat = db_create_database (driver, &handle);
+    db_shutdown_driver (driver);
+
+    exit(stat == DB_OK ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+
+static void
+parse_command_line(int argc, char **argv)
+{
+    struct Option *driver, *database;
+    struct GModule *module;
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    driver 		= G_define_standard_option(G_OPT_DRIVER);
+    driver->options     = db_list_drivers();
+    driver->required 	= YES;
+
+    database 		= G_define_standard_option(G_OPT_DATABASE);
+    database->required 	= YES;
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("Creates an empty database.");
+
+    if(G_parser(argc, argv))
+        exit (EXIT_FAILURE);
+
+    parms.driver	= driver->answer;
+    parms.database	= database->answer;
+}

+ 97 - 0
db/base/databases.c

@@ -0,0 +1,97 @@
+/****************************************************************************
+ *
+ * MODULE:       db.databases
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>, Markus Neteler <neteler itc.it>
+ * PURPOSE:      lists all databases for a given driver
+ * COPYRIGHT:    (C) 2002-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+
+
+struct {
+	char *driver;
+	char *location;
+} parms;
+
+
+/* function prototypes */
+static void parse_command_line (int, char **);
+
+
+int
+main (int argc, char **argv)
+{
+    dbDriver *driver;
+    dbHandle *handles;
+    dbString locations;
+    int nlocs = 0;
+    int count, i;
+
+    db_init_string ( &locations );
+    parse_command_line(argc, argv);
+
+    if ( parms.location ) {
+        db_set_string ( &locations, parms.location );
+	nlocs = 1;
+    }
+    
+    driver = db_start_driver (parms.driver);
+    if (driver == NULL)
+        G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
+        
+    if(db_list_databases (driver, &locations, nlocs, &handles, &count) != DB_OK)
+	G_fatal_error(_("Unable to list databases"));
+
+    db_shutdown_driver (driver);
+
+    for (i = 0; i < count; i++) {
+	fprintf(stdout, "%s", db_get_handle_dbname(&handles[i]));
+	fprintf(stdout, "\n");
+    }
+
+    exit(EXIT_SUCCESS);
+}
+
+
+static void
+parse_command_line (int argc, char **argv)
+{
+    struct Option *driver, *location;
+    struct GModule *module;
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    driver 		= G_define_standard_option(G_OPT_DRIVER);
+    driver->options     = db_list_drivers();
+
+    location 		  = G_define_option();
+    location->key 	  = "location";
+    location->type 	  = TYPE_STRING;
+    location->required 	  = NO;
+    location->multiple 	  = YES;
+    location->description = _("Location name");
+
+    
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("List all databases for a given driver and location.");
+
+    if(G_parser(argc, argv))
+        exit(EXIT_FAILURE);
+
+    parms.driver     = driver->answer;
+    parms.location   = location->answer;
+}

+ 47 - 0
db/base/db.columns.html

@@ -0,0 +1,47 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.columns</em> lists all columns for a give table. Connection to 
+databases are supported through dbf, shp, odbc and pg drivers.  
+
+<h2>NOTE</h2>
+
+If parameters for database connection are already set with 
+<a HREF="db.connect.html">db.connect</a>, they are taken as default values and
+do not need to be spcified each time.
+
+<h2>EXAMPLE</h2>
+
+<em>List columns from PostgreSQL attribute table</em><br>
+<div class="code"><pre>
+db.columns table=markveggy driver=pg database=grass60test
+</pre></div>
+
+<p>
+
+<em>If database parameters are already set</em><br>
+<div class="code"><pre>
+db.columns table=markveggy
+</pre></div>
+
+<p>
+
+<em>List columns from Shape file with DBF attribute table</em><br>
+<div class="code"><pre>
+db.columns table=network driver=dbf database=/daten/grassdata/fire/PERMANENT/dbf/
+</pre></div>
+
+<h2>SEE ALSO</h2>
+<em><a HREF="db.connect.html">db.connect</a>,
+<a HREF="db.describe.html">db.describe</a>,
+<a HREF="db.drivers.html">db.drivers</a>,
+<a HREF="db.droptable.html">db.droptable</a>,
+<a HREF="db.execute.html">db.execute</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.tables.html">db.tables</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+
+Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date$</i>

+ 126 - 0
db/base/db.connect.html

@@ -0,0 +1,126 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.connect</em> allows the user to set database connection parameters.
+These parameters are then taken as default values by modules so that the
+user does not need to enter the parameters each time.
+
+
+<H2>NOTES</H2>
+
+Values are stored in the mapset's <tt>VAR</tt> file;
+the connection is not tested for validity.
+<P>
+The <b>-p</b> flag will display the current connection parameters. 
+<P>
+The <b>-c</b> flag will silently check if the connection parameters have
+been set, and if not will set them to use GRASS's default values.
+(useful in scripts before you attempt to create a new database table)
+<P>
+To connect a vector map to a database table, use <em>v.db.connect</em>
+or <em>v.db.addtable</em>.
+
+
+<h2>EXAMPLES</h2>
+
+<h3>DBF</h3>
+
+Local storage (the dbf/ subdirectory in the mapset must exist or must be
+created by the user):
+<br>
+<div class="code"><pre>
+db.connect driver=dbf database='$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/'
+db.tables -p
+</pre></div>
+
+
+<h3>SQLite</h3>
+
+Local storage:
+<br>
+<div class="code"><pre>
+db.connect driver=sqlite database='$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite.db'
+db.connect -p
+db.tables -p
+</pre></div>
+<P>
+The SQLite database is created automatically when used the first time.
+
+
+<h3>ODBC</h3>
+
+Network storage: (may require the use of <a href=db.login.html>db.login</a>):
+<br> 
+<div class="code"><pre>
+db.connect driver=odbc database=gtest
+db.login user=myname [pass=secret]
+db.connect -p
+db.tables -p
+</pre></div>
+
+
+<h3>PostgreSQL</h3>
+
+Network storage: (may require the use of <a href=db.login.html>db.login</a>):
+<br>
+<div class="code"><pre>
+db.connect driver=pg database="host=myserver.itc.it,dbname=mydb"
+db.login user=myname [pass=secret]
+db.connect -p
+db.tables -p
+</pre></div>
+
+
+<h3>PostgreSQL with different port</h3>
+
+Network storage: (may require the use of <a href=db.login.html>db.login</a>):
+<br>
+<div class="code"><pre>
+db.connect driver=pg database="host=myserver.itc.it,dbname=mydb,port=6666"
+db.login user=myname [pass=secret]
+db.connect -p
+db.tables -p
+</pre></div>
+
+
+<h3>MySQL (local)</h3>
+
+Local storage (<a href=db.login.html>db.login</a> may not be needed):
+<br>
+<div class="code"><pre>
+db.connect driver=mysql database=mydb
+db.login user=myname [pass=secret]
+db.connect -p
+db.tables -p
+</pre></div>
+
+
+<h3>MySQL (external server)</h3>
+
+Network storage: (may require the use of <a href=db.login.html>db.login</a>):
+<br>
+<div class="code"><pre>
+db.connect driver=mysql database="host=myserver.itc.it,dbname=mydb"
+db.login user=myname [pass=secret]
+db.connect -p
+db.tables -p
+</pre></div>
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="db.columns.html">db.columns</a>,
+<a HREF="db.drivers.html">db.drivers</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.tables.html">db.tables</a>,
+<a HREF="v.db.addtable.html">v.db.addtable</a>,
+<a HREF="v.db.connect.html">v.db.connect</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+
+<h2>AUTHOR</h2>
+
+Radim Blazek, ITC-Irst, Trento, Italy
+
+<p>
+<i>Last changed: $Date$</i>

+ 75 - 0
db/base/db.copy.html

@@ -0,0 +1,75 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.copy</em> allows the user to copy a table between two databases.
+Databases can be connected through different drivers (see example).
+
+<h2>NOTES</h2>
+
+Attribute tables can be copied manually using db.copy and 
+<em><a HREF="v.db.connect.html">v.db.connect</a></em>. Current connection 
+settings are saved in <em>$LOCATION/vector_map/dbln</em>.  
+
+<h2>EXAMPLES</h2>
+
+<h3>DBF -> PG</h3>
+
+<em>Storing table 'markveggy.dbf' (in current directory) into PostgreSQL
+through ODBC:</em><br>
+
+<div class="code"><pre>
+db.copy from_driver=dbf from_database=$HOME/grassdata/spearfish60/user1/dbf \
+  from_table=markveggy to_driver=pg to_database="host=pgserver,dbname=grass6test" \
+  to_table=markveggy 
+</pre></div>
+
+
+<h3>PG -> DBF</h3>
+
+<div class="code"><pre>
+db.copy from_driver=pg  from_database="host=pgserver.itc.it,dbname=testdb" \
+  from_table=origtable to_driver=dbf \
+  to_database=$HOME/grassdata/spearfish60/user1/dbf to_table=origtable
+</pre></div>
+
+
+<h3>PG -> PG with condition</h3>
+
+<div class="code"><pre>
+db.copy from_driver=pg  from_database="host=localhost,dbname=meteo" \
+  from_table=ukraine to_driver=pg to_database="host=localhost,dbname=meteo" \
+  to_table=selection where="cat < 500" 
+</pre></div>
+
+<h3>DBF -> SQLite</h3>
+
+<div class="code"><pre>
+db.copy from_driver=dbf from_database=$HOME/grassdata/spearfish60/user1/dbf \
+   from_table=ammprv to_driver=sqlite \
+   to_database=$HOME/grassdata/spearfish60/user1/mysqlite.db to_table=ammprv
+
+# convenient viewer:
+sqlitebrowser $HOME/grassdata/spearfish60/user1/mysqlite.db
+</pre></div>
+
+<h3>SQLite -> DBF</h3>
+<div class="code"><pre>
+db.copy from_driver=sqlite from_database=$HOME/grassdata/spearfish60/user1/mysqlite.db \
+   from_table=ammprv to_driver=dbf to_database=$HOME/grassdata/spearfish60/user1/dbf \
+   to_table=ammprv
+</pre></div>
+
+
+<h2>SEE ALSO</h2>
+
+<em><a HREF="v.db.connect.html">v.db.connect</a>,
+<a HREF="db.drivers.html">db.drivers</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="v.clean.html">v.clean</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+
+Radim Blazek, ITC-irst, Trento, Italy
+
+<p>
+<i>Last changed: $Date$</i>

+ 39 - 0
db/base/db.createdb.html

@@ -0,0 +1,39 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.createdb</em> allows the user to create a new empty database through
+different drivers. A working database connection needs to be established.  
+
+<h2>EXAMPLE</h2>
+
+<em>Create a new PostgreSQL database (if PostgreSQL connection is established
+through odbc driver)</em><br>
+
+<div class="code"><pre>
+db.createdb driver=odbc database=grass60test
+</pre></div>
+
+<p>
+
+<em>Create a new PostgreSQL database (if PostgreSQL connection is established
+through pg driver)</em><br>
+<div class="code"><pre>
+db.createdb driver=pg database='host=pgserver.itc.it,dbname=grass60test'
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="db.columns.html">db.columns</a>,
+<a HREF="db.describe.html">db.describe</a>,
+<a HREF="db.drivers.html">db.drivers</a>,
+<a HREF="db.droptable.html">db.droptable</a>,
+<a HREF="db.execute.html">db.execute</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.tables.html">db.tables</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+
+Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date$</i>

+ 20 - 0
db/base/db.databases.html

@@ -0,0 +1,20 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.databases</em> lists all databases for a given driver. Supported drivers
+are dbf, shp, odbc and pg.
+
+<h2>SEE ALSO</h2>
+
+<em><a HREF="db.columns.html">db.columns</a>,
+<a HREF="db.describe.html">db.describe</a>,
+<a HREF="db.drivers.html">db.drivers</a>,
+<a HREF="db.execute.html">db.execute</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.tables.html">db.tables</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+
+Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date$</i>

+ 58 - 0
db/base/db.describe.html

@@ -0,0 +1,58 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.describe</em> displays table information. If parameter <b>-c</b> is used 
+ only column names instead of full column descriptions is given. 
+
+<h2>NOTE</h2>
+
+If parameters for database connection are already set with 
+<a HREF="db.connect.html">db.connect</a>, they are taken as default values and
+do not need to be spcified each time.
+ 
+<h2>EXAMPLE</h2>
+
+<div class="code"><pre>
+db.describe -c table=roads database='$GISDBASE/$LOCATION_NAME/PERMANENT/dbf/' \
+            driver=dbf
+ncols:2
+Column 1:cat:INTEGER:11
+Column 2:label:CHARACTER:43
+</pre></div>
+
+<div class="code"><pre>
+db.describe table=roads database='$GISDBASE/$LOCATION_NAME/PERMANENT/dbf/' \
+            driver=dbf
+table:roads
+description:
+insert:yes
+delete:yes
+ncols:2
+
+column:cat
+description:
+type:INTEGER
+len:11
+scale:0
+precision:10
+default:
+nullok:yes
+select:yes
+update:yes
+[...]
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="db.columns.html">db.columns</a>,
+<a HREF="db.droptable.html">db.droptable</a>,
+<a HREF="db.execute.html">db.execute</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.tables.html">db.tables</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+
+Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date$</i>

+ 19 - 0
db/base/db.drivers.html

@@ -0,0 +1,19 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.drivers</em> lists all database drivers. 
+
+<h2>SEE ALSO</h2>
+<em><a HREF="db.connect.html">db.connect</a>,
+<a HREF="db.describe.html">db.describe</a>,
+<a HREF="db.drivers.html">db.drivers</a>,
+<a HREF="db.droptable.html">db.droptable</a>,
+<a HREF="db.execute.html">db.execute</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.tables.html">db.tables</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+
+Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date$</i>

+ 23 - 0
db/base/db.dropdb.html

@@ -0,0 +1,23 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.dropdb</em> removes an existing database. 
+
+<h2>EXAMPLE</h2>
+
+<em>Remove an existing database connected through odbc</em><br>
+<b>db.dropdb driver=</b><em>odbc</em> <b>database=</b><em>g51test</em>
+
+<h2>SEE ALSO</h2>
+<em>
+<a HREF="db.describe.html">db.describe</a>,
+<a HREF="db.droptable.html">db.droptable</a>,
+<a HREF="db.execute.html">db.execute</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.tables.html">db.tables</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+
+Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date$</i>

+ 39 - 0
db/base/db.droptable.html

@@ -0,0 +1,39 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.droptable</em> removes an existing database table. 
+
+<h2>NOTE</h2>
+
+If parameters for database connection are already set with 
+<a HREF="db.connect.html">db.connect</a>, they are taken as default values and
+do not need to be spcified each time.
+
+<h2>EXAMPLE</h2>
+
+<em>Remove an existing attribute table connected through odbc</em><br>
+<div class="code"><pre>
+db.droptable table=test driver=odbc database=g60test
+</pre></div>
+
+<p>
+
+<em>Remove attribute table with if database connection is set with db.connect</em><br>
+<div class="code"><pre>
+db.droptable table=test
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="db.describe.html">db.describe</a>,
+<a HREF="db.droptable.html">db.droptable</a>,
+<a HREF="db.execute.html">db.execute</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.tables.html">db.tables</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+
+Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date$</i>

+ 109 - 0
db/base/db.execute.html

@@ -0,0 +1,109 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.execute</em> allows the user to execute SQL statements.  
+
+<h2>NOTES</h2>
+
+<em>db.execute</em> only executes SQL statements and does not return 
+any data. If you need data returned from the database, use <em>db.select</em>.
+<P>
+If parameters for database connection are already set with 
+<a HREF="db.connect.html">db.connect</a>, they are taken as default values and
+do not need to be specified each time.
+<P>
+If you have a large number of SQL commands to process, it is much much faster
+to place all the SQL statements into a text file and use <em>db.execute</em>'s
+<b>input</b> file parameter than it is to process each statement individually
+in a loop. If multiple instruction lines are given, each SQL line must end
+with a semicolon.
+<p>
+Please see the individual <a href="sql.html">sql driver</a> pages for how to create
+a new database.
+
+<h2>EXAMPLES</h2>
+
+<em>Create a new table with columns 'cat' and 'soiltype':</em><br>
+<div class="code"><pre>
+echo 'create table soils (cat integer, soiltype varchar(10) )' | db.execute
+</pre></div>
+
+<p>
+<em>Create a new table using a file with SQL statements:</em><br>
+<div class="code"><pre>
+db.execute driver=odbc database=g60test input=file.sql
+</pre></div>
+
+<P>
+<em>Insert new row into attribute table:</em><br>
+<div class="code"><pre>
+echo "INSERT INTO nobugs (id,name,east_gb,north_gb) values (30,'Ala',1657340,5072301)" | db.execute
+</pre></div>
+
+<P>
+<em>Update attribute entries to new value based on SQL rule:</em><br>
+<div class="code"><pre>
+echo "UPDATE roads SET travelcost=5 WHERE cat=1" | db.execute
+</pre></div>
+
+<P>
+<em>Update attribute entries to new value based on SQL rule:</em><br>
+<div class="code"><pre>
+echo "UPDATE dourokukan SET testc=50 WHERE testc is NULL" | db.execute
+</pre></div>
+
+<P>
+<em>Delete selected rows from attribute table:</em><br>
+<div class="code"><pre>
+echo "DELETE FROM gsod_stationlist WHERE latitude < -91" | db.execute
+</pre></div>
+
+<P>
+<em>Add new column to attribute table:</em><br>
+<div class="code"><pre>
+echo "ALTER TABLE roads ADD COLUMN length double" | db.execute
+</pre></div>
+
+<P>
+<em>Column type conversion - update new column from existing column (all drivers except for DBF):</em><br>
+<div class="code"><pre>
+# 'z_value' is varchar and 'z' is double precision:
+echo "update geodetic_pts SET z = CAST(z_value AS numeric)" | db.execute
+</pre></div>
+
+<P>
+<em>Drop column from attribute table:</em><br>
+<div class="code"><pre>
+echo "ALTER TABLE roads DROP COLUMN length" | db.execute
+</pre></div>
+
+<P>
+<em>Drop table (not supported by all drivers)</em><br>
+<div class="code"><pre>
+echo "DROP TABLE fmacopy" | db.execute
+</pre></div>
+
+<p>
+<em>Update attribute with multiple SQL instructions in file (e.g., file.sql,
+    instruction line must end with a semicolon):</em><br>
+<div class="code"><pre>
+UPDATE roads SET travelcost=5 WHERE cat=1;
+UPDATE roads SET travelcost=2 WHERE cat=2;
+ 
+cat file.sql | db.execute
+</pre></div>
+
+<h2>SEE ALSO</h2>
+<em><a HREF="db.columns.html">db.columns</a>,
+<a HREF="db.describe.html">db.describe</a>,
+<a HREF="db.drivers.html">db.drivers</a>,
+<a HREF="db.droptable.html">db.droptable</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.select.html">db.select</a>,
+<a HREF="db.tables.html">db.tables</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+
+CERL
+
+<p><i>Last changed: $Date$</i></p>

+ 69 - 0
db/base/db.select.html

@@ -0,0 +1,69 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.select</em> prints result of selection from database 
+based on SQL statement read from input file or from standard input 
+to standard output.
+
+<h2>NOTE</h2>
+
+If parameters for database connection are already set with 
+<a HREF="db.connect.html">db.connect</a>, they are taken as default values and
+do not need to be spcified each time. Output will be displayed to stdout or can
+be directed to a file.
+
+<h2>EXAMPLES</h2>
+
+<div class="code"><pre>
+echo "select * from roads" | db.select 
+or
+ cat file.sql | db.select 
+or
+ db.select input=file.sql
+</pre></div>
+
+<p>
+
+<em>Select all from table roads</em><br>
+<div class="code"><pre>
+db.select -c driver=odbc database=g51test table=roads input=file.sql > result.csv
+</pre></div>
+
+<P>
+
+<em>Select some string attribute, exclude others:</em><br>
+<div class="code"><pre>
+echo "SELECT * FROM archsites WHERE str1 <> 'No Name'" | db.select
+</pre></div>
+
+<P>
+
+<em>Select some string attribute with ZERO length:</em><br>
+<div class="code"><pre>
+echo "SELECT * FROM archsites WHERE str1 IS NULL" | db.select
+</pre></div>
+
+<P>
+
+<em>Select coordinates from PostGIS table:</em><br>
+<div class="code"><pre>
+echo "SELECT x(geo),y(geo) FROM localizzazione" | db.select
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em><a HREF="sql.html">GRASS SQL interface</a>,
+<a HREF="db.connect.html">db.connect</a>,
+<a HREF="db.describe.html">db.describe</a>,
+<a HREF="db.drivers.html">db.drivers</a>,
+<a HREF="db.droptable.html">db.droptable</a>,
+<a HREF="db.execute.html">db.execute</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.tables.html">db.tables</a></em>
+
+
+<h2>AUTHOR</h2>
+?<br>
+Modifications: Radim Blazek, ITC-Irst, Trento, Italy
+
+<p><i>Last changed: $Date$</i>
+

+ 35 - 0
db/base/db.tables.html

@@ -0,0 +1,35 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.tables</em> lists all tables for a given database. 
+
+<h2>NOTE</h2>
+
+If parameters for database connection are already set with 
+<a HREF="db.connect.html">db.connect</a>, they are taken as default values and
+do not need to be spcified each time.
+
+<h2>EXAMPLES</h2>
+
+<em>List all tables if database connection is already set</em><br>
+<div class="code"><pre>
+db.tables -p
+</pre></div>
+
+<p>
+
+<em>List all tables of existing dbf database</em><br>
+<div class="code"><pre>
+db.tables driver=dbf database=/home/user/grassdata/fire/PERMANENT/dbf
+</pre></div>
+
+<h2>SEE ALSO</h2>
+<em><a HREF="db.columns.html">db.columns</a>,
+<a HREF="db.droptable.html">db.droptable</a>,
+<a HREF="db.login.html">db.login</a>,
+<a HREF="db.execute.html">db.execute</a>,
+<a HREF="sql.html">GRASS SQL interface</a></em>
+
+<h2>AUTHOR</h2>
+?
+
+<p><i>Last changed: $Date$</i>

+ 136 - 0
db/base/describe.c

@@ -0,0 +1,136 @@
+/****************************************************************************
+ *
+ * MODULE:       db.describe
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>,
+ *               Markus Neteler <neteler itc.it>,
+ *               Stephan Holl
+ * PURPOSE:      Displays table information
+ * COPYRIGHT:    (C) 2002-2008 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+
+struct {
+	char *driver, *database, *table;
+	int printcolnames;
+} parms;
+
+
+/* function prototypes */
+static void parse_command_line (int, char **);
+
+
+int
+main (int argc, char **argv)
+{
+    dbDriver *driver;
+    dbHandle handle;
+    dbTable *table;
+    dbString table_name;
+    int col, ncols, nrows;
+    dbColumn *column;
+    char buf[1024];
+    dbString stmt;
+
+    parse_command_line (argc, argv);
+    driver = db_start_driver(parms.driver);
+    if (driver == NULL)
+        G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
+
+    db_init_handle (&handle);
+    db_set_handle (&handle, parms.database, NULL );
+    if (db_open_database(driver, &handle) != DB_OK)
+	G_fatal_error (_("Unable to open database <%s>"),
+		       parms.database);
+
+    db_init_string(&table_name);
+    db_set_string(&table_name, parms.table);
+
+    if(db_describe_table (driver, &table_name, &table) != DB_OK)
+        G_fatal_error (_("Unable to describe table <%s>"), table_name); 
+
+    if(!parms.printcolnames)
+        print_table_definition(driver, table);
+    else
+    {
+        ncols = db_get_table_number_of_columns(table);
+
+        db_init_string ( &stmt );
+        sprintf(buf, "select * from %s", db_get_table_name (table));
+        db_set_string (&stmt, buf);
+        nrows = db_get_table_number_of_rows (driver, &stmt);
+        fprintf(stdout, "ncols: %d\n", ncols);
+        fprintf(stdout, "nrows: %d\n", nrows);
+        for (col = 0; col < ncols; col++)
+        {
+          column = db_get_table_column (table, col);
+          fprintf(stdout, "Column %d: %s:%s:%d\n", (col+1), db_get_column_name (column), 
+              db_sqltype_name(db_get_column_sqltype(column)),db_get_column_length(column));
+        }
+    }
+    
+    db_close_database(driver);
+    db_shutdown_driver(driver);
+
+    exit(EXIT_SUCCESS);
+}
+
+
+static void
+parse_command_line(int argc, char **argv)
+{
+    struct Option *driver, *database, *table;
+    struct Flag *cols, *tdesc;
+    struct GModule *module;
+    char *drv, *db;
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    cols = G_define_flag();
+    cols->key               = 'c';
+    cols->description       = _("Print column names only instead "
+				"of full column descriptions");
+
+    tdesc = G_define_flag();
+    tdesc->key               = 't';
+    tdesc->description       = _("Print table structure");
+
+    table 		= G_define_standard_option(G_OPT_TABLE);
+    table->required 	= YES;
+
+    driver 		= G_define_standard_option(G_OPT_DRIVER);
+    driver->options     = db_list_drivers();
+    if ( (drv=db_get_default_driver_name()) )
+        driver->answer = drv;
+
+    database 		= G_define_standard_option(G_OPT_DATABASE);
+    if ( (db=db_get_default_database_name()) )
+        database->answer = db;
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("Describes a table in detail.");
+
+    if(G_parser(argc, argv))
+        exit (EXIT_FAILURE);
+
+    parms.driver	= driver->answer;
+    parms.database	= database->answer;
+    parms.table		= table->answer;
+    parms.printcolnames = cols->answer;
+}

+ 80 - 0
db/base/drivers.c

@@ -0,0 +1,80 @@
+/****************************************************************************
+ *
+ * MODULE:       db.drivers
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>, Markus Neteler <neteler itc.it>, Stephan Holl
+ * PURPOSE:      lists all database drivers
+ * COPYRIGHT:    (C) 2002-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <grass/codes.h>
+#include <grass/dbmi.h>
+#include <grass/codes.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+
+struct {
+	int f;
+} parms;
+
+/* function prototypes */
+static void parse_command_line (int, char **);
+
+
+int
+main (int argc, char **argv)
+{
+    dbDbmscap *list, *p;
+
+    parse_command_line (argc, argv);
+
+    list = db_read_dbmscap();
+    if (list == NULL) {
+      G_message ( _("Error trying to read dbmscap file\n"));
+      exit (EXIT_FAILURE);
+    }
+
+    for (p = list; p; p = p->next) {
+      fprintf(stdout, "%s", p->driverName);
+      if (parms.f) fprintf(stdout, ":%s", p->comment);
+      fprintf(stdout, "\n");
+    }
+
+    exit (EXIT_SUCCESS);
+}
+
+
+static void
+parse_command_line (int argc, char **argv)
+{
+    struct Flag *full, *print;
+    struct GModule *module;
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    full = G_define_flag();
+    full->key = 'f';
+    full->description = _("Full output");
+
+    print = G_define_flag();
+    print->key          = 'p';
+    print->description  = _("print drivers and exit");    
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("List all database drivers.");
+
+    if (G_parser(argc, argv))
+        exit (EXIT_FAILURE);
+
+    parms.f = full->answer;
+}

+ 79 - 0
db/base/dropdb.c

@@ -0,0 +1,79 @@
+/****************************************************************************
+ *
+ * MODULE:       db.dropdb
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>, Markus Neteler <neteler itc.it>, Stephan Holl
+ * PURPOSE:      removes an existing database
+ * COPYRIGHT:    (C) 2002-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+
+
+struct {
+	char *driver, *database;
+} parms;
+
+
+/* function prototypes */
+static void parse_command_line (int, char **);
+
+
+int
+main (int argc, char **argv)
+{
+    dbDriver *driver;
+    dbHandle handle;
+    int stat;
+
+    parse_command_line (argc, argv);
+
+    driver = db_start_driver (parms.driver); 
+    if (driver == NULL)
+        G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
+
+    db_init_handle (&handle);
+    db_set_handle (&handle, parms.database, NULL);
+    stat = db_delete_database (driver, &handle);
+    db_shutdown_driver (driver);
+
+    exit(stat == DB_OK ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+
+static void
+parse_command_line (int argc, char **argv)
+{
+    struct Option *driver, *database;
+    struct GModule *module;
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    driver 		= G_define_standard_option(G_OPT_DRIVER);
+    driver->options     = db_list_drivers();
+    driver->required 	= YES;
+
+    database 		= G_define_standard_option(G_OPT_DATABASE);
+    database->required 	= YES;
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("Removes a database.");
+
+    if(G_parser(argc, argv))
+        exit(EXIT_FAILURE);
+
+    parms.driver	= driver->answer;
+    parms.database	= database->answer;
+}

+ 87 - 0
db/base/droptable.c

@@ -0,0 +1,87 @@
+/****************************************************************************
+ *
+ * MODULE:       db.droptable
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>, Markus Neteler <neteler itc.it>, Stephan Holl
+ * PURPOSE:      removes an existing database table
+ * COPYRIGHT:    (C) 2002-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+
+
+struct {
+	char *driver, *database, *table;
+} parms;
+
+
+/* function prototypes */
+static void parse_command_line (int, char **);
+
+
+int
+main (int argc, char **argv)
+{
+    dbDriver *driver;
+    dbHandle handle;
+    dbString table;
+    int stat;
+
+    parse_command_line (argc, argv);
+
+    driver = db_start_driver (parms.driver);
+    if (driver == NULL)
+        G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
+        
+    db_init_handle (&handle);
+    db_set_handle (&handle, parms.database, NULL);
+
+    db_init_string (&table);
+    db_set_string (&table, parms.table);
+    stat = db_open_database (driver, &handle);
+    if(stat == DB_OK)
+	stat = db_drop_table (driver, &table);
+    db_shutdown_driver (driver);
+
+    exit(stat == DB_OK ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+
+static void
+parse_command_line (int argc, char **argv)
+{
+    struct Option *driver, *database, *table;
+    struct GModule *module;
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    table 		= G_define_standard_option(G_OPT_DRIVER);
+    table->required 	= YES;
+
+    driver 		= G_define_standard_option(G_OPT_DRIVER);
+    driver->options     = db_list_drivers();
+
+    database 		= G_define_standard_option(G_OPT_DATABASE);
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("Removes a table from database.");
+
+    if(G_parser(argc, argv))
+        exit(EXIT_FAILURE);
+
+    parms.driver	= driver->answer;
+    parms.database	= database->answer;
+    parms.table		= table->answer;
+}

+ 176 - 0
db/base/execute.c

@@ -0,0 +1,176 @@
+/****************************************************************************
+ *
+ * MODULE:       db.execute
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Huidae Cho <grass4u gmail.com>, Glynn Clements <glynn gclements.plus.com>, Hamish Bowman <hamish_nospam yahoo.com>, Markus Neteler <neteler itc.it>, Stephan Holl
+ * PURPOSE:      process one non-select sql statement
+ * COPYRIGHT:    (C) 2002-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+
+
+struct {
+	char *driver, *database, *input;
+	int i;
+} parms;
+
+
+/* function prototypes */
+static void parse_command_line(int, char **);
+static int get_stmt (FILE *, dbString *);
+static int stmt_is_empty (dbString *);
+
+
+int
+main (int argc, char **argv)
+{
+    dbString stmt;
+    dbDriver *driver;
+    dbHandle handle;
+    int ret;
+    FILE *fd;
+    int error = 0;
+
+    parse_command_line (argc, argv);
+
+    if (parms.input)
+    {
+	fd = fopen (parms.input, "r");
+	if (fd == NULL)
+	{
+	    perror (parms.input);
+	    exit(EXIT_FAILURE);
+	}
+    }
+    else
+	fd = stdin;
+
+    driver = db_start_driver(parms.driver);
+    if (driver == NULL) {
+	G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
+    }
+
+    db_init_handle (&handle);
+    db_set_handle (&handle, parms.database, NULL);
+    if (db_open_database(driver, &handle) != DB_OK)
+	G_fatal_error(_("Unable to open database <%s>"), parms.database);
+
+    while( get_stmt(fd, &stmt) )
+    {
+	if(!stmt_is_empty(&stmt)) {
+	    G_debug (3, "sql: %s", db_get_string(&stmt) );
+
+        ret = db_execute_immediate (driver, &stmt);
+
+	    if ( ret != DB_OK ) {
+	       if (parms.i){ /* ignore SQL errors */
+		   G_warning(_("Error while executing: '%s'"),
+			     db_get_string(&stmt));
+		   error++;
+	       }
+	       else
+	           G_fatal_error(_("Error while executing: '%s'"),
+				 db_get_string(&stmt));
+	    }
+	}
+    }
+
+    db_close_database(driver);
+    db_shutdown_driver(driver);
+
+    exit(error ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+
+static void parse_command_line (int argc, char **argv)
+{
+    struct Option *driver, *database, *input;
+    struct Flag *i;
+    struct GModule *module;
+    char *drv, *db;
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("Executes any SQL statement.");
+
+    input 		= G_define_standard_option(G_OPT_F_INPUT);
+    input->required 	= NO;
+    input->description 	= _("Name of file containing SQL statements");
+
+    driver 		= G_define_standard_option(G_OPT_DRIVER);
+    driver->options     = db_list_drivers();
+    if ( (drv=db_get_default_driver_name()) )
+        driver->answer = drv;
+
+    database 		= G_define_standard_option(G_OPT_DATABASE);
+    if ( (db=db_get_default_database_name()) )
+        database->answer = db;
+
+    i = G_define_flag();
+    i->key              = 'i';
+    i->description      = _("Ignore SQL errors and continue");
+    
+    if(G_parser(argc, argv))
+	exit(EXIT_SUCCESS);
+
+    parms.driver	= driver->answer;
+    parms.database	= database->answer;
+    parms.input		= input->answer;
+    parms.i		= i->answer;
+}
+
+
+static int get_stmt (FILE *fd, dbString *stmt)
+{
+    char buf[4000], buf2[4000], buf3[7];
+    int len, row = 0;
+
+    db_init_string (stmt);
+
+    while ( fgets (buf, 4000, fd) != NULL ) {
+        strcpy ( buf2, buf );
+        G_chop (buf2);
+        len = strlen (buf2);
+
+	G_strncpy(buf3, buf2, 6);
+        if (G_strcasecmp(buf3, "select") == 0)
+            G_fatal_error (_("Use db.select for SELECT SQL statements"));
+
+	len = strlen (buf2);
+	if ( buf2[ len - 1 ] == ';' ) {  /* end of statement */
+	    buf2 [len - 1] = 0;          /* truncate ';' */
+	    db_append_string (stmt, buf2); /* append truncated */
+	    return 1;
+	} else {
+	    db_append_string (stmt, buf); /* append not truncated string (\n may be part of value) */
+	}
+	row++;
+    }
+
+    if ( row > 0 ) return 1;
+
+    return 0;
+}
+
+
+static int stmt_is_empty (dbString *stmt)
+{
+    char dummy[2];
+
+    return (sscanf (db_get_string(stmt), "%1s", dummy) != 1);
+}

+ 8 - 0
db/base/local_proto.h

@@ -0,0 +1,8 @@
+#ifndef __LOCAL_PROTO_H__
+#define __LOCAL_PROTO_H__
+
+int print_priv (char *, int);
+int print_column_definition(dbColumn *);
+int print_table_definition (dbDriver *, dbTable *);
+
+#endif /* __LOCAL_PROTO_H__ */

+ 79 - 0
db/base/printtab.c

@@ -0,0 +1,79 @@
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include "local_proto.h"
+#include <grass/glocale.h>
+
+int
+print_table_definition (dbDriver *driver, dbTable *table)
+
+{
+    int ncols, col, nrows;
+    dbColumn *column;
+    char buf[1024];
+    dbString stmt;
+
+    fprintf(stdout, "table:%s\n", db_get_table_name(table));
+    fprintf(stdout, "description:%s\n", db_get_table_description(table));
+    print_priv ("insert", db_get_table_insert_priv(table));
+    print_priv ("delete", db_get_table_delete_priv(table));
+
+    ncols = db_get_table_number_of_columns(table);
+
+    db_init_string ( &stmt );
+    sprintf(buf, "select * from %s", db_get_table_name (table));
+    db_set_string (&stmt, buf);
+    nrows = db_get_table_number_of_rows (driver, &stmt);
+    fprintf(stdout, "ncols:%d\n", ncols);
+    fprintf(stdout, "nrows:%d\n", nrows);
+    for (col = 0; col < ncols; col++)
+    {
+	column = db_get_table_column (table, col);
+	fprintf(stdout, "\n");
+	print_column_definition (column);
+    }
+    
+    return 0;
+}
+
+int
+print_column_definition (dbColumn *column)
+
+{
+    dbString value_string;
+
+    fprintf(stdout, "column:%s\n", db_get_column_name(column));
+    fprintf(stdout, "description:%s\n", db_get_column_description(column));
+    fprintf(stdout, "type:%s\n", db_sqltype_name(db_get_column_sqltype(column)));
+    fprintf(stdout, "len:%d\n", db_get_column_length(column));
+    fprintf(stdout, "scale:%d\n", db_get_column_scale(column));
+    fprintf(stdout, "precision:%d\n", db_get_column_precision(column));
+    fprintf(stdout, "default:");
+    if (db_test_column_has_default_value(column))
+    {
+      db_init_string(&value_string);
+      db_convert_column_default_value_to_string (column, &value_string);
+      fprintf(stdout, "%s", db_get_string(&value_string));
+    }
+    fprintf(stdout, "\n");
+    fprintf(stdout, "nullok:%s\n", db_test_column_null_allowed(column) ? "yes" : "no");
+    print_priv ("select", db_get_column_select_priv(column));
+    print_priv ("update", db_get_column_update_priv(column));
+    
+    return 0;
+}
+
+int
+print_priv  (char *label, int  priv)
+
+{
+    fprintf(stdout, "%s:", label);
+    switch (priv)
+    {
+    case DB_GRANTED:     fprintf(stdout, "yes"); break;
+    case DB_NOT_GRANTED: fprintf(stdout, "no"); break;
+    default:             fprintf(stdout, "?"); break;
+    }
+    fprintf(stdout, "\n");
+    
+    return 0;
+}

+ 294 - 0
db/base/select.c

@@ -0,0 +1,294 @@
+/****************************************************************************
+ *
+ * MODULE:       db.select
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Huidae Cho <grass4u gmail.com>, Glynn Clements <glynn gclements.plus.com>, Jachym Cepicky <jachym les-ejk.cz>, Markus Neteler <neteler itc.it>, Stephan Holl
+ * PURPOSE:      process one sql select statement
+ * COPYRIGHT:    (C) 2002-2007 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+
+struct {
+	char *driver, *database, *table, *sql, *fs, *vs, *nv, *input;
+	int c,d,h, test_only;
+} parms;
+
+
+/* function prototypes */
+static void parse_command_line (int, char **);
+static int sel (dbDriver *, dbString *);
+static int get_stmt (FILE *, dbString *);
+static int stmt_is_empty (dbString *);
+
+
+int
+main (int argc, char **argv)
+{
+    dbString stmt;
+    dbDriver *driver;
+    dbHandle handle;
+    int stat;
+    FILE *fd;
+
+    parse_command_line (argc, argv);
+
+    if (parms.input)
+    {
+	fd = fopen (parms.input, "r");
+	if (fd == NULL)
+	{
+	    perror (parms.input);
+	    exit(ERROR);
+	}
+    }
+    else
+	fd = stdin;
+       
+    db_init_string ( &stmt );
+    
+    driver = db_start_driver(parms.driver);
+    if (driver == NULL) {
+	G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
+    }
+
+    db_init_handle (&handle);
+    db_set_handle (&handle, parms.database, NULL);
+    if (db_open_database(driver, &handle) != DB_OK)
+      	G_fatal_error(_("Unable to open database <%s>"), parms.database);
+
+    if ( parms.sql ) {
+	db_set_string ( &stmt, parms.sql );
+	stat = sel(driver, &stmt );
+    } else if ( parms.table ) {
+	db_set_string ( &stmt, "select * from "); 
+	db_append_string ( &stmt, parms.table); 
+	stat = sel(driver, &stmt);
+    } else { /* read stdin */
+	stat = OK;
+	while(stat == OK && get_stmt (fd, &stmt))
+	{
+	    if(!stmt_is_empty(&stmt))
+		stat = sel(driver, &stmt);
+	}
+    }
+
+    db_close_database(driver);
+    db_shutdown_driver(driver);
+
+    exit(stat);
+}
+
+
+static int
+sel (dbDriver *driver, dbString *stmt)
+{
+    dbCursor cursor;
+    dbTable *table;
+    dbColumn *column;
+    dbValue *value;
+    dbString value_string;
+    int col, ncols;
+    int more;
+
+    if (db_open_select_cursor(driver, stmt, &cursor, DB_SEQUENTIAL) != DB_OK)
+        return ERROR;
+    if (parms.test_only)
+        return OK;
+
+    table = db_get_cursor_table (&cursor);
+    ncols = db_get_table_number_of_columns (table);
+    if(parms.d)
+    {
+	for(col = 0; col < ncols; col++)
+	{
+	    column = db_get_table_column(table, col);
+	    print_column_definition(column);
+	}
+
+	return OK;
+    }
+
+    db_init_string (&value_string);
+
+    /* column names if horizontal output */
+    if (parms.h && parms.c)
+    {
+	for (col = 0; col < ncols; col++)
+	{
+	    column = db_get_table_column(table, col);
+	    if (col) fprintf (stdout, "%s", parms.fs);
+	    fprintf (stdout, "%s", db_get_column_name (column));
+	}
+	fprintf (stdout, "\n");
+    }
+
+    /* fetch the data */
+    while(1)
+    {
+	if(db_fetch (&cursor, DB_NEXT, &more) != DB_OK)
+	    return ERROR;
+	if (!more)
+	    break;
+
+	for (col = 0; col < ncols; col++)
+	{
+	    column = db_get_table_column(table, col);
+	    value  = db_get_column_value(column);
+	    db_convert_column_value_to_string (column, &value_string);
+	    if (parms.c && !parms.h)
+		fprintf (stdout, "%s%s", db_get_column_name (column), parms.fs);
+	    if (col && parms.h)
+		fprintf (stdout, "%s", parms.fs);
+	    if(parms.nv && db_test_value_isnull(value))
+		fprintf (stdout, "%s", parms.nv);
+	    else
+		fprintf (stdout, "%s", db_get_string (&value_string));
+	    if (!parms.h)
+		fprintf (stdout, "\n");
+	}
+	if (parms.h)
+	    fprintf (stdout, "\n");
+	else if (parms.vs)
+	    fprintf (stdout, "%s\n", parms.vs);
+    }
+
+    return OK;
+}
+
+
+static void
+parse_command_line (int argc, char **argv)
+{
+    struct Option *driver, *database, *table, *sql, *fs, *vs, *nv, *input;
+    struct Flag *c,*d,*v, *flag_test;
+    struct GModule *module;
+    char *drv, *db;
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    table 		= G_define_standard_option(G_OPT_TABLE);
+
+    database 		= G_define_standard_option(G_OPT_DATABASE);
+    if ( (db=db_get_default_database_name()) )
+        database->answer = db;
+
+    driver 		= G_define_standard_option(G_OPT_DRIVER);
+    driver->options     = db_list_drivers();
+    if ( (drv=db_get_default_driver_name()) )
+        driver->answer = drv;
+
+    sql 		= G_define_option();
+    sql->key 	        = "sql";
+    sql->type 	        = TYPE_STRING;
+    sql->required 	= NO;         
+    sql->label          = _("SQL select statement");
+    sql->description    = _("For example: 'select * from rybniky where kapri = 'hodne'");
+
+    fs 			= G_define_standard_option(G_OPT_F_SEP);
+    fs->description 	= _("Output field separator");
+
+    vs 			= G_define_standard_option(G_OPT_F_SEP);
+    vs->key 		= "vs";
+    vs->description 	= _("Output vertical record separator");
+    vs->answer          = NULL;
+
+    nv 			= G_define_option();
+    nv->key 		= "nv";
+    nv->type 		= TYPE_STRING;
+    nv->required 	= NO;
+    nv->description 	= _("Null value indicator");
+
+    input 		= G_define_standard_option(G_OPT_F_INPUT);
+    input->required 	= NO;
+    input->description 	= _("Name of file with sql statement");
+
+    c			= G_define_flag();
+    c->key		= 'c';
+    c->description	= _("Do not include column names in output");
+
+    d			= G_define_flag();
+    d->key		= 'd';
+    d->description	= _("Describe query only (don't run it)");
+
+    v			= G_define_flag();
+    v->key		= 'v';
+    v->description	= _("Vertical output (instead of horizontal)");
+
+    flag_test			= G_define_flag();
+    flag_test->key		= 't';
+    flag_test->description	= _("Only test query, do not execute");
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("Selects data from table.");
+
+    if(G_parser(argc, argv))
+        exit(EXIT_SUCCESS);
+
+    parms.driver	= driver->answer;
+    parms.database	= database->answer;
+    parms.table 	= table->answer;
+    parms.sql  	        = sql->answer;
+    parms.fs		= fs->answer;
+    parms.vs		= vs->answer;
+    parms.nv		= nv->answer;
+    parms.input		= input->answer;
+    if ( !c->answer )  parms.c = 1; else  parms.c = 0;
+    parms.d		= d->answer;
+    if ( !v->answer )  parms.h = 1; else  parms.h = 0;
+    parms.test_only     = flag_test->answer;
+
+    if (!parms.fs) parms.fs = "";
+    if (parms.input && *parms.input == 0)
+    {
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+}
+
+
+static int
+get_stmt (FILE *fd, dbString *stmt)
+{
+    char buf[1024];
+    int n;
+    static int first = 1;
+
+    db_zero_string (stmt);
+
+    /* this is until get_stmt is smart enough to handle multiple stmts */
+    if (!first)
+	return 0;
+    first = 0;
+
+    while ( ( n = fread (buf, 1, sizeof(buf)-1, fd)) > 0)
+    {
+	buf[n] = 0;
+	db_append_string (stmt, buf);
+    }
+
+    return 1;
+}
+
+
+static int
+stmt_is_empty (dbString *stmt)
+{
+    char dummy[2];
+
+    return (sscanf (db_get_string(stmt), "%1s", dummy) != 1);
+}

+ 104 - 0
db/base/tables.c

@@ -0,0 +1,104 @@
+/****************************************************************************
+ *
+ * MODULE:       db.tables
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>, Markus Neteler <neteler itc.it>, Stephan Holl
+ * PURPOSE:      lists all tables for a given database
+ * COPYRIGHT:    (C) 2002-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/codes.h>
+#include <grass/glocale.h>
+
+
+struct {
+	char *driver, *database;
+	int s;
+} parms;
+
+
+/* function prototypes */
+static void parse_command_line (int, char **);
+
+
+int
+main (int argc, char **argv)
+{
+    dbDriver *driver;
+    dbHandle handle;
+    dbString *names;
+    int i, count;
+    int system_tables;
+
+    parse_command_line (argc, argv);
+
+    driver = db_start_driver(parms.driver);
+    if (driver == NULL)
+	G_fatal_error(_("Unable to start driver <%s>"), parms.driver);
+
+    db_init_handle (&handle);
+    db_set_handle (&handle, parms.database, NULL);
+    if (db_open_database(driver, &handle) != DB_OK)
+      	G_fatal_error(_("Unable to open database <%s>"), parms.database);
+
+    system_tables = parms.s;
+    if(db_list_tables (driver, &names, &count, system_tables) != DB_OK)
+	exit(ERROR);
+    for (i = 0; i < count; i++)
+	fprintf(stdout, "%s\n", db_get_string (&names[i]));
+
+    db_close_database(driver);
+    db_shutdown_driver(driver);
+
+    exit(EXIT_SUCCESS);
+}
+
+
+static void
+parse_command_line (int argc, char **argv)
+{
+    struct Option *driver, *database;
+    struct Flag *p, *s;
+    struct GModule *module;
+    char *drv, *db;
+
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    driver 		= G_define_standard_option(G_OPT_DRIVER);
+    driver->options     = db_list_drivers();
+    if ( (drv=db_get_default_driver_name()) ) 
+	driver->answer = drv;
+
+    database 		= G_define_standard_option(G_OPT_DATABASE);
+    if ( (db=db_get_default_database_name()) ) 
+	database->answer = db;
+
+    p = G_define_flag();
+    p->key              = 'p';
+    p->description      = _("Print tables and exit");    
+
+    s			= G_define_flag();
+    s->key		= 's';
+    s->description	= _("System tables instead of user tables");
+
+    /* Set description */
+    module              = G_define_module();
+    module->keywords = _("database, SQL");
+    module->description = _("Lists all tables for a given database.");
+
+    if(G_parser(argc, argv))
+        exit(EXIT_SUCCESS);
+
+    parms.driver	= driver->answer;
+    parms.database	= database->answer;
+    parms.s		= s->answer;
+}

+ 119 - 0
db/databaseintro.html

@@ -0,0 +1,119 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title>Database management in GRASS GIS</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Markus Neteler/GRASS Development Team">
+ <link rel="stylesheet" href="grassdocs.css" type="text/css">
+</head>
+<body bgcolor="white">
+
+<!-- This page is grass6/db/databaseintro.html -->
+
+<img src="grass_logo.png" alt="_\|/_ GRASS logo"><hr align=center size=6 noshade>
+
+<h2>Database management in GRASS GIS</h2>
+
+<h3>Attribute management in general</h3>
+
+GRASS can be linked to one or many database management systems (DBMS).
+The <em>db.*</em> set of commands provides basic SQL support for
+attribute management, while the <em>v.db.*</em> set of commands operates
+on the vector map (see <a href="vectorintro.html">Vector introduction</a>).
+
+<h3>Available drivers</h3>
+
+Available drivers are listed in <a href="sql.html">SQL support in GRASS GIS</a>.
+<p>
+<b>Notes</b>:<br>
+The default DBF driver provides only very limited SQL
+support (as DBF is not an SQL DB) while the other DBMS backends (such
+as PostgreSQL, MySQL etc) provide full SQL support since the SQL
+commands are sent directly to the DBMS. 
+
+<h3>DB connection management</h3>
+
+The current database management settings are shown or modified with
+<a href="db.connect.html">db.connect</a> for current mapset. Available DBMI drivers
+are listed with <a href="db.drivers.html">db.drivers</a>. Some DBMI backends
+require a user/password for driver/database to be set with <a href="db.login.html">db.login</a>. 
+In order to test a driver, run <a href="db.test.html">db.test</a>. 
+
+<h3>Attribute data import and export</h3>
+
+Attribute data can be imported with <a href="db.in.ogr.html">db.in.ogr</a> from
+various formats and exported with <a href="db.out.ogr.html">db.out.ogr</a>. To internally 
+copy a a full table or selectively parts of it, use <a href="db.copy.html">db.copy</a>.
+<p>
+
+Further conversion tools:
+<ul>
+<li><a href="http://mdbtools.sourceforge.net/">MDB Tools</a>: Convert MS-Access data to SQL, DBF, etc.</li>
+<li><a href="http://grass.gdf-hannover.de/wiki/Openoffice.org_with_SQL_Databases">Openoffice.org with SQL Databases</a>
+</ul>
+
+
+<h3>SQL commands</h3>
+
+GRASS supports to main SQL operations, execution of an SQL statement 
+(<a href="db.execute.html">db.execute</a>) and selection
+of data from a table (<a href="db.select.html">db.select</a>).
+See the <a href="sql.html">SQL help page</a> for examples.
+
+<h3>Managing the default DBMI settings</h3>
+ 
+Per default vector map attributes are stored in DBF table files. This default
+definition can be modified with <a href="db.connect.html">db.connect</a>. If an
+external DBMS is used, <a href="db.login.html">db.login</a> may be required.
+
+<h3>Creating a database</h3>
+
+Specific commands are explained on the individual driver pages (these
+pages are only available if driver was compiled in this installation):
+
+<ul>
+<li>DBF: see <a href="grass-dbf.html">DBF</a> page</li>
+<li>SQLite: <a href="grass-sqlite.html">SQLite</a> page</li>
+<li>mySQL: <a href="grass-mysql.html">mySQL</a> and <a href="grass-mesql.html">meSQL</a> pages</li>
+<li>ODBC: <a href="grass-odbc.html">ODBC</a> page  (connect to Oracle, etc.)</li>
+<li>PostgreSQL: <a href="grass-pg.html">PostgreSQL</a> and PostGIS page</li>
+</ul>
+
+<h3>Metadata</h3>
+All columns for a given table are listed with <a href="db.columns.html">db.columns</a>.
+The command <a href="db.describe.html">db.describe</a> describes a table in detail. To
+list all available tables for a given database, run <a href="db.tables.html">db.tables</a>.
+
+<h3>Table maintenance</h3>
+To drop a column from a selected attribute table, use <a href="db.dropcol.html">db.dropcol</a>.
+With <a href="db.droptable.html">db.droptable</a> an attribute table can be deleted.
+
+
+<h3>Database Schema</h3>
+
+Currently schema support only works for PostgreSQL connections. Default schema
+can be set with <a href="db.connect.html">db.connect</a>. Note that the default 
+schema will be used by all db.* modules.
+<p>
+<a href="db.tables.html">db.tables</a> returns 'schema.table' if schemas are
+available in the database.
+
+
+<h3>See also</h3>
+
+<ul>
+<li><a href="vectorintro.html">Introduction to GRASS vector map processing</a></li>
+<li><a href="rasterintro.html">Introduction to GRASS raster map processing</a></li>
+</ul>
+
+<HR>
+<BR>
+<a href="index.html">Main index</a> -
+<a href="database.html">database index</a> -
+<a href="full_index.html">full index</a>
+
+<p><i>Last changed: $Date$</i></p>
+<P>&copy; 2008 <a href="http://grass.osgeo.org">GRASS Development Team</a></P>
+
+</body>
+</html>

+ 10 - 0
db/db.login/Makefile

@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = db.login
+
+LIBES     = $(DBMILIB) $(GISLIB)
+DEPENDENCIES = $(DBMIDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd

+ 46 - 0
db/db.login/description.html

@@ -0,0 +1,46 @@
+<h2>DESCRIPTION</h2>
+
+<em>db.login</em> sets user/password for driver/database.
+
+<h2>NOTE</h2>
+
+This is only related to SQL database backends (PostgreSQL, MySQL etc).
+The passwords are stored in a hidden file in the user account ('home' 
+directory) called <em>.grasslogin6</em>. Only the file owner
+can access this file.
+
+<h2>EXAMPLES</h2>
+
+Example 1: Username specified, password will be invisibly queried interactively:
+
+<div class="code"><pre>
+db.login user=bacava
+</pre></div>
+
+<P>
+Example 2: Username and password specified (note that the command
+lines history will store the password in this way):
+
+<div class="code"><pre>
+db.login user=bacava pass=secret
+</pre></div>
+
+<P>
+Example 3: Username and empty password specified (note that the command
+lines history will store the password in this way):
+
+<div class="code"><pre>
+db.login user=bacava pass=""
+</pre></div>
+
+<h2>SEE ALSO</h2>
+<em>
+<a HREF="db.connect.html">db.connect</a>,
+<a HREF="db.test.html">db.test</a>
+</em>
+
+<h2>AUTHOR</h2>
+
+Radim Blazek
+
+<p><i>Last changed: $Date$</i>

+ 107 - 0
db/db.login/main.c

@@ -0,0 +1,107 @@
+/****************************************************************************
+ *
+ * MODULE:       db.login
+ * AUTHOR(S):    Radim Blazek <radim.blazek gmail.com> (original contributor)
+ *               Glynn Clements <glynn gclements.plus.com>, Markus Neteler <neteler itc.it>
+ * PURPOSE:      
+ * COPYRIGHT:    (C) 2004-2006 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <grass/config.h>
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+int
+main(int argc, char *argv[])
+{
+    struct Option *driver, *database, *user, *password;
+    struct GModule *module;
+#ifdef HAVE_TERMIOS_H
+    struct termios tios, tios2;
+#endif
+    char answer[200];
+    
+    /* Initialize the GIS calls */
+    G_gisinit(argv[0]) ;
+
+    module              = G_define_module();
+    module->keywords    = _("database, SQL");
+    module->description = _("Sets user/password for driver/database.");
+    
+    driver             = G_define_standard_option(G_OPT_DRIVER) ;
+    driver->options    = db_list_drivers();
+    driver->required   = YES;
+    driver->answer     = db_get_default_driver_name();
+
+    database             = G_define_standard_option(G_OPT_DATABASE) ;
+    database->required   = YES ;
+    database->answer     = db_get_default_database_name();
+
+    user             = G_define_option() ;
+    user->key        = "user" ;
+    user->type       = TYPE_STRING ;
+    user->required   = NO  ;
+    user->multiple   = NO ;
+    user->description= _("Username") ;
+
+    password             = G_define_option() ;
+    password->key        = "password" ;
+    password->type       = TYPE_STRING ;
+    password->required   = NO ;
+    password->multiple   = NO ;
+    password->description= _("Password") ;
+
+    if(G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* set connection */
+    if (!password->answer && isatty(fileno(stdin)) ){
+        for(;;) {
+#ifdef HAVE_TERMIOS_H
+          tcgetattr(STDIN_FILENO, &tios);
+          tios2 = tios;
+          tios2.c_lflag &= ~ECHO;
+          tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios2);
+#endif
+          do {
+              fprintf (stderr,_("\nEnter database password for connection\n<%s:%s:user=%s>\n"), driver->answer, database->answer, user->answer);
+              fprintf (stderr, _("Hit RETURN to cancel request\n"));
+              fprintf (stderr,">");
+          } while(!G_gets(answer));
+#ifdef HAVE_TERMIOS_H
+          tcsetattr(STDIN_FILENO, TCSANOW, &tios);
+#endif
+          G_strip(answer);
+          if(strlen(answer)==0) {
+	     G_message(_("Exiting. Not changing current settings"));
+	     return -1;
+	  } else {
+	     G_message(_("New password set"));
+	     password->answer = G_store(answer);
+	     break;
+	  }
+	}
+    }
+    if (  db_set_login ( driver->answer, database->answer, user->answer, password->answer ) == DB_FAILED ) {
+	G_fatal_error ( _("Unable to set user/password") );
+    }
+
+    if ( password->answer )
+        G_warning ( _("The password was stored in file") );
+	
+    exit(EXIT_SUCCESS);
+}

+ 40 - 0
db/drivers/Makefile

@@ -0,0 +1,40 @@
+
+MODULE_TOPDIR = ../..
+
+#always compile dialog lib and dbf driver:
+SUBDIRS1 = dbf
+
+include $(MODULE_TOPDIR)/include/Make/Platform.make
+
+# add odbc:
+ifneq ($(strip $(ODBCLIB)),)
+    SUBDIRS2 = odbc
+endif
+
+# add postgresql:
+ifneq ($(strip $(PQLIB)),)
+    SUBDIRS3 = postgres
+endif
+
+# add mysql:
+ifneq ($(strip $(MYSQLLIB)),)
+    SUBDIRS4 = mysql
+endif
+
+# add SQLite:
+ifneq ($(strip $(SQLITELIB)),)
+    SUBDIRS5 = sqlite
+endif
+
+# add ogr:
+ifneq ($(strip $(USE_OGR)),)
+    SUBDIRS6 = ogr
+endif
+
+SUBDIRS =  $(SUBDIRS1) $(SUBDIRS2) $(SUBDIRS3) $(SUBDIRS4) $(SUBDIRS5) $(SUBDIRS6)
+
+include $(MODULE_TOPDIR)/include/Make/Dir.make
+
+default: parsubdirs
+
+clean: cleansubdirs

+ 28 - 0
db/drivers/README

@@ -0,0 +1,28 @@
+This directory contains drivers for the DBMI library.
+The driver functions are for internal usage.
+
+The DBMI API to be used for module programming is available in:
+grass6/lib/db/
+
+
+NOTE:
+db__driver_* functions are implemented in a driver.  If some of them
+are not used or defined, the driver will use stub functions in
+grass6/lib/db/stubs/
+
+For some platforms like Cygwin, multiply defined symbols are not
+resolved in a way that UNIX does.  Even worse is that it is impossible
+to build shared libraries with undefined symbols.  For example,
+libgrass_dbmidriver.so cannot be built without any implementations
+of db__driver_* functions which should be specific to a db driver.
+
+To work around this problem, function pointers are defined to use
+driver's implementations instead of those of the db stubs library.
+To do this automatically, run '../mk_dbdriver_h.sh' in driver's
+directory, #include "dbdriver.h" from main.c, and execute init_dbdriver().
+
+Function pointers are defined in grass6/lib/db/dbmi_driver/dbstubs.h
+This header file can be generated with
+grass6/lib/db/dbmi_driver/mk_dbstubs_h.sh
+
+Please read grass6/lib/db/README

+ 41 - 0
db/drivers/dbf/Makefile

@@ -0,0 +1,41 @@
+
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/Platform.make
+include $(MODULE_TOPDIR)/include/Make/Grass.make
+include $(MODULE_TOPDIR)/include/Make/Rules.make
+
+DRIVER=$(DBDRIVERDIR)/dbf$(EXE)
+DEPENDENCIES = $(GISDEP)
+EXTRA_INC = -I$(MODULE_TOPDIR)/lib/db/dbmi_driver
+
+LIBES = $(DBMIDRIVERLIB) $(DBMIBASELIB) $(DBMIEXTRALIB) $(SQLPLIB) $(SHAPELIB) $(DBSTUBSLIB) $(GISLIB) $(DATETIMELIB)
+
+DRVDOC=$(GISBASE)/docs/html/grass-dbf.html
+
+OBJS 	=  \
+	column.o \
+	cursor.o \
+	db.o \
+	dbfexe.o \
+	describe.o \
+	driver.o \
+	error.o \
+	execute.o \
+	fetch.o \
+	listtab.o \
+	main.o \
+	select.o \
+	str.o \
+	table.o \
+	create_table.o
+
+ARCH_OBJS := $(foreach obj,$(OBJS),$(OBJDIR)/$(obj))
+
+default: $(DRIVER) $(DRVDOC)
+
+$(DRIVER): $(ARCH_OBJS)
+	$(CC) $(LDFLAGS) -o $@ $(ARCH_OBJS) $(FMODE_OBJ) $(LIBES) $(MATHLIB) $(XDRLIB)
+
+$(DRVDOC): grass-dbf.html
+	$(INSTALL_DATA) grass-dbf.html $(DRVDOC)

+ 125 - 0
db/drivers/dbf/column.c

@@ -0,0 +1,125 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include "globals.h"
+#include "proto.h" 
+
+/* add column to table */
+int add_column (int tab, int type, char *name, int width, int decimals)
+{
+    int c;
+
+    G_debug (3, "add_column(): tab = %d, type = %d, name = %s, width = %d, decimals = %d",
+	                       tab, type, name, width, decimals);
+
+    /* Check if the column exists */
+    for ( c = 0; c < db.tables[tab].ncols; c++ ) {
+	if ( G_strcasecmp( db.tables[tab].cols[c].name, name ) == 0 ) {
+	    append_error( "Column '%s' already exists (duplicate name)\n", name);
+	    return DB_FAILED;
+	}
+    }
+	    
+    c = db.tables[tab].ncols; 
+    
+    if ( db.tables[tab].ncols == db.tables[tab].acols )
+      {
+        db.tables[tab].acols += 15; 
+	db.tables[tab].cols = (COLUMN *) G_realloc ( db.tables[tab].cols, db.tables[tab].acols * sizeof (TABLE) ); 
+      }
+    
+    strncpy ( db.tables[tab].cols[c].name, name, DBF_COL_NAME-1 );
+    db.tables[tab].cols[c].name[DBF_COL_NAME-1] = '\0';
+    
+    db.tables[tab].cols[c].type = type; 
+    db.tables[tab].cols[c].width = width; 
+    db.tables[tab].cols[c].decimals = decimals; 
+    
+    db.tables[tab].ncols++; 
+    
+    return DB_OK;
+}
+
+/* returns column index or -1 */
+int find_column (int tab, char *col)
+{
+    int i;
+     
+    for ( i = 0; i < db.tables[tab].ncols; i++ )
+      {
+        if ( G_strcasecmp( db.tables[tab].cols[i].name, col ) == 0 )
+            return (i);
+      } 
+    return (-1);
+}
+
+/* drop column from table */
+int drop_column (int tab, char *name)
+{
+    int i, j, c;
+    
+    G_debug (3, "drop_column(): tab = %d, name = %s", tab, name);
+
+    /* Check if the column exists */
+    c = find_column (tab, name);
+    if (c == -1)
+    {
+	append_error( "Column '%s' does not exist\n", name);
+	return DB_FAILED;
+    }
+    
+    db.tables[tab].ncols--;
+
+    for (i = c; i < db.tables[tab].ncols; i++)
+    {
+	strcpy (db.tables[tab].cols[i].name, db.tables[tab].cols[i+1].name);
+	db.tables[tab].cols[i].type = db.tables[tab].cols[i+1].type;
+	db.tables[tab].cols[i].width = db.tables[tab].cols[i+1].width;
+	db.tables[tab].cols[i].decimals = db.tables[tab].cols[i+1].decimals; 
+    }
+
+/* drop column from each row */
+    for (i = 0; i < db.tables[tab].nrows; i++)
+    {
+	for (j = c; j < db.tables[tab].ncols; j++)
+	{
+	    VALUE* dbval_c  = &(db.tables[tab].rows[i].values[j]);
+	    VALUE* dbval_c1 = &(db.tables[tab].rows[i].values[j + 1]);
+
+	    dbval_c->i = dbval_c1->i;
+	    dbval_c->d = dbval_c1->d;
+
+	    if (dbval_c1->c != NULL) 
+	    {
+		save_string(dbval_c, dbval_c1->c);
+		G_free ((char*) dbval_c1->c);
+		dbval_c1->c = NULL;
+	    }
+
+	    dbval_c->is_null = dbval_c1->is_null;
+	}
+
+	db.tables[tab].rows[i].values = 
+	    (VALUE *) G_realloc (db.tables[tab].rows[i].values,
+				 db.tables[tab].ncols * sizeof(VALUE));
+    }
+    return DB_OK;
+}

+ 28 - 0
db/drivers/dbf/create_table.c

@@ -0,0 +1,28 @@
+#include <grass/dbmi.h>
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_create_table (dbTable *table)
+{
+    dbString sql;
+    int ret;
+    
+    G_debug (3, "db__driver_create_table()");
+
+    db_init_string (&sql);
+
+    db_table_to_sql ( table, &sql );
+
+    G_debug (3, " SQL: %s", db_get_string(&sql) );
+
+    ret = execute ( db_get_string(&sql), NULL);    
+
+    if ( ret == DB_FAILED ) {
+	append_error("Cannot create table" );
+	report_error( );
+	return DB_FAILED;
+    }
+    
+    return DB_OK;
+}

+ 71 - 0
db/drivers/dbf/cursor.c

@@ -0,0 +1,71 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+#include <stdlib.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_close_cursor (dbCursor *dbc)
+
+{
+    cursor *c;
+
+    /* get my cursor via the dbc token */
+    c = (cursor *) db_find_token(db_get_cursor_token(dbc));
+    if (c == NULL)
+	return DB_FAILED;
+
+    /* free_cursor(cursor) */
+    free_cursor(c);
+
+    return DB_OK;
+}
+
+
+cursor * alloc_cursor()
+{
+    cursor     *c;
+
+    /* allocate the cursor */
+    c = (cursor *) db_malloc(sizeof(cursor));
+    if (c == NULL)
+    {
+        append_error ("cannot alloc new cursor");
+        return c; 
+    } 
+    
+    /* tokenize it */
+    c->token = db_new_token(c);
+    if (c->token < 0)       
+    {
+	free_cursor (c);
+	c = NULL;
+	append_error ("cannot tokenize new cursor\n");
+    }
+
+    return c;
+}
+
+void free_cursor( cursor *c)
+{
+    db_drop_token(c->token);
+    sqpFreeStmt( c->st );  
+    G_free (c);  
+}
+
+

+ 127 - 0
db/drivers/dbf/db.c

@@ -0,0 +1,127 @@
+
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include "globals.h"
+#include "proto.h"
+
+int db__driver_open_database(dbHandle * handle)
+{
+    char *name;
+    int len;
+    dbConnection connection;
+    char buf[1024];
+    DIR *dir;
+    struct dirent *ent;
+    char **tokens;
+    int no_tokens, n;
+
+    G_debug(2, "DBF: db__driver_open_database() name = '%s'",
+	    db_get_handle_dbname(handle));
+
+    db.name[0] = '\0';
+    db.tables = NULL;
+    db.atables = 0;
+    db.ntables = 0;
+
+    db_get_connection(&connection);
+    name = db_get_handle_dbname(handle);
+
+    /* if name is empty use connection.databaseName */
+    if (strlen(name) == 0) {
+	name = connection.databaseName;
+    }
+
+    strcpy(db.name, name);
+
+    /* open database dir and read table ( *.dbf files ) names 
+     * to structure */
+
+    /* parse variables in db.name if present */
+    if (db.name[0] == '$') {
+	tokens = G_tokenize(db.name, "/");
+	no_tokens = G_number_of_tokens(tokens);
+	db.name[0] = '\0';	/* re-init */
+
+	for (n = 0; n < no_tokens; n++) {
+	    G_debug(3, "tokens[%d] = %s", n, tokens[n]);
+	    if (tokens[n][0] == '$') {
+		G_strchg(tokens[n], '$', ' ');
+		G_chop(tokens[n]);
+		strcat(db.name, G__getenv(tokens[n]));
+		G_debug(3, "   -> %s", G__getenv(tokens[n]));
+	    }
+	    else
+		strcat(db.name, tokens[n]);
+
+	    strcat(db.name, "/");
+	}
+	G_free_tokens(tokens);
+    }
+
+    G_debug(2, "db.name = %s", db.name);
+
+    errno = 0;
+    dir = opendir(db.name);
+    if (dir == NULL) {
+	if (errno == ENOENT) {
+	    int status;
+
+	    status = G_mkdir(db.name);
+	    if (status != 0) {	/* mkdir failed */
+		append_error("Cannot create dbf database: %s\n", name);
+		report_error();
+		return DB_FAILED;
+	    }
+	} else { /* some other problem */
+	    append_error("Cannot open dbf database: %s\n", name);
+	    report_error();
+	    return DB_FAILED;
+	}
+    }
+
+    while ((ent = readdir(dir))) {
+	len = strlen(ent->d_name) - 4;
+	if ((len > 0) && (G_strcasecmp(ent->d_name + len, ".dbf") == 0)) {
+	    strcpy(buf, ent->d_name);
+	    buf[len] = '\0';
+	    add_table(buf, ent->d_name);
+	}
+    }
+
+    closedir(dir);
+    return DB_OK;
+}
+
+int db__driver_close_database()
+{
+    int i;
+
+    for (i = 0; i < db.ntables; i++) {
+	save_table(i);
+	free_table(i);
+    }
+    G_free(db.tables);
+
+    return DB_OK;
+}

+ 34 - 0
db/drivers/dbf/dbdriver.h

@@ -0,0 +1,34 @@
+/* this file was automatically generated by ../mk_dbdriver_h.sh */
+#ifndef DBDRIVER_H
+#define	DBDRIVER_H
+
+#include "dbstubs.h"
+
+int db__driver_create_table();
+int db__driver_close_cursor();
+int db__driver_open_database();
+int db__driver_close_database();
+int db__driver_describe_table();
+int db__driver_init();
+int db__driver_finish();
+int db__driver_execute_immediate();
+int db__driver_fetch();
+int db__driver_get_num_rows();
+int db__driver_list_tables();
+int db__driver_open_select_cursor();
+#define	init_dbdriver() do{\
+db_driver_create_table = db__driver_create_table;\
+db_driver_close_cursor = db__driver_close_cursor;\
+db_driver_open_database = db__driver_open_database;\
+db_driver_close_database = db__driver_close_database;\
+db_driver_describe_table = db__driver_describe_table;\
+db_driver_init = db__driver_init;\
+db_driver_finish = db__driver_finish;\
+db_driver_execute_immediate = db__driver_execute_immediate;\
+db_driver_fetch = db__driver_fetch;\
+db_driver_get_num_rows = db__driver_get_num_rows;\
+db_driver_list_tables = db__driver_list_tables;\
+db_driver_open_select_cursor = db__driver_open_select_cursor;\
+}while(0)
+
+#endif

BIN
db/drivers/dbf/dbf_catalog/datetime.dbf


BIN
db/drivers/dbf/dbf_catalog/river.dbf


File diff suppressed because it is too large
+ 1075 - 0
db/drivers/dbf/dbfexe.c


+ 141 - 0
db/drivers/dbf/describe.c

@@ -0,0 +1,141 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+
+#include <grass/dbmi.h>
+#include <grass/datetime.h>
+#include <grass/shapefil.h>
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_describe_table  (dbString *table_name, dbTable **table)
+
+{
+    int         tab;	
+    char        *name;
+
+    name = db_get_string (table_name);
+    
+    tab = find_table ( name );
+    if ( tab == -1 ) {
+	append_error("Table '%s' doesn't exist", db_get_string(table_name)); 
+	report_error();
+	return DB_FAILED;
+    }
+    describe_table ( tab, NULL, 0, table );
+
+    return DB_OK;
+}
+
+/* scols is array of indexes selected columns or null,
+ * if nscols == 0 => describe all columns */
+int
+describe_table (int tab, int *scols, int nscols, dbTable **table)
+{
+    int         i, col, ncols, dbtype, precision, scale;
+    dbColumn    *column;
+    COLUMN      *dcol;
+
+    load_table_head ( tab );
+    ncols = db.tables[tab].ncols;
+
+    if ( nscols > 0 )
+        ncols = nscols;
+    
+    if (!(*table = db_alloc_table(ncols))) {
+        return DB_FAILED;
+    }
+    
+    for (i=0; i < ncols; i++)
+      {
+        if ( nscols > 0 )
+	    col = scols[i];
+        else
+	    col = i;
+
+	dcol = &(db.tables[tab].cols[col]);
+        column = db_get_table_column (*table, i);
+	
+        db_set_column_name (column, dcol->name);
+        db_set_column_length (column, dcol->width);
+	db_set_column_host_type (column, dcol->type);
+	
+        switch ( dcol->type )
+          {  
+            case DBF_INT:
+                dbtype = DB_SQL_TYPE_INTEGER;
+                precision = dcol->width - 1;  /* one char for sign */
+                scale = 0;  
+		break;
+            case DBF_DOUBLE:
+                dbtype = DB_SQL_TYPE_DOUBLE_PRECISION;
+                precision = dcol->width - 2;  /* one char for sign second for decimal point */
+                scale = dcol->decimals;  
+                break;
+            case DBF_CHAR:
+                dbtype = DB_SQL_TYPE_CHARACTER;
+                precision = 0;
+                scale = 0; 
+	        break;
+
+            default:
+                dbtype = DB_SQL_TYPE_UNKNOWN;
+                break;
+          }
+
+        db_set_column_sqltype (column, dbtype);
+
+	/* precision is number of digits */
+        db_set_column_precision (column, precision);
+	/* scale is number of digits to the right of decimal point */
+	db_set_column_scale (column, scale);
+	
+	db_set_column_null_allowed (column);
+        db_set_column_has_undefined_default_value(column);
+        db_unset_column_use_default_value(column);
+	
+        db_set_column_select_priv_granted (column);
+	
+        if ( db.tables[tab].write )
+            db_set_column_update_priv_granted (column);
+	else
+            db_set_column_update_priv_not_granted (column); 
+
+	
+      }
+    
+    /* set the table name */
+    db_set_table_name (*table, db.tables[tab].name);
+
+    /* set the table description */
+    db_set_table_description(*table, "");
+    
+    if ( db.tables[tab].write )
+      {	    
+        db_set_table_delete_priv_granted (*table);
+        db_set_table_insert_priv_granted (*table);
+      } 
+    else 
+      {
+        db_set_table_delete_priv_not_granted (*table);
+        db_set_table_insert_priv_not_granted (*table);
+      }
+	
+    return DB_OK;
+}
+
+
+

+ 31 - 0
db/drivers/dbf/driver.c

@@ -0,0 +1,31 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+
+#include <grass/dbmi.h>
+#include "globals.h"
+
+int
+db__driver_init  (int argc, char *argv[])
+
+{
+    return DB_OK;
+}
+
+int
+db__driver_finish()
+{
+    return DB_OK;
+}

+ 49 - 0
db/drivers/dbf/error.c

@@ -0,0 +1,49 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include "globals.h"
+
+/* init error message */
+void
+init_error ( void )
+{
+    if ( !errMsg ) {
+	errMsg = (dbString *) G_malloc(sizeof(dbString));
+        db_init_string (errMsg);
+    }
+
+    db_set_string ( errMsg, "DBMI-DBF driver error:\n");
+}
+
+/* append error message */
+void
+append_error ( const char *fmt, ...)
+{
+    FILE *fp = NULL;
+    char *work = NULL;
+    int count = 0;
+    va_list ap;
+
+    va_start (ap, fmt);
+    if ((fp = tmpfile())) {
+        count = vfprintf (fp, fmt, ap);
+        if (count >= 0 && (work = G_calloc (count+1,1)) ) {
+	    rewind (fp);
+	    fread (work, 1, count, fp);
+	    db_append_string ( errMsg, work);
+	    G_free (work);
+        }
+        fclose (fp);
+    }
+    va_end (ap);
+}
+
+void
+report_error ( void )
+{
+    db_append_string ( errMsg, "\n");
+    db_error ( db_get_string (errMsg) );
+}
+

+ 41 - 0
db/drivers/dbf/execute.c

@@ -0,0 +1,41 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+#include <grass/dbmi.h>
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_execute_immediate  (dbString *sql)
+
+{
+    char *s;
+    int  ret;
+
+    s = db_get_string (sql);
+    
+    ret = execute ( s, NULL);
+    
+    if ( ret == DB_FAILED )
+      {
+         append_error("Error in db_execute_immediate()");
+         report_error( );
+         return DB_FAILED;
+      }
+    
+    return DB_OK;
+}
+
+

+ 125 - 0
db/drivers/dbf/fetch.c

@@ -0,0 +1,125 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+#include <grass/dbmi.h>
+#include "globals.h"
+#include "proto.h" 
+
+int
+db__driver_fetch (dbCursor *cn, int position, int *more)
+
+{
+    cursor     *c;
+    dbToken    token;    
+    dbTable    *table;
+    dbColumn   *column;
+    dbValue    *value;
+    int        col, ncols;
+    int        htype, sqltype, ctype;
+    int  dbfrow, dbfcol;
+
+    /* get cursor token */
+    token = db_get_cursor_token(cn);
+
+    /* get the cursor by its token */
+    if (!(c = (cursor *) db_find_token(token))) 
+    {
+	db_error("cursor not found");
+	return DB_FAILED;
+    }
+
+    /* fetch on position */
+    switch (position)
+    { 
+    case DB_NEXT:
+	c->cur++;    
+	break;
+    case DB_CURRENT:
+	break;
+    case DB_PREVIOUS:
+	c->cur--;    
+    	break;
+    case DB_FIRST:
+	c->cur = 0;    
+	break;
+    case DB_LAST:
+	c->cur = c->nrows - 1;
+	break;
+    };
+
+    if ( (c->cur >= c->nrows) || (c->cur < 0) )
+    {
+	*more = 0;
+	return DB_OK;
+    }
+    *more = 1;
+
+    
+    /* get the data out of the descriptor into the table */
+    table = db_get_cursor_table(cn);
+    ncols = db_get_table_number_of_columns (table);
+    dbfrow = c->set[c->cur];
+    for (col = 1; col <= ncols; col++)
+    {
+        dbfcol = c->cols[col-1];
+	column = db_get_table_column (table, col-1);
+	value  = db_get_column_value (column);
+	db_free_string (&value->s);
+	
+	sqltype = db_get_column_sqltype(column);
+	ctype   = db_sqltype_to_Ctype(sqltype);
+	htype   = db_get_column_host_type(column);
+	
+	if ( db.tables[c->table].rows[dbfrow].values[dbfcol].is_null ) {
+	    db_set_value_null ( value ) ;
+	} else {
+	    db_set_value_not_null ( value ) ;
+	    switch (ctype)
+	    {
+	    case DB_C_TYPE_STRING:
+		    db_set_string ( &(value->s), db.tables[c->table].rows[dbfrow].values[dbfcol].c);
+		break;
+	    case DB_C_TYPE_INT:
+		value->i = db.tables[c->table].rows[dbfrow].values[dbfcol].i;
+		break;
+	    case DB_C_TYPE_DOUBLE:
+		value->d = db.tables[c->table].rows[dbfrow].values[dbfcol].d;
+		break;
+	    }
+	}
+    }
+    return DB_OK;
+}
+
+int
+db__driver_get_num_rows  (dbCursor *cn)
+
+{
+    cursor     *c;
+    dbToken    token;    
+
+    /* get cursor token */
+    token = db_get_cursor_token(cn);
+
+    /* get the cursor by its token */
+    if (!(c = (cursor *) db_find_token(token))) 
+    {
+	db_error("cursor not found");
+	return DB_FAILED;
+    }
+
+    return ( c->nrows );
+
+}

+ 82 - 0
db/drivers/dbf/globals.h

@@ -0,0 +1,82 @@
+#include <grass/sqlp.h>
+
+#define DBF_COL_NAME 20 /* maximum column name (in fact shouldn't be > 10) */
+
+/* 
+* DBF API:      http://shapelib.maptools.org/dbf_api.html
+*            or ../../../lib/external/shapelib/shapefil.h
+*
+* DBFFieldType: FTString, FTInteger, FTDouble, FTLogical, FTInvalid
+*                  0          1          2         4         5
+*                DBF_CHAR   DBF_INT   DBF_DOUBLE
+*                  1          2          3
+*/
+#define DBF_CHAR   1
+#define DBF_INT    2
+#define DBF_DOUBLE 3
+
+typedef struct {
+    char name[DBF_COL_NAME]; 
+    int  type; 
+    int  width; 
+    int  decimals; 
+} COLUMN;
+
+typedef struct {
+    char  *c; 
+    int    i; 
+    double d; 
+    int    is_null;
+} VALUE;
+
+typedef struct {
+    int   alive; 
+    VALUE *values;
+} ROW;
+
+typedef struct {
+    char  name[1024]; /* table name (without .dbf) */
+    char  file[1024]; /* full path to file (including .dbf) */
+    int   read;       /* TRUE if user has read access to the file */  
+    int   write;      /* TRUE if user has write access to the file */
+    int   alive; 
+    int   described;  /* columns definitions were loaded to heads */
+    int   loaded;     /* data were loaded to rows */
+    int   updated;     
+    COLUMN *cols;
+    ROW  *rows;
+    int   acols;      /* allocated columns */
+    int   ncols;      /* number of columns */
+    int   arows;      /* allocated rows */
+    int   nrows;      /* number of rows */
+} TABLE;
+
+typedef struct {
+    char   name[1024]; /* db name = full path to db dir */
+    TABLE *tables;
+    int    atables;    /* allocated space for tables */
+    int    ntables;    /* number of tables */
+} DATABASE;
+
+/* cursors */
+typedef struct {
+    SQLPSTMT *st;
+    int table;   /* table */
+    int *set;    /* array of indexes to table for selected rows */
+    int nrows;   /* number of rows in set */
+    int cur;     /* position of cursor */
+    int *cols;   /* array of indexes of selected columns */
+    int ncols;
+    dbToken token;
+    int type;    /* type of cursor: SELECT, UPDATE, INSERT */
+    int *order;  /* array of row indexes (sorted by ORDER BY) */
+} cursor;
+
+#ifdef MAIN
+    DATABASE db;
+    dbString *errMsg = NULL;
+#else
+    extern DATABASE db;
+    extern dbString *errMsg;
+#endif 
+

+ 109 - 0
db/drivers/dbf/grass-dbf.html

@@ -0,0 +1,109 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>GRASS-DBF driver</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="grassdocs.css" type="text/css">
+</head>
+
+<body bgcolor="white">
+
+<img src="grass_logo.png" alt="GRASS logo"><hr align=center size=6 noshade>
+
+<h1>DBF driver in GRASS</h1>
+
+<H2>Defining the DBF driver</H2>
+
+The DBF driver is the default driver, in theory no user interaction is
+required. However, if the settings should be set back from a different
+to the DBF driver, the following step is required:
+
+<div class="code"><pre>
+# keep single quotes:
+db.connect driver=dbf database='$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/'
+db.connect -p
+</pre></div>
+
+The dbf/ subdirectory in the mapset must exist or must be created by the user.
+
+<H2>Creating a DBF table</H2>
+
+Usually DBF tables are created by GRASS when generating a vector map
+with attributes (and using DBF as default attribute driver).
+<p>
+If a DBF table has to be created manually, <a href="db.execute.html">db.execute</a>
+can be used or a spreadsheet application. Also <a href="db.copy.html">db.copy</a>
+is sometimes useful as well as <a href="db.in.ogr.html">db.in.ogr</a> to import external
+tables.
+
+<H2>Supported SQL commands by DBF driver</H2>
+<div class="code"><pre>
+  ALTER TABLE table ADD [COLUMN] columndef
+  ALTER TABLE table DROP COLUMN colname
+  CREATE TABLE table ( columndefs )
+  DROP TABLE table
+  SELECT columns FROM table
+  SELECT columns FROM table WHERE condition
+  DELETE FROM table
+  DELETE FROM table WHERE condition
+  INSERT INTO table VALUES (value1[,value2,...])
+  INSERT INTO table ( column1[,column2,...] ) VALUES (value1[,value2,...])
+  UPDATE table SET assignment1[,assignment2,...]
+  UPDATE table SET assignment1[,assignment2,...] WHERE condition
+</pre></div>
+
+<H2>Operators available in conditions</H2>
+<div class="code"><pre>
+  "="  : equal
+  "&lt;"  : smaller than
+  "&lt;=" : smaller/equal than
+  "&gt;"  : larger than
+  "&gt;=" : larger/equal than
+  "&lt;&gt;" : not equal
+  "~"  : Substring matching  (non-standard SQL)
+  "%"  : Substring matching  (limited functionality)
+</pre></div>
+
+<p> Arithmetic expressions using constants and field values are allowed 
+in condition clauses and in the RHS of assignments. 
+Usual precedence rules and bracketing (using '(' and ')') are supported. 
+Type conversion is performed if necessary (experimental). </p>
+
+<p> Aggregate functions (sum, count, min, max,...) are NOT currently supported 
+    in SELECT clauses. </p>
+
+<p> Mathematic functions (sin, cos, exp, log,...) are NOT currently supported 
+    in expressions. </p>
+
+<p> Conditions allow boolean expressions using the AND, OR and NOT operators, 
+    with the usual precedence rules. </p>
+
+<p> NULLs can be tested by 'colname IS NULL' in conditions. The negation is 'colname NOT NULL'.</p>
+
+<h2>ERROR MESSAGES</h2>
+
+An error message such as:
+
+<div class="code"><pre>
+DBMI-DBF driver error:
+SQL parser error: syntax error, unexpected DESC, expecting NAME processing 'DESC'
+</pre></div>
+
+indicates that a column name corresponds to a reserved SQL word (here: 'DESC').
+A different column name should be used. If this happens during import with
+<em>v.in.ogr</em>, the <em>cnames</em> parameter can be used to assign different
+column names on the fly.
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="db.connect.html">db.connect</a>,
+<a HREF="sql.html">SQL support in GRASS GIS</a><br>
+<a href="http://shapelib.maptools.org/dbf_api.html">DBF Specifications</a> (Shapelib)
+</em>
+
+<p><i>Last changed: $Date$</i>
+<HR>
+<BR><a href=index.html>Help Index</a>
+</body>
+</html>

+ 48 - 0
db/drivers/dbf/listtab.c

@@ -0,0 +1,48 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+
+#include <grass/dbmi.h>
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_list_tables  (dbString **tlist, int *tcount, int system)
+
+{
+    dbString 	*list;
+    int 	i;
+    
+    *tlist = NULL;
+    *tcount = 0;
+
+    list = db_alloc_string_array( db.ntables );
+    if (list == NULL && db.ntables > 0)
+	return DB_FAILED;
+
+    for ( i = 0; i < db.ntables; i++ )  
+      {
+    	if(db_set_string (&list[i], (char *) db.tables[i].name) != DB_OK)
+	  {
+	    return DB_FAILED;
+	  }	
+      }
+    						
+
+    *tlist = list;
+    *tcount = db.ntables;
+    return DB_OK;
+}
+

+ 48 - 0
db/drivers/dbf/main.c

@@ -0,0 +1,48 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+
+#define MAIN
+#include <stdlib.h>
+#include <string.h>
+#include <grass/dbmi.h>
+#include "globals.h"
+#include "proto.h"
+#include "dbdriver.h"
+
+int
+main(int argc, char *argv[])
+{
+    char *name;
+
+    init_dbdriver();
+    init_error();
+
+    /* Do not call G_getenv() nor other functions reading GISRC here! It may be that grass variables are
+     * not available here, but will be set in db_driver() */
+    
+    /* Set pointer to driver name */
+    name = argv[0] + strlen ( argv[0] );
+    
+    while ( name > argv[0] ) {
+        if ( name[0] == '/' ) {
+	    name++;
+	    break;
+	}
+	name--;
+    }
+    
+    exit (db_driver (argc, argv));
+}

+ 113 - 0
db/drivers/dbf/main_debug.c

@@ -0,0 +1,113 @@
+/*****************************************************************************
+* just a test for debugging purpose, imitating dbf driver -a.sh.
+*****************************************************************************/
+
+#define MAIN
+#include <stdlib.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include "globals.h"
+
+int
+main(int argc, char *argv[])
+{
+
+    dbCursor *cursor;
+    int stat;
+    dbToken token;
+    dbString * select;
+    int mode = 0;
+    dbDriver *driver;
+    dbHandle handle;
+
+    driver = db_start_driver("dbf");
+    if (driver == NULL)
+	exit(-1);
+
+    db_init_handle (&handle);
+    db_set_handle (&handle, "dbf_catalog", NULL);
+
+    if (db__test_database_open())
+    {
+	db_error ("Multiple open databases not allowed");
+	return DB_OK;
+    }
+
+/* call the procedure */
+    stat = db_driver_open_database (&handle);
+
+/* send the return code */
+    if (stat != DB_OK)
+    {
+	db_free_handle (&handle);
+	return DB_OK;
+    }
+
+/* record the open in the driver state */
+    db__mark_database_open (
+    	db_get_handle_dbname (&handle),
+    	db_get_handle_dbpath (&handle));
+/* DO NOT free the handle since we saved the pointers to the name,path */
+    
+    select = (dbString *) G_malloc (1024);
+
+    db_init_string (select);
+
+    db_set_string(select,
+"select id, quality, flow from river where (flow = 10) or (flow = 20) or (flow = 30) or (flow = 5) or (flow = 7)");
+
+/* create a cursor */
+    cursor = (dbCursor *) db_malloc (sizeof(dbCursor));
+    if (cursor == NULL)
+	return db_get_error_code();
+    token = db_new_token ( (dbAddress) cursor);
+    if (token < 0)
+	return db_get_error_code();
+    db_init_cursor(cursor);
+    cursor->driver = driver;
+
+G_debug(3, "sql is %s", *select);
+G_debug(3, "driver is %s", cursor->driver);
+
+/* call the procedure */
+    stat = db_driver_open_select_cursor (select, cursor, mode);
+    db_free_string (select);
+
+/* mark this as a readonly cursor */
+    db_set_cursor_type_readonly (cursor);
+
+/* add this cursor to the cursors managed by the driver state */
+    db__add_cursor_to_driver_state(cursor);
+G_debug(3, "db_d_close_database()");
+
+/* see if a database is open */
+    if (!db__test_database_open())
+    {
+	db_error ("no database is open");
+G_debug(3, "db_d_close_database(): would sent DB_FAILURE");
+	return DB_OK;
+    };
+/* make sure all cursors are closed */
+    db__close_all_cursors();
+
+/* call the procedure */
+    stat = db_driver_close_database();
+G_debug(3, "db_d_close_database(): would have stat = %d", stat);
+
+/* send the return code */
+    if (stat != DB_OK)
+    {
+G_debug(3, "db_d_close_database(): would sent DB_FAILURE");
+	return DB_OK;
+    }
+G_debug(3, "db_d_close_database(): would sent DB_OK");
+
+/* clear the driver state */
+    db__mark_database_closed ();
+    db__init_driver_state();
+
+
+G_debug(3, "main(): ok");
+    return DB_OK;
+
+}

+ 25 - 0
db/drivers/dbf/proto.h

@@ -0,0 +1,25 @@
+/* error.c */
+void init_error ( void );
+void append_error ( const char *fmt, ...);
+void report_error ( void );
+
+int save_string (VALUE *, char *);
+
+cursor * alloc_cursor ();
+void free_cursor ( cursor * );
+
+/* column.c */
+int add_column ( int table, int type,  char *name , int width, int decimals );
+int find_column ( int, char * );
+int drop_column ( int, char * );
+
+int add_table ( char *, char *);
+int execute ( char *, cursor *);
+int free_table ( int );
+int find_table ( char * );
+int load_table_head( int );
+int load_table( int );
+int save_table( int );
+int describe_table( int, int *, int, dbTable ** );
+
+

+ 61 - 0
db/drivers/dbf/select.c

@@ -0,0 +1,61 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+
+#include <grass/dbmi.h>
+#include <grass/shapefil.h>
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_open_select_cursor (dbString *sel, dbCursor *dbc, int mode)
+
+{
+    int ret;	
+    cursor      *c;
+    char        *sql;      
+    dbTable     *table;   
+    
+    /* allocate cursor */
+    c = alloc_cursor();
+    if (c == NULL)
+	return DB_FAILED;
+
+    db_set_cursor_mode(dbc,mode);
+    db_set_cursor_type_readonly(dbc);
+
+    sql = db_get_string(sel);
+    
+    ret = execute ( sql, c); 
+		    
+    if ( ret == DB_FAILED )
+      {
+        append_error("Error in db_open_select_cursor()");
+	report_error( );
+	return DB_FAILED;
+      } 
+		
+    describe_table( c->table, c->cols, c->ncols, &table);
+    
+    /* record table with dbCursor */
+    db_set_cursor_table(dbc, table);
+    
+    /* set dbCursor's token for my cursor */
+    db_set_cursor_token(dbc, c->token);
+
+    return DB_OK;
+}
+
+

+ 35 - 0
db/drivers/dbf/str.c

@@ -0,0 +1,35 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+*****************************************************************************/
+#include <stdlib.h>
+#include <string.h>
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include "globals.h"
+
+/* save string to value */
+int save_string ( VALUE *val, char *c )
+{
+    int len;
+
+    len = strlen ( c ) + 1;
+    val->c = (char *) G_realloc (val->c, len);
+
+    strcpy ( val->c, c );
+
+    return (1);
+}
+    
+

+ 341 - 0
db/drivers/dbf/table.c

@@ -0,0 +1,341 @@
+/*****************************************************************************
+*
+* MODULE:       DBF driver 
+*   	    	
+* AUTHOR(S):    Radim Blazek
+*
+* PURPOSE:      Simple driver for reading and writing dbf files     
+*
+* COPYRIGHT:    (C) 2000 by the GRASS Development Team
+*
+*               This program is free software under the GNU General Public
+*   	    	License (>=v2). Read the file COPYING that comes with GRASS
+*   	    	for details.
+*
+* DBF API:      http://shapelib.maptools.org/dbf_api.html
+*
+* DBFFieldType: FTString, FTInteger, FTDouble, FTLogical, FTInvalid
+*                  0          1          2         4         5
+*                DBF_CHAR   DBF_INT   DBF_DOUBLE  
+*                  1          2          3
+*****************************************************************************/
+#ifdef __MINGW32__
+#  include <windows.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <grass/dbmi.h>
+#include <grass/shapefil.h>
+#include <grass/gis.h>
+#include "globals.h"
+#include "proto.h" 
+
+/* add table to database */
+int add_table (char *table, char *name)
+{
+    G_debug (2, "add_table(): table = %s name = %s", table, name );
+
+    if ( db.atables == db.ntables )
+      {
+        db.atables += 15; 
+	db.tables = (TABLE *) G_realloc ( db.tables, db.atables * sizeof (TABLE) ); 
+      }
+    
+    strcpy ( db.tables[db.ntables].name, table );
+    
+    sprintf ( db.tables[db.ntables].file, "%s/%s", db.name, name );
+    
+    db.tables[db.ntables].alive = TRUE;
+    db.tables[db.ntables].described = FALSE;
+    db.tables[db.ntables].loaded = FALSE;
+    db.tables[db.ntables].updated = FALSE;
+    db.tables[db.ntables].cols = NULL;
+    db.tables[db.ntables].rows = NULL;
+    db.tables[db.ntables].acols = 0;
+    db.tables[db.ntables].ncols = 0;
+    db.tables[db.ntables].arows = 0;
+    db.tables[db.ntables].nrows = 0;
+
+    db.ntables++ ;
+    
+    return DB_OK;
+}
+
+
+/* returns table index or -1 */
+int find_table (char *table)
+{
+    int i;
+
+    G_debug ( 2, "find_table(): table = %s", table );
+	
+    for ( i = 0; i < db.ntables; i++ ) {
+         G_debug ( 2, "  ? %s", db.tables[i].name );
+         if ( G_strcasecmp( db.tables[i].name, table ) == 0 )
+	     return (i);   
+   }
+    
+    return (-1);
+}
+
+int
+load_table_head( int t)
+{
+    int  i, ncol, dtype, type, width, decimals;
+    DBFHandle   dbf;
+    char fname[20];
+
+    G_debug ( 2, "load_table_head(): tab = %d, %s", t, db.tables[t].file);
+
+    if ( db.tables[t].described == TRUE ) /*already described */
+        return DB_OK;
+     
+    if ( access( db.tables[t].file, R_OK ) == 0 )
+	db.tables[t].read = TRUE;
+    else
+        db.tables[t].read = FALSE;
+    
+    if ( access( db.tables[t].file, W_OK ) == 0 )
+	db.tables[t].write = TRUE;
+    else
+        db.tables[t].write = FALSE;
+    
+    /* load */
+    dbf = DBFOpen( db.tables[t].file, "r" );
+    if( dbf == NULL ) {
+	append_error("Cannot open dbf file.\n");
+        return DB_FAILED;
+    }
+
+    ncol = DBFGetFieldCount(dbf);
+    G_debug ( 2, "  ncols = %d", ncol);
+
+    for( i = 0; i < ncol; i++ )
+      {
+         dtype = DBFGetFieldInfo( dbf, i, fname, &width, &decimals );
+         G_debug ( 2, "  DBFFieldType %d", dtype);
+	 
+	 switch ( dtype )
+	   {
+             case FTString:
+		 type = DBF_CHAR;    
+                 break;
+             case FTInteger:
+		 type = DBF_INT;    
+                 break;
+             case FTDouble:
+		 type = DBF_DOUBLE;    
+                 break;
+	     case FTInvalid:
+	    	 G_warning ("invalid/unsupported DBFFieldType");
+		 break;
+	     default:
+	      	 G_warning ("unknown DBFFieldType");
+	      	 break;
+	   }
+	 
+	 add_column ( t, type, fname, width, decimals);  
+      }
+    
+    DBFClose ( dbf );
+    db.tables[t].described = TRUE;
+	
+    return DB_OK;
+}
+
+int
+load_table ( int t)
+{
+    int  i, j, ncols, nrows, dbfcol;
+    DBFHandle   dbf;
+    char *buf;
+    ROW  *rows;
+    VALUE *val;
+
+    G_debug ( 2, "load_table(): tab = %d", t);
+    
+    if ( db.tables[t].loaded == TRUE ) /*already loaded */
+        return DB_OK;
+    
+    dbf = DBFOpen( db.tables[t].file, "r" );
+    if( dbf == NULL ) {
+	append_error("Cannot open dbf file.\n");
+        return DB_FAILED;
+    }
+
+    ncols = db.tables[t].ncols;
+    nrows = DBFGetRecordCount( dbf );
+    rows = db.tables[t].rows;
+    rows = (ROW *) G_malloc ( nrows * sizeof(ROW) );
+    db.tables[t].arows = nrows;
+    
+    G_debug ( 2, "  ncols = %d nrows = %d", ncols, nrows);
+    
+    for( i = 0; i < nrows; i++ )
+      {
+         rows[i].alive = TRUE;
+         rows[i].values = (VALUE *) G_calloc ( ncols, sizeof (VALUE) );
+
+         for( j = 0; j < ncols; j++ )
+           {
+             val = &(rows[i].values[j]);		   
+	     
+	     dbfcol = j;
+
+	     val->is_null = DBFIsAttributeNULL ( dbf, i, dbfcol );
+	     if ( !(val->is_null) ) {
+		 switch ( db.tables[t].cols[j].type )
+		   {
+		     case DBF_INT:    
+			 val->i = DBFReadIntegerAttribute( dbf, i, dbfcol );
+			 break;
+		     case DBF_CHAR:    
+			 buf = (char *) DBFReadStringAttribute( dbf, i, dbfcol );
+			 save_string ( val, buf);
+			 break;
+		     case DBF_DOUBLE:    
+			 val->d = DBFReadDoubleAttribute( dbf, i, dbfcol );
+			 break;
+		   }
+	     }
+           }
+      }
+
+    DBFClose ( dbf );
+    
+    db.tables[t].rows = rows;
+    db.tables[t].nrows = nrows;
+    db.tables[t].loaded = TRUE;
+    
+    return DB_OK;
+}
+
+int
+save_table ( int t)
+{
+    int  i, j, ncols, nrows, ret, field, rec;
+    char name[2000], fname[20], element[100];
+    DBFHandle   dbf;
+    ROW  *rows;
+    VALUE *val;
+    int  dbftype, width, decimals;
+
+    G_debug (2, "save_table %d", t);
+
+    /* Note: because if driver is killed during the time the table is written, the process
+    *        is not completed and DATA ARE LOST. To minimize this, data are first written
+    *        to temporary file and then this file is renamed to 'database/table.dbf'.
+    *        Hopefully both file are on the same disk/partition */
+    
+    if ( !(db.tables[t].alive) || !(db.tables[t].updated) )
+        return DB_OK;
+    
+    /* Construct our temp name because shapelib doesn't like '.' in name */
+    G__temp_element(element);
+    sprintf (fname, "%d.dbf", getpid()) ;
+    G__file_name (name, element, fname, G_mapset()) ;
+    G_debug (2, "Write table to tempfile: '%s'", name);
+    
+    dbf = DBFCreate( name );
+    if( dbf == NULL )
+        return DB_FAILED;
+
+    ncols = db.tables[t].ncols;
+    rows = db.tables[t].rows;
+    nrows = db.tables[t].nrows;
+
+    for( i = 0; i < ncols; i++ )
+      {
+	switch ( db.tables[t].cols[i].type )
+          {
+            case DBF_INT:
+		dbftype = FTInteger;
+		break;
+            case DBF_CHAR:
+		dbftype = FTString;
+		break;
+            case DBF_DOUBLE:
+		dbftype = FTDouble;
+		break;
+	  }
+	      
+        width = db.tables[t].cols[i].width;
+	decimals = db.tables[t].cols[i].decimals;
+        DBFAddField( dbf, db.tables[t].cols[i].name, dbftype, width, decimals );
+
+      }
+    
+    G_debug (2, "Write %d rows", nrows);
+    rec = 0;
+    for( i = 0; i < nrows; i++ )
+      {
+         if ( rows[i].alive == FALSE ) continue;
+		 
+         for( j = 0; j < ncols; j++ )
+           {
+	     field = j;
+		 
+             val = &(rows[i].values[j]);		   
+	     if ( val->is_null ) {
+	         DBFWriteNULLAttribute ( dbf, rec, field );
+	     } else { 
+		 switch ( db.tables[t].cols[j].type ) {
+		     case DBF_INT:    
+			 ret = DBFWriteIntegerAttribute( dbf, rec, field, val->i ); 
+			 break;
+		     case DBF_CHAR:    
+			 if ( val->c != NULL )
+			     ret = DBFWriteStringAttribute( dbf, rec, field, val->c ); 
+			 else
+			     ret = DBFWriteStringAttribute( dbf, rec, field, "" ); 
+			 break;
+		     case DBF_DOUBLE:    
+			 ret = DBFWriteDoubleAttribute( dbf, rec, field, val->d ); 
+			 break;
+		 }
+	     }
+           }
+	 rec++;
+      }
+    G_debug (2, "Written %d records", rec);
+
+    DBFClose ( dbf );
+
+    /* Copy */
+    if ( G_rename_file ( name, db.tables[t].file ) ) {
+	    append_error( "Cannot move %s\nto %s\n", 
+                          name, db.tables[t].file );
+            return DB_FAILED;
+    };
+
+    return DB_OK;
+}
+
+int free_table (int tab)
+{
+    int i,j;
+
+    for ( i = 0; i < db.tables[tab].nrows; i++ )
+      {
+	for( j = 0; j < db.tables[tab].ncols; j++ )
+	  {
+            if ( db.tables[tab].cols[j].type == DBF_CHAR && db.tables[tab].rows[i].values[j].c != NULL )
+	      {	    
+                G_free ( db.tables[tab].rows[i].values[j].c );
+	      }
+	  }
+        G_free ( db.tables[tab].rows[i].values );
+      }
+    
+    G_free ( db.tables[tab].rows );
+	      
+    return DB_OK;
+}
+
+

+ 30 - 0
db/drivers/mk_dbdriver_h.sh

@@ -0,0 +1,30 @@
+#!/bin/sh
+# generates dbdriver.h
+
+tmp=mk_dbdriver_h.tmp.$$
+cat <<'EOT'> dbdriver.h
+/* this file was automatically generated by ../mk_dbdriver_h.sh */
+#ifndef DBDRIVER_H
+#define	DBDRIVER_H
+
+#include "dbstubs.h"
+
+EOT
+
+grep -h '^\( *int *\)\?db__driver' *.c | sed \
+	-e 's/^\( *int *\)*/int /' \
+	-e 's/ *(.*$/();/' > $tmp
+cat $tmp >> dbdriver.h
+
+cat <<'EOT' >> dbdriver.h
+#define	init_dbdriver() do{\
+EOT
+
+sed 's/^int *db__\([a-zA-Z_]*\).*$/db_\1 = db__\1;\\/' $tmp >> dbdriver.h
+cat <<'EOT'>> dbdriver.h
+}while(0)
+
+#endif
+EOT
+
+rm $tmp

+ 67 - 0
db/drivers/mysql/Makefile

@@ -0,0 +1,67 @@
+
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/Platform.make
+include $(MODULE_TOPDIR)/include/Make/Grass.make
+include $(MODULE_TOPDIR)/include/Make/Rules.make
+
+CLIENT_DRIVER=$(DBDRIVERDIR)/mysql$(EXE)
+EMBEDED_DRIVER=$(DBDRIVERDIR)/mesql$(EXE)
+
+LIBES = $(DBMIDRIVERLIB) $(DBMIBASELIB) $(SQLPLIB) $(DBSTUBSLIB) \
+	 $(GISLIB) $(DATETIMELIB) 
+
+EXTRA_CFLAGS = $(MYSQLINCPATH) $(TCLINCDIR) $(TKINCDIR)
+EXTRA_INC = -I$(MODULE_TOPDIR)/lib/db/dbmi_driver
+
+DEPENDENCIES = $(GISDEP)
+
+DRVDOC=$(GISBASE)/docs/html/grass-mysql.html
+EDRVDOC=$(GISBASE)/docs/html/grass-mesql.html
+
+OBJS 	=  \
+	create_table.o \
+	cursor.o \
+	describe.o \
+	driver.o \
+	error.o \
+	execute.o \
+	fetch.o \
+	index.o \
+	listtab.o \
+	main.o \
+	parse.o	\
+	select.o 
+
+CLIENT_OBJS = $(OBJS) db.o
+EMBEDED_OBJS = $(OBJS) dbe.o 
+
+CLIENT_ARCH_OBJS := $(foreach obj,$(CLIENT_OBJS),$(OBJDIR)/$(obj))
+EMBEDED_ARCH_OBJS := $(foreach obj,$(EMBEDED_OBJS),$(OBJDIR)/$(obj))
+
+ifneq ($(strip $(MYSQLDLIB)),) 
+ifneq ($(strip $(CXX)),) 
+    EDRIVER = $(EMBEDED_DRIVER)
+endif
+endif
+
+default: $(CLIENT_DRIVER) $(EDRIVER) $(DRVDOC) $(EDRVDOC)
+
+$(CLIENT_DRIVER): $(CLIENT_ARCH_OBJS)
+	$(CC) $(LDFLAGS) -o $@ $(CLIENT_ARCH_OBJS) $(FMODE_OBJ) $(LIBES) \
+		$(MYSQLLIBPATH) $(MYSQLLIB) $(MATHLIB) $(XDRLIB)
+
+$(EMBEDED_DRIVER): $(EMBEDED_ARCH_OBJS)
+	$(CXX) $(LDFLAGS) -o $@ $(EMBEDED_ARCH_OBJS) $(FMODE_OBJ) \
+		$(MYSQLDLIB) $(LIBES) $(MATHLIB) $(XDRLIB)
+
+$(OBJDIR)/dbe.o : db.c $(DEPENDENCIES) $(LOCAL_HEADERS)
+	@test -d $(OBJDIR) || mkdir $(OBJDIR)
+	$(CC) -DMESQL=1 $(CFLAGS) $(EXTRA_CFLAGS) $(NLS_CFLAGS) $(EXTRA_INC) $(INC) \
+		-o $@ -c db.c
+
+$(DRVDOC): grass-mysql.html
+	$(INSTALL_DATA) grass-mysql.html $(DRVDOC)
+
+$(EDRVDOC): grass-mesql.html
+	$(INSTALL_DATA) grass-mesql.html $(EDRVDOC)

+ 149 - 0
db/drivers/mysql/create_table.c

@@ -0,0 +1,149 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_create_table (dbTable *table)
+{
+    int col, ncols;
+    dbColumn   *column;
+    char *colname;
+    int sqltype;
+    char buf[500];
+    dbString sql;
+    /* dbConnection conn_par; */
+    
+    G_debug (3, "db__driver_create_table()");
+
+    init_error();
+
+    db_init_string (&sql);
+
+    db_set_string ( &sql, "CREATE TABLE ");
+    db_append_string ( &sql, db_get_table_name ( table ) );
+    db_append_string ( &sql, " ( ");
+
+    ncols = db_get_table_number_of_columns(table);
+
+    for ( col = 0; col < ncols; col++ ) {
+        column = db_get_table_column (table, col);
+	colname = db_get_column_name (column);
+	sqltype = db_get_column_sqltype (column);
+	
+	G_debug ( 3, "%s (%s)", colname, db_sqltype_name(sqltype) );
+
+	if ( col > 0 ) db_append_string ( &sql, ", " );
+	db_append_string ( &sql, colname );
+	db_append_string ( &sql, " " );
+	switch ( sqltype ) 
+        {
+	    case DB_SQL_TYPE_SMALLINT:
+		db_append_string ( &sql, "SMALLINT");
+		break;
+	    case DB_SQL_TYPE_INTEGER:
+		db_append_string ( &sql, "INT");
+		break;
+
+	    case DB_SQL_TYPE_REAL:
+		db_append_string ( &sql, "FLOAT");
+		break;
+
+            /* TODO: better numeric types */
+	    case DB_SQL_TYPE_DOUBLE_PRECISION:
+	    case DB_SQL_TYPE_DECIMAL:
+	    case DB_SQL_TYPE_NUMERIC:
+	    case DB_SQL_TYPE_INTERVAL:
+		db_append_string ( &sql, "DOUBLE");
+		break;
+
+            /* GRASS does not distinguish TIMESTAMP and DATETIME */
+            /*
+            case DB_SQL_TYPE_DATETIME|DB_DATETIME_MASK:
+                db_append_string ( &sql, "DATETIME");
+                break;
+	    */
+            case DB_SQL_TYPE_TIMESTAMP:
+                /* db_append_string ( &sql, "TIMESTAMP"); */
+                db_append_string ( &sql, "DATETIME");
+                break;
+
+            case DB_SQL_TYPE_DATE:
+                db_append_string ( &sql, "DATE");
+                break;
+            case DB_SQL_TYPE_TIME:
+                db_append_string ( &sql, "TIME");
+                break;
+
+	    case DB_SQL_TYPE_CHARACTER:
+                sprintf (buf, "VARCHAR(%d)", 
+			db_get_column_length (column) );
+                db_append_string ( &sql, buf);
+		break;
+	    case DB_SQL_TYPE_TEXT:
+		db_append_string ( &sql, "TEXT");
+                break;
+
+ 	    default:
+                G_warning ( "Unknown column type (%s)", colname);
+		return DB_FAILED;
+	}
+    }
+    db_append_string ( &sql, " )" );
+
+    G_debug (3, " SQL: %s", db_get_string(&sql) );
+    
+    if ( mysql_query ( connection, db_get_string(&sql) ) != 0 )
+    {
+        append_error( "Cannot create table:\n");
+	append_error( db_get_string(&sql) );
+	append_error( "\n" );
+	append_error ( mysql_error(connection) );
+	report_error();
+	db_free_string ( &sql);
+	return DB_FAILED;
+    }
+
+    /* Grant privileges */
+
+    /*
+     * 1) MySQL does not support user groups but it is possible 
+     *    to specify list of users. 
+     * 2) Only root can grant privileges.
+     */
+    /*
+    db_get_connection(&conn_par);
+
+    if ( conn_par.group ) 
+    {
+	db_set_string ( &sql, "GRANT SELECT ON on " );
+	db_append_string ( &sql, db_get_table_name ( table ) );
+	db_append_string ( &sql, " TO " );
+	db_append_string ( &sql, conn_par.group );
+
+	G_debug (3, " SQL: %s", db_get_string(&sql) );
+
+	if ( mysql_query ( connection, db_get_string(&sql) ) != 0 )
+	{
+	    G_warning ( "Cannot grant select on table: \n%s\n%s",
+			 db_get_string(&sql), mysql_error(connection) );
+	}
+    }
+    */
+    
+    db_free_string ( &sql);
+    
+    return DB_OK;
+}

+ 77 - 0
db/drivers/mysql/cursor.c

@@ -0,0 +1,77 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdio.h>
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_close_cursor(dbCursor *dbc)
+{
+    cursor *c;
+
+    init_error();
+
+    /* get my cursor via the dbc token */
+    c = (cursor *) db_find_token(db_get_cursor_token(dbc));
+    if (c == NULL)
+	return DB_FAILED;
+
+    /* free_cursor(cursor) */
+    free_cursor(c);
+
+    return DB_OK;
+}
+
+
+cursor * alloc_cursor()
+{
+    cursor     *c;
+
+    /* allocate the cursor */
+    c = (cursor *) db_malloc(sizeof(cursor));
+    if (c == NULL) {
+        append_error( _("Cannot allocate cursor.") );
+        return NULL; 
+    } 
+
+    c->res = NULL;
+    
+    /* tokenize it */
+    c->token = db_new_token(c);
+    if (c->token < 0) {
+        append_error( _("Cannot ad new token.") );
+        return NULL; 
+    }
+
+    c->cols = NULL;
+    c->ncols = 0;
+
+    return c;
+}
+
+void free_cursor( cursor *c)
+{
+    db_drop_token(c->token);
+
+    if ( c->res ) 
+    {
+	mysql_free_result ( c->res );
+    }
+
+    G_free ( c->cols );
+    G_free(c);  
+}
+

+ 194 - 0
db/drivers/mysql/db.c

@@ -0,0 +1,194 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdlib.h>
+#include <string.h>
+
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+int replace_variables ( char *, char **, char ** );
+
+int db__driver_open_database(dbHandle *handle)
+{
+    char *name;
+    dbConnection default_connection;
+    MYSQL *res;
+
+    init_error();
+    db_get_connection(&default_connection);
+    name = db_get_handle_dbname(handle);
+
+    /* if name is empty use default_connection.databaseName */
+    if (strlen(name) == 0) 
+	name = default_connection.databaseName;
+
+    G_debug(3, "db_driver_open_database() mysql: database definition = '%s'", name );
+
+#ifndef MESQL
+  {
+    /* Client version */
+    char *user, *password;
+    CONNPAR connpar;
+
+    if ( parse_conn ( name, &connpar ) == DB_FAILED ) {
+	report_error();
+	return DB_FAILED;
+    }
+    
+    G_debug(3, "host = %s, port = %d, dbname = %s, "
+	       "user = %s, password = %s", 
+	       connpar.host, connpar.port, connpar.dbname, 
+	       connpar.user, connpar.password );
+
+    db_get_login ( "mysql", name, &user, &password );
+
+    connection = mysql_init(NULL);
+    res = mysql_real_connect ( connection, connpar.host, user, password,
+	                       connpar.dbname, connpar.port, NULL, 0);
+
+    G_free ( user );
+    G_free ( password );
+    
+    if ( res == NULL ) 
+    {
+	append_error ( _("Cannot connect to MySQL: ") );
+        append_error ( mysql_error(connection) );
+	report_error ();
+	return DB_FAILED;
+    }
+  }
+
+#else
+
+    /* Embedded version */
+  {
+    char *datadir, *database;
+    char *server_args[4];
+    char *buf;
+
+    if ( !replace_variables ( name, &datadir, &database ) )
+    {
+	append_error ( _("Cannot parse MySQL embedded database name") );
+        append_error ( mysql_error(connection) );
+	report_error ();
+	return DB_FAILED;
+    }
+    
+    server_args[0] = "mesql"; /* this string is not used */
+    G_asprintf ( &buf, "--datadir=%s", datadir ); 
+    server_args[1] = buf;
+    /* With InnoDB it is very slow to close the database */
+    server_args[2] = "--skip-innodb"; /* OK? */
+    /* Without --bootstrap it complains about missing 
+     * mysql.time_zone_leap_second table */
+    server_args[3] = "--bootstrap"; /* OK? */
+
+    if ( mysql_server_init(4, server_args, NULL) )
+    {
+	append_error ( _("Cannot initialize MySQL embedded server") );
+        append_error ( mysql_error(connection) );
+	report_error ();
+	free ( datadir );
+	free ( database );
+	return DB_FAILED;
+    }
+
+    connection = mysql_init(NULL);
+    mysql_options ( connection, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
+
+    res = mysql_real_connect ( connection, NULL,NULL,NULL, database, 0,NULL,0);
+
+    free ( datadir );
+    free ( database );
+    
+    if ( res == NULL ) 
+    {
+	append_error ( _("Cannot connect to MySQL embedded server: ") );
+        append_error ( mysql_error(connection) );
+	report_error ();
+	return DB_FAILED;
+    }
+  }
+
+#endif
+
+    return DB_OK;
+}
+
+int db__driver_close_database()
+{
+    init_error();
+    mysql_close ( connection ); /* this will also release connection */
+
+#ifdef MESQL
+    mysql_server_end();
+#endif
+    
+    return DB_OK;
+}
+
+int replace_variables ( char *in, char **datadir, char **database )
+{
+    *datadir = NULL;
+    *database = NULL;
+
+    /* parse/replace variables in input string */
+    char tmp[2000];
+    char **tokens;
+    int no_tokens, n;
+
+    if ( !strchr(in,'/') ) /* no path */
+    {
+	*datadir = G_store ( "./" );
+	*database = G_store ( in );
+    } 
+    else
+    {
+	tokens = G_tokenize (in, "/");
+	no_tokens = G_number_of_tokens(tokens);
+    
+	G_debug(3, "no_tokens = %d", no_tokens );
+
+	tmp[0] = '\0';
+	for (n = 0; n < no_tokens-1 ; n++)
+	{
+	   if ( n > 0 )
+		strcat ( tmp, "/" );
+
+	   G_debug (3, "tokens[%d] = %s", n, tokens[n] );
+	   if ( tokens[n][0] == '$' )
+	   {
+	       G_strchg(tokens[n],'$', ' ' );
+	       G_chop(tokens[n]);
+	       strcat(tmp, G__getenv(tokens[n]) );
+	       G_debug (3, "   -> %s", G__getenv(tokens[n]) );
+	   }
+	   else
+	   {
+	       strcat (tmp, tokens[n]);
+	   }
+	}
+	*datadir = G_store ( tmp );
+	*database = G_store ( tokens[n] );
+
+	G_free_tokens ( tokens );
+    }
+
+    G_debug(2, "datadir = '%s'", *datadir );
+    G_debug(2, "database = '%s'", *database );
+
+    return 1;
+}
+

+ 40 - 0
db/drivers/mysql/dbdriver.h

@@ -0,0 +1,40 @@
+/* this file was automatically generated by ../mk_dbdriver_h.sh */
+#ifndef DBDRIVER_H
+#define	DBDRIVER_H
+
+#include "dbstubs.h"
+
+int db__driver_create_table();
+int db__driver_close_cursor();
+int db__driver_open_database();
+int db__driver_close_database();
+int db__driver_describe_table();
+int db__driver_init();
+int db__driver_finish();
+int db__driver_execute_immediate();
+int db__driver_begin_transaction();
+int db__driver_commit_transaction();
+int db__driver_fetch();
+int db__driver_get_num_rows();
+int db__driver_create_index();
+int db__driver_list_tables();
+int db__driver_open_select_cursor();
+#define	init_dbdriver() do{\
+db_driver_create_table = db__driver_create_table;\
+db_driver_close_cursor = db__driver_close_cursor;\
+db_driver_open_database = db__driver_open_database;\
+db_driver_close_database = db__driver_close_database;\
+db_driver_describe_table = db__driver_describe_table;\
+db_driver_init = db__driver_init;\
+db_driver_finish = db__driver_finish;\
+db_driver_execute_immediate = db__driver_execute_immediate;\
+db_driver_begin_transaction = db__driver_begin_transaction;\
+db_driver_commit_transaction = db__driver_commit_transaction;\
+db_driver_fetch = db__driver_fetch;\
+db_driver_get_num_rows = db__driver_get_num_rows;\
+db_driver_create_index = db__driver_create_index;\
+db_driver_list_tables = db__driver_list_tables;\
+db_driver_open_select_cursor = db__driver_open_select_cursor;\
+}while(0)
+
+#endif

+ 243 - 0
db/drivers/mysql/describe.c

@@ -0,0 +1,243 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+int db__driver_describe_table( dbString *table_name, dbTable **table)
+{
+    dbString sql;
+    MYSQL_RES *res;
+
+    db_init_string ( &sql );
+
+    db_set_string( &sql, "select * from ");
+    db_append_string ( &sql, db_get_string(table_name) );
+    db_append_string( &sql, " where 1 = 0");
+
+    if ( mysql_query ( connection, db_get_string(&sql) ) != 0 )
+    {
+	append_error ( db_get_string(&sql) );
+	append_error ( "\n" );
+	append_error ( mysql_error(connection) );
+	report_error();
+	return DB_FAILED;
+    }
+
+    res = mysql_store_result ( connection );
+
+    if ( res == NULL ) {
+	append_error ( db_get_string(&sql) );
+	append_error ( "\n" );
+	append_error ( mysql_error(connection) );
+	report_error();
+	return DB_FAILED;
+    }
+
+    if ( describe_table( res, table, NULL) == DB_FAILED ) {
+	append_error("Cannot describe table\n");
+	report_error();
+	mysql_free_result(res);
+	return DB_FAILED;
+    }
+
+    mysql_free_result(res);
+
+    db_set_table_name( *table, db_get_string(table_name) );
+
+    return DB_OK;
+}
+
+/* describe table, if c is not NULL cur->cols and cur->ncols is also set */
+int describe_table( MYSQL_RES *res, dbTable **table, cursor *c)
+{
+    int  i, ncols, kcols;
+    char *name;
+    int  sqltype, length;
+    dbColumn *column;
+    MYSQL_FIELD *fields;
+
+    G_debug (3, "describe_table()");
+
+    ncols = mysql_num_fields ( res );
+    fields = mysql_fetch_fields ( res );
+    
+    /* Count columns of known type */
+    kcols = 0;
+    for (i = 0; i < ncols; i++) {
+	field_info ( &(fields[i]), &sqltype, &length );
+
+	if ( sqltype == DB_SQL_TYPE_UNKNOWN ) continue;
+	    
+	kcols++; /* known types */
+    }
+
+    G_debug (3, "kcols = %d", kcols);
+
+    if (!(*table = db_alloc_table(kcols))) {
+	return DB_FAILED;
+    }
+
+    if ( c ) {
+	c->ncols = kcols;
+	c->cols = (int *) G_malloc ( kcols * sizeof(int) );
+    }
+
+    db_set_table_name ( *table, "" );
+    db_set_table_description ( *table, "" );
+
+    /* Currently not used in GRASS */
+    /*
+    db_set_table_delete_priv_granted (*table);
+    db_set_table_insert_priv_granted (*table);
+    db_set_table_delete_priv_not_granted (*table);
+    db_set_table_insert_priv_not_granted (*table);
+    */
+
+    kcols = 0;
+    for ( i = 0; i < ncols; i++ ) {
+	name = fields[i].name;
+	field_info ( &(fields[i]), &sqltype, &length );
+
+	G_debug(3, "col: %s, kcols %d, sqltype %d", 
+		    name, kcols, sqltype );
+
+	G_debug(3, "flags = %d", fields[i].flags ); 
+
+	if ( sqltype == DB_SQL_TYPE_UNKNOWN ) {
+	    /* Print warning and continue */
+	    G_warning ( _("MySQL driver: column '%s', type %d "
+			  "is not supported"), name, fields[i].type);
+	    continue;
+	}
+
+	if ( fields[i].type == MYSQL_TYPE_LONGLONG )
+	    G_warning ( _("column '%s' : type BIGINT is stored as "
+		"integer (4 bytes) some data may be damaged"), name);
+	
+	column = db_get_table_column(*table, kcols);
+
+	db_set_column_name(column, name);
+	db_set_column_length(column, length);
+	db_set_column_host_type(column, (int)fields[i].type);
+	db_set_column_sqltype(column, sqltype);
+
+        db_set_column_precision ( column, (int)fields[i].decimals );
+ 	db_set_column_scale ( column, 0 );
+
+	if ( !(fields[i].flags & NOT_NULL_FLAG ) )
+	{
+	    db_set_column_null_allowed(column);
+	}
+	db_set_column_has_undefined_default_value(column);
+	db_unset_column_use_default_value(column);
+
+	/* Currently not used in GRASS */
+	/*
+        db_set_column_select_priv_granted (column);
+        db_set_column_update_priv_granted (column);
+        db_set_column_update_priv_not_granted (column); 
+	*/
+
+	if ( c ) {
+	    c->cols[kcols] = i;
+	}
+
+	kcols++;
+    }
+
+    return DB_OK;
+}
+
+/* Get sqltype for field */
+void field_info ( MYSQL_FIELD *field, int * sqltype, int * length )
+{
+    *length = field->length;
+
+    switch ( field->type ) 
+    {
+	case MYSQL_TYPE_TINY:
+	    *sqltype = DB_SQL_TYPE_SMALLINT;
+	    break;
+
+	case MYSQL_TYPE_SHORT:
+	case MYSQL_TYPE_LONG:
+	case MYSQL_TYPE_INT24:
+	case MYSQL_TYPE_LONGLONG:
+	    *sqltype = DB_SQL_TYPE_INTEGER;
+	    break;
+
+	case MYSQL_TYPE_DECIMAL:
+	    *sqltype = DB_SQL_TYPE_DECIMAL;
+	    break;
+
+	case MYSQL_TYPE_FLOAT:
+	    *sqltype = DB_SQL_TYPE_REAL;
+	    break;
+
+	case MYSQL_TYPE_DOUBLE:
+	    *sqltype = DB_SQL_TYPE_DOUBLE_PRECISION;
+	    break;
+
+	case MYSQL_TYPE_TIMESTAMP: 
+	    *sqltype = DB_SQL_TYPE_TIMESTAMP;
+	    break;
+
+	case MYSQL_TYPE_DATE:
+	    *sqltype = DB_SQL_TYPE_DATE;
+	    break;
+
+	case MYSQL_TYPE_TIME:
+	    *sqltype = DB_SQL_TYPE_TIME;
+	    break;
+
+	case MYSQL_TYPE_DATETIME:
+	    //*sqltype = DB_SQL_TYPE_DATETIME;
+	    //*sqltype |= DB_DATETIME_MASK;
+	    *sqltype = DB_SQL_TYPE_TIMESTAMP;
+	    break;
+
+	case MYSQL_TYPE_YEAR:
+	    *sqltype = DB_SQL_TYPE_INTEGER;
+	    break;
+
+	case MYSQL_TYPE_STRING:
+	case MYSQL_TYPE_VAR_STRING:
+	case MYSQL_TYPE_SET:
+	case MYSQL_TYPE_ENUM:
+	    *sqltype = DB_SQL_TYPE_CHARACTER;
+	    break;
+	    
+	case MYSQL_TYPE_BLOB: 
+	    if ( field->flags & BINARY_FLAG  )
+	    {	
+		*sqltype = DB_SQL_TYPE_UNKNOWN;
+	    }
+	    else
+	    {
+	        *sqltype = DB_SQL_TYPE_TEXT;
+	    }
+	    break;
+
+	case MYSQL_TYPE_GEOMETRY:
+	case MYSQL_TYPE_NULL:
+	    *sqltype = DB_SQL_TYPE_UNKNOWN;
+	    break;
+
+	default:
+	    *sqltype = DB_SQL_TYPE_UNKNOWN;
+    }
+
+    return;
+}

+ 31 - 0
db/drivers/mysql/driver.c

@@ -0,0 +1,31 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdlib.h>
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_init  (int argc, char *argv[])
+
+{
+    init_error();
+    return DB_OK;
+}
+
+int
+db__driver_finish()
+{
+    return DB_OK;
+}

+ 45 - 0
db/drivers/mysql/error.c

@@ -0,0 +1,45 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdio.h>
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+/* init error message */
+void
+init_error ( void )
+{
+    if ( !errMsg ) {
+	errMsg = (dbString *) G_malloc(sizeof(dbString));
+        db_init_string (errMsg);
+    }
+
+    db_set_string ( errMsg, _("DBMI-MySQL driver error:\n") );
+}
+
+/* append error message */
+void
+append_error ( const char *msg )
+{
+    db_append_string ( errMsg, (char *)msg);
+}
+
+void
+report_error ( void )
+{
+    db_append_string ( errMsg, "\n");
+    db_error ( db_get_string (errMsg) );
+}
+

+ 90 - 0
db/drivers/mysql/execute.c

@@ -0,0 +1,90 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdlib.h>
+
+#include <grass/dbmi.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+int db__driver_execute_immediate(dbString *sql)
+{
+    char     *str;
+
+    init_error();
+
+    /* In addition to standard escape character ' (apostrophe) 
+     * MySQL supports also \ (backslash). Because this is not SQL
+     * standard, GRASS modules cannot escape all \ in the text
+     * because other drivers do not support this feature. 
+     * For example, if a text contains string \' GRASS modules 
+     * escape ' by another ' and the string passed to the driver is \''
+     * MySQL converts \' to ' but second ' remains not escaped and 
+     * result is error. 
+     * Because of this, all occurencies of \ in sql must be 
+     * escaped by \ */
+    str = G_str_replace ( db_get_string(sql), "\\", "\\\\" );
+
+    G_debug ( 3, "Escaped SQL: %s", str );
+
+    if ( mysql_query ( connection, str ) != 0 )
+    {
+	append_error( "Cannot execute: \n" );
+	append_error( str );
+	append_error( "\n" );
+	append_error ( mysql_error(connection) );
+	report_error();
+	if ( str ) 
+	    G_free ( str );
+	return DB_FAILED;
+    }
+    
+    if ( str ) 
+	G_free ( str );
+
+    return DB_OK;
+}
+
+int db__driver_begin_transaction(void)
+{
+    G_debug (2, "mysql: START TRANSACTION");
+
+    init_error();
+
+    if ( mysql_query ( connection, "START TRANSACTION" ) != 0 )
+    {
+	append_error( "Cannot start transaction: \n" );
+	append_error ( mysql_error(connection) );
+	report_error();
+	return DB_FAILED;
+    }
+
+    return DB_OK;
+}
+
+int db__driver_commit_transaction(void)
+{
+    G_debug (2, "mysql: COMMIT");
+
+    init_error();
+
+    if ( mysql_query ( connection, "COMMIT" ) != 0 )
+    {
+	append_error( "Cannot commit transaction: \n" );
+	append_error ( mysql_error(connection) );
+	report_error();
+	return DB_FAILED;
+    }
+
+    return DB_OK;
+}

+ 270 - 0
db/drivers/mysql/fetch.c

@@ -0,0 +1,270 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdlib.h>
+#include <string.h>
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h" 
+
+int
+db__driver_fetch(dbCursor *cn, int position, int *more)
+{
+    cursor     *c;
+    dbToken    token;    
+    dbTable    *table;
+    int        i;
+
+    /* get cursor token */
+    token = db_get_cursor_token(cn);
+
+    /* get the cursor by its token */
+    if (!(c = (cursor *) db_find_token(token))) {
+	append_error ( _("Cursor not found") );
+	report_error();
+	return DB_FAILED;
+    }
+
+    /* fetch on position */
+    switch (position)
+    { 
+	case DB_NEXT:
+	    c->row = mysql_fetch_row(c->res);
+	    break;
+	    
+	case DB_CURRENT:
+	    break;
+	    
+	case DB_PREVIOUS:
+	case DB_FIRST:
+	case DB_LAST:
+	default:
+	    append_error ( _("Cursor position is not supported "
+			     "by MySQL driver") );
+	    report_error();
+	    return DB_FAILED;
+    }
+
+    G_debug ( 3, "row = %d nrows = %d", c->row, c->nrows );
+    if ( c->row == NULL ) 
+    {
+	*more = 0;
+	return DB_OK;
+    }
+
+    *more = 1;
+
+    /* get the data out of the descriptor into the table */
+    table = db_get_cursor_table(cn);
+
+    for (i = 0; i < c->ncols; i++) 
+    {
+	int col, sqltype, mysqltype;
+	dbColumn   *column;
+	dbValue    *value;
+	char *val;
+
+	col = c->cols[i]; /* known column */
+ 		
+	column = db_get_table_column (table, i);
+	mysqltype  = db_get_column_host_type(column);
+	sqltype = db_get_column_sqltype(column);
+
+	value  = db_get_column_value (column);
+	db_zero_string (&value->s);
+	value->t.year = 0;
+	value->t.month = 0;
+	value->t.day = 0;
+	value->t.hour = 0;
+	value->t.minute = 0;
+	value->t.seconds = 0.0;
+	
+	val = c->row[i];
+	if ( !val ) {
+	    value->isNull = 1;
+	    continue;
+	} else {
+	    value->isNull = 0;
+	}
+
+	G_debug (3, "col %d, mysqltype %d, sqltype %d, val = '%s'", 
+		    col, mysqltype, sqltype, c->row[col] );
+
+	/* defined in /usr/include/mysql/mysql_com.h */	
+	switch (mysqltype) 
+	{
+	    int ns;
+
+	    case MYSQL_TYPE_TINY:
+	    case MYSQL_TYPE_SHORT:
+	    case MYSQL_TYPE_LONG:
+	    case MYSQL_TYPE_INT24:
+	    case MYSQL_TYPE_LONGLONG:
+            case MYSQL_TYPE_YEAR:
+	    	value->i = atoi ( val );
+		break;
+
+	    case MYSQL_TYPE_FLOAT:
+	    case MYSQL_TYPE_DOUBLE:
+	    	value->d = atof ( val );
+		break;
+
+	    /* MySQL TIMESTAMP < 4.1: YYYYMMDDHHMMSS TIMESTAMP(14)
+	     *                        YYMMDDHHMMSS   TIMESTAMP(12)
+	     *                        YYMMDDHHMM     TIMESTAMP(10)
+	     *                        YYYYMMDD       TIMESTAMP(8)
+	     *                        YYMMDD         TIMESTAMP(6)
+	     *                        YYMM           TIMESTAMP(4)
+	     * 			      YY             YY
+	     * MySQL TIMESTAMP >= 4.1: 'YYYY-MM-DD HH:MM:SS' (19 chars) */
+	    case MYSQL_TYPE_TIMESTAMP:
+	    {
+		char valbuf[25], buf[10];
+	        memset ( valbuf, 0, 25 );	
+		strcpy ( valbuf, val );
+
+		switch ( strlen(val) ) 
+		{
+		    case 2: 
+		    case 4: 
+		    case 6: 
+		    case 10: 
+		    case 12: 
+		        strncpy ( buf, val, 2 ); buf[2] = 0;
+			value->t.year = atoi ( buf );
+		        strncpy ( buf, val+2, 2 ); buf[2] = 0;
+			value->t.month = atoi ( buf );
+		        strncpy ( buf, val+4, 2 ); buf[2] = 0;
+			value->t.day = atoi ( buf );
+		        strncpy ( buf, val+6, 2 ); buf[2] = 0;
+			value->t.hour = atoi ( buf );
+		        strncpy ( buf, val+8, 2 ); buf[2] = 0;
+			value->t.minute = atoi ( buf );
+		        strncpy ( buf, val+10, 2 ); buf[2] = 0;
+			value->t.seconds = atof ( buf );
+			break;
+
+		    case 8:
+		    case 14:
+		        strncpy ( buf, val, 4 ); buf[4] = 0;
+			value->t.year = atoi ( buf );
+		        strncpy ( buf, val+4, 2 ); buf[2] = 0;
+			value->t.month = atoi ( buf );
+		        strncpy ( buf, val+6, 2 ); buf[2] = 0;
+			value->t.day = atoi ( buf );
+		        strncpy ( buf, val+8, 2 ); buf[2] = 0;
+			value->t.hour = atoi ( buf );
+		        strncpy ( buf, val+10, 2 ); buf[2] = 0;
+			value->t.minute = atoi ( buf );
+		        strncpy ( buf, val+12, 2 ); buf[2] = 0;
+			value->t.seconds = atof ( buf );
+			break;
+
+		    case 19:
+		        ns = sscanf( val, "%4d-%2d-%2d %2d:%2d:%lf",
+			     &(value->t.year), &(value->t.month), 
+			     &(value->t.day), &(value->t.hour), 
+			     &(value->t.minute), &(value->t.seconds) );
+
+			if ( ns != 6 ) {
+			    append_error ( _("Cannot scan timestamp: ") );
+			    append_error ( val );
+			    report_error();
+			    return DB_FAILED;
+			}
+			break;
+
+		    default:
+			append_error ( _("Unknown timestamp format: ") );
+			append_error ( val );
+			report_error();
+			return DB_FAILED;
+		}
+	    }
+		break;
+
+	    /* MySQL DATE: 'YYYY-MM-DD' */
+	    case MYSQL_TYPE_DATE:
+		ns = sscanf( val, "%4d-%2d-%2d", &(value->t.year), 
+			     &(value->t.month), &(value->t.day) ); 
+
+		if ( ns != 3 ) {
+		    append_error ( _("Cannot scan date: ") );
+		    append_error ( val );
+		    report_error();
+		    return DB_FAILED;
+		}
+		break;
+			
+	    /* MySQL DATETIME: 'HH:MM:SS' */
+	    case MYSQL_TYPE_TIME:
+		ns = sscanf( val, "%2d:%2d:%lf", &(value->t.hour), 
+			     &(value->t.minute), &(value->t.seconds) );
+
+		if ( ns != 3 ) {
+		    append_error ( _("Cannot scan time: ") );
+		    append_error ( val );
+		    report_error();
+		    return DB_FAILED;
+		}
+		break;
+
+	    /* MySQL DATETIME: 'YYYY-MM-DD HH:MM:SS' */
+	    case MYSQL_TYPE_DATETIME:
+		ns = sscanf( val, "%4d-%2d-%2d %2d:%2d:%lf",
+			     &(value->t.year), &(value->t.month), 
+			     &(value->t.day), &(value->t.hour), 
+			     &(value->t.minute), &(value->t.seconds) );
+
+		if ( ns != 6 ) {
+		    append_error ( _("Cannot scan datetime: ") );
+		    append_error ( val );
+		    report_error();
+		    return DB_FAILED;
+		}
+		break;
+
+	    case MYSQL_TYPE_STRING:
+	    case MYSQL_TYPE_VAR_STRING:
+	    case MYSQL_TYPE_SET:
+	    case MYSQL_TYPE_ENUM:
+	    case MYSQL_TYPE_BLOB:
+		db_set_string ( &(value->s),  val );
+		break;
+	}
+    }
+    G_debug (3, "Row fetched" );
+    return DB_OK;
+}
+
+int
+db__driver_get_num_rows (cn )
+            dbCursor *cn;
+{
+    cursor     *c;
+    dbToken    token;
+
+    /* get cursor token */
+    token = db_get_cursor_token(cn);
+
+    /* get the cursor by its token */
+    if (!(c = (cursor *) db_find_token(token))) {
+       append_error("Cursor not found");
+       report_error();
+       return DB_FAILED;
+    }
+
+    return ( c->nrows );
+}
+

+ 27 - 0
db/drivers/mysql/globals.h

@@ -0,0 +1,27 @@
+#include "mysql.h"
+
+/* cursors */
+typedef struct _cursor {
+    MYSQL_RES *res;
+    int nrows;             /* number of rows in query result */
+    MYSQL_ROW row;
+    dbToken token;
+    int type;              /* type of cursor: SELECT, UPDATE, INSERT */
+    int *cols;             /* indexes of known (type) columns */ 
+    int ncols;             /* number of known columns */
+} cursor;  
+
+typedef struct {
+    char *host, *dbname, *user, *password;
+    unsigned int port;
+} CONNPAR;
+
+#ifdef MAIN
+    MYSQL *connection; /* Database connection */
+    dbString *errMsg = NULL; /* error message */
+#else
+    extern MYSQL *connection; 
+    extern dbString *errMsg;
+#endif 
+
+

+ 74 - 0
db/drivers/mysql/grass-mesql.html

@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>GRASS-MySQL embedded driver</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="grassdocs.css" type="text/css">
+</head>
+<body bgcolor="white">
+
+<img src="grass_logo.png" alt="GRASS logo"><hr align=center size=6 noshade>
+    
+<h1>MySQL embedded driver in GRASS</h1>
+
+MySQL database driver in GRASS enables GRASS to store vector
+attributes in MySQL embedded database without necessity 
+to run MySQL server.
+<p>
+
+<h2>Driver and database name</h2>
+GRASS modules require 2 parameters to connect to a database.
+Those parameters are 'driver' and 'database'. For MySQL embedded 
+driver the parameter 'driver' should be set to value 'mesql'.
+The parameter 'database' is a full path to the directory 
+where database tables are stored. The best place is 
+a directory in the mapset. The directory must be created 
+before use of the driver. In the name of database 
+it is possible to use 3 variables:
+<ul>
+  <li> $GISDBASE - path to current GISBASE
+  <li> $LOCATION_NAME - name of current location
+  <li> $MAPSET - name of current mapset
+</ul>
+
+<p>
+Examples of connection parameters:
+<pre>
+  db.connect driver=mesql database='$GISDBASE/$LOCATION_NAME/$MAPSET/mysql'
+  db.connect driver=mesql database=/home/user1/db
+</pre>
+
+<h2>Data types, indexes</h2>
+For more informations about supported data types and indexes
+see the documentation for 
+<a href="grass-mysql.html">MySQL (mysql) driver</a>
+
+<h2>Database type</h2>
+Because database closing was found very slow if InnoDB was used,
+the InnoDB storage is disabled by default (hardcoded 
+'--skip-innodb' server option).
+
+<h2>Note</h2>
+The embedded server is started with hardcoded '--bootstrap'
+option to avoid warning about missing 
+mysql.time_zone_leap_second table. This can be fixed in future.
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="db.connect.html">db.connect</a>,
+<a HREF="sql.html">SQL support in GRASS GIS</a></em>
+
+<h2>Credits</h2>
+Development of the driver was sponsored by
+<a href="http://www.faunalia.it">Faunalia</a> (Italy)
+as part of a project for <a href="http://www.atac.roma.it/">ATAC</a>.
+
+<H2>AUTHOR</H2>
+Radim Blazek
+
+<p><i>Last changed: $Date$</i>
+<HR>
+<BR><a href=index.html>Help Index</a>
+</body>
+</html>

+ 125 - 0
db/drivers/mysql/grass-mysql.html

@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>GRASS-MySQL driver</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="grassdocs.css" type="text/css">
+</head>
+<body bgcolor="white">
+
+<img src="grass_logo.png" alt="GRASS logo"><hr align=center size=6 noshade>
+    
+<h1>MySQL driver in GRASS</h1>
+
+MySQL database driver in GRASS enables GRASS to store vector
+attributes in MySQL server.
+<p>
+Because vector attribute tables 
+are created automaticaly when a new vector is written and the 
+name of the table is the same as the name of the vector it is 
+good practice to create a new database for each GRASS mapset.
+
+<H2>Creating a MySQL database</H2>
+
+A new database is created within MySQL:
+
+<div class="code"><pre>
+mysql> CREATE DATABASE mydb;
+</pre></div>
+
+See the MySQL manual for details.
+
+<h2>Driver and database name</h2>
+GRASS modules require 2 parameters to connect to a database.
+Those parameters are 'driver' and 'database'. For MySQL driver 
+the parameter 'driver' should be set to value 'mysql'.
+The parameter 'database' can be given in two formats:
+
+<ul>
+    <li> Database name - in case of connection from localhost
+    <li> String of comma separated list of kye=value options. 
+         Supported options are:
+	 <ul>
+	     <li> dbname - database name
+	     <li> host - host name or IP address
+	     <li> port - server port number 
+	 </ul>
+</ul>
+Examples of connection parameters:
+<pre>
+  db.connect driver=mysql database=mytest
+  db.connect driver=mysql database='dbname=mytest,host=test.grass.org'
+</pre>
+
+<h2>Data types</h2>
+GRASS supports almost all MySQL data types with following limitations:
+<ul>
+    <li> Binary columns (BINARY, VARBINARY, TINYBLOB, MEDIUMBLOB,
+    BLOB, LONGBLOB) are not not supported. 
+    If a table with binary column(s) is used in GRASS
+    a warning is printed and only the supported columns are 
+    returned in query results.
+
+    <li> Columns of type SET and ENUM are represented as string (VARCHAR). 
+
+    <li> Very large integers in columns of type BIGINT can be lost 
+    or corrupted because GRASS does not support 64 bin integeres
+    on most platforms. 
+
+    <li> GRASS does not currently distinguish types TIMESTAMP and 
+    DATETIME. Both types are in GRASS interpreted as TIMESTAMP.
+</ul>
+
+<h2>Indexes</h2>
+GRASS modules automaticaly create index on key column of vector
+attributes table. The index on key column is important 
+for performance of modules which update the attribute table,
+for example v.to.db, v.distance and v.what.rast.
+
+<h2>Privileges</h2>
+Because MySQL does not support groups of users and because 
+only MySQL 'root' can grant privileges to other users
+GRASS cannot automaticaly grant select privileges on created
+tables to group of users.
+<p>
+If you want to give privilege to read data from your mapset 
+to other users you have to ask your MySQL server administrator
+to grant select privilege to them on the MySQL database used 
+for that mapset. For example, to allow  everybody to read data 
+in from your database 'mydb':<br>
+<pre>
+shell&gt; mysql --user=root mysql
+mysql&gt; GRANT SELECT ON mydb.* TO ''@'%';
+</pre>
+
+<h2>Schemas</h2>
+Because MySQL does not support database schemas the parameter 
+'schema' of module db.connect should never be set to any
+value. If you set that parameter for MySQL driver GRASS will 
+try to write tables to the specified schema which will result 
+in errors.
+
+<h2>Groups</h2>
+MySQL does not support user groups. Any settings specified 
+by 'group' parameter of module db.connect are ignored by
+GRASS for MySQL driver.
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="db.connect.html">db.connect</a>,
+<a HREF="sql.html">SQL support in GRASS GIS</a></em>
+	
+<h2>Credits</h2>
+Development of the driver was sponsored by 
+<a href="http://www.faunalia.it">Faunalia</a> (Italy)
+as part of a project for <a href="http://www.atac.roma.it/">ATAC</a>.
+
+<H2>AUTHOR</H2>
+Radim Blazek
+
+<p><i>Last changed: $Date$</i>
+<HR>
+<BR><a href=index.html>Help Index</a>
+</body>
+</html>

+ 68 - 0
db/drivers/mysql/index.c

@@ -0,0 +1,68 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+int
+db__driver_create_index ( dbIndex *index )
+{
+    int i, ncols;
+    dbString sql;
+    
+    G_debug (3, "db__create_index()");
+
+    db_init_string (&sql);
+    init_error();
+
+    ncols = db_get_index_number_of_columns ( index );
+
+    db_set_string ( &sql, "CREATE" );
+    if ( db_test_index_type_unique(index) ) 
+	db_append_string ( &sql, " UNIQUE" );
+
+    db_append_string ( &sql, " INDEX " );
+    db_append_string ( &sql, db_get_index_name(index) );
+    db_append_string ( &sql, " ON " );
+    
+    db_append_string ( &sql, db_get_index_table_name(index) );
+    
+    db_append_string ( &sql, " ( " );
+
+    for ( i = 0; i < ncols; i++ ) {
+	if ( i > 0 )
+            db_append_string ( &sql, ", " );
+	
+        db_append_string ( &sql, db_get_index_column_name(index,i) );
+    }
+    
+    db_append_string ( &sql, " )" );
+
+    G_debug (3, " SQL: %s", db_get_string(&sql) );
+    
+    if ( mysql_query ( connection, db_get_string(&sql) ) != 0 )
+    {
+        append_error( "Cannot create index:\n");
+	append_error( db_get_string(&sql) );
+	append_error( "\n" );
+	append_error ( mysql_error(connection) );
+	report_error();
+	db_free_string ( &sql);
+	return DB_FAILED;
+    }
+    
+    db_free_string ( &sql);
+    
+    return DB_OK;
+}

+ 59 - 0
db/drivers/mysql/listtab.c

@@ -0,0 +1,59 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdlib.h>
+#include <string.h>
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+int db__driver_list_tables(dbString **tlist, int *tcount,
+                            int system)
+{
+    int i;
+    dbString *list;
+    int nrows;
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+
+    *tlist = NULL;
+    *tcount = 0;
+
+    res = mysql_list_tables ( connection, NULL );
+    
+    if ( res  == NULL ) 
+    {
+	append_error ( _("Cannot get list of tables:\n") );
+	append_error ( mysql_error(connection) );
+	report_error();
+	return DB_FAILED;
+    }
+    mysql_store_result ( connection );
+
+    nrows = (int) mysql_num_rows ( res );
+    list = db_alloc_string_array ( nrows );
+
+    i = 0;
+    while ( (row = mysql_fetch_row(res)) != NULL )
+    {
+	db_set_string ( &list[i], row[0] );
+	i++;
+    }
+
+    mysql_free_result ( res );
+
+    *tlist = list;
+    *tcount = nrows;
+    return DB_OK;
+}

+ 24 - 0
db/drivers/mysql/main.c

@@ -0,0 +1,24 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdlib.h>
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include "dbdriver.h"
+
+#define MAIN
+#include "globals.h"
+
+int main(int argc, char *argv[])
+{
+	init_dbdriver();
+	exit(db_driver(argc, argv));
+}

+ 94 - 0
db/drivers/mysql/parse.c

@@ -0,0 +1,94 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdlib.h>
+#include <string.h>
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+/*
+* \brief Parse connection string in form:
+*    1) 'database_name'
+*    2) 'host=xx,port=xx,dbname=xx'
+*  \return DB_OK Success
+*  \return DB_FAILED Failed to parse database
+*/
+int parse_conn ( char *str, CONNPAR *conn )
+{
+    int  i;
+    char **tokens, delm[2];
+
+    G_debug (3, "parse_conn : %s", str ); 
+    
+    /* reset */
+    conn->host 	   = NULL;
+    conn->port 	   = 0;
+    conn->dbname   = NULL;
+    conn->user 	   = NULL;
+    conn->password = NULL;
+    
+    if ( strchr(str, '=') == NULL ) { /*db name only */
+	conn->dbname = G_store ( str );
+    } else {
+	delm[0] = ','; delm[1] = '\0';
+        tokens = G_tokenize ( str, delm );
+	i = 0;
+	while ( tokens[i] ) {
+	   G_debug (3, "token %d : %s", i, tokens[i] ); 
+	   if ( strncmp(tokens[i], "host", 4 ) == 0 )
+	   {
+	       conn->host = G_store ( tokens[i] + 5 );
+	   }
+	   else if ( strncmp(tokens[i], "port", 4 ) == 0 )
+	   {
+	       long port = atol( tokens[i] + 5 );
+	       if ( port <= 0 )
+	       { 
+	           append_error ( _("Wrong port number in MySQL database "
+			            "definition: ") );
+		   append_error ( tokens[i] + 5 );
+		   return DB_FAILED;
+	       }
+	       conn->port = (unsigned int)port;
+	   }
+	   else if ( strncmp(tokens[i], "dbname", 6 ) == 0 )
+	   {
+	       conn->dbname = G_store ( tokens[i] + 7 );
+	   }
+	   else if ( strncmp(tokens[i], "user", 4 ) == 0 )
+	   {
+	       G_warning ( _("'user' in database definition "
+			     "is not supported, use db.login") );
+	   }
+	   else if ( strncmp(tokens[i], "password", 8 ) == 0 )
+	   {
+	       G_warning ( _("'password' in database definition "
+			     "is not supported, use db.login") );
+	   }
+	   else 
+	   {
+	       append_error ( _("Unknown option in database definition for ") );
+	       append_error ( "MySQL: " );
+	       append_error ( tokens[i] );
+	       return DB_FAILED;
+	   }
+	   i++;
+	}
+	G_free_tokens ( tokens );	
+    }
+
+    return DB_OK;
+}
+

+ 15 - 0
db/drivers/mysql/proto.h

@@ -0,0 +1,15 @@
+/* error.c */
+void init_error ( void );
+void append_error ( const char * );
+void report_error ( void );
+
+/* cursor.c */
+cursor * alloc_cursor ();
+void free_cursor ( cursor * );
+
+/* describe.c*/
+int describe_table( MYSQL_RES *, dbTable **, cursor * );
+void field_info ( MYSQL_FIELD *, int *, int * );
+
+/* parse.c */
+int parse_conn ( char *, CONNPAR *);

+ 80 - 0
db/drivers/mysql/select.c

@@ -0,0 +1,80 @@
+/**********************************************************
+ * MODULE:    mysql
+ * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com)
+ * PURPOSE:   MySQL database driver
+ * COPYRIGHT: (C) 2001 by the GRASS Development Team
+ *            This program is free software under the 
+ *            GNU General Public License (>=v2). 
+ *            Read the file COPYING that comes with GRASS
+ *            for details.
+ **********************************************************/
+#include <stdlib.h>
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+int db__driver_open_select_cursor (dbString *sel, dbCursor *dbc, int mode)
+
+{
+    cursor   *c;
+    dbTable  *table;
+    char     *str;
+
+    init_error();
+
+    /* allocate cursor */
+    c = alloc_cursor();
+    if (c == NULL)
+	return DB_FAILED;
+
+    db_set_cursor_mode(dbc, mode);
+    db_set_cursor_type_readonly(dbc);
+
+    /* \ must be escaped, see explanation in 
+     * db_driver_execute_immediate() */
+    str = G_str_replace ( db_get_string(sel), "\\", "\\\\" );
+    G_debug ( 3, "Escaped SQL: %s", str );
+
+    if ( mysql_query ( connection, str ) != 0 )
+    {
+	append_error(_("Cannot select data: \n"));
+	append_error ( db_get_string(sel) );
+	append_error ( "\n" );
+	append_error ( mysql_error(connection) );
+        if ( str ) G_free ( str );
+	report_error();
+	return DB_FAILED;
+    }
+
+    if ( str ) G_free ( str );
+    c->res = mysql_store_result ( connection );
+
+    if ( c->res == NULL ) {
+	append_error ( db_get_string(sel) );
+	append_error ( "\n" );
+	append_error ( mysql_error(connection) );
+	report_error();
+	return DB_FAILED;
+    }
+
+    if ( describe_table( c->res, &table, c) == DB_FAILED ) {
+	append_error("Cannot describe table\n");
+	report_error();
+	mysql_free_result(c->res);
+	return DB_FAILED;
+    }
+
+    c->nrows = (int) mysql_num_rows ( c->res );
+
+    /* record table with dbCursor */
+    db_set_cursor_table(dbc, table);
+
+    /* set dbCursor's token for my cursor */
+    db_set_cursor_token(dbc, c->token);
+
+    return DB_OK;
+}

+ 0 - 0
db/drivers/odbc/INSTALL


Some files were not shown because too many files changed in this diff