From: Bryan Henderson Date: Mon, 9 Dec 1996 01:55:51 +0000 (+0000) Subject: Monitor has been obsoleted by psql. X-Git-Tag: REL6_1~883 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9e60c1711d359f2cefe18c0b62f76a182aadfbd5;p=postgresql Monitor has been obsoleted by psql. --- diff --git a/src/bin/monitor/Makefile b/src/bin/monitor/Makefile deleted file mode 100644 index 53e6f0d514..0000000000 --- a/src/bin/monitor/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -#------------------------------------------------------------------------- -# -# Makefile.inc-- -# Makefile for bin/monitor -# -# Copyright (c) 1994, Regents of the University of California -# -# -# IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/monitor/Attic/Makefile,v 1.1.1.1 1996/07/09 06:22:13 scrappy Exp $ -# -#------------------------------------------------------------------------- - -PROG= monitor - -MKDIR= ../../mk -include $(MKDIR)/postgres.mk -include ../Makefile.global - -SRCS= monitor.c - -include $(MKDIR)/postgres.prog.mk - diff --git a/src/bin/monitor/monitor.c b/src/bin/monitor/monitor.c deleted file mode 100644 index b1f9554637..0000000000 --- a/src/bin/monitor/monitor.c +++ /dev/null @@ -1,1066 +0,0 @@ -/*------------------------------------------------------------------------- - * - * monitor.c-- - * POSTGRES Terminal Monitor - * - * Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/monitor/Attic/monitor.c,v 1.6 1996/11/04 03:59:26 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -#include -#include "libpq/pqsignal.h" /* substitute for */ -#include -#include -#include -#include /* for MAXHOSTNAMELEN on most */ -#ifndef WIN32 -#include -#endif -#if defined(sparc_solaris) || defined(i386_solaris) -#include /* for MAXHOSTNAMELEN on some */ -#endif -#include -/* #include */ -#include - -#include "libpq-fe.h" -#include "libpq/libpq-fs.h" - -extern char *getenv(); - -/* - * monitor.c -- function prototypes (all private) - */ -static void do_input(FILE *ifp); -static void init_tmon(); -static void welcome(); -static void handle_editor(); -static void handle_shell(); -static void handle_send(); -static int handle_execution(char *query); -static void handle_file_insert(FILE *ifp); -static void handle_print(); -static void handle_exit(int exit_status); -static void handle_clear(); -static void handle_print_time(); -static int handle_write_to_file(); -static void handle_help(); -static void stuff_buffer(char c); -static void argsetup(int *argcP, char ***argvP); -static void handle_copy_out(PGresult *res); -static void handle_copy_in(PGresult *res); - - -/* - * Functions which maintain the logical query buffer in - * /tmp/PQxxxxx. It in general just does a copy from input - * to query buffer, unless it gets a backslash escape character. - * It recognizes the following escapes: - * - * \e -- enter editor - * \g -- "GO": submit query to POSTGRES - * \i -- include (switch input to external file) - * \p -- print query buffer - * \q -- quit POSTGRES - * \r -- force reset (clear) of query buffer - * \s -- call shell - * \t -- print current time - * \w -- write query buffer to external file - * \h -- print the list of commands - * \? -- print the list of commands - * \\ -- produce a single backslash in query buffer - * - */ - -/* - * Declaration of global variables (but only to the file monitor.c - */ - -#define DEFAULT_EDITOR "/usr/ucb/vi" -#define COPYBUFSIZ 8192 -static char *user_editor; /* user's desired editor */ -static int tmon_temp; /* file descriptor for temp. buffer file */ -static char *tmon_temp_filename; -static char query_buffer[8192]; /* Max postgres buffer size */ -static char *RunOneFile = NULL; -bool RunOneCommand = false; -bool Debugging; -bool Verbose; -bool Silent; -bool TerseOutput = false; -bool PrintAttNames = true; -bool SingleStepMode = false; -bool SemicolonIsGo = true; - -#define COLWIDTH 12 - -extern char *optarg; -extern int optind,opterr; -FILE *debug_port; - -/* - * As of release 4, we allow the user to specify options in the environment - * variable PGOPTION. These are treated as command-line options to the - * terminal monitor, and are parsed before the actual command-line args. - * The arge struct is used to construct an argv we can pass to getopt() - * containing the union of the environment and command line arguments. - */ - -typedef struct arge { - char *a_arg; - struct arge *a_next; -} arge; - -/* the connection to the backend */ -PGconn *conn; - -void -main(int argc, char **argv) -{ - int c; - int errflag = 0; - char *progname; - char *debug_file; - char *dbname; - char *command; - int exit_status = 0; - char errbuf[ERROR_MSG_LENGTH]; - char *username, usernamebuf[NAMEDATALEN + 1]; - - char *pghost = NULL; - char *pgtty = NULL; - char *pgoptions = NULL; - char *pgport = NULL; - int pgtracep = 0; - - /* - * Processing command line arguments. - * - * h : sets the hostname. - * p : sets the coom. port - * t : sets the tty. - * o : sets the other options. (see doc/libpq) - * d : enable debugging mode. - * q : run in quiet mode - * Q : run in VERY quiet mode (no output except on errors) - * c : monitor will run one POSTQUEL command and exit - * - * s : step mode (pauses after each command) - * S : don't use semi colon as \g - * - * T : terse mode - no formatting - * N : no attribute names - only columns of data - * (these two options are useful in conjunction with the "-c" option - * in scripts.) - */ - - progname = *argv; - Debugging = false; - Verbose = true; - Silent = false; - - /* prepend PGOPTION, if any */ - argsetup(&argc, &argv); - - while ((c = getopt(argc, argv, "a:h:f:p:t:d:qsSTNQc:")) != EOF) { - switch (c) { - case 'a': - fe_setauthsvc(optarg, errbuf); - break; - case 'h' : - pghost = optarg; - break; - case 'f' : - RunOneFile = optarg; - break; - case 'p' : - pgport = optarg; - break; - case 't' : - pgtty = optarg; - break; - case 'T' : - TerseOutput = true; - break; - case 'N' : - PrintAttNames = false; - break; - case 'd' : - - /* - * When debugging is turned on, the debugging messages - * will be sent to the specified debug file, which - * can be a tty .. - */ - - Debugging = true; - debug_file = optarg; - debug_port = fopen(debug_file,"w+"); - if (debug_port == NULL) { - fprintf(stderr,"Unable to open debug file %s \n", debug_file); - exit(1); - } - pgtracep = 1; - break; - case 'q' : - Verbose = false; - break; - case 's' : - SingleStepMode = true; - SemicolonIsGo = true; - break; - case 'S' : - SemicolonIsGo = false; - break; - case 'Q' : - Verbose = false; - Silent = true; - break; - case 'c' : - Verbose = false; - Silent = true; - RunOneCommand = true; - command = optarg; - break; - case '?' : - default : - errflag++; - break; - } - } - - if (errflag ) { - fprintf(stderr, "usage: %s [options...] [dbname]\n", progname); - fprintf(stderr, "\t-a authsvc\tset authentication service\n"); - fprintf(stderr, "\t-c command\t\texecute one command\n"); - fprintf(stderr, "\t-d debugfile\t\tdebugging output file\n"); - fprintf(stderr, "\t-h host\t\t\tserver host name\n"); - fprintf(stderr, "\t-f file\t\t\trun query from file\n"); - fprintf(stderr, "\t-p port\t\t\tserver port number\n"); - fprintf(stderr, "\t-q\t\t\tquiet output\n"); - fprintf(stderr, "\t-t logfile\t\terror-logging tty\n"); - fprintf(stderr, "\t-N\t\t\toutput without attribute names\n"); - fprintf(stderr, "\t-Q\t\t\tREALLY quiet output\n"); - fprintf(stderr, "\t-T\t\t\tterse output\n"); - exit(2); - } - - /* Determine our username (according to the authentication system, if - * there is one). - */ - if ((username = fe_getauthname(errbuf)) == (char *) NULL) { - fprintf(stderr, "%s: could not find a valid user name\n", - progname); - exit(2); - } - memset(usernamebuf, 0, sizeof(usernamebuf)); - (void) strncpy(usernamebuf, username, NAMEDATALEN); - username = usernamebuf; - - /* find database */ - if (!(dbname = argv[optind]) && - !(dbname = getenv("DATABASE")) && - !(dbname = username)) { - fprintf(stderr, "%s: no database name specified\n", progname); - exit (2); - } - - conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbname); - if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr,"Connection to database '%s' failed.\n", dbname); - fprintf(stderr,"%s",PQerrorMessage(conn)); - exit(1); - } - - if (pgtracep) - PQtrace(conn,debug_port); - - /* print out welcome message and start up */ - welcome(); - init_tmon(); - - /* parse input */ - if (RunOneCommand) { - exit_status = handle_execution(command); - } else if (RunOneFile) { - bool oldVerbose; - FILE *ifp; - - if ((ifp = fopen(RunOneFile, "r")) == NULL) { - fprintf(stderr, "Cannot open %s\n", RunOneFile); - } - - if (SingleStepMode) { - oldVerbose = Verbose; - Verbose = false; - } - do_input(ifp); - fclose(ifp); - if (SingleStepMode) - Verbose = oldVerbose; - } else { - do_input(stdin); - } - - handle_exit(exit_status); -} - -static void -do_input(FILE *ifp) -{ - int c; - char escape; - - /* - * Processing user input. - * Basically we stuff the user input to a temp. file until - * an escape char. is detected, after which we switch - * to the appropriate routine to handle the escape. - */ - - if (ifp == stdin) { - if (Verbose) - fprintf(stdout,"\nGo \n* "); - else { - if (!Silent) - fprintf(stdout, "* "); - } - } - while ((c = getc(ifp)) != EOF ) { - if ( c == '\\') { - /* handle escapes */ - escape = getc(ifp); - switch( escape ) { - case 'e': - handle_editor(); - break; - case 'g': - handle_send(); - break; - case 'i': - { - bool oldVerbose; - - if (SingleStepMode) { - oldVerbose = Verbose; - Verbose = false; - } - handle_file_insert(ifp); - if (SingleStepMode) - Verbose = oldVerbose; - } - break; - case 'p': - handle_print(); - break; - case 'q': - handle_exit(0); - break; - case 'r': - handle_clear(); - break; - case 's': - handle_shell(); - break; - case 't': - handle_print_time(); - break; - case 'w': - handle_write_to_file(); - break; - case '?': - case 'h': - handle_help(); - break; - case '\\': - c = escape; - stuff_buffer(c); - break; - case ';': - c = escape; - stuff_buffer(c); - break; - default: - fprintf(stderr, "unknown escape given\n"); - break; - } /* end-of-switch */ - if (ifp == stdin && escape != '\\') { - if (Verbose) - fprintf(stdout,"\nGo \n* "); - else { - if (!Silent) - fprintf(stdout, "* "); - } - } - } else { - stuff_buffer(c); - if (c == ';' && SemicolonIsGo) { - handle_send(); - if (Verbose) - fprintf(stdout,"\nGo \n* "); - else { - if (!Silent) - fprintf(stdout, "* "); - } - } - } - } -} - -/* - * init_tmon() - * - * set the following : - * user_editor, defaults to DEFAULT_EDITOR if env var is not set - */ -static void -init_tmon() -{ - if (!RunOneCommand) - { - char *temp_editor = getenv("EDITOR"); - - if (temp_editor != NULL) - user_editor = temp_editor; - else - user_editor = DEFAULT_EDITOR; - - tmon_temp_filename = malloc(20); - sprintf(tmon_temp_filename, "/tmp/PQ%d", getpid()); - tmon_temp = open(tmon_temp_filename,O_CREAT | O_RDWR | O_APPEND,0666); - } - - /* - * Catch signals so we can delete the scratch file GK - * but only if we aren't already ignoring them -mer - */ - -#ifndef WIN32 - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, handle_exit); - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) - signal(SIGQUIT, handle_exit); -#endif /* WIN32 we'll have to figure out how to handle these */ - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, handle_exit); - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, handle_exit); -} - -/* - * welcome simply prints the Postgres welcome mesg. - */ -static -void welcome() -{ - if (Verbose) { - fprintf(stdout,"Welcome to the POSTGRES95 terminal monitor\n"); - fprintf(stdout," Please read the file COPYRIGHT for copyright terms of POSTGRES95\n"); - } -} - - -/* - * handle_editor() - * - * puts the user into edit mode using the editor specified - * by the variable "user_editor". - */ -static void -handle_editor() -{ - char edit_line[100]; - - close(tmon_temp); - sprintf(edit_line,"%s %s",user_editor,tmon_temp_filename); - system(edit_line); - tmon_temp = open(tmon_temp_filename,O_CREAT | O_RDWR | O_APPEND,0666); -} - -static void -handle_shell() -{ - char *user_shell; - - user_shell = getenv("SHELL"); - if (user_shell != NULL) { - system(user_shell); - } else { - system("/bin/sh"); - } -} - -/* - * handle_send() - * - * This is the routine that initialises the comm. with the - * backend. After the tuples have been returned and - * displayed, the query_buffer is cleared for the - * next query. - * - */ - -#include - -static void -handle_send() -{ - char c = (char)0; - off_t pos; - int cc = 0; - int i = 0; - - pos = lseek(tmon_temp, (off_t) 0, SEEK_SET); - - if (pos != 0) - fprintf(stderr, "Bogus file position\n"); - - if (Verbose) - printf("\n"); - - /* discard leading white space */ - while ( ( cc = read(tmon_temp,&c,1) ) != 0 && isspace((int)c)) - continue; - - if ( cc != 0 ) { - pos = lseek(tmon_temp, (off_t) -1, SEEK_CUR); - } - - if (SingleStepMode) { - char buf[1024]; - fprintf(stdout, "\n*******************************************************************************\n"); - while ((cc = read(tmon_temp,buf,1024))>0) { - buf[cc] = '\0'; - fprintf(stdout, "%s", buf); - } - fprintf(stdout, "\n*******************************************************************************\n\n"); - (void)lseek(tmon_temp, (off_t)pos, SEEK_SET); - } - - query_buffer[0] = 0; - - /* - * Stripping out comments (if any) from the query (should really be - * handled in the parser, of course). - */ - while ( ( cc = read(tmon_temp,&c,1) ) != 0) { - switch(c) { - case '\n': - query_buffer[i++] = ' '; - break; - case '-': { - int temp; - char temp_c; - if ((temp = read(tmon_temp,&temp_c,1)) > 0) { - if (temp_c == '-' ) { - /* read till end of line */ - while ((temp = read(tmon_temp,&temp_c,1)) != 0) { - if (temp_c=='\n') - break; - } - }else { - query_buffer[i++] = c; - query_buffer[i++] = temp_c; - } - } else { - query_buffer[i++] = c; - } - break; - } - case '$': { - int temp; - char temp_c[4]; - /* - * monitor feature, not POSTGRES SQL. When monitor sees $PWD, - * it will substitute in the current directory. - */ - if ((temp = read(tmon_temp,temp_c,3)) > 0) { - temp_c[temp] = '\0'; - if (!strncmp(temp_c, "PWD", 3)) { - int len; - char cwdPath[MAXPATHLEN]; - if (getcwd(cwdPath, MAXPATHLEN)==NULL) { - fprintf(stderr, - "cannot get current working directory\n"); - break; - } - len = strlen(cwdPath); - query_buffer[i] = '\0'; - strcat(query_buffer, cwdPath); - i += len; - } else { - int j; - query_buffer[i++] = c; - for(j = 0; j < temp; j++) { - query_buffer[i++] = temp_c[j]; - } - } - } else { - query_buffer[i++] = c; - } - break; - } - default: - query_buffer[i++] = c; - break; - } - } - - if (query_buffer[0] == 0) { - query_buffer[0] = ' '; - query_buffer[1] = 0; - } - - if (Verbose && !SingleStepMode) - fprintf(stdout,"Query sent to backend is \"%s\"\n", query_buffer); - - fflush(stderr); - fflush(stdout); - - /* - * Repeat commands until done. - */ - - handle_execution(query_buffer); - - /* clear the query buffer and temp file -- this is very expensive */ - handle_clear(); - memset(query_buffer,0,i); -} - -/* - * Actually execute the query in *query. - * - * Returns 0 if the query finished successfully, 1 otherwise. - */ -static int -handle_execution(char *query) -{ - PGresult *result; - int retval = 0; - PQprintOpt opt; - - result = PQexec(conn, query); - - if (result == NULL) { - fprintf(stderr,"%s", PQerrorMessage(conn)); - return 1; - } - - switch (PQresultStatus(result)) { - case PGRES_EMPTY_QUERY: - break; - case PGRES_COMMAND_OK: - break; - case PGRES_TUPLES_OK: -/* PQprintTuples(result,stdout,PrintAttNames,TerseOutput,COLWIDTH); */ -/* if (TerseOutput) - PQdisplayTuples(result,stdout,1,"",PrintAttNames,TerseOutput); - else - PQdisplayTuples(result,stdout,1,"|",PrintAttNames,TerseOutput); */ - memset(&opt, 0, sizeof opt); - opt.header = opt.align = opt.standard = 1; - if (TerseOutput) - opt.fieldSep = ""; - else - opt.fieldSep = "|"; - PQprint(stdout, result, &opt); - break; - case PGRES_COPY_OUT: - handle_copy_out(result); - break; - case PGRES_COPY_IN: - handle_copy_in(result); - break; - case PGRES_BAD_RESPONSE: - retval = 1; - break; - case PGRES_NONFATAL_ERROR: - retval = 1; - break; - case PGRES_FATAL_ERROR: - retval = 1; - break; - } - - if (SingleStepMode) { - fflush(stdin); - printf("\npress return to continue ...\n"); - getc(stdin); /* assume stdin is not a file! */ - } - return(retval); -} - -/* - * handle_file_insert() - * - * allows the user to insert a query file and execute it. - * NOTE: right now the full path name must be specified. - */ -static void -handle_file_insert(FILE *ifp) -{ - char user_filename[50]; - FILE *nifp; - - fscanf(ifp, "%s",user_filename); - nifp = fopen(user_filename, "r"); - if (nifp == (FILE *) NULL) { - fprintf(stderr, "Cannot open %s\n", user_filename); - } else { - do_input(nifp); - fclose (nifp); - } -} - -/* - * handle_print() - * - * This routine prints out the contents (query) of the temp. file - * onto stdout. - */ -static void -handle_print() -{ - char c; - off_t pos; - int cc; - - pos = lseek(tmon_temp, (off_t) 0, SEEK_SET); - - if (pos != 0 ) - fprintf(stderr, "Bogus file position\n"); - - printf("\n"); - - while ( ( cc = read(tmon_temp,&c,1) ) != 0) - putchar(c); - - printf("\n"); -} - - -/* - * handle_exit() - * - * ends the comm. with the backend and exit the tm. - */ -static void -handle_exit(int exit_status) -{ - if (!RunOneCommand) { - close(tmon_temp); - unlink(tmon_temp_filename); - } - PQfinish(conn); - exit(exit_status); -} - -/* - * handle_clear() - * - * This routine clears the temp. file. - */ -static void -handle_clear() -{ - /* high cost */ - close(tmon_temp); - tmon_temp = open(tmon_temp_filename,O_TRUNC|O_RDWR|O_CREAT ,0666); -} - -/* - * handle_print_time() - * prints out the date using the "date" command. - */ -static void -handle_print_time() -{ - system("date"); -} - -/* - * handle_write_to_file() - * - * writes the contents of the temp. file to the - * specified file. - */ -static int -handle_write_to_file() -{ - char filename[50]; - static char command_line[512]; - int status; - - status = scanf("%s", filename); - if (status < 1 || !filename[0]) { - fprintf(stderr, "error: filename is empty\n"); - return(-1); - } - - /* XXX portable way to check return status? $%&! ultrix ... */ - (void) sprintf(command_line, "rm -f %s", filename); - (void) system(command_line); - (void) sprintf(command_line, "cp %s %s", tmon_temp_filename, filename); - (void) system(command_line); - - return(0); -} - -/* - * - * Prints out a help message. - * - */ -static void -handle_help() -{ - printf("Available commands include \n\n"); - printf("\\e -- enter editor\n"); - printf("\\g -- \"GO\": submit query to POSTGRES\n"); - printf("\\i -- include (switch input to external file)\n"); - printf("\\p -- print query buffer\n"); - printf("\\q -- quit POSTGRES\n"); - printf("\\r -- force reset (clear) of query buffer\n"); - printf("\\s -- shell escape \n"); - printf("\\t -- print current time\n"); - printf("\\w -- write query buffer to external file\n"); - printf("\\h -- print the list of commands\n"); - printf("\\? -- print the list of commands\n"); - printf("\\\\ -- produce a single backslash in query buffer\n"); - fflush(stdin); -} - -/* - * stuff_buffer() - * - * writes the user input into the temp. file. - */ -static void -stuff_buffer(char c) -{ - int cc; - - cc = write(tmon_temp,&c,1); - - if(cc == -1) - fprintf(stderr, "error writing to temp file\n"); -} - -static void -argsetup(int *argcP, char ***argvP) -{ - int argc; - char **argv, **curarg; - char *eopts; - char *envopts; - int neopts; - char *start, *end; - arge *head, *tail, *cur; - - /* if no options specified in environment, we're done */ - if ((envopts = getenv("PGOPTION")) == (char *) NULL) - return; - - if ((eopts = (char *) malloc(strlen(envopts) + 1)) == (char *) NULL) { - fprintf(stderr, "cannot malloc copy space for PGOPTION\n"); - fflush(stderr); - exit (2); - } - - (void) strcpy(eopts, envopts); - - /* - * okay, we have PGOPTION from the environment, and we want to treat - * them as user-specified options. to do this, we construct a new - * argv that has argv[0] followed by the arguments from the environment - * followed by the arguments on the command line. - */ - - head = cur = (arge *) NULL; - neopts = 0; - - for (;;) { - while (isspace(*eopts) && *eopts) - eopts++; - - if (*eopts == '\0') - break; - - if ((cur = (arge *) malloc(sizeof(arge))) == (arge *) NULL) { - fprintf(stderr, "cannot malloc space for arge\n"); - fflush(stderr); - exit (2); - } - - end = start = eopts; - - if (*start == '"') { - start++; - while (*++end != '\0' && *end != '"') - continue; - if (*end == '\0') { - fprintf(stderr, "unterminated string constant in env var PGOPTION\n"); - fflush(stderr); - exit (2); - } - eopts = end + 1; - } else if (*start == '\'') { - start++; - while (*++end != '\0' && *end != '\'') - continue; - if (*end == '\0') { - fprintf(stderr, "unterminated string constant in env var PGOPTION\n"); - fflush(stderr); - exit (2); - } - eopts = end + 1; - } else { - while (!isspace(*end) && *end) - end++; - if (isspace(*end)) - eopts = end + 1; - else - eopts = end; - } - - if (head == (arge *) NULL) { - head = tail = cur; - } else { - tail->a_next = cur; - tail = cur; - } - - cur->a_arg = start; - cur->a_next = (arge *) NULL; - - *end = '\0'; - neopts++; - } - - argc = *argcP + neopts; - - if ((argv = (char **) malloc(argc * sizeof(char *))) == (char **) NULL) { - fprintf(stderr, "can't malloc space for modified argv\n"); - fflush(stderr); - exit (2); - } - - curarg = argv; - *curarg++ = *(*argvP)++; - - /* copy env args */ - while (head != (arge *) NULL) { - cur = head; - *curarg++ = head->a_arg; - head = head->a_next; - free(cur); - } - - /* copy rest of args from command line */ - while (--(*argcP)) - *curarg++ = *(*argvP)++; - - /* all done */ - *argvP = argv; - *argcP = argc; -} - -static void -handle_copy_out(PGresult *res) -{ - bool copydone = false; - char copybuf[COPYBUFSIZ]; - int ret; - - if (!Silent) - fprintf(stdout, "Copy command returns...\n"); - - while (!copydone) { - ret = PQgetline(res->conn, copybuf, COPYBUFSIZ); - - if (copybuf[0] == '.' && copybuf[1] =='\0') { - copydone = true; /* don't print this... */ - } else { - fputs(copybuf, stdout); - switch (ret) { - case EOF: - copydone = true; - /*FALLTHROUGH*/ - case 0: - fputc('\n', stdout); - break; - case 1: - break; - } - } - } - fflush(stdout); - PQendcopy(res->conn); -} - -static void -handle_copy_in(PGresult *res) -{ - bool copydone = false; - bool firstload; - bool linedone; - char copybuf[COPYBUFSIZ]; - char *s; - int buflen; - int c; - - if (!Silent) { - fputs("Enter info followed by a newline\n", stdout); - fputs("End with a dot on a line by itself.\n", stdout); - } - - /* - * eat inevitable newline still in input buffer - * - * XXX the 'inevitable newline' is not always present - * for example `cat file | monitor -c "copy from stdin"' - */ - fflush(stdin); - if ((c = getc(stdin)) != '\n' && c != EOF) { - (void) ungetc(c, stdin); - } - - while (!copydone) { /* for each input line ... */ - if (!Silent) { - fputs(">> ", stdout); - fflush(stdout); - } - firstload = true; - linedone = false; - while (!linedone) { /* for each buffer ... */ - s = copybuf; - buflen = COPYBUFSIZ; - for (; buflen > 1 && - !(linedone = (c = getc(stdin)) == '\n' || c == EOF); - --buflen) { - *s++ = c; - } - if (c == EOF) { - /* reading from stdin, but from a file */ - PQputline(res->conn, "."); - copydone = true; - break; - } - *s = '\0'; - PQputline(res->conn, copybuf); - if (firstload) { - if (!strcmp(copybuf, ".")) { - copydone = true; - } - firstload = false; - } - } - PQputline(res->conn, "\n"); - } - PQendcopy(res->conn); -}