]> granicus.if.org Git - postgresql/blob - src/backend/libpq/pqcomm.c
Add auto-size to screen to \d? commands. Use UNION to show all
[postgresql] / src / backend / libpq / pqcomm.c
1  /*-------------------------------------------------------------------------
2  *
3  * pqcomm.c--
4  *        Communication functions between the Frontend and the Backend
5  *
6  * Copyright (c) 1994, Regents of the University of California
7  *
8  *
9  * IDENTIFICATION
10  *        $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.49 1998/07/18 18:34:03 momjian Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 /*
15  * INTERFACE ROUTINES
16  *              pq_gettty               - return the name of the tty in the given buffer
17  *              pq_getport              - return the PGPORT setting
18  *              pq_close                - close input / output connections
19  *              pq_flush                - flush pending output
20  *              pq_getstr               - get a null terminated string from connection
21  *              pq_getnchar             - get n characters from connection
22  *              pq_getint               - get an integer from connection
23  *              pq_putstr               - send a null terminated string to connection
24  *              pq_putnchar             - send n characters to connection
25  *              pq_putint               - send an integer to connection
26  *              pq_putncharlen          - send n characters to connection
27  *                                        (also send an int header indicating
28  *                                         the length)
29  *              pq_getinaddr    - initialize address from host and port number
30  *              pq_getinserv    - initialize address from host and service name
31  *              pq_connect              - create remote input / output connection
32  *              pq_accept               - accept remote input / output connection
33  *
34  * NOTES
35  *              These functions are used by both frontend applications and
36  *              the postgres backend.
37  *
38  */
39 #include "postgres.h"
40
41 #include <stdio.h>
42 #if defined(HAVE_STRING_H)
43 #include <string.h>
44 #else
45 #include <strings.h>
46 #endif
47 #include <signal.h>
48 #include <errno.h>
49 #include <fcntl.h>
50 #include <unistd.h>                             /* for ttyname() */
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 #include <sys/socket.h>
54 #include <netdb.h>
55 #include <netinet/in.h>
56 #include <netinet/tcp.h>
57 #include <arpa/inet.h>
58
59 #if defined(linux)
60 #ifndef SOMAXCONN
61 #define SOMAXCONN 5                             /* from Linux listen(2) man page */
62 #endif                                                  /* SOMAXCONN */
63 #endif                                                  /* linux */
64
65 #include "miscadmin.h"
66 #include "libpq/pqsignal.h"
67 #include "libpq/auth.h"
68 #include "libpq/libpq.h"                /* where the declarations go */
69 #include "storage/ipc.h"
70 #ifdef MULTIBYTE
71 #include "commands/variable.h"
72 #endif
73
74 /* ----------------
75  *              declarations
76  * ----------------
77  */
78 FILE       *Pfout,
79                    *Pfin;
80 FILE       *Pfdebug;                    /* debugging libpq */
81
82 /* --------------------------------
83  *              pq_init - open portal file descriptors
84  * --------------------------------
85  */
86 void
87 pq_init(int fd)
88 {
89         Pfin = fdopen(fd, "r");
90         Pfout = fdopen(dup(fd), "w");
91         if (!Pfin || !Pfout)
92                 elog(FATAL, "pq_init: Couldn't initialize socket connection");
93         PQnotifies_init();
94         if (getenv("LIBPQ_DEBUG"))
95                 Pfdebug = stderr;
96         else
97                 Pfdebug = NULL;
98 }
99
100 /* -------------------------
101  *       pq_getc(File* fin)
102  *
103  *       get a character from the input file,
104  *
105  *       if Pfdebug is set, also echo the character fetched into Pfdebug
106  *
107  *       used for debugging libpq
108  */
109 static int
110 pq_getc(FILE *fin)
111 {
112         int                     c;
113
114         c = getc(fin);
115         if (Pfdebug && c != EOF)
116                 putc(c, Pfdebug);
117         return c;
118 }
119
120 /* --------------------------------
121  *              pq_gettty - return the name of the tty in the given buffer
122  * --------------------------------
123  */
124 void
125 pq_gettty(char *tp)
126 {
127         strncpy(tp, ttyname(0), 19);
128 }
129
130 /* --------------------------------
131  *              pq_getport - return the PGPORT setting
132  * --------------------------------
133  */
134 int
135 pq_getport()
136 {
137         char       *envport = getenv("PGPORT");
138
139         if (envport)
140                 return (atoi(envport));
141         return (atoi(DEF_PGPORT));
142 }
143
144 /* --------------------------------
145  *              pq_close - close input / output connections
146  * --------------------------------
147  */
148 void
149 pq_close()
150 {
151         if (Pfin)
152         {
153                 fclose(Pfin);
154                 Pfin = NULL;
155         }
156         if (Pfout)
157         {
158                 fclose(Pfout);
159                 Pfout = NULL;
160         }
161         PQnotifies_init();
162 }
163
164 /* --------------------------------
165  *              pq_flush - flush pending output
166  * --------------------------------
167  */
168 void
169 pq_flush()
170 {
171         if (Pfout)
172                 fflush(Pfout);
173 }
174
175 /* --------------------------------
176  *              pq_getstr - get a null terminated string from connection
177  * --------------------------------
178  */
179 int
180 pq_getstr(char *s, int maxlen)
181 {
182         int                     c = '\0';
183
184 #ifdef MULTIBYTE
185         unsigned char *p, *ps;
186         int len;
187
188         ps = s;
189         len = maxlen;
190 #endif
191
192         if (Pfin == (FILE *) NULL)
193         {
194 /*              elog(DEBUG, "Input descriptor is null"); */
195                 return (EOF);
196         }
197
198         while (maxlen-- && (c = pq_getc(Pfin)) != EOF && c)
199                 *s++ = c;
200         *s = '\0';
201
202 #ifdef MULTIBYTE
203         p = pg_client_to_server(ps, len);
204         if (ps != p) {  /* actual conversion has been done? */
205           strcpy(ps, p);
206         }
207 #endif
208         
209         /* -----------------
210          *         If EOF reached let caller know.
211          *         (This will only happen if we hit EOF before the string
212          *         delimiter is reached.)
213          * -----------------
214          */
215         if (c == EOF)
216                 return (EOF);
217         return (!EOF);
218 }
219
220 /*
221  * USER FUNCTION - gets a newline-terminated string from the backend.
222  *
223  * Chiefly here so that applications can use "COPY <rel> to stdout"
224  * and read the output string.  Returns a null-terminated string in s.
225  *
226  * PQgetline reads up to maxlen-1 characters (like fgets(3)) but strips
227  * the terminating \n (like gets(3)).
228  *
229  * RETURNS:
230  *              EOF if it is detected or invalid arguments are given
231  *              0 if EOL is reached (i.e., \n has been read)
232  *                              (this is required for backward-compatibility -- this
233  *                               routine used to always return EOF or 0, assuming that
234  *                               the line ended within maxlen bytes.)
235  *              1 in other cases
236  */
237 int
238 PQgetline(char *s, int maxlen)
239 {
240         if (!Pfin || !s || maxlen <= 1)
241                 return (EOF);
242
243         if (fgets(s, maxlen - 1, Pfin) == NULL)
244                 return feof(Pfin) ? EOF : 1;
245         else
246         {
247                 for (; *s; s++)
248                 {
249                         if (*s == '\n')
250                         {
251                                 *s = '\0';
252                                 break;
253                         }
254                 }
255         }
256
257         return 0;
258 }
259
260 /*
261  * USER FUNCTION - sends a string to the backend.
262  *
263  * Chiefly here so that applications can use "COPY <rel> from stdin".
264  *
265  * RETURNS:
266  *              0 in all cases.
267  */
268 int
269 PQputline(char *s)
270 {
271         if (Pfout)
272         {
273                 fputs(s, Pfout);
274                 fflush(Pfout);
275         }
276         return (0);
277 }
278
279 /* --------------------------------
280  *              pq_getnchar - get n characters from connection
281  * --------------------------------
282  */
283 int
284 pq_getnchar(char *s, int off, int maxlen)
285 {
286         return pqGetNBytes(s + off, maxlen, Pfin);
287 }
288
289 /* --------------------------------
290  *              pq_getint - get an integer from connection
291  *       we receive an integer a byte at a type and reconstruct it so that
292  *       machines with different ENDIAN representations can talk to each
293  *       other
294  * --------------------------------
295  */
296 int
297 pq_getint(int b)
298 {
299         int                     n,
300                                 status = 1;
301
302         if (!Pfin)
303                 return EOF;
304
305         /*
306          * mjl: Seems inconsisten w/ return value of pq_putint (void). Also,
307          * EOF is a valid return value for an int! XXX
308          */
309
310         switch (b)
311         {
312                 case 1:
313                         status = ((n = fgetc(Pfin)) == EOF);
314                         break;
315                 case 2:
316                         status = pqGetShort(&n, Pfin);
317                         break;
318                 case 4:
319                         status = pqGetLong(&n, Pfin);
320                         break;
321                 default:
322                         fprintf(stderr, "** Unsupported size %d\n", b);
323         }
324
325         if (status)
326         {
327                 sprintf(PQerrormsg,
328                                 "FATAL: pq_getint failed: errno=%d\n", errno);
329                 fputs(PQerrormsg, stderr);
330                 pqdebug("%s", PQerrormsg);
331                 n = 0;
332         }
333
334         return n;
335 }
336
337 /* --------------------------------
338  *              pq_putstr - send a null terminated string to connection
339  * --------------------------------
340  */
341 void
342 pq_putstr(char *s)
343 {
344 #ifdef MULTIBYTE
345         unsigned char *p;
346
347         p = pg_server_to_client(s, strlen(s));
348         if (pqPutString(p, Pfout))
349 #else
350         if (pqPutString(s, Pfout))
351 #endif
352         {
353                 sprintf(PQerrormsg,
354                                 "FATAL: pq_putstr: fputs() failed: errno=%d\n", errno);
355                 fputs(PQerrormsg, stderr);
356                 pqdebug("%s", PQerrormsg);
357         }
358 }
359
360 /* --------------------------------
361  *              pq_putnchar - send n characters to connection
362  * --------------------------------
363  */
364 void
365 pq_putnchar(char *s, int n)
366 {
367         if (pqPutNBytes(s, n, Pfout))
368         {
369                 sprintf(PQerrormsg,
370                                 "FATAL: pq_putnchar: fputc() failed: errno=%d\n",
371                                 errno);
372                 fputs(PQerrormsg, stderr);
373                 pqdebug("%s", PQerrormsg);
374         }
375 }
376
377 /* --------------------------------
378  *              pq_putint - send an integer to connection
379  *       we chop an integer into bytes and send individual bytes
380  *       machines with different ENDIAN representations can still talk to each
381  *       other
382  * --------------------------------
383  */
384 void
385 pq_putint(int i, int b)
386 {
387         int                     status;
388
389         if (!Pfout)
390                 return;
391
392         status = 1;
393         switch (b)
394         {
395                 case 1:
396                         status = (fputc(i, Pfout) == EOF);
397                         break;
398                 case 2:
399                         status = pqPutShort(i, Pfout);
400                         break;
401                 case 4:
402                         status = pqPutLong(i, Pfout);
403                         break;
404                 default:
405                         fprintf(stderr, "** Unsupported size %d\n", b);
406         }
407
408         if (status)
409         {
410                 sprintf(PQerrormsg,
411                                 "FATAL: pq_putint failed: errno=%d\n", errno);
412                 fputs(PQerrormsg, stderr);
413                 pqdebug("%s", PQerrormsg);
414         }
415 }
416
417 /* --------------------------------
418  *              pq_getinaddr - initialize address from host and port number
419  * --------------------------------
420  */
421 int
422 pq_getinaddr(struct sockaddr_in * sin,
423                          char *host,
424                          int port)
425 {
426         struct hostent *hs;
427
428         MemSet((char *) sin, 0, sizeof(*sin));
429
430         if (host)
431         {
432                 if (*host >= '0' && *host <= '9')
433                         sin->sin_addr.s_addr = inet_addr(host);
434                 else
435                 {
436                         if (!(hs = gethostbyname(host)))
437                         {
438                                 perror(host);
439                                 return (1);
440                         }
441                         if (hs->h_addrtype != AF_INET)
442                         {
443                                 sprintf(PQerrormsg,
444                                                 "FATAL: pq_getinaddr: %s not on Internet\n",
445                                                 host);
446                                 fputs(PQerrormsg, stderr);
447                                 pqdebug("%s", PQerrormsg);
448                                 return (1);
449                         }
450                         memmove((char *) &sin->sin_addr,
451                                         hs->h_addr,
452                                         hs->h_length);
453                 }
454         }
455         sin->sin_family = AF_INET;
456         sin->sin_port = htons(port);
457         return (0);
458 }
459
460 /* --------------------------------
461  *              pq_getinserv - initialize address from host and servive name
462  * --------------------------------
463  */
464 int
465 pq_getinserv(struct sockaddr_in * sin, char *host, char *serv)
466 {
467         struct servent *ss;
468
469         if (*serv >= '0' && *serv <= '9')
470                 return (pq_getinaddr(sin, host, atoi(serv)));
471         if (!(ss = getservbyname(serv, NULL)))
472         {
473                 sprintf(PQerrormsg,
474                                 "FATAL: pq_getinserv: unknown service: %s\n",
475                                 serv);
476                 fputs(PQerrormsg, stderr);
477                 pqdebug("%s", PQerrormsg);
478                 return (1);
479         }
480         return (pq_getinaddr(sin, host, ntohs(ss->s_port)));
481 }
482
483 /*
484  * Streams -- wrapper around Unix socket system calls
485  *
486  *
487  *              Stream functions are used for vanilla TCP connection protocol.
488  */
489
490 /*
491  * StreamServerPort -- open a sock stream "listening" port.
492  *
493  * This initializes the Postmaster's connection
494  *              accepting port.
495  *
496  * ASSUME: that this doesn't need to be non-blocking because
497  *              the Postmaster uses select() to tell when the socket
498  *              is ready.
499  *
500  * RETURNS: STATUS_OK or STATUS_ERROR
501  */
502
503 static char sock_path[MAXPGPATH + 1] = "";
504
505 /* do_unlink()
506  * Shutdown routine for backend connection
507  * If a Unix socket is used for communication, explicitly close it.
508  */
509 void
510 StreamDoUnlink()
511 {
512         Assert(sock_path[0]);
513         unlink(sock_path);
514 }
515
516 int
517 StreamServerPort(char *hostName, short portName, int *fdP)
518 {
519         SockAddr        saddr;
520         int                     fd,
521                                 err,
522                                 family;
523         size_t          len;
524         int                     one = 1;
525
526         family = ((hostName != NULL) ? AF_INET : AF_UNIX);
527
528         if ((fd = socket(family, SOCK_STREAM, 0)) < 0)
529         {
530                 sprintf(PQerrormsg,
531                                 "FATAL: StreamServerPort: socket() failed: errno=%d\n",
532                                 errno);
533                 fputs(PQerrormsg, stderr);
534                 pqdebug("%s", PQerrormsg);
535                 return (STATUS_ERROR);
536         }
537         if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
538                                         sizeof(one))) == -1)
539         {
540                 sprintf(PQerrormsg,
541                                 "FATAL: StreamServerPort: setsockopt (SO_REUSEADDR) failed: errno=%d\n",
542                                 errno);
543                 fputs(PQerrormsg, stderr);
544                 pqdebug("%s", PQerrormsg);
545                 return (STATUS_ERROR);
546         }
547         MemSet((char *) &saddr, 0, sizeof(saddr));
548         saddr.sa.sa_family = family;
549         if (family == AF_UNIX)
550         {
551                 len = UNIXSOCK_PATH(saddr.un, portName);
552                 strcpy(sock_path, saddr.un.sun_path);
553         }
554         else
555         {
556                 saddr.in.sin_addr.s_addr = htonl(INADDR_ANY);
557                 saddr.in.sin_port = htons(portName);
558                 len = sizeof(struct sockaddr_in);
559         }
560         err = bind(fd, &saddr.sa, len);
561         if (err < 0)
562         {
563                 sprintf(PQerrormsg,
564                                 "FATAL: StreamServerPort: bind() failed: errno=%d\n",
565                                 errno);
566                 pqdebug("%s", PQerrormsg);
567                 strcat(PQerrormsg, "\tIs another postmaster already running on that port?\n");
568                 if (family == AF_UNIX)
569                         strcat(PQerrormsg, "\tIf not, remove socket node (/tmp/.s.PGSQL.<portnumber>)and retry.\n");
570                 else
571                         strcat(PQerrormsg, "\tIf not, wait a few seconds and retry.\n");
572                 fputs(PQerrormsg, stderr);
573                 return (STATUS_ERROR);
574         }
575
576         if (family == AF_UNIX)
577                 on_proc_exit(StreamDoUnlink, NULL);
578
579         listen(fd, SOMAXCONN);
580
581         /*
582          * MS: I took this code from Dillon's version.  It makes the listening
583          * port non-blocking.  That is not necessary (and may tickle kernel
584          * bugs).
585          *
586          * fcntl(fd, F_SETFD, 1); fcntl(fd, F_SETFL, FNDELAY);
587          */
588
589         *fdP = fd;
590         if (family == AF_UNIX)
591                 chmod(sock_path, 0777);
592         return (STATUS_OK);
593 }
594
595 /*
596  * StreamConnection -- create a new connection with client using
597  *              server port.
598  *
599  * This one should be non-blocking.
600  *
601  * RETURNS: STATUS_OK or STATUS_ERROR
602  */
603 int
604 StreamConnection(int server_fd, Port *port)
605 {
606         int                     len,
607                                 addrlen;
608         int                     family = port->raddr.sa.sa_family;
609
610         /* accept connection (and fill in the client (remote) address) */
611         len = family == AF_INET ?
612                 sizeof(struct sockaddr_in) : sizeof(struct sockaddr_un);
613         addrlen = len;
614         if ((port->sock = accept(server_fd,
615                                                          (struct sockaddr *) & port->raddr,
616                                                          &addrlen)) < 0)
617         {
618                 elog(ERROR, "postmaster: StreamConnection: accept: %m");
619                 return (STATUS_ERROR);
620         }
621
622         /* fill in the server (local) address */
623         addrlen = len;
624         if (getsockname(port->sock, (struct sockaddr *) & port->laddr,
625                                         &addrlen) < 0)
626         {
627                 elog(ERROR, "postmaster: StreamConnection: getsockname: %m");
628                 return (STATUS_ERROR);
629         }
630         if (family == AF_INET)
631         {
632                 struct protoent *pe;
633                 int                     on = 1;
634
635                 pe = getprotobyname("TCP");
636                 if (pe == NULL)
637                 {
638                         elog(ERROR, "postmaster: getprotobyname failed");
639                         return (STATUS_ERROR);
640                 }
641                 if (setsockopt(port->sock, pe->p_proto, TCP_NODELAY,
642                                            &on, sizeof(on)) < 0)
643                 {
644                         elog(ERROR, "postmaster: setsockopt failed");
645                         return (STATUS_ERROR);
646                 }
647         }
648
649         /* reset to non-blocking */
650         fcntl(port->sock, F_SETFL, 1);
651
652         return (STATUS_OK);
653 }
654
655 /*
656  * StreamClose -- close a client/backend connection
657  */
658 void
659 StreamClose(int sock)
660 {
661         close(sock);
662 }
663
664 /* ---------------------------
665  * StreamOpen -- From client, initiate a connection with the
666  *              server (Postmaster).
667  *
668  * RETURNS: STATUS_OK or STATUS_ERROR
669  *
670  * NOTE: connection is NOT established just because this
671  *              routine exits.  Local state is ok, but we haven't
672  *              spoken to the postmaster yet.
673  * ---------------------------
674  */
675 int
676 StreamOpen(char *hostName, short portName, Port *port)
677 {
678         int                     len,
679                                 err;
680         struct hostent *hp;
681         extern int      errno;
682
683         /* set up the server (remote) address */
684         MemSet((char *) &port->raddr, 0, sizeof(port->raddr));
685         if (hostName)
686         {
687                 if (!(hp = gethostbyname(hostName)) || hp->h_addrtype != AF_INET)
688                 {
689                         sprintf(PQerrormsg,
690                                         "FATAL: StreamOpen: unknown hostname: %s\n",
691                                         hostName);
692                         fputs(PQerrormsg, stderr);
693                         pqdebug("%s", PQerrormsg);
694                         return (STATUS_ERROR);
695                 }
696                 memmove((char *) &(port->raddr.in.sin_addr),
697                                 (char *) hp->h_addr,
698                                 hp->h_length);
699                 port->raddr.in.sin_family = AF_INET;
700                 port->raddr.in.sin_port = htons(portName);
701                 len = sizeof(struct sockaddr_in);
702         }
703         else
704         {
705                 port->raddr.un.sun_family = AF_UNIX;
706                 len = UNIXSOCK_PATH(port->raddr.un, portName);
707         }
708         /* connect to the server */
709         if ((port->sock = socket(port->raddr.sa.sa_family, SOCK_STREAM, 0)) < 0)
710         {
711                 sprintf(PQerrormsg,
712                                 "FATAL: StreamOpen: socket() failed: errno=%d\n",
713                                 errno);
714                 fputs(PQerrormsg, stderr);
715                 pqdebug("%s", PQerrormsg);
716                 return (STATUS_ERROR);
717         }
718         err = connect(port->sock, &port->raddr.sa, len);
719         if (err < 0)
720         {
721                 sprintf(PQerrormsg,
722                                 "FATAL: StreamOpen: connect() failed: errno=%d\n",
723                                 errno);
724                 fputs(PQerrormsg, stderr);
725                 pqdebug("%s", PQerrormsg);
726                 return (STATUS_ERROR);
727         }
728
729         /* fill in the client address */
730         if (getsockname(port->sock, &port->laddr.sa, &len) < 0)
731         {
732                 sprintf(PQerrormsg,
733                                 "FATAL: StreamOpen: getsockname() failed: errno=%d\n",
734                                 errno);
735                 fputs(PQerrormsg, stderr);
736                 pqdebug("%s", PQerrormsg);
737                 return (STATUS_ERROR);
738         }
739
740         return (STATUS_OK);
741 }
742
743 #ifdef MULTIBYTE
744 void
745 pq_putncharlen(char *s, int n)
746 {
747   unsigned char *p;
748   int len;
749
750   p = pg_server_to_client(s, n);
751   len = strlen(p);
752   pq_putint(len, sizeof(int));
753   pq_putnchar(p, len);
754 }
755 #endif