OSDN Git Service

Reimplement create and drop scripts in C, to reduce repetitive
authorPeter Eisentraut <peter_e@gmx.net>
Tue, 18 Mar 2003 22:19:47 +0000 (22:19 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Tue, 18 Mar 2003 22:19:47 +0000 (22:19 +0000)
connections, increase robustness, add NLS, and prepare for Windows port.
(vacuumdb and clusterdb will follow later.)

23 files changed:
doc/src/sgml/manage-ag.sgml
doc/src/sgml/ref/createdb.sgml
doc/src/sgml/ref/createlang.sgml
doc/src/sgml/ref/createuser.sgml
doc/src/sgml/ref/dropdb.sgml
doc/src/sgml/ref/droplang.sgml
doc/src/sgml/ref/dropuser.sgml
src/bin/scripts/Makefile
src/bin/scripts/common.c [new file with mode: 0644]
src/bin/scripts/common.h [new file with mode: 0644]
src/bin/scripts/createdb [deleted file]
src/bin/scripts/createdb.c [new file with mode: 0644]
src/bin/scripts/createlang.c [new file with mode: 0644]
src/bin/scripts/createlang.sh [deleted file]
src/bin/scripts/createuser [deleted file]
src/bin/scripts/createuser.c [new file with mode: 0644]
src/bin/scripts/dropdb [deleted file]
src/bin/scripts/dropdb.c [new file with mode: 0644]
src/bin/scripts/droplang [deleted file]
src/bin/scripts/droplang.c [new file with mode: 0644]
src/bin/scripts/dropuser [deleted file]
src/bin/scripts/dropuser.c [new file with mode: 0644]
src/bin/scripts/nls.mk [new file with mode: 0644]

index bb73233..783aee1 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/manage-ag.sgml,v 2.25 2003/03/13 01:30:29 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/manage-ag.sgml,v 2.26 2003/03/18 22:19:46 petere Exp $
 -->
 
 <chapter id="managing-databases">
@@ -120,8 +120,8 @@ createdb <replaceable class="parameter">dbname</replaceable>
 
    <command>createdb</> does no magic. It connects to the <literal>template1</>
    database and issues the <command>CREATE DATABASE</> command,
-   exactly as described above. It uses the <command>psql</> program
-   internally. The reference page on <command>createdb</> contains the invocation
+   exactly as described above.
+   The reference page on <command>createdb</> contains the invocation
    details. Note that <command>createdb</> without any arguments will create
    a database with the current user name, which may or may not be what
    you want.
index e6256cc..43c7046 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/createdb.sgml,v 1.30 2002/10/11 23:03:48 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/createdb.sgml,v 1.31 2003/03/18 22:19:46 petere Exp $
 PostgreSQL documentation
 -->
 
@@ -42,16 +42,13 @@ PostgreSQL documentation
   </para>
 
   <para>
-   <application>createdb</application> is a shell script wrapper around the
-   <acronym>SQL</acronym> command
-   <xref linkend="SQL-CREATEDATABASE" endterm="SQL-CREATEDATABASE-title"> via
-   the <productname>PostgreSQL</productname> interactive terminal
-   <xref linkend="APP-PSQL">. Thus, there is nothing
-   special about creating databases via this or other methods. This means
-   that the <application>psql</application> program must be found by the script and that
-   a database server must be running at the targeted port. Also, any default
-   settings and environment variables available to <application>psql</application>
-   and the <application>libpq</application> front-end library will apply.
+   <application>createdb</application> is a wrapper around the
+   <acronym>SQL</acronym> command <xref linkend="SQL-CREATEDATABASE"
+   endterm="SQL-CREATEDATABASE-title">.  Thus, there is nothing
+   special about creating databases via this or other methods.  This
+   means that a database server must be running at the targeted
+   port. Also, any default settings and environment variables used by
+   the <application>libpq</application> front-end library will apply.
   </para>
  </refsect1>
 
@@ -245,7 +242,7 @@ PostgreSQL documentation
    <para>
     If there is an error condition, the backend error message will be displayed.
     See <xref linkend="SQL-CREATEDATABASE" endterm="SQL-CREATEDATABASE-TITLE">
-    and <xref linkend="APP-PSQL"> for possibilities.
+    for possibilities.
    </para>
  </refsect1>
 
index 507d9d1..72f82b7 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/createlang.sgml,v 1.29 2003/02/13 05:37:43 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/createlang.sgml,v 1.30 2003/03/18 22:19:46 petere Exp $
 PostgreSQL documentation
 -->
 
@@ -197,8 +197,7 @@ PostgreSQL documentation
     Most error messages are self-explanatory. If not, run
     <application>createlang</application> with the <option>--echo</option>
     option and see under the respective <acronym>SQL</acronym> command
-    for details. Check also under <xref linkend="APP-PSQL">
-    for more possibilities.
+    for details.
    </para>
  </refsect1>
 
@@ -209,13 +208,6 @@ PostgreSQL documentation
   <para>
    Use <xref linkend="app-droplang"> to remove a language.
   </para>
-
-  <para>
-   <application>createlang</application> is a shell script that invokes
-   <application>psql</application> several times.  If you have things
-   arranged so that a password prompt is required to connect, you will be
-   prompted for a password several times.
-  </para>
  </refsect1>
  
 
index 4825d27..faaaa68 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/createuser.sgml,v 1.30 2003/02/13 05:37:43 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/createuser.sgml,v 1.31 2003/03/18 22:19:46 petere Exp $
 PostgreSQL documentation
 -->
 
@@ -43,17 +43,13 @@ PostgreSQL documentation
   </para>
 
   <para>
-   <application>createuser</application> is a shell script wrapper around the
-   <acronym>SQL</acronym> command
-   <xref linkend="SQL-CREATEUSER" endterm="SQL-CREATEUSER-title"> via
-   the <productname>PostgreSQL</productname> interactive terminal
-   <xref linkend="APP-PSQL">. Thus, there is nothing
-   special about creating users via this or other methods. This means
-   that the <application>psql</application> application must be found by the
-   script and that 
-   a database server must be running at the targeted host. Also, any default
-   settings and environment variables used by <application>psql</application>
-   and the <application>libpq</application> front-end library will apply.
+   <application>createuser</application> is a wrapper around the
+   <acronym>SQL</acronym> command <xref linkend="SQL-CREATEUSER"
+   endterm="SQL-CREATEUSER-title">.  Thus, there is nothing special
+   about creating users via this or other methods. This means that a
+   database server must be running at the targeted host. Also, any
+   default settings and environment variables used by the
+   <application>libpq</application> front-end library will apply.
   </para>
 
  </refsect1>
@@ -293,7 +289,7 @@ PostgreSQL documentation
    <para>
     If there is an error condition, the backend error message will be displayed.
     See <xref linkend="SQL-CREATEUSER" endterm="SQL-CREATEUSER-title">
-    and <xref linkend="APP-PSQL"> for possibilities.
+    for possibilities.
    </para>
  </refsect1>
 
index 191f5e5..302d512 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/dropdb.sgml,v 1.19 2002/10/11 23:03:48 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/dropdb.sgml,v 1.20 2003/03/18 22:19:46 petere Exp $
 PostgreSQL documentation
 -->
 
@@ -35,16 +35,13 @@ PostgreSQL documentation
   </para>
 
   <para>
-   <application>dropdb</application> is a shell script wrapper around the
-   <acronym>SQL</acronym> command
-   <xref linkend="SQL-DROPDATABASE" endterm="SQL-DROPDATABASE-title"> via
-   the <productname>PostgreSQL</productname> interactive terminal
-   <xref linkend="APP-PSQL">. Thus, there is nothing
-   special about dropping databases via this or other methods. This means
-   that the <application>psql</application> must be found by the script and that
-   a database server is running at the targeted host. Also, any default
-   settings and environment variables available to <application>psql</application>
-   and the <application>libpq</application> front-end library do apply.
+   <application>dropdb</application> is a wrapper around the
+   <acronym>SQL</acronym> command <xref linkend="SQL-DROPDATABASE"
+   endterm="SQL-DROPDATABASE-title">.  Thus, there is nothing special
+   about dropping databases via this or other methods. This means that
+   a database server is running at the targeted host. Also, any
+   default settings and environment variables used by the
+   <application>libpq</application> front-end library do apply.
   </para>
  </refsect1>
 
@@ -176,7 +173,7 @@ PostgreSQL documentation
    <para>
     If there is an error condition, the backend error message will be displayed.
     See <xref linkend="SQL-DROPDATABASE" endterm="SQL-DROPDATABASE-title">
-    and <xref linkend="APP-PSQL"> for possibilities.
+    for possibilities.
    </para>
  </refsect1>
 
index 7b4b7f3..a716352 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/droplang.sgml,v 1.21 2002/09/21 18:32:54 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/droplang.sgml,v 1.22 2003/03/18 22:19:46 petere Exp $
 PostgreSQL documentation
 -->
 
@@ -186,8 +186,7 @@ PostgreSQL documentation
     Most error messages are self-explanatory. If not, run
     <application>droplang</application> with the <option>--echo</option>
     option and see under the respective <acronym>SQL</acronym> command
-    for details. Check also under <xref linkend="APP-PSQL">
-    for more possibilities.
+    for details.
    </para>
  </refsect1>
 
index 0348931..53e371c 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/dropuser.sgml,v 1.22 2002/10/11 23:03:48 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/dropuser.sgml,v 1.23 2003/03/18 22:19:46 petere Exp $
 PostgreSQL documentation
 -->
 
@@ -37,16 +37,14 @@ PostgreSQL documentation
   </para>
 
   <para>
-   <application>dropuser</application> is a shell script wrapper around the
-   <acronym>SQL</acronym> command
-   <xref linkend="SQL-DROPUSER" endterm="SQL-DROPUSER-title"> via
-   the <productname>PostgreSQL</productname> interactive terminal
-   <xref linkend="APP-PSQL">. Thus, there is nothing
-   special about removing users via this or other methods. This means
-   that the <application>psql</application> must be found by the script and that
-   a database server is running at the targeted host. Also, any default
-   settings and environment variables available to <application>psql</application>
-   and the <application>libpq</application> front-end library do apply.
+   <application>dropuser</application> is a shell script wrapper
+   around the <acronym>SQL</acronym> command <xref
+   linkend="SQL-DROPUSER" endterm="SQL-DROPUSER-title">.  Thus, there
+   is nothing special about removing users via this or other
+   methods. This means that a database server is running at the
+   targeted host. Also, any default settings and environment variables
+   used by the <application>libpq</application> front-end library do
+   apply.
   </para>
  </refsect1>
 
index 7c18b7d..e46b6bd 100644 (file)
@@ -5,7 +5,7 @@
 # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $Header: /cvsroot/pgsql/src/bin/scripts/Makefile,v 1.18 2002/10/18 19:35:28 tgl Exp $
+# $Header: /cvsroot/pgsql/src/bin/scripts/Makefile,v 1.19 2003/03/18 22:19:46 petere Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -13,28 +13,56 @@ subdir = src/bin/scripts
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
-SCRIPTS := createdb dropdb createuser dropuser createlang droplang vacuumdb \
-           clusterdb
+SCRIPTS := vacuumdb clusterdb
+PROGRAMS = createdb createlang createuser dropdb droplang dropuser
 
-all: $(SCRIPTS)
+override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
+
+
+all: submake-libpq submake-backend $(PROGRAMS)
+
+%: %.o
+       $(CC) $(CFLAGS) $^ $(libpq) $(LDFLAGS) $(LIBS) -o $@
+
+createdb: createdb.o common.o dumputils.o sprompt.o $(top_builddir)/src/backend/parser/keywords.o
+createlang: createlang.o common.o sprompt.o print.o mbprint.o
+createuser: createuser.o common.o dumputils.o sprompt.o $(top_builddir)/src/backend/parser/keywords.o
+dropdb: dropdb.o common.o dumputils.o sprompt.o $(top_builddir)/src/backend/parser/keywords.o
+droplang: droplang.o common.o sprompt.o print.o mbprint.o
+dropuser: dropuser.o common.o dumputils.o sprompt.o $(top_builddir)/src/backend/parser/keywords.o
+
+createdb.o createuser.o dropdb.o dropuser.o dumputils.o: dumputils.h
+
+createlang.o droplang.o: print.h
+print.o: print.h mbprint.h
+
+dumputils.c dumputils.h sprompt.c : % : $(top_srcdir)/src/bin/pg_dump/%
+       rm -f $@ && $(LN_S) $< .
+
+print.c print.h mbprint.c mbprint.h : % : $(top_srcdir)/src/bin/psql/%
+       rm -f $@ && $(LN_S) $< .
+
+.PHONY: submake-backend
+submake-backend:
+       $(MAKE) -C $(top_builddir)/src/backend/parser keywords.o
 
-# we don't really need to edit createlang.sh at the moment,
-# but keep the old generation procedure in case we need it again.
-createlang: createlang.sh
-       cp $< $@
-       chmod a+x $@
 
 install: all installdirs
-       for i in $(filter-out createlang, $(SCRIPTS)); do \
-         $(INSTALL_SCRIPT) $(srcdir)/$$i $(DESTDIR)$(bindir)/$$i || exit; \
-       done
-       $(INSTALL_SCRIPT) createlang $(DESTDIR)$(bindir)/createlang
+       $(INSTALL_PROGRAM) createdb$(X)   $(DESTDIR)$(bindir)/createdb$(X)
+       $(INSTALL_PROGRAM) dropdb$(X)     $(DESTDIR)$(bindir)/dropdb$(X)
+       $(INSTALL_PROGRAM) createlang$(X) $(DESTDIR)$(bindir)/createlang$(X)
+       $(INSTALL_PROGRAM) droplang$(X)   $(DESTDIR)$(bindir)/droplang$(X)
+       $(INSTALL_PROGRAM) createuser$(X) $(DESTDIR)$(bindir)/createuser$(X)
+       $(INSTALL_PROGRAM) dropuser$(X)   $(DESTDIR)$(bindir)/dropuser$(X)
+       $(INSTALL_SCRIPT) $(srcdir)/clusterdb $(DESTDIR)$(bindir)/clusterdb
+       $(INSTALL_SCRIPT) $(srcdir)/vacuumdb  $(DESTDIR)$(bindir)/vacuumdb
 
 installdirs:
        $(mkinstalldirs) $(DESTDIR)$(bindir)
 
 uninstall:
-       rm -f $(addprefix $(DESTDIR)$(bindir)/, $(SCRIPTS))
+       rm -f $(addprefix $(DESTDIR)$(bindir)/, $(SCRIPTS) $(addsuffix $(X), $(PROGRAMS)))
+
 
 clean distclean maintainer-clean:
-       rm -f createlang
+       rm -f $(addsuffix $(X), $(PROGRAMS)) $(addsuffix .o, $(PROGRAMS)) common.o dumputils.o sprompt.o print.o mbprint.o dumputils.c dumputils.h sprompt.c print.c print.h mbprint.c mbprint.h
diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c
new file mode 100644 (file)
index 0000000..a04cf19
--- /dev/null
@@ -0,0 +1,168 @@
+/*-------------------------------------------------------------------------
+ *
+ * Miscellaneous shared code
+ *
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Header: /cvsroot/pgsql/src/bin/scripts/common.c,v 1.1 2003/03/18 22:19:46 petere Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+#include "common.h"
+
+#include <pwd.h>
+#include <unistd.h>
+
+
+/*
+ * Returns the current user name.
+ */
+const char *
+get_user_name(const char *progname)
+{
+       struct passwd *pw;
+
+       pw = getpwuid(getuid());
+       if (!pw)
+       {
+               perror(progname);
+               exit(1);
+       }
+       return pw->pw_name;
+}
+
+
+/*
+ * Extracts the actual name of the program as called.
+ */
+char *
+get_progname(char *argv0)
+{
+       if (!strrchr(argv0, '/'))
+               return argv0;
+       else
+               return strrchr(argv0, '/') + 1;
+}
+
+
+/*
+ * Initialized NLS if enabled.
+ */
+void
+init_nls(void)
+{
+#ifdef ENABLE_NLS
+       setlocale(LC_ALL, "");
+       bindtextdomain("pgscripts", LOCALEDIR);
+       textdomain("pgscripts");
+#endif
+}
+
+
+/*
+ * Provide strictly harmonized handling of --help and --version
+ * options.
+ */
+void
+handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp)
+{
+       if (argc > 1)
+       {
+               if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
+               {
+                       hlp(get_progname(argv[0]));
+                       exit(0);
+               }
+               if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
+               {
+                       printf("%s (PostgreSQL) " PG_VERSION "\n", fixed_progname);
+                       exit(0);
+               }
+       }
+}
+
+
+/*
+ * Make a database connection with the given parameters.  An
+ * interactive password prompt is automatically issued if required.
+ */
+PGconn *
+connectDatabase(const char *dbname, const char *pghost, const char *pgport,
+                               const char *pguser, bool require_password, const char *progname)
+{
+       PGconn     *conn;
+       char       *password = NULL;
+       bool            need_pass = false;
+
+       if (require_password)
+               password = simple_prompt("Password: ", 100, false);
+
+       /*
+        * Start the connection.  Loop until we have a password if requested
+        * by backend.
+        */
+       do
+       {
+               need_pass = false;
+               conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
+
+               if (!conn)
+               {
+                       fprintf(stderr, _("%s: could not connect to database %s\n"),
+                                       progname, dbname);
+                       exit(1);
+               }
+
+               if (PQstatus(conn) == CONNECTION_BAD &&
+                       strcmp(PQerrorMessage(conn), "fe_sendauth: no password supplied\n") == 0 &&
+                       !feof(stdin))
+               {
+                       PQfinish(conn);
+                       need_pass = true;
+                       free(password);
+                       password = NULL;
+                       password = simple_prompt("Password: ", 100, false);
+               }
+       } while (need_pass);
+
+       if (password)
+               free(password);
+
+       /* check to see that the backend connection was successfully made */
+       if (PQstatus(conn) == CONNECTION_BAD)
+       {
+               fprintf(stderr, _("%s: could not connect to database %s: %s"),
+                               progname, dbname, PQerrorMessage(conn));
+               exit(1);
+       }
+
+       return conn;
+}
+
+
+/*
+ * Run a query, return the results, exit program on failure.
+ */
+PGresult *
+executeQuery(PGconn *conn, const char *query, const char *progname, bool echo)
+{
+       PGresult   *res;
+
+       if (echo)
+               printf("%s\n", query);
+
+       res = PQexec(conn, query);
+       if (!res ||
+               PQresultStatus(res) != PGRES_TUPLES_OK)
+       {
+               fprintf(stderr, _("%s: query failed: %s"), progname, PQerrorMessage(conn));
+               fprintf(stderr, _("%s: query was: %s\n"), progname, query);
+               PQfinish(conn);
+               exit(1);
+       }
+
+       return res;
+}
diff --git a/src/bin/scripts/common.h b/src/bin/scripts/common.h
new file mode 100644 (file)
index 0000000..52e7b0c
--- /dev/null
@@ -0,0 +1,35 @@
+#include "postgres_fe.h"
+
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+
+#ifndef HAVE_GETOPT_LONG
+#include "getopt_long.h"
+#endif
+
+#include "libpq-fe.h"
+#include "pqexpbuffer.h"
+
+#ifndef HAVE_OPTRESET
+int optreset;
+#endif
+
+const char *get_user_name(const char *progname);
+char *get_progname(char *argv0);
+
+#define _(x) gettext((x))
+void init_nls(void);
+
+typedef void (*help_handler)(const char *);
+
+void handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp);
+
+extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
+
+PGconn *
+connectDatabase(const char *dbname, const char *pghost, const char *pgport,
+                               const char *pguser, bool require_password, const char *progname);
+
+PGresult *
+executeQuery(PGconn *conn, const char *command, const char *progname, bool echo);
diff --git a/src/bin/scripts/createdb b/src/bin/scripts/createdb
deleted file mode 100644 (file)
index 751de6c..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/bin/sh
-#-------------------------------------------------------------------------
-#
-# createdb--
-#    create a postgres database
-#
-#    This program runs psql with the "-c" option to create
-#    the requested database.
-#
-# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
-# Portions Copyright (c) 1994, Regents of the University of California
-#
-#
-# IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createdb,v 1.28 2002/10/18 22:05:36 petere Exp $
-#
-#-------------------------------------------------------------------------
-
-CMDNAME=`basename "$0"`
-PATHNAME=`echo "$0" | sed "s,$CMDNAME\$,,"`
-
-MB=
-TEMPLATE=
-PSQLOPT=
-dbname=
-dbowner=
-dbcomment=
-dbpath=
-
-while [ "$#" -gt 0 ]
-do
-    case "$1" in
-       --help|-\?)
-               usage=t
-                break
-               ;;
-# options passed on to psql
-       --host|-h)
-               PSQLOPT="$PSQLOPT -h $2"
-               shift;;
-        -h*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --host=*)
-                PSQLOPT="$PSQLOPT -h `echo \"$1\" | sed 's/^--host=//'`"
-                ;;
-       --port|-p)
-               PSQLOPT="$PSQLOPT -p $2"
-               shift;;
-        -p*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --port=*)
-                PSQLOPT="$PSQLOPT -p `echo \"$1\" | sed 's/^--port=//'`"
-                ;;
-       --username|-U)
-               PSQLOPT="$PSQLOPT -U $2"
-               shift;;
-        -U*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --username=*)
-                PSQLOPT="$PSQLOPT -U `echo \"$1\" | sed 's/^--username=//'`"
-                ;;
-       --password|-W)
-               PSQLOPT="$PSQLOPT -W"
-               ;;
-       --echo|-e)
-               PSQLOPT="$PSQLOPT -e"
-               ;;
-       --quiet|-q)
-               PSQLOPT="$PSQLOPT -o /dev/null"
-               ;;
-# options converted into SQL command
-       --owner|-O)
-               dbowner="$2"
-               shift;;
-        -O*)
-                dbowner=`echo "$1" | sed 's/^-O//'`
-                ;;
-        --owner=*)
-                dbowner=`echo "$1" | sed 's/^--owner=//'`
-                ;;
-       --location|-D)
-               dbpath="$2"
-               shift;;
-        -D*)
-                dbpath=`echo "$1" | sed 's/^-D//'`
-                ;;
-        --location=*)
-                dbpath=`echo "$1" | sed 's/^--location=//'`
-                ;;
-       --template|-T)
-               TEMPLATE="$2"
-               shift;;
-        -T*)
-                TEMPLATE=`echo "$1" | sed 's/^-T//'`
-                ;;
-        --template=*)
-                TEMPLATE=`echo "$1" | sed 's/^--template=//'`
-                ;;
-       --encoding|-E)
-               MB="$2"
-               shift;;
-        -E*)
-                MB=`echo "$1" | sed 's/^-E//'`
-                ;;
-        --encoding=*)
-                MB=`echo "$1" | sed 's/^--encoding=//'`
-                ;;
-       -*)
-               echo "$CMDNAME: invalid option: $1" 1>&2
-                echo "Try '$CMDNAME --help' for more information." 1>&2
-               exit 1
-               ;;
-       *)
-               dbname="$1"
-               if [ "$2" ]
-               then
-                       shift
-                       dbcomment="$1"
-               fi
-               if [ "$#" -ne 1 ]; then
-                       echo "$CMDNAME: invalid option: $2" 1>&2
-                       echo "Try '$CMDNAME --help' for more information." 1>&2
-                       exit 1
-               fi
-               ;;
-    esac
-    shift
-done
-
-if [ "$usage" ]; then
-        echo "$CMDNAME creates a PostgreSQL database."
-        echo
-       echo "Usage:"
-        echo "  $CMDNAME [OPTION]... [DBNAME] [DESCRIPTION]"
-        echo
-       echo "Options:"
-       echo "  -D, --location=PATH       alternative place to store the database"
-       echo "  -E, --encoding=ENCODING   encoding for the database"
-       echo "  -O, --owner=OWNER         database user to own the new database"
-       echo "  -T, --template=TEMPLATE   template database to copy"
-       echo "  -e, --echo                show the query being sent to the backend"
-        echo "  -q, --quiet               don't write any messages"
-       echo "  --help                    show this help, then exit"
-       echo
-       echo "Connection options:"
-       echo "  -h, --host=HOSTNAME       database server host"
-       echo "  -p, --port=PORT           database server port"
-       echo "  -U, --username=USERNAME   user name to connect as"
-       echo "  -W, --password            prompt for password"
-        echo
-        echo "By default, a database with the same name as the current user is created."
-       echo
-       echo "Report bugs to <pgsql-bugs@postgresql.org>."
-       exit 0
-fi
-
-
-if [ -n "$MB" ]
-then
-        mbcode=`${PATHNAME}pg_encoding "$MB"`
-        if [ -z "$mbcode" ]
-       then
-               echo "$CMDNAME: \"$MB\" is not a valid encoding name" 1>&2
-               exit 1
-       fi
-fi
-
-if [ -z "$dbname" ]; then
-        if [ "$PGDATABASE" ]; then
-                dbname="$PGDATABASE"
-        elif [ "$PGUSER" ]; then
-                dbname="$PGUSER"
-        else
-                dbname=`${PATHNAME}pg_id -u -n`
-        fi
-        [ "$?" -ne 0 ] && exit 1
-fi
-
-
-# escape the quotes
-dbpath=`echo "$dbpath" | sed "s/'/\\\\\'/g"`
-dbname=`echo "$dbname" | sed 's/\"/\\\"/g'`
-TEMPLATE=`echo "$TEMPLATE" | sed 's/\"/\"\"/g'`
-
-withstring=
-[ "$dbowner" ] &&    withstring="$withstring OWNER = \"$dbowner\""
-[ "$dbpath" ] &&     withstring="$withstring LOCATION = '$dbpath'"
-[ "$MB" ] &&         withstring="$withstring ENCODING = '$MB'"
-[ "$TEMPLATE" ] &&   withstring="$withstring TEMPLATE = \"$TEMPLATE\""
-[ "$withstring" ] && withstring=" WITH$withstring"
-
-${PATHNAME}psql $PSQLOPT -d template1 -c "SET autocommit TO 'on';CREATE DATABASE \"$dbname\"$withstring"
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: database creation failed" 1>&2
-       exit 1
-fi
-
-# Insert comment as well, if requested
-[ -z "$dbcomment" ] && exit 0
-
-dbcomment=`echo "$dbcomment" | sed "s/'/\\\\\'/g"`
-
-${PATHNAME}psql $PSQLOPT -d "$dbname" -c "SET autocommit TO 'on';COMMENT ON DATABASE \"$dbname\" IS '$dbcomment'"
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: comment creation failed (database was created)" 1>&2
-       exit 1
-fi
-
-exit 0
diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c
new file mode 100644 (file)
index 0000000..084bebb
--- /dev/null
@@ -0,0 +1,232 @@
+/*-------------------------------------------------------------------------
+ *
+ * createdb
+ *
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Header: /cvsroot/pgsql/src/bin/scripts/createdb.c,v 1.1 2003/03/18 22:19:46 petere Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+#include "common.h"
+#include "dumputils.h"
+
+#include "mb/pg_wchar.h"
+
+
+static void help(const char *progname);
+
+
+int
+main(int argc, char *argv[])
+{
+       static struct option long_options[] = {
+               {"host", required_argument, NULL, 'h'},
+               {"port", required_argument, NULL, 'p'},
+               {"username", required_argument, NULL, 'U'},
+               {"password", no_argument, NULL, 'W'},
+               {"echo", no_argument, NULL, 'e'},
+               {"quiet", no_argument, NULL, 'q'},
+               {"owner", required_argument, NULL, 'O'},
+               {"location", required_argument, NULL, 'D'},
+               {"template", required_argument, NULL, 'T'},
+               {"encoding", required_argument, NULL, 'E'},
+               {NULL, 0, NULL, 0}
+       };
+
+       char       *progname;
+       int                     optindex;
+       int                     c;
+
+       const char *dbname = NULL;
+       char       *comment = NULL;
+       char       *host = NULL;
+       char       *port = NULL;
+       char       *username = NULL;
+       bool            password = false;
+       bool            echo = false;
+       bool            quiet = false;
+       char       *owner = NULL;
+       char       *location = NULL;
+       char       *template = NULL;
+       char       *encoding = NULL;
+
+       PQExpBufferData sql;
+
+       PGconn     *conn;
+       PGresult   *result;
+
+       progname = get_progname(argv[0]);
+       init_nls();
+       handle_help_version_opts(argc, argv, "createdb", help);
+
+       while ((c = getopt_long(argc, argv, "h:p:U:WeqO:D:T:E:", long_options, &optindex)) != -1)
+       {
+               switch (c)
+               {
+                       case 'h':
+                               host = optarg;
+                               break;
+                       case 'p':
+                               port = optarg;
+                               break;
+                       case 'U':
+                               username = optarg;
+                               break;
+                       case 'W':
+                               password = true;
+                               break;
+                       case 'e':
+                               echo = true;
+                               break;
+                       case 'q':
+                               quiet = true;
+                               break;
+                       case 'O':
+                               owner = optarg;
+                               break;
+                       case 'D':
+                               location = optarg;
+                               break;
+                       case 'T':
+                               template = optarg;
+                               break;
+                       case 'E':
+                               encoding = optarg;
+                               break;
+                       default:
+                               fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                               exit(1);
+               }
+       }
+
+       switch (argc - optind)
+       {
+               case 0:
+                       break;
+               case 1:
+                       dbname = argv[optind];
+                       break;
+               case 2:
+                       dbname = argv[optind];
+                       comment = argv[optind + 1];
+                       break;
+               default:
+                       fprintf(stderr, _("%s: too many command-line arguments (first is '%s')\n"),
+                                       progname, argv[optind + 2]);
+                       fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                       exit(1);
+       }
+
+       if (encoding)
+       {
+               if (pg_char_to_encoding(encoding) < 0)
+               {
+                       fprintf(stderr, _("%s: \"%s\" is not a valid encoding name\n"),
+                                       progname, encoding);
+                       exit(1);
+               }
+       }
+
+       if (dbname == NULL)
+       {
+               if (getenv("PGDATABASE"))
+                       dbname = getenv("PGDATABASE");
+               else if (getenv("PGUSER"))
+                       dbname = getenv("PGUSER");
+               else
+                       dbname = get_user_name(progname);
+       }
+
+       initPQExpBuffer(&sql);
+
+       appendPQExpBuffer(&sql, "SET autocommit TO on;\nCREATE DATABASE %s",
+                                         fmtId(dbname));
+
+       if (owner)
+               appendPQExpBuffer(&sql, " OWNER %s", fmtId(owner));
+       if (location)
+       {
+               appendPQExpBuffer(&sql, " LOCATION ");
+               appendStringLiteral(&sql, location, false);
+       }
+       if (encoding)
+               appendPQExpBuffer(&sql, " ENCODING '%s'", encoding);
+       if (template)
+               appendPQExpBuffer(&sql, " TEMPLATE %s", fmtId(template));
+       appendPQExpBuffer(&sql, ";\n");
+
+       conn = connectDatabase("template1", host, port, username, password, progname);
+
+       if (echo)
+               printf("%s", sql.data);
+       result = PQexec(conn, sql.data);
+
+       if (PQresultStatus(result) != PGRES_COMMAND_OK)
+       {
+               fprintf(stderr, _("%s: database creation failed: %s"),
+                               progname, PQerrorMessage(conn));
+               PQfinish(conn);
+               exit(1);
+       }
+
+       PQclear(result);
+       PQfinish(conn);
+
+       if (!quiet)
+               puts("CREATE DATABASE");
+
+       if (comment)
+       {
+               printfPQExpBuffer(&sql, "SET autocommit TO on;\nCOMMENT ON DATABASE %s IS ", fmtId(dbname));
+               appendStringLiteral(&sql, comment, false);
+               appendPQExpBuffer(&sql, ";\n");
+
+               conn = connectDatabase(dbname, host, port, username, password, progname);
+               if (echo)
+                       printf("%s", sql.data);
+               result = PQexec(conn, sql.data);
+
+               if (PQresultStatus(result) != PGRES_COMMAND_OK)
+               {
+                       fprintf(stderr, _("%s: comment creation failed (database was created): %s"),
+                                       progname, PQerrorMessage(conn));
+                       PQfinish(conn);
+                       exit(1);
+               }
+
+               PQfinish(conn);
+               if (!quiet)
+                       puts("COMMENT");
+       }
+
+       exit(0);
+}
+
+
+static void
+help(const char *progname)
+{
+       printf(_("%s creates a PostgreSQL database.\n\n"), progname);
+       printf(_("Usage:\n"));
+       printf(_("  %s [OPTION]... [DBNAME] [DESCRIPTION]\n"), progname);
+       printf(_("\nOptions:\n"));
+       printf(_("  -D, --location=PATH       alternative place to store the database\n"));
+       printf(_("  -E, --encoding=ENCODING   encoding for the database\n"));
+       printf(_("  -O, --owner=OWNER         database user to own the new database\n"));
+       printf(_("  -T, --template=TEMPLATE   template database to copy\n"));
+       printf(_("  -e, --echo                show the commands being sent to the server\n"));
+       printf(_("  -q, --quiet               don't write any messages\n"));
+       printf(_("  --help                    show this help, then exit\n"));
+       printf(_("  --version                 output version information, then exit\n"));
+       printf(_("\nConnection options:\n"));
+       printf(_("  -h, --host=HOSTNAME       database server host\n"));
+       printf(_("  -p, --port=PORT           database server port\n"));
+       printf(_("  -U, --username=USERNAME   user name to connect as\n"));
+       printf(_("  -W, --password            prompt for password\n"));
+       printf(_("\nBy default, a database with the same name as the current user is created.\n"));
+       printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
+}
diff --git a/src/bin/scripts/createlang.c b/src/bin/scripts/createlang.c
new file mode 100644 (file)
index 0000000..ad562c7
--- /dev/null
@@ -0,0 +1,286 @@
+/*-------------------------------------------------------------------------
+ *
+ * createlang
+ *
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Header: /cvsroot/pgsql/src/bin/scripts/createlang.c,v 1.1 2003/03/18 22:19:46 petere Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+#include "common.h"
+#include "print.h"
+
+
+static void help(const char *progname);
+
+
+int
+main(int argc, char *argv[])
+{
+       static struct option long_options[] = {
+               {"list", no_argument, NULL, 'l'},
+               {"host", required_argument, NULL, 'h'},
+               {"port", required_argument, NULL, 'p'},
+               {"username", required_argument, NULL, 'U'},
+               {"password", no_argument, NULL, 'W'},
+               {"dbname", required_argument, NULL, 'd'},
+               {"pglib", required_argument, NULL, 'L'},
+               {"echo", no_argument, NULL, 'e'},
+               {NULL, 0, NULL, 0}
+       };
+
+       char       *progname;
+       int                     optindex;
+       int                     c;
+
+       bool            listlangs = false;
+       const char *dbname = NULL;
+       char       *host = NULL;
+       char       *port = NULL;
+       char       *username = NULL;
+       bool            password = false;
+       bool            echo = false;
+       char       *pglib = NULL;
+       char       *langname = NULL;
+
+       char       *p;
+       bool            handlerexists;
+       bool            trusted;
+       char       *handler;
+       char       *object;
+
+       PQExpBufferData sql;
+
+       PGconn     *conn;
+       PGresult   *result;
+
+       progname = get_progname(argv[0]);
+       init_nls();
+       handle_help_version_opts(argc, argv, "createlang", help);
+
+       while ((c = getopt_long(argc, argv, "lh:p:U:Wd:L:e", long_options, &optindex)) != -1)
+       {
+               switch (c)
+               {
+                       case 'l':
+                               listlangs = true;
+                               break;
+                       case 'h':
+                               host = optarg;
+                               break;
+                       case 'p':
+                               port = optarg;
+                               break;
+                       case 'U':
+                               username = optarg;
+                               break;
+                       case 'W':
+                               password = true;
+                               break;
+                       case 'd':
+                               dbname = optarg;
+                               break;
+                       case 'L':
+                               pglib = optarg;
+                               break;
+                       case 'e':
+                               echo = true;
+                               break;
+                       default:
+                               fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                               exit(1);
+               }
+       }
+
+       if (argc - optind > 0)
+       {
+               if (listlangs)
+                       dbname = argv[optind++];
+               else
+               {
+                       langname = argv[optind++];
+                       if (argc - optind > 0)
+                               dbname = argv[optind++];
+               }
+       }
+
+       if (argc - optind > 0)
+       {
+               fprintf(stderr, _("%s: too many command-line arguments (first is '%s')\n"),
+                               progname, argv[optind]);
+           fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+               exit(1);
+       }
+
+       if (dbname == NULL)
+       {
+               if (getenv("PGDATABASE"))
+                       dbname = getenv("PGDATABASE");
+               else if (getenv("PGUSER"))
+                       dbname = getenv("PGUSER");
+               else
+                       dbname = get_user_name(progname);
+       }
+
+       initPQExpBuffer(&sql);
+
+       /*
+        * List option
+        */
+       if (listlangs)
+       {
+               printQueryOpt popt;
+
+               conn = connectDatabase(dbname, host, port, username, password, progname);
+
+               printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language WHERE lanispl IS TRUE;", _("Name"), _("yes"), _("no"), _("Trusted?"));
+               result = executeQuery(conn, sql.data, progname, echo);
+
+               memset(&popt, 0, sizeof(popt));
+               popt.topt.format = PRINT_ALIGNED;
+               popt.topt.border = 1;
+               popt.topt.encoding = PQclientEncoding(conn);
+               popt.title = _("Procedural Languages");
+               printQuery(result, &popt, stdout);
+
+               PQfinish(conn);
+               exit(0);
+       }
+
+       if (langname == NULL)
+       {
+               fprintf(stderr, _("%s: missing required argument language name\n"), progname);
+           fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+               exit(1);
+       }
+
+       if (!pglib)
+               pglib = "$libdir";
+
+       for (p = langname; *p; p++)
+               if (*p >= 'A' && *p <= 'Z')
+                       *p += ('a' - 'A');
+
+       if (strcmp(langname, "plpgsql")==0)
+       {
+               trusted = true;
+               handler = "plpgsql_call_handler";
+               object = "plpgsql";
+       }
+       else if (strcmp(langname, "pltcl")==0)
+       {
+               trusted = true;
+               handler = "pltcl_call_handler";
+               object = "pltcl";
+       }
+       else if (strcmp(langname, "pltclu")==0)
+       {
+               trusted = false;
+               handler = "pltclu_call_handler";
+               object = "pltcl";
+       }
+       else if (strcmp(langname, "plperl")==0)
+       {
+               trusted = true;
+               handler = "plperl_call_handler";
+               object = "plperl";
+       }
+       else if (strcmp(langname, "plperlu")==0)
+       {
+               trusted = false;
+               handler = "plperl_call_handler";
+               object = "plperl";
+       }
+       else if (strcmp(langname, "plpython")==0)
+       {
+               trusted = true;
+               handler = "plpython_call_handler";
+               object = "plpython";
+       }
+       else
+       {
+               fprintf(stderr, _("%s: unsupported language \"%s\"\n"), progname, langname);
+               fprintf(stderr, _("Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpython.\n"));
+               exit(1);
+       }
+
+       conn = connectDatabase(dbname, host, port, username, password, progname);
+
+       /*
+        * Make sure the language isn't already installed
+        */
+       printfPQExpBuffer(&sql, "SELECT oid FROM pg_language WHERE lanname = '%s';", langname);
+       result = executeQuery(conn, sql.data, progname, echo);
+       if (PQntuples(result) > 0)
+       {
+               PQfinish(conn);
+               fprintf(stderr,
+                               _("%s: language \"%s\" is already installed in database \"%s\"\n"),
+                               progname, langname, dbname);
+               /* separate exit status for "already installed" */
+               exit(2);
+       }
+       PQclear(result);
+
+       /*
+        * Check whether the call handler exists
+        */
+       printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' AND prorettype = (SELECT oid FROM pg_type WHERE typname = 'language_handler') AND pronargs = 0;", handler);
+       result = executeQuery(conn, sql.data, progname, echo);
+       handlerexists = (PQntuples(result) > 0);
+       PQclear(result);
+
+       /*
+        * Create the call handler and the language
+        */
+       printfPQExpBuffer(&sql, "SET autocommit TO on;\n");
+
+       if (!handlerexists)
+               appendPQExpBuffer(&sql,
+                                                 "CREATE FUNCTION \"%s\" () RETURNS language_handler AS '%s/%s' LANGUAGE C;\n",
+                                                 handler, pglib, object);
+
+       appendPQExpBuffer(&sql,
+                                         "CREATE %sLANGUAGE \"%s\" HANDLER \"%s\";\n",
+                                         (trusted ? "TRUSTED " : ""), langname, handler);
+
+       if (echo)
+               printf("%s", sql.data);
+       result = PQexec(conn, sql.data);
+       if (PQresultStatus(result) != PGRES_COMMAND_OK)
+       {
+               fprintf(stderr, _("%s: language installation failed: %s"),
+                               progname, PQerrorMessage(conn));
+               PQfinish(conn);
+               exit(1);
+       }
+
+       PQfinish(conn);
+       exit(0);
+}
+
+
+
+static void
+help(const char *progname)
+{
+       printf(_("%s installs a procedural language into a PostgreSQL database.\n\n"), progname);
+       printf(_("Usage:\n"));
+       printf(_("  %s [OPTION]... LANGNAME [DBNAME]\n"), progname);
+       printf(_("\nOptions:\n"));
+       printf(_("  -d, --dbname=DBNAME       database to install language in\n"));
+       printf(_("  -e, --echo                show the commands being sent to the server\n"));
+       printf(_("  -l, --list                show a list of currently installed languages\n"));
+       printf(_("  -L, --pglib=DIRECTORY     find language interpreter file in DIRECTORY\n"));
+       printf(_("  -h, --host=HOSTNAME       database server host\n"));
+       printf(_("  -p, --port=PORT           database server port\n"));
+       printf(_("  -U, --username=USERNAME   user name to connect as\n"));
+       printf(_("  -W, --password            prompt for password\n"));
+       printf(_("  --help                    show this help, then exit\n"));
+       printf(_("  --version                 output version information, then exit\n"));
+       printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
+}
diff --git a/src/bin/scripts/createlang.sh b/src/bin/scripts/createlang.sh
deleted file mode 100644 (file)
index ff94874..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-#! /bin/sh
-#-------------------------------------------------------------------------
-#
-# createlang --
-#   Install a procedural language in a database
-#
-# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
-# Portions Copyright (c) 1994, Regents of the University of California
-#
-# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.42 2002/10/18 22:05:36 petere Exp $
-#
-#-------------------------------------------------------------------------
-
-CMDNAME=`basename "$0"`
-PATHNAME=`echo "$0" | sed "s,$CMDNAME\$,,"`
-
-PSQLOPT=
-dbname=
-langname=
-list=
-showsql=
-PGLIB=
-
-# Check for echo -n vs echo \c
-
-if echo '\c' | grep -s c >/dev/null 2>&1
-then
-    ECHO_N="echo -n"
-    ECHO_C=""
-else
-    ECHO_N="echo"
-    ECHO_C='\c'
-fi
-
-
-
-# ----------
-# Get options, language name and dbname
-# ----------
-while [ "$#" -gt 0 ]
-do
-    case "$1" in 
-       --help|-\?)
-               usage=t
-                break
-               ;;
-        --list|-l)
-                list=t
-                ;;
-# options passed on to psql
-       --host|-h)
-               PSQLOPT="$PSQLOPT -h $2"
-               shift;;
-        -h*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --host=*)
-                PSQLOPT="$PSQLOPT -h `echo \"$1\" | sed 's/^--host=//'`"
-                ;;
-       --port|-p)
-               PSQLOPT="$PSQLOPT -p $2"
-               shift;;
-        -p*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --port=*)
-                PSQLOPT="$PSQLOPT -p `echo \"$1\" | sed 's/^--port=//'`"
-                ;;
-       --username|-U)
-               PSQLOPT="$PSQLOPT -U $2"
-               shift;;
-        -U*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --username=*)
-                PSQLOPT="$PSQLOPT -U `echo \"$1\" | sed 's/^--username=//'`"
-                ;;
-       --password|-W)
-               PSQLOPT="$PSQLOPT -W"
-               ;;
-       --dbname|-d)
-               dbname="$2"
-               shift;;
-        -d*)
-                dbname=`echo "$1" | sed 's/^-d//'`
-                ;;
-        --dbname=*)
-                dbname=`echo "$1" | sed 's/^--dbname=//'`
-                ;;
-# misc options
-       --pglib|-L)
-                PGLIB="$2"
-                shift;;
-        -L*)
-                PGLIB=`echo "$1" | sed 's/^-L//'`
-                ;;
-        --pglib=*)
-                PGLIB=`echo "$1" | sed 's/^--pglib=//'`
-                ;;
-       --echo|-e)
-               showsql=yes
-               ;;
-
-       -*)
-               echo "$CMDNAME: invalid option: $1" 1>&2
-                echo "Try '$CMDNAME --help' for more information." 1>&2
-               exit 1
-               ;;
-        *)
-               if [ "$list" != "t" ]
-               then    langname="$1"
-                       if [ "$2" ]
-                       then
-                               shift
-                               dbname="$1"
-                       fi
-               else    dbname="$1"
-               fi
-               if [ "$#" -ne 1 ]; then
-                       echo "$CMDNAME: invalid option: $2" 1>&2
-                       echo "Try '$CMDNAME --help' for more information." 1>&2
-                       exit 1
-               fi
-                ;;
-    esac
-    shift
-done
-
-if [ -n "$usage" ]; then       
-        echo "$CMDNAME installs a procedural language into a PostgreSQL database."
-       echo
-       echo "Usage:"
-        echo "  $CMDNAME [OPTION]... LANGNAME [DBNAME]"
-        echo
-       echo "Options:"
-       echo "  -d, --dbname=DBNAME       database to install language in"
-       echo "  -l, --list                show a list of currently installed languages"
-       echo "  -L, --pglib=DIRECTORY     find language interpreter file in DIRECTORY"
-       echo "  -h, --host=HOSTNAME       database server host"
-       echo "  -p, --port=PORT           database server port"
-       echo "  -U, --username=USERNAME   user name to connect as"
-       echo "  -W, --password            prompt for password"
-       echo " --help                     show this help, then exit"
-        echo
-       echo "Report bugs to <pgsql-bugs@postgresql.org>."
-       exit 0
-fi
-
-
-if [ -z "$dbname" ]; then
-        if [ "$PGDATABASE" ]; then
-                dbname="$PGDATABASE"
-        elif [ "$PGUSER" ]; then
-                dbname="$PGUSER"
-        else
-                dbname=`${PATHNAME}pg_id -u -n`
-        fi
-        [ "$?" -ne 0 ] && exit 1
-fi
-
-
-# ----------
-# List option, doesn't need langname
-# ----------
-if [ "$list" ]; then
-       sqlcmd="SELECT lanname as \"Name\", lanpltrusted as \"Trusted?\" FROM pg_language WHERE lanispl = TRUE;"
-       if [ "$showsql" = yes ]; then
-               echo "$sqlcmd"
-       fi
-        ${PATHNAME}psql $PSQLOPT -d "$dbname" -P 'title=Procedural languages' -c "$sqlcmd"
-        exit $?
-fi
-
-
-# ----------
-# We can't go any farther without a langname
-# ----------
-if [ -z "$langname" ]; then
-       echo "$CMDNAME: missing required argument language name" 1>&2
-        echo "Try '$CMDNAME --help' for help." 1>&2
-       exit 1
-fi
-
-# ----------
-# Check that we have PGLIB
-# ----------
-if [ -z "$PGLIB" ]; then
-       PGLIB='$libdir'
-fi
-
-# ----------
-# Check if supported and set related values
-# ----------
-
-langname=`echo "$langname" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-
-case "$langname" in
-       plpgsql)
-               trusted="TRUSTED "
-               handler="plpgsql_call_handler"
-               object="plpgsql"
-               ;;
-       pltcl)
-               trusted="TRUSTED "
-               handler="pltcl_call_handler"
-               object="pltcl"
-               ;;
-       pltclu)
-               trusted=""
-               handler="pltclu_call_handler"
-               object="pltcl"
-               ;;
-       plperl)
-               trusted="TRUSTED "
-               handler="plperl_call_handler"
-               object="plperl"
-               ;;
-       plperlu)
-               trusted=""
-               handler="plperl_call_handler"
-               object="plperl"
-               ;;
-       plpython)
-               trusted="TRUSTED "
-               handler="plpython_call_handler"
-               object="plpython"
-               ;;
-       *)
-               echo "$CMDNAME: unsupported language \"$langname\"" 1>&2
-               echo "Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpython." 1>&2
-               exit 1
-        ;;
-esac
-
-
-PSQL="${PATHNAME}psql -A -t -q $PSQLOPT -d $dbname -c"
-
-# ----------
-# Make sure the language isn't already installed
-# ----------
-sqlcmd="SELECT oid FROM pg_language WHERE lanname = '$langname';"
-if [ "$showsql" = yes ]; then
-       echo "$sqlcmd"
-fi
-res=`$PSQL "$sqlcmd"`
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: external error" 1>&2
-       exit 1
-fi
-if [ -n "$res" ]; then
-       echo "$CMDNAME: language \"$langname\" is already installed in database $dbname" 1>&2
-       # separate exit status for "already installed"
-       exit 2
-fi
-
-# ----------
-# Check whether the call handler exists
-# ----------
-sqlcmd="SELECT oid FROM pg_proc WHERE proname = '$handler' AND prorettype = 0 AND pronargs = 0;"
-if [ "$showsql" = yes ]; then
-       echo "$sqlcmd"
-fi
-res=`$PSQL "$sqlcmd"`
-if [ -n "$res" ]; then
-       handlerexists=yes
-else
-       handlerexists=no
-fi
-
-# ----------
-# Create the call handler and the language
-# ----------
-if [ "$handlerexists" = no ]; then
-       sqlcmd="SET autocommit TO 'on';CREATE FUNCTION \"$handler\" () RETURNS LANGUAGE_HANDLER AS '$PGLIB/${object}' LANGUAGE C;"
-       if [ "$showsql" = yes ]; then
-               echo "$sqlcmd"
-       fi
-       $PSQL "$sqlcmd"
-       if [ "$?" -ne 0 ]; then
-               echo "$CMDNAME: language installation failed" 1>&2
-               exit 1
-       fi
-fi
-
-sqlcmd="SET autocommit TO 'on';CREATE ${trusted}LANGUAGE \"$langname\" HANDLER \"$handler\";"
-if [ "$showsql" = yes ]; then
-       echo "$sqlcmd"
-fi
-$PSQL "$sqlcmd"
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: language installation failed" 1>&2
-       exit 1
-fi
-
-# ----------
-# Grant privileges.  As of 7.3 the default privileges for a language include
-# public USAGE, so we need not change them for a trusted language; but it
-# seems best to disable public USAGE for an untrusted one.
-# ----------
-if test -z "$trusted"; then
-    sqlcmd="SET autocommit TO 'on';REVOKE ALL ON LANGUAGE \"$langname\" FROM PUBLIC;"
-    if [ "$showsql" = yes ]; then
-        echo "$sqlcmd"
-    fi
-    $PSQL "$sqlcmd"
-    if [ "$?" -ne 0 ]; then
-        echo "$CMDNAME: language installation failed" 1>&2
-        exit 1
-    fi
-fi
-
-exit 0
diff --git a/src/bin/scripts/createuser b/src/bin/scripts/createuser
deleted file mode 100644 (file)
index 62263e9..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-#!/bin/sh
-#-------------------------------------------------------------------------
-#
-# createuser--
-#    Utility for creating a user in the PostgreSQL database
-#
-# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
-# Portions Copyright (c) 1994, Regents of the University of California
-#
-#
-# IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createuser,v 1.31 2003/02/19 03:52:57 momjian Exp $
-#
-# Note - this should NOT be setuid.
-#
-#-------------------------------------------------------------------------
-
-CMDNAME=`basename "$0"`
-PATHNAME=`echo "$0" | sed "s,$CMDNAME\$,,"`
-
-NewUser=
-SysID=
-CanAddUser=
-CanCreateDb=
-PwPrompt=
-Password=
-PSQLOPT=
-Encrypted=     # blank uses default
-
-# These handle spaces/tabs in identifiers
-_IFS="$IFS"
-NL="
-"
-# Check for echo -n vs echo \c
-
-if echo '\c' | grep -s c >/dev/null 2>&1
-then
-    ECHO_N="echo -n"
-    ECHO_C=""
-else
-    ECHO_N="echo"
-    ECHO_C='\c'
-fi
-
-
-while [ "$#" -gt 0 ]
-do
-    case "$1" in
-       --help|-\?)
-               usage=t
-                break
-               ;;
-# options passed on to psql
-       --host|-h)
-               PSQLOPT="$PSQLOPT -h $2"
-               shift;;
-        -h*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --host=*)
-                PSQLOPT="$PSQLOPT -h `echo \"$1\" | sed 's/^--host=//'`"
-                ;;
-       --port|-p)
-               PSQLOPT="$PSQLOPT -p $2"
-               shift;;
-        -p*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --port=*)
-                PSQLOPT="$PSQLOPT -p `echo \"$1\" | sed 's/^--port=//'`"
-                ;;
-# Note: These two specify the user to connect as (like in psql),
-#       not the user you're creating.
-       --username|-U)
-               PSQLOPT="$PSQLOPT -U $2"
-               shift;;
-        -U*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --username=*)
-                PSQLOPT="$PSQLOPT -U `echo \"$1\" | sed 's/^--username=//'`"
-                ;;
-       --password|-W)
-               PSQLOPT="$PSQLOPT -W"
-               ;;
-       --echo|-e)
-               PSQLOPT="$PSQLOPT -e"
-               ;;
-       --quiet|-q)
-               PSQLOPT="$PSQLOPT -o /dev/null"
-               ;;
-# options converted into SQL command   
-        --createdb|-d)
-               CanCreateDb=t
-               ;;
-        --no-createdb|-D)
-               CanCreateDb=f
-               ;;
-        --adduser|-a)
-               CanAddUser=t
-               ;;
-        --no-adduser|-A)
-               CanAddUser=f
-               ;;
-        --sysid|-i)
-                SysID="$2"
-                shift;;
-        --sysid=*)
-                SysID=`echo "$1" | sed 's/^--sysid=//'`
-                ;;
-        --encrypted|-E)
-               Encrypted=t
-               ;;
-        --unencrypted|-N)
-               Encrypted=f
-               ;;
-        -i*)
-                SysID=`echo "$1" | sed 's/^-i//'`
-                ;;
-       --pwprompt|--pw|-P)
-               PwPrompt=t
-               ;;
-       -*)
-               echo "$CMDNAME: invalid option: $1" 1>&2
-                echo "Try '$CMDNAME --help' for more information." 1>&2
-               exit 1
-               ;;
-         *)
-               NewUser="$1"
-               if [ "$#" -ne 1 ]; then
-                       echo "$CMDNAME: invalid option: $2" 1>&2
-                       echo "Try '$CMDNAME --help' for more information." 1>&2
-                       exit 1
-               fi
-               ;;
-    esac
-    shift;
-done
-
-if [ "$usage" ]; then  
-        echo "$CMDNAME creates a new PostgreSQL user."
-        echo
-       echo "Usage:"
-        echo "  $CMDNAME [OPTION]... [USERNAME]"
-        echo
-       echo "Options:"
-       echo "  -a, --adduser             user can add new users"
-       echo "  -A, --no-adduser          user cannot add new users"
-       echo "  -d, --createdb            user can create new databases"
-       echo "  -D, --no-createdb         user cannot create databases"
-       echo "  -P, --pwprompt            assign a password to new user"
-       echo "  -E, --encrypted           encrypt stored password"
-       echo "  -N, --unencrypted         do no encrypt stored password"
-       echo "  -i, --sysid=SYSID         select sysid for new user"     
-       echo "  -e, --echo                show the query being sent to the backend"
-       echo "  -q, --quiet               don't write any messages"
-       echo "  --help                    show this help, then exit"
-       echo
-       echo "Connection options:"
-       echo "  -h, --host=HOSTNAME       database server host"
-       echo "  -p, --port=PORT           database server port"
-       echo "  -U, --username=USERNAME   user name to connect as (not the one to create)"
-       echo "  -W, --password            prompt for password to connect"
-       echo
-        echo "If one of -a, -A, -d, -D, and USERNAME is not specified, you will"
-        echo "be prompted interactively."
-        echo
-       echo "Report bugs to <pgsql-bugs@postgresql.org>."
-       exit 0
-fi
-
-if [ "$SysID" ]; then
-        if [ "$SysID" != "`echo $SysID | sed 's/[^0-9]//g'`" ]; then
-                echo "$CMDNAME: user sysid must be a positive number" 1>&2
-                exit 1
-        fi
-fi
-
-# Don't want to leave the user blind if he breaks
-# during password entry.
-
-trap 'stty echo >/dev/null 2>&1; echo; exit 1' 1 2 3 15
-
-# Get missing user attributes
-
-if [ -z "$NewUser" ]; then
-       $ECHO_N "Enter name of user to add: "$ECHO_C
-        IFS="$NL"
-        read NewUser
-        IFS="$_IFS"
-       [ "$?" -ne 0 ] && exit 1
-fi
-
-if [ "$PwPrompt" ]; then
-       $ECHO_N "Enter password for user \"$NewUser\": "$ECHO_C
-        stty -echo >/dev/null 2>&1
-        IFS="$NL"
-        read FirstPw
-        IFS="$_IFS"
-        stty echo >/dev/null 2>&1
-        echo
-        $ECHO_N "Enter it again: "$ECHO_C
-        stty -echo >/dev/null 2>&1
-        IFS="$NL"
-        read SecondPw
-        IFS="$_IFS"
-        stty echo >/dev/null 2>&1
-        echo
-        if [ "$FirstPw" != "$SecondPw" ]; then
-            echo "Passwords didn't match." 1>&2
-            exit 1
-        fi
-       Password="$FirstPw"
-fi
-
-if [ -z "$CanCreateDb" ]; then
-       $ECHO_N "Shall the new user be allowed to create databases? (y/n) "$ECHO_C
-       read REPLY
-       [ "$?" -ne 0 ] && exit 1
-       if [ "$REPLY" = "y" -o "$REPLY" = "Y" ]; then
-               CanCreateDb=t
-       else
-               CanCreateDb=f
-       fi
-fi
-
-if [ -z "$CanAddUser" ]; then
-       $ECHO_N "Shall the new user be allowed to create more new users? (y/n) "$ECHO_C
-       read REPLY
-       [ "$?" -ne 0 ] && exit 1
-       if [ "$REPLY" = "y" -o "$REPLY" = "Y" ]; then
-               CanAddUser=t
-       else
-               CanAddUser=f
-       fi
-fi
-
-
-#
-# build SQL command
-#
-NewUser=`echo "$NewUser" | sed 's/\"/\\\"/g'`
-Password=`echo "$Password" | sed 's/\"/\\\"/g'`
-
-QUERY="CREATE USER \"$NewUser\""
-
-SUBQUERY=
-[ "$SysID" ] &&    SUBQUERY="$SUBQUERY SYSID $SysID"
-[ "$Encrypted" = t ] &&   SUBQUERY="$SUBQUERY ENCRYPTED"
-[ "$Encrypted" = f ] &&   SUBQUERY="$SUBQUERY UNENCRYPTED"
-[ "$Password" ] &&        SUBQUERY="$SUBQUERY PASSWORD '$Password'"
-[ "$SUBQUERY" ] &&        QUERY="$QUERY WITH $SUBQUERY"
-
-[ "$CanCreateDb" = t ] && QUERY="$QUERY CREATEDB"
-[ "$CanCreateDb" = f ] && QUERY="$QUERY NOCREATEDB"
-[ "$CanAddUser" = t ] &&  QUERY="$QUERY CREATEUSER"
-[ "$CanAddUser" = f ] &&  QUERY="$QUERY NOCREATEUSER"
-
-${PATHNAME}psql -c "SET autocommit TO 'on';$QUERY" -d template1 $PSQLOPT
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: creation of user \"$NewUser\" failed" 1>&2
-       exit 1
-fi
-               
-exit 0
diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c
new file mode 100644 (file)
index 0000000..c67aebf
--- /dev/null
@@ -0,0 +1,258 @@
+/*-------------------------------------------------------------------------
+ *
+ * createuser
+ *
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Header: /cvsroot/pgsql/src/bin/scripts/createuser.c,v 1.1 2003/03/18 22:19:46 petere Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+#include "common.h"
+#include "dumputils.h"
+
+
+static void help(const char *progname);
+
+
+int
+main(int argc, char *argv[])
+{
+       static struct option long_options[] = {
+               {"host", required_argument, NULL, 'h'},
+               {"port", required_argument, NULL, 'p'},
+               {"username", required_argument, NULL, 'U'},
+               {"password", no_argument, NULL, 'W'},
+               {"echo", no_argument, NULL, 'e'},
+               {"quiet", no_argument, NULL, 'q'},
+               {"createdb", no_argument, NULL, 'd'},
+               {"no-createdb", no_argument, NULL, 'D'},
+               {"adduser", no_argument, NULL, 'a'},
+               {"no-adduser", no_argument, NULL, 'A'},
+               {"sysid", required_argument, NULL, 'i'},
+               {"pwprompt", no_argument, NULL, 'P'},
+               {"encrypted", no_argument, NULL, 'E'},
+               {"unencrypted", no_argument, NULL, 'N'},
+               {NULL, 0, NULL, 0}
+       };
+
+       char       *progname;
+       int                     optindex;
+       int                     c;
+
+       char       *newuser = NULL;
+       char       *host = NULL;
+       char       *port = NULL;
+       char       *username = NULL;
+       bool            password = false;
+       bool            echo = false;
+       bool            quiet = false;
+       int                     createdb = 0;
+       int                     adduser = 0;
+       char       *sysid = NULL;
+       bool            pwprompt = false;
+       int                     encrypted = 0;  /* 0 uses server default */
+       char       *newpassword = NULL;
+
+       PQExpBufferData sql;
+
+       PGconn     *conn;
+       PGresult   *result;
+
+       progname = get_progname(argv[0]);
+       init_nls();
+       handle_help_version_opts(argc, argv, "createuser", help);
+
+       while ((c = getopt_long(argc, argv, "h:p:U:WeqaAdDi:PEN", long_options, &optindex)) != -1)
+       {
+               switch (c)
+               {
+                       case 'h':
+                               host = optarg;
+                               break;
+                       case 'p':
+                               port = optarg;
+                               break;
+                       case 'U':
+                               username = optarg;
+                               break;
+                       case 'W':
+                               password = true;
+                               break;
+                       case 'e':
+                               echo = true;
+                               break;
+                       case 'q':
+                               quiet = true;
+                               break;
+                       case 'a':
+                               adduser = +1;
+                               break;
+                       case 'A':
+                               adduser = -1;
+                               break;
+                       case 'd':
+                               createdb = +1;
+                               break;
+                       case 'D':
+                               createdb = -1;
+                               break;
+                       case 'i':
+                               sysid = optarg;
+                               break;
+                       case 'P':
+                               pwprompt = true;
+                               break;
+                       case 'E':
+                               encrypted = +1;
+                               break;
+                       case 'N':
+                               encrypted = -1;
+                               break;
+                       default:
+                               fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                               exit(1);
+               }
+       }
+
+       switch (argc - optind)
+       {
+               case 0:
+                       break;
+               case 1:
+                       newuser = argv[optind];
+                       break;
+               default:
+                       fprintf(stderr, _("%s: too many command-line arguments (first is '%s')\n"),
+                                       progname, argv[optind + 1]);
+                       fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                       exit(1);
+       }
+
+       if (sysid)
+       {
+               char       *endptr;
+
+               if (strtol(sysid, &endptr, 10) <= 0 || *endptr != '\0')
+               {
+                       fprintf(stderr, _("%s: user ID must be a positive number\n"), progname);
+                       exit(1);
+               }
+       }
+
+       if (newuser == NULL)
+               newuser = simple_prompt("Enter name of user to add: ", 128, true);
+
+       if (pwprompt)
+       {
+               char       *pw1, *pw2;
+
+               pw1 = simple_prompt("Enter password for new user: ", 100, false);
+               pw2 = simple_prompt("Enter it again: ", 100, false);
+               if (strcmp(pw1, pw2)!=0)
+               {
+                       fprintf(stderr, _("Passwords didn't match.\n"));
+                       exit(1);
+               }
+               newpassword = pw1;
+               free(pw2);
+       }
+
+       if (createdb == 0)
+       {
+               char       *reply;
+
+               reply = simple_prompt("Shall the new user be allowed to create databases? (y/n) ", 1, true);
+               if (reply[0] == 'y' || reply[0] == 'Y')
+                       createdb = +1;
+               else
+                       createdb = -1;
+       }
+
+       if (adduser == 0)
+       {
+               char       *reply;
+
+               reply = simple_prompt("Shall the new user be allowed to create more new users? (y/n) ", 1, true);
+               if (reply[0] == 'y' || reply[0] == 'Y')
+                       adduser = +1;
+               else
+                       adduser = -1;
+       }
+
+       initPQExpBuffer(&sql);
+
+       printfPQExpBuffer(&sql, "SET autocommit TO on;\nCREATE USER %s", fmtId(newuser));
+       if (sysid)
+               appendPQExpBuffer(&sql, " SYSID %s", sysid);
+       if (encrypted == +1)
+               appendPQExpBuffer(&sql, " ENCRYPTED");
+       if (encrypted == -1)
+               appendPQExpBuffer(&sql, " UNENCRYPTED");
+       if (newpassword)
+       {
+               appendPQExpBuffer(&sql, " PASSWORD ");
+               appendStringLiteral(&sql, newpassword, false);
+       }
+       if (createdb == +1)
+               appendPQExpBuffer(&sql, " CREATEDB");
+       if (createdb == -1)
+               appendPQExpBuffer(&sql, " NOCREATEDB");
+       if (adduser == +1)
+               appendPQExpBuffer(&sql, " CREATEUSER");
+       if (adduser == -1)
+               appendPQExpBuffer(&sql, " NOCREATEUSER");
+       appendPQExpBuffer(&sql, ";\n");
+
+       conn = connectDatabase("template1", host, port, username, password, progname);
+
+       if (echo)
+               printf("%s", sql.data);
+       result = PQexec(conn, sql.data);
+
+       if (PQresultStatus(result) != PGRES_COMMAND_OK)
+       {
+               fprintf(stderr, _("%s: creation of new user failed: %s"),
+                               progname, PQerrorMessage(conn));
+               PQfinish(conn);
+               exit(1);
+       }
+
+       PQfinish(conn);
+       if (!quiet)
+               puts("CREATE USER");
+       exit(0);
+}
+
+
+static void
+help(const char *progname)
+{
+       printf(_("%s creates a new PostgreSQL user.\n\n"), progname);
+       printf(_("Usage:\n"));
+       printf(_("  %s [OPTION]... [USERNAME]\n"), progname);
+       printf(_("\nOptions:\n"));
+       printf(_("  -a, --adduser             user can add new users\n"));
+       printf(_("  -A, --no-adduser          user cannot add new users\n"));
+       printf(_("  -d, --createdb            user can create new databases\n"));
+       printf(_("  -D, --no-createdb         user cannot create databases\n"));
+       printf(_("  -P, --pwprompt            assign a password to new user\n"));
+       printf(_("  -E, --encrypted           encrypt stored password\n"));
+       printf(_("  -N, --unencrypted         do no encrypt stored password\n"));
+       printf(_("  -i, --sysid=SYSID         select sysid for new user\n"     ));
+       printf(_("  -e, --echo                show the commands being sent to the server\n"));
+    printf(_("  -q, --quiet               don't write any messages\n"));
+       printf(_("  --help                    show this help, then exit\n"));
+       printf(_("  --version                 output version information, then exit\n"));
+       printf(_("\nConnection options:\n"));
+       printf(_("  -h, --host=HOSTNAME       database server host\n"));
+       printf(_("  -p, --port=PORT           database server port\n"));
+       printf(_("  -U, --username=USERNAME   user name to connect as (not the one to create)\n"));
+       printf(_("  -W, --password            prompt for password to connect\n"));
+       printf(_("\nIf one of -a, -A, -d, -D, and USERNAME is not specified, you will\n"
+                        "be prompted interactively.\n"));
+       printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
+}
diff --git a/src/bin/scripts/dropdb b/src/bin/scripts/dropdb
deleted file mode 100644 (file)
index e8df0d5..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/bin/sh
-#-------------------------------------------------------------------------
-#
-# dropdb--
-#    destroy a postgres database
-#
-#    this program runs psql to drop the requested database.
-#
-# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
-# Portions Copyright (c) 1994, Regents of the University of California
-#
-#
-# IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/bin/scripts/Attic/dropdb,v 1.19 2002/10/18 22:05:36 petere Exp $
-#
-#-------------------------------------------------------------------------
-
-CMDNAME=`basename "$0"`
-PATHNAME=`echo "$0" | sed "s,$CMDNAME\$,,"`
-
-PSQLOPT=
-dbname=
-forcedel=t
-
-# Check for echo -n vs echo \c
-
-if echo '\c' | grep -s c >/dev/null 2>&1
-then
-    ECHO_N="echo -n"
-    ECHO_C=""
-else
-    ECHO_N="echo"
-    ECHO_C='\c'
-fi
-
-
-while [ "$#" -gt 0 ]
-do
-    case "$1" in 
-       --help|-\?)
-               usage=t
-               break
-               ;;
-# options passed on to psql
-       --host|-h)
-               PSQLOPT="$PSQLOPT -h $2"
-               shift;;
-        -h*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --host=*)
-                PSQLOPT="$PSQLOPT -h `echo \"$1\" | sed 's/^--host=//'`"
-                ;;
-       --port|-p)
-               PSQLOPT="$PSQLOPT -p $2"
-               shift;;
-        -p*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --port=*)
-                PSQLOPT="$PSQLOPT -p `echo \"$1\" | sed 's/^--port=//'`"
-                ;;
-       --username|-U)
-               PSQLOPT="$PSQLOPT -U $2"
-               shift;;
-        -U*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --username=*)
-                PSQLOPT="$PSQLOPT -U `echo \"$1\" | sed 's/^--username=//'`"
-                ;;
-       --password|-W)
-               PSQLOPT="$PSQLOPT -W"
-               ;;
-       --echo|-e)
-               PSQLOPT="$PSQLOPT -e"
-               ;;
-       --quiet|-q)
-               PSQLOPT="$PSQLOPT -o /dev/null"
-               ;;
-# other options
-        --interactive|-i)
-               forcedel=f
-               ;;
-       -*)
-               echo "$CMDNAME: invalid option: $1" 1>&2
-                echo "Try '$CMDNAME --help' for more information." 1>&2
-               exit 1
-               ;;
-        *)
-               dbname="$1"
-               if [ "$#" -ne 1 ]; then
-                       echo "$CMDNAME: invalid option: $2" 1>&2
-                       echo "Try '$CMDNAME --help' for more information." 1>&2
-                       exit 1
-               fi
-               ;;
-    esac
-    shift
-done
-
-
-if [ "$usage" ]; then
-        echo "$CMDNAME removes a PostgreSQL database."
-        echo
-       echo "Usage:"
-        echo "  $CMDNAME [OPTION]... DBNAME"
-        echo
-       echo "Options:"
-       echo "  -e, --echo                show the query being sent to the backend"
-       echo "  -i, --interactive         prompt before deleting anything"
-        echo "  -q, --quiet               don't write any messages"
-       echo "  -h, --host=HOSTNAME       database server host"
-       echo "  -p, --port=PORT           database server port"
-       echo "  -U, --username=USERNAME   user name to connect as"
-       echo "  -W, --password            prompt for password"
-       echo " --help                     show this help, then exit"
-       echo
-       echo "Report bugs to <pgsql-bugs@postgresql.org>."
-       exit 0
-fi
-
-if [ -z "$dbname" ]; then
-       echo "$CMDNAME: missing required argument database name" 1>&2
-        echo "Try '$CMDNAME -?' for help." 1>&2
-       exit 1
-fi
-
-
-if [ "$forcedel" = f ]; then
-       echo "Database \"$dbname\" will be permanently deleted."
-       $ECHO_N "Are you sure? (y/n) "$ECHO_C
-       read REPLY
-
-       [ "$?" -eq 1 ] && exit 1
-       [ "$REPLY" != "y" -a "$REPLY" != "Y" ] && exit 0
-fi
-
-
-dbname=`echo "$dbname" | sed 's/\"/\\\"/g'`
-
-${PATHNAME}psql $PSQLOPT -d template1 -c "SET autocommit TO 'on';DROP DATABASE \"$dbname\""
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: database removal failed" 1>&2
-       exit 1
-fi
-
-exit 0
diff --git a/src/bin/scripts/dropdb.c b/src/bin/scripts/dropdb.c
new file mode 100644 (file)
index 0000000..784c7c2
--- /dev/null
@@ -0,0 +1,156 @@
+/*-------------------------------------------------------------------------
+ *
+ * dropdb
+ *
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Header: /cvsroot/pgsql/src/bin/scripts/dropdb.c,v 1.1 2003/03/18 22:19:46 petere Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+#include "common.h"
+#include "dumputils.h"
+
+
+static void help(const char *progname);
+
+
+int
+main(int argc, char *argv[])
+{
+       static struct option long_options[] = {
+               {"host", required_argument, NULL, 'h'},
+               {"port", required_argument, NULL, 'p'},
+               {"username", required_argument, NULL, 'U'},
+               {"password", no_argument, NULL, 'W'},
+               {"echo", no_argument, NULL, 'e'},
+               {"quiet", no_argument, NULL, 'q'},
+               {"interactive", no_argument, NULL, 'i'},
+               {NULL, 0, NULL, 0}
+       };
+
+       char       *progname;
+       int                     optindex;
+       int                     c;
+
+       char       *dbname = NULL;
+       char       *host = NULL;
+       char       *port = NULL;
+       char       *username = NULL;
+       bool            password = false;
+       bool            echo = false;
+       bool            quiet = false;
+       bool            interactive = false;
+
+       PQExpBufferData sql;
+
+       PGconn     *conn;
+       PGresult   *result;
+
+       progname = get_progname(argv[0]);
+       init_nls();
+       handle_help_version_opts(argc, argv, "dropdb", help);
+
+       while ((c = getopt_long(argc, argv, "h:p:U:Weqi", long_options, &optindex)) != -1)
+       {
+               switch (c)
+               {
+                       case 'h':
+                               host = optarg;
+                               break;
+                       case 'p':
+                               port = optarg;
+                               break;
+                       case 'U':
+                               username = optarg;
+                               break;
+                       case 'W':
+                               password = true;
+                               break;
+                       case 'e':
+                               echo = true;
+                               break;
+                       case 'q':
+                               quiet = true;
+                               break;
+                       case 'i':
+                               interactive = true;
+                               break;
+                       default:
+                               fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                               exit(1);
+               }
+       }
+
+       switch (argc - optind)
+       {
+               case 0:
+                       fprintf(stderr, _("%s: missing required argument database name\n"), progname);
+                       fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                       exit(1);
+               case 1:
+                       dbname = argv[optind];
+                       break;
+               default:
+                       fprintf(stderr, _("%s: too many command-line arguments (first is '%s')\n"),
+                                       progname, argv[optind + 1]);
+                       fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                       exit(1);
+       }
+
+       if (interactive)
+       {
+               char       *reply;
+
+               printf(_("Database \"%s\" will be permanently deleted.\n"), dbname);
+               reply = simple_prompt("Are you sure? (y/n) ", 1, true);
+               if (reply[0] != 'y' && reply[0] != 'Y')
+                       exit(0);
+       }
+
+       initPQExpBuffer(&sql);
+
+       appendPQExpBuffer(&sql, "SET autocommit TO on;\nDROP DATABASE %s;\n",
+                                         fmtId(dbname));
+
+       conn = connectDatabase("template1", host, port, username, password, progname);
+
+       if (echo)
+               printf("%s", sql.data);
+       result = PQexec(conn, sql.data);
+       if (PQresultStatus(result) != PGRES_COMMAND_OK)
+       {
+               fprintf(stderr, _("%s: database removal failed: %s"),
+                               progname, PQerrorMessage(conn));
+               PQfinish(conn);
+               exit(1);
+       }
+
+       PQfinish(conn);
+       if (!quiet)
+               puts("DROP DATABASE");
+       exit(0);
+}
+
+
+static void
+help(const char *progname)
+{
+       printf(_("%s removes a PostgreSQL database.\n\n"), progname);
+       printf(_("Usage:\n"));
+       printf(_("  %s [OPTION]... DBNAME\n"), progname);
+       printf(_("\nOptions:\n"));
+       printf(_("  -e, --echo                show the commands being sent to the server\n"));
+       printf(_("  -i, --interactive         prompt before deleting anything\n"));
+       printf(_("  -q, --quiet               don't write any messages\n"));
+       printf(_("  -h, --host=HOSTNAME       database server host\n"));
+       printf(_("  -p, --port=PORT           database server port\n"));
+       printf(_("  -U, --username=USERNAME   user name to connect as\n"));
+       printf(_("  -W, --password            prompt for password\n"));
+       printf(_("  --help                    show this help, then exit\n"));
+       printf(_("  --version                 output version information, then exit\n"));
+       printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
+}
diff --git a/src/bin/scripts/droplang b/src/bin/scripts/droplang
deleted file mode 100644 (file)
index 5792e79..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-#! /bin/sh
-#-------------------------------------------------------------------------
-#
-# droplang --
-#   Remove a procedural language from a database
-#
-# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
-# Portions Copyright (c) 1994, Regents of the University of California
-#
-# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/droplang,v 1.27 2002/10/18 22:05:36 petere Exp $
-#
-#-------------------------------------------------------------------------
-
-CMDNAME=`basename "$0"`
-PATHNAME=`echo "$0" | sed "s,$CMDNAME\$,,"`
-
-PSQLOPT=
-dbname=
-langname=
-echo=
-list=
-showsql=
-
-# Check for echo -n vs echo \c
-
-if echo '\c' | grep -s c >/dev/null 2>&1
-then
-    ECHO_N="echo -n"
-    ECHO_C=""
-else
-    ECHO_N="echo"
-    ECHO_C='\c'
-fi
-
-
-# ----------
-# Get options, language name and dbname
-# ----------
-while [ "$#" -gt 0 ]
-do
-    case "$1" in 
-       --help|-\?)
-               usage=t
-                break
-               ;;
-        --list|-l)
-                list=t
-                ;;
-# options passed on to psql
-       --host|-h)
-               PSQLOPT="$PSQLOPT -h $2"
-               shift;;
-        -h*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --host=*)
-                PSQLOPT="$PSQLOPT -h `echo \"$1\" | sed 's/^--host=//'`"
-                ;;
-       --port|-p)
-               PSQLOPT="$PSQLOPT -p $2"
-               shift;;
-        -p*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --port=*)
-                PSQLOPT="$PSQLOPT -p `echo \"$1\" | sed 's/^--port=//'`"
-                ;;
-       --username|-U)
-               PSQLOPT="$PSQLOPT -U $2"
-               shift;;
-        -U*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --username=*)
-                PSQLOPT="$PSQLOPT -U `echo \"$1\" | sed 's/^--username=//'`"
-                ;;
-       --password|-W)
-               PSQLOPT="$PSQLOPT -W"
-               ;;
-       --dbname|-d)
-               dbname="$2"
-               shift;;
-        -d*)
-                dbname=`echo "$1" | sed 's/^-d//'`
-                ;;
-        --dbname=*)
-                dbname=`echo "$1" | sed 's/^--dbname=//'`
-                ;;
-       --echo|-e)
-               showsql=yes
-               ;;
-
-       -*)
-               echo "$CMDNAME: invalid option: $1" 1>&2
-                echo "Try '$CMDNAME --help' for more information." 1>&2
-               exit 1
-               ;;
-        *)
-               if [ "$list" != "t" ]
-               then    langname="$1"
-                       if [ "$2" ]
-                       then
-                               shift
-                               dbname="$1"
-                       fi
-               else    dbname="$1"
-               fi
-               if [ "$#" -ne 1 ]; then
-                       echo "$CMDNAME: invalid option: $2" 1>&2
-                       echo "Try '$CMDNAME --help' for more information." 1>&2
-                       exit 1
-               fi
-                ;;
-    esac
-    shift
-done
-
-
-if [ "$usage" ]; then
-        echo "$CMDNAME removes a procedural language from a database."
-       echo
-       echo "Usage:"
-        echo "  $CMDNAME [OPTION]... LANGNAME [DBNAME]"
-        echo
-       echo "Options:"
-       echo "  -d, --dbname=DBNAME       database to remove language from"
-       echo "  -l, --list                show a list of currently installed languages"
-       echo "  -h, --host=HOSTNAME       database server host"
-       echo "  -p, --port=PORT           database server port"
-       echo "  -U, --username=USERNAME   user name to connect as"
-       echo "  -W, --password            prompt for password"
-       echo " --help                     show this help, then exit"
-        echo
-       echo "Report bugs to <pgsql-bugs@postgresql.org>."
-       exit 0
-fi
-
-
-if [ -z "$dbname" ]; then
-        if [ "$PGDATABASE" ]; then
-                dbname="$PGDATABASE"
-        elif [ "$PGUSER" ]; then
-                dbname="$PGUSER"
-        else
-                dbname=`${PATHNAME}pg_id -u -n`
-        fi
-        [ "$?" -ne 0 ] && exit 1
-fi
-
-
-# ----------
-# List option, doesn't need langname
-# ----------
-if [ "$list" ]; then
-       sqlcmd="SELECT lanname as \"Name\", lanpltrusted as \"Trusted?\" FROM pg_language WHERE lanispl = TRUE"
-       if [ "$showsql" = yes ]; then
-               echo "$sqlcmd"
-       fi
-        ${PATHNAME}psql $PSQLOPT -d "$dbname" -P 'title=Procedural languages' -c "$sqlcmd"
-        exit $?
-fi
-
-
-# ----------
-# We can't go any farther without a langname
-# ----------
-if [ -z "$langname" ]; then
-       echo "$CMDNAME: missing required argument language name" 1>&2
-        echo "Try '$CMDNAME --help' for help." 1>&2
-       exit 1
-fi
-
-PSQL="${PATHNAME}psql -A -t -q $PSQLOPT -d $dbname -c"
-
-
-# ----------
-# Make sure the language is installed and find the oid of the handler function
-# ----------
-sqlcmd="SELECT lanplcallfoid FROM pg_language WHERE lanname = '$langname' AND lanispl;"
-if [ "$showsql" = yes ]; then
-       echo "$sqlcmd"
-fi
-lanplcallfoid=`$PSQL "$sqlcmd"`
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: external error" 1>&2
-       exit 1
-fi
-if [ -z "$lanplcallfoid" ]; then
-       echo "$CMDNAME: language \"$langname\" is not installed in database $dbname" 1>&2
-       exit 1
-fi
-
-
-# ----------
-# Check that there are no functions left defined in that language
-# ----------
-sqlcmd="SELECT COUNT(proname) FROM pg_proc P, pg_language L WHERE P.prolang = L.oid AND L.lanname = '$langname';"
-if [ "$showsql" = yes ]; then
-       echo "$sqlcmd"
-fi
-res=`$PSQL "$sqlcmd"`
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: external error" 1>&2
-       exit 1
-fi
-if [ "$res" -ne 0 ]; then
-       echo "$CMDNAME: There are $res functions/trigger procedures declared in language" 1>&2
-        echo "$langname.  Language not removed." 1>&2
-       exit 1
-fi
-
-# ----------
-# Check that the handler function isn't used by some other language
-# ----------
-sqlcmd="SELECT count(*) FROM pg_language WHERE lanplcallfoid = $lanplcallfoid AND lanname <> '$langname';"
-if [ "$showsql" = yes ]; then
-       echo "$sqlcmd"
-fi
-res=`$PSQL "$sqlcmd"`
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: external error" 1>&2
-       exit 1
-fi
-if [ "$res" -eq 0 ]; then
-       keephandler=no
-else
-       keephandler=yes
-fi
-
-# ----------
-# Drop the language
-# ----------
-sqlcmd="SET autocommit TO 'on';DROP LANGUAGE \"$langname\";"
-if [ "$showsql" = yes ]; then
-       echo "$sqlcmd"
-fi
-$PSQL "$sqlcmd"
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: language removal failed" 1>&2
-       exit 1
-fi
-
-# ----------
-# Drop the call handler
-# ----------
-if [ "$keephandler" = yes ]; then
-        exit 0
-fi
-
-sqlcmd="SELECT proname FROM pg_proc WHERE oid = $lanplcallfoid;"
-if [ "$showsql" = yes ]; then
-       echo "$sqlcmd"
-fi
-handler=`$PSQL "$sqlcmd"`
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: external error" 1>&2
-       exit 1
-fi
-
-sqlcmd="SET autocommit TO 'on';DROP FUNCTION \"$handler\" ();"
-if [ "$showsql" = yes ]; then
-       echo "$sqlcmd"
-fi
-$PSQL "$sqlcmd"
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: language removal failed" 1>&2
-       exit 1
-fi
-
-exit 0
diff --git a/src/bin/scripts/droplang.c b/src/bin/scripts/droplang.c
new file mode 100644 (file)
index 0000000..3b9701d
--- /dev/null
@@ -0,0 +1,255 @@
+/*-------------------------------------------------------------------------
+ *
+ * droplang
+ *
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Header: /cvsroot/pgsql/src/bin/scripts/droplang.c,v 1.1 2003/03/18 22:19:47 petere Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+#include "common.h"
+#include "print.h"
+
+
+static void help(const char *progname);
+
+
+int
+main(int argc, char *argv[])
+{
+       static struct option long_options[] = {
+               {"list", no_argument, NULL, 'l'},
+               {"host", required_argument, NULL, 'h'},
+               {"port", required_argument, NULL, 'p'},
+               {"username", required_argument, NULL, 'U'},
+               {"password", no_argument, NULL, 'W'},
+               {"dbname", required_argument, NULL, 'd'},
+               {"echo", no_argument, NULL, 'e'},
+               {NULL, 0, NULL, 0}
+       };
+
+       char       *progname;
+       int                     optindex;
+       int                     c;
+
+       bool            listlangs = false;
+       const char *dbname = NULL;
+       char       *host = NULL;
+       char       *port = NULL;
+       char       *username = NULL;
+       bool            password = false;
+       bool            echo = false;
+       char       *langname = NULL;
+
+       char       *p;
+       char       *lanplcallfoid;
+       char       *handler;
+       bool            keephandler;
+
+       PQExpBufferData sql;
+
+       PGconn     *conn;
+       PGresult   *result;
+
+       progname = get_progname(argv[0]);
+       init_nls();
+       handle_help_version_opts(argc, argv, "droplang", help);
+
+       while ((c = getopt_long(argc, argv, "lh:p:U:Wd:e", long_options, &optindex)) != -1)
+       {
+               switch (c)
+               {
+                       case 'l':
+                               listlangs = true;
+                               break;
+                       case 'h':
+                               host = optarg;
+                               break;
+                       case 'p':
+                               port = optarg;
+                               break;
+                       case 'U':
+                               username = optarg;
+                               break;
+                       case 'W':
+                               password = true;
+                               break;
+                       case 'd':
+                               dbname = optarg;
+                               break;
+                       case 'e':
+                               echo = true;
+                               break;
+                       default:
+                               fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                               exit(1);
+               }
+       }
+
+       if (argc - optind > 0)
+       {
+               if (listlangs)
+                       dbname = argv[optind++];
+               else
+               {
+                       langname = argv[optind++];
+                       if (argc - optind > 0)
+                               dbname = argv[optind++];
+               }
+       }
+
+       if (argc - optind > 0)
+       {
+               fprintf(stderr, _("%s: too many command line options (first is '%s')\n"),
+                               progname, argv[optind]);
+           fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+               exit(1);
+       }
+
+       if (dbname == NULL)
+       {
+               if (getenv("PGDATABASE"))
+                       dbname = getenv("PGDATABASE");
+               else if (getenv("PGUSER"))
+                       dbname = getenv("PGUSER");
+               else
+                       dbname = get_user_name(progname);
+       }
+
+       initPQExpBuffer(&sql);
+
+       /*
+        * List option
+        */
+       if (listlangs)
+       {
+               printQueryOpt popt;
+
+               conn = connectDatabase(dbname, host, port, username, password, progname);
+
+               printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language WHERE lanispl IS TRUE;", _("Name"), _("yes"), _("no"), _("Trusted?"));
+               result = executeQuery(conn, sql.data, progname, echo);
+
+               memset(&popt, 0, sizeof(popt));
+               popt.topt.format = PRINT_ALIGNED;
+               popt.topt.border = 1;
+               popt.topt.encoding = PQclientEncoding(conn);
+               popt.title = _("Procedural Languages");
+               printQuery(result, &popt, stdout);
+
+               PQfinish(conn);
+               exit(0);
+       }
+
+       if (langname == NULL)
+       {
+               fprintf(stderr, _("%s: missing required argument language name\n"), progname);
+           fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+               exit(1);
+       }
+
+       for (p = langname; *p; p++)
+               if (*p >= 'A' && *p <= 'Z')
+                       *p += ('a' - 'A');
+
+       conn = connectDatabase(dbname, host, port, username, password, progname);
+
+       /*
+        * Make sure the language is installed and find the OID of the handler function
+        */
+       printfPQExpBuffer(&sql, "SELECT lanplcallfoid FROM pg_language WHERE lanname = '%s' AND lanispl;", langname);
+       result = executeQuery(conn, sql.data, progname, echo);
+       if (PQntuples(result) == 0)
+       {
+               PQfinish(conn);
+               fprintf(stderr, _("%s: language \"%s\" is not installed in database \"%s\"\n"),
+                               progname, langname, dbname);
+               exit(1);
+       }
+       lanplcallfoid = PQgetvalue(result, 0, 0);
+       /* result not cleared! */
+
+       /*
+        * Check that there are no functions left defined in that language
+        */
+       printfPQExpBuffer(&sql, "SELECT count(proname) FROM pg_proc P, pg_language L WHERE P.prolang = L.oid AND L.lanname = '%s';", langname);
+       result = executeQuery(conn, sql.data, progname, echo);
+       if (strcmp(PQgetvalue(result, 0, 0), "0")!=0)
+       {
+               PQfinish(conn);
+               fprintf(stderr,
+                               _("%s: There are %s functions declared in language \"%s\".  Language not removed.\n"),
+                               progname, PQgetvalue(result, 0, 0), langname);
+               exit(1);
+       }
+       PQclear(result);
+
+       /*
+        * Check that the handler function isn't used by some other language
+        */
+       printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language WHERE lanplcallfoid = %s AND lanname <> '%s';", lanplcallfoid, langname);
+       result = executeQuery(conn, sql.data, progname, echo);
+       if (strcmp(PQgetvalue(result, 0, 0), "0")==0)
+               keephandler = false;
+       else
+               keephandler = true;
+       PQclear(result);
+
+       /*
+        * Find the handler name
+        */
+       if (!keephandler)
+       {
+               printfPQExpBuffer(&sql, "SELECT proname FROM pg_proc WHERE oid = %s;", lanplcallfoid);
+               result = executeQuery(conn, sql.data, progname, echo);
+               handler = PQgetvalue(result, 0, 0);
+               /* result not cleared! */
+       }
+       else
+               handler = NULL;
+
+       /*
+        * Drop the language
+        */
+       printfPQExpBuffer(&sql, "SET autocommit TO on;\n");
+       appendPQExpBuffer(&sql, "DROP LANGUAGE \"%s\";\n", langname);
+       if (!keephandler)
+               appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\" ();\n", handler);
+       if (echo)
+               printf("%s", sql.data);
+       result = PQexec(conn, sql.data);
+       if (PQresultStatus(result) != PGRES_COMMAND_OK)
+       {
+               fprintf(stderr, _("%s: language removal failed: %s"),
+                               progname, PQerrorMessage(conn));
+               PQfinish(conn);
+               exit(1);
+       }
+
+       PQfinish(conn);
+       exit(0);
+}
+
+
+static void
+help(const char *progname)
+{
+       printf(_("%s removes a procedural language from a database.\n\n"), progname);
+       printf(_("Usage:\n"));
+       printf(_("  %s [OPTION]... LANGNAME [DBNAME]\n"), progname);
+       printf(_("\nOptions:\n"));
+       printf(_("  -d, --dbname=DBNAME       database to install language in\n"));
+       printf(_("  -e, --echo                show the commands being sent to the server\n"));
+       printf(_("  -l, --list                show a list of currently installed languages\n"));
+       printf(_("  -h, --host=HOSTNAME       database server host\n"));
+       printf(_("  -p, --port=PORT           database server port\n"));
+       printf(_("  -U, --username=USERNAME   user name to connect as\n"));
+       printf(_("  -W, --password            prompt for password\n"));
+       printf(_("  --help                    show this help, then exit\n"));
+       printf(_("  --version                 output version information, then exit\n"));
+       printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
+}
diff --git a/src/bin/scripts/dropuser b/src/bin/scripts/dropuser
deleted file mode 100644 (file)
index af11305..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/bin/sh
-#-------------------------------------------------------------------------
-#
-# dropuser--
-#    Utility for removing a user from the PostgreSQL database.
-#
-# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
-# Portions Copyright (c) 1994, Regents of the University of California
-#
-#
-# IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/bin/scripts/Attic/dropuser,v 1.21 2002/10/18 22:05:36 petere Exp $
-#
-# Note - this should NOT be setuid.
-#
-#-------------------------------------------------------------------------
-
-CMDNAME=`basename "$0"`
-PATHNAME=`echo "$0" | sed "s,$CMDNAME\$,,"`
-
-PSQLOPT=
-forcedel=t
-DelUser=
-
-# These handle spaces/tabs in identifiers
-_IFS="$IFS"
-NL="
-"
-# Check for echo -n vs echo \c
-
-if echo '\c' | grep -s c >/dev/null 2>&1
-then
-    ECHO_N="echo -n"
-    ECHO_C=""
-else
-    ECHO_N="echo"
-    ECHO_C='\c'
-fi
-
-
-while [ "$#" -gt 0 ]
-do
-    case "$1" in
-       --help|-\?)
-               usage=t
-                break
-               ;;
-# options passed on to psql
-       --host|-h)
-               PSQLOPT="$PSQLOPT -h $2"
-               shift;;
-        -h*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --host=*)
-                PSQLOPT="$PSQLOPT -h `echo \"$1\" | sed 's/^--host=//'`"
-                ;;
-       --port|-p)
-               PSQLOPT="$PSQLOPT -p $2"
-               shift;;
-        -p*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --port=*)
-                PSQLOPT="$PSQLOPT -p `echo \"$1\" | sed 's/^--port=//'`"
-                ;;
-# Note: These two specify the user to connect as (like in psql),
-#       not the user you're dropping.
-       --username|-U)
-               PSQLOPT="$PSQLOPT -U $2"
-               shift;;
-        -U*)
-                PSQLOPT="$PSQLOPT $1"
-                ;;
-        --username=*)
-                PSQLOPT="$PSQLOPT -U `echo \"$1\" | sed 's/^--username=//'`"
-                ;;
-       --password|-W)
-               PSQLOPT="$PSQLOPT -W"
-               ;;
-       --echo|-e)
-               PSQLOPT="$PSQLOPT -e"
-               ;;
-       --quiet|-q)
-               PSQLOPT="$PSQLOPT -o /dev/null"
-               ;;
-# other options
-       --interactive|-i)
-               forcedel=f
-               ;;
-       -*)
-               echo "$CMDNAME: invalid option: $1" 1>&2
-                echo "Try '$CMDNAME --help' for more information." 1>&2
-               exit 1
-               ;;
-         *)
-               DelUser="$1"
-               if [ "$#" -ne 1 ]; then
-                       echo "$CMDNAME: invalid option: $2" 1>&2
-                       echo "Try '$CMDNAME --help' for more information." 1>&2
-                       exit 1
-               fi
-               ;;
-    esac
-    shift;
-done
-
-
-if [ "$usage" ]; then
-       echo "$CMDNAME removes a PostgreSQL user."
-        echo
-       echo "Usage:"
-        echo "  $CMDNAME [OPTION]... [USERNAME]"
-        echo
-       echo "Options:"
-        echo "  -e, --echo                show the query being sent to the backend"
-       echo "  -i, --interactive         prompt before deleting anything"
-        echo "  -q, --quiet               don't write any messages"
-       echo "  -h, --host=HOSTNAME       database server host"
-       echo "  -p, --port=PORT           database server port"
-       echo "  -U, --username=USERNAME   user name to connect as (not the one to drop)"
-       echo "  -W, --password            prompt for password to connect"
-       echo " --help                     show this help, then exit"
-       echo
-       echo "Report bugs to <pgsql-bugs@postgresql.org>."
-       exit 0
-fi
-
-# Prompt for username if missing
-
-if [ -z "$DelUser" ]; then
-       $ECHO_N "Enter name of user to delete: "$ECHO_C
-        IFS="$NL"
-        read DelUser
-        IFS="$_IFS"
-       [ "$?" -ne 0 ] && exit 1
-fi
-
-
-if [ "$forcedel" = f ]; then
-       echo "User \"$DelUser\" will be permanently deleted."
-       $ECHO_N "Are you sure? (y/n) "$ECHO_C
-       read REPLY
-
-       [ "$?" -eq 1 ] && exit 1
-       [ "$REPLY" != "y" -a "$REPLY" != "Y" ] && exit 0
-fi
-
-
-DelUser=`echo "$DelUser" | sed 's/\"/\\\"/g'`
-
-${PATHNAME}psql $PSQLOPT -d template1 -c "SET autocommit TO 'on';DROP USER \"$DelUser\""
-
-if [ "$?" -ne 0 ]; then
-       echo "$CMDNAME: deletion of user \"$DelUser\" failed" 1>&2
-       exit 1
-fi
-
-exit 0
diff --git a/src/bin/scripts/dropuser.c b/src/bin/scripts/dropuser.c
new file mode 100644 (file)
index 0000000..df82f21
--- /dev/null
@@ -0,0 +1,156 @@
+/*-------------------------------------------------------------------------
+ *
+ * dropuser
+ *
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Header: /cvsroot/pgsql/src/bin/scripts/dropuser.c,v 1.1 2003/03/18 22:19:47 petere Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+#include "common.h"
+#include "dumputils.h"
+
+
+static void help(const char *progname);
+
+
+int
+main(int argc, char *argv[])
+{
+       static struct option long_options[] = {
+               {"host", required_argument, NULL, 'h'},
+               {"port", required_argument, NULL, 'p'},
+               {"username", required_argument, NULL, 'U'},
+               {"password", no_argument, NULL, 'W'},
+               {"echo", no_argument, NULL, 'e'},
+               {"quiet", no_argument, NULL, 'q'},
+               {"interactive", no_argument, NULL, 'i'},
+               {NULL, 0, NULL, 0}
+       };
+
+       char       *progname;
+       int                     optindex;
+       int                     c;
+
+       char       *dropuser = NULL;
+       char       *host = NULL;
+       char       *port = NULL;
+       char       *username = NULL;
+       bool            password = false;
+       bool            echo = false;
+       bool            quiet = false;
+       bool            interactive = false;
+
+       PQExpBufferData sql;
+
+       PGconn     *conn;
+       PGresult   *result;
+
+       progname = get_progname(argv[0]);
+       init_nls();
+       handle_help_version_opts(argc, argv, "dropuser", help);
+
+       while ((c = getopt_long(argc, argv, "h:p:U:Weqi", long_options, &optindex)) != -1)
+       {
+               switch (c)
+               {
+                       case 'h':
+                               host = optarg;
+                               break;
+                       case 'p':
+                               port = optarg;
+                               break;
+                       case 'U':
+                               username = optarg;
+                               break;
+                       case 'W':
+                               password = true;
+                               break;
+                       case 'e':
+                               echo = true;
+                               break;
+                       case 'q':
+                               quiet = true;
+                               break;
+                       case 'i':
+                               interactive = true;
+                               break;
+                       default:
+                               fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                               exit(1);
+               }
+       }
+
+       switch (argc - optind)
+       {
+               case 0:
+                       break;
+               case 1:
+                       dropuser = argv[optind];
+                       break;
+               default:
+                       fprintf(stderr, _("%s: too many command-line arguments (first is '%s')\n"),
+                                       progname, argv[optind + 1]);
+                       fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                       exit(1);
+       }
+
+       if (dropuser == NULL)
+               dropuser = simple_prompt("Enter name of user to drop: ", 128, true);
+
+       if (interactive)
+       {
+               char       *reply;
+
+               printf(_("User \"%s\" will be permanently deleted.\n"), dropuser);
+               reply = simple_prompt("Are you sure? (y/n) ", 1, true);
+               if (reply[0] != 'y' && reply[0] != 'Y')
+                       exit(0);
+       }
+
+       initPQExpBuffer(&sql);
+       appendPQExpBuffer(&sql, "SET autocommit TO on;\nDROP USER %s;\n", fmtId(dropuser));
+
+       conn = connectDatabase("template1", host, port, username, password, progname);
+
+       if (echo)
+               printf("%s", sql.data);
+       result = PQexec(conn, sql.data);
+
+       if (PQresultStatus(result) != PGRES_COMMAND_OK)
+       {
+               fprintf(stderr, _("%s: deletion of user %s failed: %s"),
+                               progname, dropuser, PQerrorMessage(conn));
+               PQfinish(conn);
+               exit(1);
+       }
+
+       PQfinish(conn);
+       if (!quiet)
+               puts("DROP USER");
+       exit(0);
+}
+
+
+static void
+help(const char *progname)
+{
+       printf(_("%s removes a PostgreSQL user.\n\n"), progname);
+       printf(_("Usage:\n"));
+       printf(_("  %s [OPTION]... [USERNAME]\n"), progname);
+       printf(_("\nOptions:\n"));
+    printf(_("  -e, --echo                show the commands being sent to the server\n"));
+       printf(_("  -i, --interactive         prompt before deleting anything\n"));
+    printf(_("  -q, --quiet               don't write any messages\n"));
+       printf(_("  -h, --host=HOSTNAME       database server host\n"));
+       printf(_("  -p, --port=PORT           database server port\n"));
+       printf(_("  -U, --username=USERNAME   user name to connect as (not the one to drop)\n"));
+       printf(_("  -W, --password            prompt for password to connect\n"));
+       printf(_("  --help                    show this help, then exit\n"));
+       printf(_("  --version                 output version information, then exit\n"));
+       printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
+}
diff --git a/src/bin/scripts/nls.mk b/src/bin/scripts/nls.mk
new file mode 100644 (file)
index 0000000..365b879
--- /dev/null
@@ -0,0 +1,7 @@
+# $Header: /cvsroot/pgsql/src/bin/scripts/nls.mk,v 1.1 2003/03/18 22:19:47 petere Exp $
+CATALOG_NAME    := pgscripts
+AVAIL_LANGUAGES := 
+GETTEXT_FILES   := createdb.c createlang.c createuser.c \
+                   dropdb.c droplang.c dropuser.c \
+                   common.c
+GETTEXT_TRIGGERS:= _ simple_prompt