Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
9e60c171
Commit
9e60c171
authored
Dec 09, 1996
by
Bryan Henderson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Monitor has been obsoleted by psql.
parent
33edbdb5
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
0 additions
and
1089 deletions
+0
-1089
src/bin/monitor/Makefile
src/bin/monitor/Makefile
+0
-23
src/bin/monitor/monitor.c
src/bin/monitor/monitor.c
+0
-1066
No files found.
src/bin/monitor/Makefile
deleted
100644 → 0
View file @
33edbdb5
#-------------------------------------------------------------------------
#
# 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
src/bin/monitor/monitor.c
deleted
100644 → 0
View file @
33edbdb5
/*-------------------------------------------------------------------------
*
* 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 <errno.h>
#include "libpq/pqsignal.h"
/* substitute for <signal.h> */
#include <stdio.h>
#include <string.h>
#include <sys/file.h>
#include <sys/param.h>
/* for MAXHOSTNAMELEN on most */
#ifndef WIN32
#include <unistd.h>
#endif
#if defined(sparc_solaris) || defined(i386_solaris)
#include <netdb.h>
/* for MAXHOSTNAMELEN on some */
#endif
#include <sys/types.h>
/* #include <sys/uio.h> */
#include <time.h>
#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
\t
set authentication service
\n
"
);
fprintf
(
stderr
,
"
\t
-c command
\t\t
execute one command
\n
"
);
fprintf
(
stderr
,
"
\t
-d debugfile
\t\t
debugging output file
\n
"
);
fprintf
(
stderr
,
"
\t
-h host
\t\t\t
server host name
\n
"
);
fprintf
(
stderr
,
"
\t
-f file
\t\t\t
run query from file
\n
"
);
fprintf
(
stderr
,
"
\t
-p port
\t\t\t
server port number
\n
"
);
fprintf
(
stderr
,
"
\t
-q
\t\t\t
quiet output
\n
"
);
fprintf
(
stderr
,
"
\t
-t logfile
\t\t
error-logging tty
\n
"
);
fprintf
(
stderr
,
"
\t
-N
\t\t\t
output without attribute names
\n
"
);
fprintf
(
stderr
,
"
\t
-Q
\t\t\t
REALLY quiet output
\n
"
);
fprintf
(
stderr
,
"
\t
-T
\t\t\t
terse 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
,
"
\n
Go
\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
,
"
\n
Go
\n
* "
);
else
{
if
(
!
Silent
)
fprintf
(
stdout
,
"* "
);
}
}
}
else
{
stuff_buffer
(
c
);
if
(
c
==
';'
&&
SemicolonIsGo
)
{
handle_send
();
if
(
Verbose
)
fprintf
(
stdout
,
"
\n
Go
\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 <ctype.h>
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
(
"
\n
press 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
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment