1 /*-------------------------------------------------------------------------
2  *
3  * fe-lobj.c
4  *	  Front-end large object interface
5  *
6  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/interfaces/libpq/fe-lobj.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #ifdef WIN32
17 /*
18  *	As unlink/rename are #define'd in port.h (via postgres_fe.h), io.h
19  *	must be included first on MS C.  Might as well do it for all WIN32's
20  *	here.
21  */
22 #include <io.h>
23 #endif
24 
25 #include "postgres_fe.h"
26 
27 #ifdef WIN32
28 #include "win32.h"
29 #else
30 #include <unistd.h>
31 #endif
32 
33 #include <fcntl.h>
34 #include <limits.h>
35 #include <sys/stat.h>
36 #include <netinet/in.h>			/* for ntohl/htonl */
37 #include <arpa/inet.h>
38 
39 #include "libpq-fe.h"
40 #include "libpq-int.h"
41 #include "libpq/libpq-fs.h"		/* must come after sys/stat.h */
42 
43 #define LO_BUFSIZE		  8192
44 
45 static int	lo_initialize(PGconn *conn);
46 static Oid	lo_import_internal(PGconn *conn, const char *filename, Oid oid);
47 static pg_int64 lo_hton64(pg_int64 host64);
48 static pg_int64 lo_ntoh64(pg_int64 net64);
49 
50 /*
51  * lo_open
52  *	  opens an existing large object
53  *
54  * returns the file descriptor for use in later lo_* calls
55  * return -1 upon failure.
56  */
57 int
lo_open(PGconn * conn,Oid lobjId,int mode)58 lo_open(PGconn *conn, Oid lobjId, int mode)
59 {
60 	int			fd;
61 	int			result_len;
62 	PQArgBlock	argv[2];
63 	PGresult   *res;
64 
65 	if (conn == NULL || conn->lobjfuncs == NULL)
66 	{
67 		if (lo_initialize(conn) < 0)
68 			return -1;
69 	}
70 
71 	argv[0].isint = 1;
72 	argv[0].len = 4;
73 	argv[0].u.integer = lobjId;
74 
75 	argv[1].isint = 1;
76 	argv[1].len = 4;
77 	argv[1].u.integer = mode;
78 
79 	res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
80 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
81 	{
82 		PQclear(res);
83 		return fd;
84 	}
85 	else
86 	{
87 		PQclear(res);
88 		return -1;
89 	}
90 }
91 
92 /*
93  * lo_close
94  *	  closes an existing large object
95  *
96  * returns 0 upon success
97  * returns -1 upon failure.
98  */
99 int
lo_close(PGconn * conn,int fd)100 lo_close(PGconn *conn, int fd)
101 {
102 	PQArgBlock	argv[1];
103 	PGresult   *res;
104 	int			retval;
105 	int			result_len;
106 
107 	if (conn == NULL || conn->lobjfuncs == NULL)
108 	{
109 		if (lo_initialize(conn) < 0)
110 			return -1;
111 	}
112 
113 	argv[0].isint = 1;
114 	argv[0].len = 4;
115 	argv[0].u.integer = fd;
116 	res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
117 			   &retval, &result_len, 1, argv, 1);
118 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
119 	{
120 		PQclear(res);
121 		return retval;
122 	}
123 	else
124 	{
125 		PQclear(res);
126 		return -1;
127 	}
128 }
129 
130 /*
131  * lo_truncate
132  *	  truncates an existing large object to the given size
133  *
134  * returns 0 upon success
135  * returns -1 upon failure
136  */
137 int
lo_truncate(PGconn * conn,int fd,size_t len)138 lo_truncate(PGconn *conn, int fd, size_t len)
139 {
140 	PQArgBlock	argv[2];
141 	PGresult   *res;
142 	int			retval;
143 	int			result_len;
144 
145 	if (conn == NULL || conn->lobjfuncs == NULL)
146 	{
147 		if (lo_initialize(conn) < 0)
148 			return -1;
149 	}
150 
151 	/* Must check this on-the-fly because it's not there pre-8.3 */
152 	if (conn->lobjfuncs->fn_lo_truncate == 0)
153 	{
154 		printfPQExpBuffer(&conn->errorMessage,
155 			libpq_gettext("cannot determine OID of function lo_truncate\n"));
156 		return -1;
157 	}
158 
159 	/*
160 	 * Long ago, somebody thought it'd be a good idea to declare this function
161 	 * as taking size_t ... but the underlying backend function only accepts a
162 	 * signed int32 length.  So throw error if the given value overflows
163 	 * int32.  (A possible alternative is to automatically redirect the call
164 	 * to lo_truncate64; but if the caller wanted to rely on that backend
165 	 * function being available, he could have called lo_truncate64 for
166 	 * himself.)
167 	 */
168 	if (len > (size_t) INT_MAX)
169 	{
170 		printfPQExpBuffer(&conn->errorMessage,
171 		   libpq_gettext("argument of lo_truncate exceeds integer range\n"));
172 		return -1;
173 	}
174 
175 	argv[0].isint = 1;
176 	argv[0].len = 4;
177 	argv[0].u.integer = fd;
178 
179 	argv[1].isint = 1;
180 	argv[1].len = 4;
181 	argv[1].u.integer = (int) len;
182 
183 	res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate,
184 			   &retval, &result_len, 1, argv, 2);
185 
186 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
187 	{
188 		PQclear(res);
189 		return retval;
190 	}
191 	else
192 	{
193 		PQclear(res);
194 		return -1;
195 	}
196 }
197 
198 /*
199  * lo_truncate64
200  *	  truncates an existing large object to the given size
201  *
202  * returns 0 upon success
203  * returns -1 upon failure
204  */
205 int
lo_truncate64(PGconn * conn,int fd,pg_int64 len)206 lo_truncate64(PGconn *conn, int fd, pg_int64 len)
207 {
208 	PQArgBlock	argv[2];
209 	PGresult   *res;
210 	int			retval;
211 	int			result_len;
212 
213 	if (conn == NULL || conn->lobjfuncs == NULL)
214 	{
215 		if (lo_initialize(conn) < 0)
216 			return -1;
217 	}
218 
219 	if (conn->lobjfuncs->fn_lo_truncate64 == 0)
220 	{
221 		printfPQExpBuffer(&conn->errorMessage,
222 		  libpq_gettext("cannot determine OID of function lo_truncate64\n"));
223 		return -1;
224 	}
225 
226 	argv[0].isint = 1;
227 	argv[0].len = 4;
228 	argv[0].u.integer = fd;
229 
230 	len = lo_hton64(len);
231 	argv[1].isint = 0;
232 	argv[1].len = 8;
233 	argv[1].u.ptr = (int *) &len;
234 
235 	res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate64,
236 			   &retval, &result_len, 1, argv, 2);
237 
238 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
239 	{
240 		PQclear(res);
241 		return retval;
242 	}
243 	else
244 	{
245 		PQclear(res);
246 		return -1;
247 	}
248 }
249 
250 /*
251  * lo_read
252  *	  read len bytes of the large object into buf
253  *
254  * returns the number of bytes read, or -1 on failure.
255  * the CALLER must have allocated enough space to hold the result returned
256  */
257 
258 int
lo_read(PGconn * conn,int fd,char * buf,size_t len)259 lo_read(PGconn *conn, int fd, char *buf, size_t len)
260 {
261 	PQArgBlock	argv[2];
262 	PGresult   *res;
263 	int			result_len;
264 
265 	if (conn == NULL || conn->lobjfuncs == NULL)
266 	{
267 		if (lo_initialize(conn) < 0)
268 			return -1;
269 	}
270 
271 	/*
272 	 * Long ago, somebody thought it'd be a good idea to declare this function
273 	 * as taking size_t ... but the underlying backend function only accepts a
274 	 * signed int32 length.  So throw error if the given value overflows
275 	 * int32.
276 	 */
277 	if (len > (size_t) INT_MAX)
278 	{
279 		printfPQExpBuffer(&conn->errorMessage,
280 			   libpq_gettext("argument of lo_read exceeds integer range\n"));
281 		return -1;
282 	}
283 
284 	argv[0].isint = 1;
285 	argv[0].len = 4;
286 	argv[0].u.integer = fd;
287 
288 	argv[1].isint = 1;
289 	argv[1].len = 4;
290 	argv[1].u.integer = (int) len;
291 
292 	res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
293 			   (void *) buf, &result_len, 0, argv, 2);
294 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
295 	{
296 		PQclear(res);
297 		return result_len;
298 	}
299 	else
300 	{
301 		PQclear(res);
302 		return -1;
303 	}
304 }
305 
306 /*
307  * lo_write
308  *	  write len bytes of buf into the large object fd
309  *
310  * returns the number of bytes written, or -1 on failure.
311  */
312 int
lo_write(PGconn * conn,int fd,const char * buf,size_t len)313 lo_write(PGconn *conn, int fd, const char *buf, size_t len)
314 {
315 	PQArgBlock	argv[2];
316 	PGresult   *res;
317 	int			result_len;
318 	int			retval;
319 
320 	if (conn == NULL || conn->lobjfuncs == NULL)
321 	{
322 		if (lo_initialize(conn) < 0)
323 			return -1;
324 	}
325 
326 	/*
327 	 * Long ago, somebody thought it'd be a good idea to declare this function
328 	 * as taking size_t ... but the underlying backend function only accepts a
329 	 * signed int32 length.  So throw error if the given value overflows
330 	 * int32.
331 	 */
332 	if (len > (size_t) INT_MAX)
333 	{
334 		printfPQExpBuffer(&conn->errorMessage,
335 			  libpq_gettext("argument of lo_write exceeds integer range\n"));
336 		return -1;
337 	}
338 
339 	argv[0].isint = 1;
340 	argv[0].len = 4;
341 	argv[0].u.integer = fd;
342 
343 	argv[1].isint = 0;
344 	argv[1].len = (int) len;
345 	argv[1].u.ptr = (int *) buf;
346 
347 	res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
348 			   &retval, &result_len, 1, argv, 2);
349 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
350 	{
351 		PQclear(res);
352 		return retval;
353 	}
354 	else
355 	{
356 		PQclear(res);
357 		return -1;
358 	}
359 }
360 
361 /*
362  * lo_lseek
363  *	  change the current read or write location on a large object
364  */
365 int
lo_lseek(PGconn * conn,int fd,int offset,int whence)366 lo_lseek(PGconn *conn, int fd, int offset, int whence)
367 {
368 	PQArgBlock	argv[3];
369 	PGresult   *res;
370 	int			retval;
371 	int			result_len;
372 
373 	if (conn == NULL || conn->lobjfuncs == NULL)
374 	{
375 		if (lo_initialize(conn) < 0)
376 			return -1;
377 	}
378 
379 	argv[0].isint = 1;
380 	argv[0].len = 4;
381 	argv[0].u.integer = fd;
382 
383 	argv[1].isint = 1;
384 	argv[1].len = 4;
385 	argv[1].u.integer = offset;
386 
387 	argv[2].isint = 1;
388 	argv[2].len = 4;
389 	argv[2].u.integer = whence;
390 
391 	res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
392 			   &retval, &result_len, 1, argv, 3);
393 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
394 	{
395 		PQclear(res);
396 		return retval;
397 	}
398 	else
399 	{
400 		PQclear(res);
401 		return -1;
402 	}
403 }
404 
405 /*
406  * lo_lseek64
407  *	  change the current read or write location on a large object
408  */
409 pg_int64
lo_lseek64(PGconn * conn,int fd,pg_int64 offset,int whence)410 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
411 {
412 	PQArgBlock	argv[3];
413 	PGresult   *res;
414 	pg_int64	retval;
415 	int			result_len;
416 
417 	if (conn == NULL || conn->lobjfuncs == NULL)
418 	{
419 		if (lo_initialize(conn) < 0)
420 			return -1;
421 	}
422 
423 	if (conn->lobjfuncs->fn_lo_lseek64 == 0)
424 	{
425 		printfPQExpBuffer(&conn->errorMessage,
426 			 libpq_gettext("cannot determine OID of function lo_lseek64\n"));
427 		return -1;
428 	}
429 
430 	argv[0].isint = 1;
431 	argv[0].len = 4;
432 	argv[0].u.integer = fd;
433 
434 	offset = lo_hton64(offset);
435 	argv[1].isint = 0;
436 	argv[1].len = 8;
437 	argv[1].u.ptr = (int *) &offset;
438 
439 	argv[2].isint = 1;
440 	argv[2].len = 4;
441 	argv[2].u.integer = whence;
442 
443 	res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek64,
444 			   (void *) &retval, &result_len, 0, argv, 3);
445 	if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
446 	{
447 		PQclear(res);
448 		return lo_ntoh64(retval);
449 	}
450 	else
451 	{
452 		PQclear(res);
453 		return -1;
454 	}
455 }
456 
457 /*
458  * lo_creat
459  *	  create a new large object
460  * the mode is ignored (once upon a time it had a use)
461  *
462  * returns the oid of the large object created or
463  * InvalidOid upon failure
464  */
465 Oid
lo_creat(PGconn * conn,int mode)466 lo_creat(PGconn *conn, int mode)
467 {
468 	PQArgBlock	argv[1];
469 	PGresult   *res;
470 	int			retval;
471 	int			result_len;
472 
473 	if (conn == NULL || conn->lobjfuncs == NULL)
474 	{
475 		if (lo_initialize(conn) < 0)
476 			return InvalidOid;
477 	}
478 
479 	argv[0].isint = 1;
480 	argv[0].len = 4;
481 	argv[0].u.integer = mode;
482 	res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
483 			   &retval, &result_len, 1, argv, 1);
484 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
485 	{
486 		PQclear(res);
487 		return (Oid) retval;
488 	}
489 	else
490 	{
491 		PQclear(res);
492 		return InvalidOid;
493 	}
494 }
495 
496 /*
497  * lo_create
498  *	  create a new large object
499  * if lobjId isn't InvalidOid, it specifies the OID to (attempt to) create
500  *
501  * returns the oid of the large object created or
502  * InvalidOid upon failure
503  */
504 Oid
lo_create(PGconn * conn,Oid lobjId)505 lo_create(PGconn *conn, Oid lobjId)
506 {
507 	PQArgBlock	argv[1];
508 	PGresult   *res;
509 	int			retval;
510 	int			result_len;
511 
512 	if (conn == NULL || conn->lobjfuncs == NULL)
513 	{
514 		if (lo_initialize(conn) < 0)
515 			return InvalidOid;
516 	}
517 
518 	/* Must check this on-the-fly because it's not there pre-8.1 */
519 	if (conn->lobjfuncs->fn_lo_create == 0)
520 	{
521 		printfPQExpBuffer(&conn->errorMessage,
522 			  libpq_gettext("cannot determine OID of function lo_create\n"));
523 		return InvalidOid;
524 	}
525 
526 	argv[0].isint = 1;
527 	argv[0].len = 4;
528 	argv[0].u.integer = lobjId;
529 	res = PQfn(conn, conn->lobjfuncs->fn_lo_create,
530 			   &retval, &result_len, 1, argv, 1);
531 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
532 	{
533 		PQclear(res);
534 		return (Oid) retval;
535 	}
536 	else
537 	{
538 		PQclear(res);
539 		return InvalidOid;
540 	}
541 }
542 
543 
544 /*
545  * lo_tell
546  *	  returns the current seek location of the large object
547  */
548 int
lo_tell(PGconn * conn,int fd)549 lo_tell(PGconn *conn, int fd)
550 {
551 	int			retval;
552 	PQArgBlock	argv[1];
553 	PGresult   *res;
554 	int			result_len;
555 
556 	if (conn == NULL || conn->lobjfuncs == NULL)
557 	{
558 		if (lo_initialize(conn) < 0)
559 			return -1;
560 	}
561 
562 	argv[0].isint = 1;
563 	argv[0].len = 4;
564 	argv[0].u.integer = fd;
565 
566 	res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
567 			   &retval, &result_len, 1, argv, 1);
568 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
569 	{
570 		PQclear(res);
571 		return retval;
572 	}
573 	else
574 	{
575 		PQclear(res);
576 		return -1;
577 	}
578 }
579 
580 /*
581  * lo_tell64
582  *	  returns the current seek location of the large object
583  */
584 pg_int64
lo_tell64(PGconn * conn,int fd)585 lo_tell64(PGconn *conn, int fd)
586 {
587 	pg_int64	retval;
588 	PQArgBlock	argv[1];
589 	PGresult   *res;
590 	int			result_len;
591 
592 	if (conn == NULL || conn->lobjfuncs == NULL)
593 	{
594 		if (lo_initialize(conn) < 0)
595 			return -1;
596 	}
597 
598 	if (conn->lobjfuncs->fn_lo_tell64 == 0)
599 	{
600 		printfPQExpBuffer(&conn->errorMessage,
601 			  libpq_gettext("cannot determine OID of function lo_tell64\n"));
602 		return -1;
603 	}
604 
605 	argv[0].isint = 1;
606 	argv[0].len = 4;
607 	argv[0].u.integer = fd;
608 
609 	res = PQfn(conn, conn->lobjfuncs->fn_lo_tell64,
610 			   (void *) &retval, &result_len, 0, argv, 1);
611 	if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
612 	{
613 		PQclear(res);
614 		return lo_ntoh64(retval);
615 	}
616 	else
617 	{
618 		PQclear(res);
619 		return -1;
620 	}
621 }
622 
623 /*
624  * lo_unlink
625  *	  delete a file
626  */
627 
628 int
lo_unlink(PGconn * conn,Oid lobjId)629 lo_unlink(PGconn *conn, Oid lobjId)
630 {
631 	PQArgBlock	argv[1];
632 	PGresult   *res;
633 	int			result_len;
634 	int			retval;
635 
636 	if (conn == NULL || conn->lobjfuncs == NULL)
637 	{
638 		if (lo_initialize(conn) < 0)
639 			return -1;
640 	}
641 
642 	argv[0].isint = 1;
643 	argv[0].len = 4;
644 	argv[0].u.integer = lobjId;
645 
646 	res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
647 			   &retval, &result_len, 1, argv, 1);
648 	if (PQresultStatus(res) == PGRES_COMMAND_OK)
649 	{
650 		PQclear(res);
651 		return retval;
652 	}
653 	else
654 	{
655 		PQclear(res);
656 		return -1;
657 	}
658 }
659 
660 /*
661  * lo_import -
662  *	  imports a file as an (inversion) large object.
663  *
664  * returns the oid of that object upon success,
665  * returns InvalidOid upon failure
666  */
667 
668 Oid
lo_import(PGconn * conn,const char * filename)669 lo_import(PGconn *conn, const char *filename)
670 {
671 	return lo_import_internal(conn, filename, InvalidOid);
672 }
673 
674 /*
675  * lo_import_with_oid -
676  *	  imports a file as an (inversion) large object.
677  *	  large object id can be specified.
678  *
679  * returns the oid of that object upon success,
680  * returns InvalidOid upon failure
681  */
682 
683 Oid
lo_import_with_oid(PGconn * conn,const char * filename,Oid lobjId)684 lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId)
685 {
686 	return lo_import_internal(conn, filename, lobjId);
687 }
688 
689 static Oid
lo_import_internal(PGconn * conn,const char * filename,Oid oid)690 lo_import_internal(PGconn *conn, const char *filename, Oid oid)
691 {
692 	int			fd;
693 	int			nbytes,
694 				tmp;
695 	char		buf[LO_BUFSIZE];
696 	Oid			lobjOid;
697 	int			lobj;
698 	char		sebuf[256];
699 
700 	/*
701 	 * open the file to be read in
702 	 */
703 	fd = open(filename, O_RDONLY | PG_BINARY, 0666);
704 	if (fd < 0)
705 	{							/* error */
706 		printfPQExpBuffer(&conn->errorMessage,
707 						  libpq_gettext("could not open file \"%s\": %s\n"),
708 						  filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
709 		return InvalidOid;
710 	}
711 
712 	/*
713 	 * create an inversion object
714 	 */
715 	if (oid == InvalidOid)
716 		lobjOid = lo_creat(conn, INV_READ | INV_WRITE);
717 	else
718 		lobjOid = lo_create(conn, oid);
719 
720 	if (lobjOid == InvalidOid)
721 	{
722 		/* we assume lo_create() already set a suitable error message */
723 		(void) close(fd);
724 		return InvalidOid;
725 	}
726 
727 	lobj = lo_open(conn, lobjOid, INV_WRITE);
728 	if (lobj == -1)
729 	{
730 		/* we assume lo_open() already set a suitable error message */
731 		(void) close(fd);
732 		return InvalidOid;
733 	}
734 
735 	/*
736 	 * read in from the file and write to the large object
737 	 */
738 	while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0)
739 	{
740 		tmp = lo_write(conn, lobj, buf, nbytes);
741 		if (tmp != nbytes)
742 		{
743 			/*
744 			 * If lo_write() failed, we are now in an aborted transaction so
745 			 * there's no need for lo_close(); furthermore, if we tried it
746 			 * we'd overwrite the useful error result with a useless one. So
747 			 * just nail the doors shut and get out of town.
748 			 */
749 			(void) close(fd);
750 			return InvalidOid;
751 		}
752 	}
753 
754 	if (nbytes < 0)
755 	{
756 		/* We must do lo_close before setting the errorMessage */
757 		int			save_errno = errno;
758 
759 		(void) lo_close(conn, lobj);
760 		(void) close(fd);
761 		printfPQExpBuffer(&conn->errorMessage,
762 					  libpq_gettext("could not read from file \"%s\": %s\n"),
763 						  filename,
764 						  pqStrerror(save_errno, sebuf, sizeof(sebuf)));
765 		return InvalidOid;
766 	}
767 
768 	(void) close(fd);
769 
770 	if (lo_close(conn, lobj) != 0)
771 	{
772 		/* we assume lo_close() already set a suitable error message */
773 		return InvalidOid;
774 	}
775 
776 	return lobjOid;
777 }
778 
779 /*
780  * lo_export -
781  *	  exports an (inversion) large object.
782  * returns -1 upon failure, 1 if OK
783  */
784 int
lo_export(PGconn * conn,Oid lobjId,const char * filename)785 lo_export(PGconn *conn, Oid lobjId, const char *filename)
786 {
787 	int			result = 1;
788 	int			fd;
789 	int			nbytes,
790 				tmp;
791 	char		buf[LO_BUFSIZE];
792 	int			lobj;
793 	char		sebuf[256];
794 
795 	/*
796 	 * open the large object.
797 	 */
798 	lobj = lo_open(conn, lobjId, INV_READ);
799 	if (lobj == -1)
800 	{
801 		/* we assume lo_open() already set a suitable error message */
802 		return -1;
803 	}
804 
805 	/*
806 	 * create the file to be written to
807 	 */
808 	fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
809 	if (fd < 0)
810 	{
811 		/* We must do lo_close before setting the errorMessage */
812 		int			save_errno = errno;
813 
814 		(void) lo_close(conn, lobj);
815 		printfPQExpBuffer(&conn->errorMessage,
816 						  libpq_gettext("could not open file \"%s\": %s\n"),
817 						  filename,
818 						  pqStrerror(save_errno, sebuf, sizeof(sebuf)));
819 		return -1;
820 	}
821 
822 	/*
823 	 * read in from the large object and write to the file
824 	 */
825 	while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
826 	{
827 		tmp = write(fd, buf, nbytes);
828 		if (tmp != nbytes)
829 		{
830 			/* We must do lo_close before setting the errorMessage */
831 			int			save_errno = errno;
832 
833 			(void) lo_close(conn, lobj);
834 			(void) close(fd);
835 			printfPQExpBuffer(&conn->errorMessage,
836 					   libpq_gettext("could not write to file \"%s\": %s\n"),
837 							  filename,
838 							  pqStrerror(save_errno, sebuf, sizeof(sebuf)));
839 			return -1;
840 		}
841 	}
842 
843 	/*
844 	 * If lo_read() failed, we are now in an aborted transaction so there's no
845 	 * need for lo_close(); furthermore, if we tried it we'd overwrite the
846 	 * useful error result with a useless one. So skip lo_close() if we got a
847 	 * failure result.
848 	 */
849 	if (nbytes < 0 ||
850 		lo_close(conn, lobj) != 0)
851 	{
852 		/* assume lo_read() or lo_close() left a suitable error message */
853 		result = -1;
854 	}
855 
856 	/* if we already failed, don't overwrite that msg with a close error */
857 	if (close(fd) && result >= 0)
858 	{
859 		printfPQExpBuffer(&conn->errorMessage,
860 					   libpq_gettext("could not write to file \"%s\": %s\n"),
861 						  filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
862 		result = -1;
863 	}
864 
865 	return result;
866 }
867 
868 
869 /*
870  * lo_initialize
871  *
872  * Initialize the large object interface for an existing connection.
873  * We ask the backend about the functions OID's in pg_proc for all
874  * functions that are required for large object operations.
875  */
876 static int
lo_initialize(PGconn * conn)877 lo_initialize(PGconn *conn)
878 {
879 	PGresult   *res;
880 	PGlobjfuncs *lobjfuncs;
881 	int			n;
882 	const char *query;
883 	const char *fname;
884 	Oid			foid;
885 
886 	if (!conn)
887 		return -1;
888 
889 	/*
890 	 * Allocate the structure to hold the functions OID's
891 	 */
892 	lobjfuncs = (PGlobjfuncs *) malloc(sizeof(PGlobjfuncs));
893 	if (lobjfuncs == NULL)
894 	{
895 		printfPQExpBuffer(&conn->errorMessage,
896 						  libpq_gettext("out of memory\n"));
897 		return -1;
898 	}
899 	MemSet((char *) lobjfuncs, 0, sizeof(PGlobjfuncs));
900 
901 	/*
902 	 * Execute the query to get all the functions at once.  In 7.3 and later
903 	 * we need to be schema-safe.  lo_create only exists in 8.1 and up.
904 	 * lo_truncate only exists in 8.3 and up.
905 	 */
906 	if (conn->sversion >= 70300)
907 		query = "select proname, oid from pg_catalog.pg_proc "
908 			"where proname in ("
909 			"'lo_open', "
910 			"'lo_close', "
911 			"'lo_creat', "
912 			"'lo_create', "
913 			"'lo_unlink', "
914 			"'lo_lseek', "
915 			"'lo_lseek64', "
916 			"'lo_tell', "
917 			"'lo_tell64', "
918 			"'lo_truncate', "
919 			"'lo_truncate64', "
920 			"'loread', "
921 			"'lowrite') "
922 			"and pronamespace = (select oid from pg_catalog.pg_namespace "
923 			"where nspname = 'pg_catalog')";
924 	else
925 		query = "select proname, oid from pg_proc "
926 			"where proname = 'lo_open' "
927 			"or proname = 'lo_close' "
928 			"or proname = 'lo_creat' "
929 			"or proname = 'lo_unlink' "
930 			"or proname = 'lo_lseek' "
931 			"or proname = 'lo_tell' "
932 			"or proname = 'loread' "
933 			"or proname = 'lowrite'";
934 
935 	res = PQexec(conn, query);
936 	if (res == NULL)
937 	{
938 		free(lobjfuncs);
939 		return -1;
940 	}
941 
942 	if (res->resultStatus != PGRES_TUPLES_OK)
943 	{
944 		free(lobjfuncs);
945 		PQclear(res);
946 		printfPQExpBuffer(&conn->errorMessage,
947 						  libpq_gettext("query to initialize large object functions did not return data\n"));
948 		return -1;
949 	}
950 
951 	/*
952 	 * Examine the result and put the OID's into the struct
953 	 */
954 	for (n = 0; n < PQntuples(res); n++)
955 	{
956 		fname = PQgetvalue(res, n, 0);
957 		foid = (Oid) atoi(PQgetvalue(res, n, 1));
958 		if (strcmp(fname, "lo_open") == 0)
959 			lobjfuncs->fn_lo_open = foid;
960 		else if (strcmp(fname, "lo_close") == 0)
961 			lobjfuncs->fn_lo_close = foid;
962 		else if (strcmp(fname, "lo_creat") == 0)
963 			lobjfuncs->fn_lo_creat = foid;
964 		else if (strcmp(fname, "lo_create") == 0)
965 			lobjfuncs->fn_lo_create = foid;
966 		else if (strcmp(fname, "lo_unlink") == 0)
967 			lobjfuncs->fn_lo_unlink = foid;
968 		else if (strcmp(fname, "lo_lseek") == 0)
969 			lobjfuncs->fn_lo_lseek = foid;
970 		else if (strcmp(fname, "lo_lseek64") == 0)
971 			lobjfuncs->fn_lo_lseek64 = foid;
972 		else if (strcmp(fname, "lo_tell") == 0)
973 			lobjfuncs->fn_lo_tell = foid;
974 		else if (strcmp(fname, "lo_tell64") == 0)
975 			lobjfuncs->fn_lo_tell64 = foid;
976 		else if (strcmp(fname, "lo_truncate") == 0)
977 			lobjfuncs->fn_lo_truncate = foid;
978 		else if (strcmp(fname, "lo_truncate64") == 0)
979 			lobjfuncs->fn_lo_truncate64 = foid;
980 		else if (strcmp(fname, "loread") == 0)
981 			lobjfuncs->fn_lo_read = foid;
982 		else if (strcmp(fname, "lowrite") == 0)
983 			lobjfuncs->fn_lo_write = foid;
984 	}
985 
986 	PQclear(res);
987 
988 	/*
989 	 * Finally check that we got all required large object interface functions
990 	 * (ones that have been added later than the stone age are instead checked
991 	 * only if used)
992 	 */
993 	if (lobjfuncs->fn_lo_open == 0)
994 	{
995 		printfPQExpBuffer(&conn->errorMessage,
996 				libpq_gettext("cannot determine OID of function lo_open\n"));
997 		free(lobjfuncs);
998 		return -1;
999 	}
1000 	if (lobjfuncs->fn_lo_close == 0)
1001 	{
1002 		printfPQExpBuffer(&conn->errorMessage,
1003 			   libpq_gettext("cannot determine OID of function lo_close\n"));
1004 		free(lobjfuncs);
1005 		return -1;
1006 	}
1007 	if (lobjfuncs->fn_lo_creat == 0)
1008 	{
1009 		printfPQExpBuffer(&conn->errorMessage,
1010 			   libpq_gettext("cannot determine OID of function lo_creat\n"));
1011 		free(lobjfuncs);
1012 		return -1;
1013 	}
1014 	if (lobjfuncs->fn_lo_unlink == 0)
1015 	{
1016 		printfPQExpBuffer(&conn->errorMessage,
1017 			  libpq_gettext("cannot determine OID of function lo_unlink\n"));
1018 		free(lobjfuncs);
1019 		return -1;
1020 	}
1021 	if (lobjfuncs->fn_lo_lseek == 0)
1022 	{
1023 		printfPQExpBuffer(&conn->errorMessage,
1024 			   libpq_gettext("cannot determine OID of function lo_lseek\n"));
1025 		free(lobjfuncs);
1026 		return -1;
1027 	}
1028 	if (lobjfuncs->fn_lo_tell == 0)
1029 	{
1030 		printfPQExpBuffer(&conn->errorMessage,
1031 				libpq_gettext("cannot determine OID of function lo_tell\n"));
1032 		free(lobjfuncs);
1033 		return -1;
1034 	}
1035 	if (lobjfuncs->fn_lo_read == 0)
1036 	{
1037 		printfPQExpBuffer(&conn->errorMessage,
1038 				 libpq_gettext("cannot determine OID of function loread\n"));
1039 		free(lobjfuncs);
1040 		return -1;
1041 	}
1042 	if (lobjfuncs->fn_lo_write == 0)
1043 	{
1044 		printfPQExpBuffer(&conn->errorMessage,
1045 				libpq_gettext("cannot determine OID of function lowrite\n"));
1046 		free(lobjfuncs);
1047 		return -1;
1048 	}
1049 
1050 	/*
1051 	 * Put the structure into the connection control
1052 	 */
1053 	conn->lobjfuncs = lobjfuncs;
1054 	return 0;
1055 }
1056 
1057 /*
1058  * lo_hton64
1059  *	  converts a 64-bit integer from host byte order to network byte order
1060  */
1061 static pg_int64
lo_hton64(pg_int64 host64)1062 lo_hton64(pg_int64 host64)
1063 {
1064 	union
1065 	{
1066 		pg_int64	i64;
1067 		uint32		i32[2];
1068 	}			swap;
1069 	uint32		t;
1070 
1071 	/* High order half first, since we're doing MSB-first */
1072 	t = (uint32) (host64 >> 32);
1073 	swap.i32[0] = htonl(t);
1074 
1075 	/* Now the low order half */
1076 	t = (uint32) host64;
1077 	swap.i32[1] = htonl(t);
1078 
1079 	return swap.i64;
1080 }
1081 
1082 /*
1083  * lo_ntoh64
1084  *	  converts a 64-bit integer from network byte order to host byte order
1085  */
1086 static pg_int64
lo_ntoh64(pg_int64 net64)1087 lo_ntoh64(pg_int64 net64)
1088 {
1089 	union
1090 	{
1091 		pg_int64	i64;
1092 		uint32		i32[2];
1093 	}			swap;
1094 	pg_int64	result;
1095 
1096 	swap.i64 = net64;
1097 
1098 	result = (uint32) ntohl(swap.i32[0]);
1099 	result <<= 32;
1100 	result |= (uint32) ntohl(swap.i32[1]);
1101 
1102 	return result;
1103 }
1104