/*-------------------------------------------------------------------------
 *
 * fe-lobj.c
 *	  Front-end large object interface
 *
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/interfaces/libpq/fe-lobj.c
 *
 *-------------------------------------------------------------------------
 */

#ifdef WIN32
/*
 *	As unlink/rename are #define'd in port.h (via postgres_fe.h), io.h
 *	must be included first on MS C.  Might as well do it for all WIN32's
 *	here.
 */
#include <io.h>
#endif

#include "postgres_fe.h"

#ifdef WIN32
#include "win32.h"
#else
#include <unistd.h>
#endif

#include <fcntl.h>
#include <limits.h>
#include <sys/stat.h>

#include "libpq-fe.h"
#include "libpq-int.h"
#include "libpq/libpq-fs.h"		/* must come after sys/stat.h */
#include "port/pg_bswap.h"

#define LO_BUFSIZE		  8192

static int	lo_initialize(PGconn *conn);
static Oid	lo_import_internal(PGconn *conn, const char *filename, Oid oid);
static pg_int64 lo_hton64(pg_int64 host64);
static pg_int64 lo_ntoh64(pg_int64 net64);

/*
 * lo_open
 *	  opens an existing large object
 *
 * returns the file descriptor for use in later lo_* calls
 * return -1 upon failure.
 */
int
lo_open(PGconn *conn, Oid lobjId, int mode)
{
	int			fd;
	int			result_len;
	PQArgBlock	argv[2];
	PGresult   *res;

	if (lo_initialize(conn) < 0)
		return -1;

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = lobjId;

	argv[1].isint = 1;
	argv[1].len = 4;
	argv[1].u.integer = mode;

	res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2);
	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return fd;
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_close
 *	  closes an existing large object
 *
 * returns 0 upon success
 * returns -1 upon failure.
 */
int
lo_close(PGconn *conn, int fd)
{
	PQArgBlock	argv[1];
	PGresult   *res;
	int			retval;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return -1;

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = fd;
	res = PQfn(conn, conn->lobjfuncs->fn_lo_close,
			   &retval, &result_len, 1, argv, 1);
	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return retval;
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_truncate
 *	  truncates an existing large object to the given size
 *
 * returns 0 upon success
 * returns -1 upon failure
 */
int
lo_truncate(PGconn *conn, int fd, size_t len)
{
	PQArgBlock	argv[2];
	PGresult   *res;
	int			retval;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return -1;

	/* Must check this on-the-fly because it's not there pre-8.3 */
	if (conn->lobjfuncs->fn_lo_truncate == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_truncate");
		return -1;
	}

	/*
	 * Long ago, somebody thought it'd be a good idea to declare this function
	 * as taking size_t ... but the underlying backend function only accepts a
	 * signed int32 length.  So throw error if the given value overflows
	 * int32.  (A possible alternative is to automatically redirect the call
	 * to lo_truncate64; but if the caller wanted to rely on that backend
	 * function being available, he could have called lo_truncate64 for
	 * himself.)
	 */
	if (len > (size_t) INT_MAX)
	{
		libpq_append_conn_error(conn, "argument of lo_truncate exceeds integer range");
		return -1;
	}

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = fd;

	argv[1].isint = 1;
	argv[1].len = 4;
	argv[1].u.integer = (int) len;

	res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate,
			   &retval, &result_len, 1, argv, 2);

	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return retval;
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_truncate64
 *	  truncates an existing large object to the given size
 *
 * returns 0 upon success
 * returns -1 upon failure
 */
int
lo_truncate64(PGconn *conn, int fd, pg_int64 len)
{
	PQArgBlock	argv[2];
	PGresult   *res;
	int			retval;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return -1;

	if (conn->lobjfuncs->fn_lo_truncate64 == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_truncate64");
		return -1;
	}

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = fd;

	len = lo_hton64(len);
	argv[1].isint = 0;
	argv[1].len = 8;
	argv[1].u.ptr = (int *) &len;

	res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate64,
			   &retval, &result_len, 1, argv, 2);

	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return retval;
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_read
 *	  read len bytes of the large object into buf
 *
 * returns the number of bytes read, or -1 on failure.
 * the CALLER must have allocated enough space to hold the result returned
 */

int
lo_read(PGconn *conn, int fd, char *buf, size_t len)
{
	PQArgBlock	argv[2];
	PGresult   *res;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return -1;

	/*
	 * Long ago, somebody thought it'd be a good idea to declare this function
	 * as taking size_t ... but the underlying backend function only accepts a
	 * signed int32 length.  So throw error if the given value overflows
	 * int32.
	 */
	if (len > (size_t) INT_MAX)
	{
		libpq_append_conn_error(conn, "argument of lo_read exceeds integer range");
		return -1;
	}

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = fd;

	argv[1].isint = 1;
	argv[1].len = 4;
	argv[1].u.integer = (int) len;

	res = PQfn(conn, conn->lobjfuncs->fn_lo_read,
			   (void *) buf, &result_len, 0, argv, 2);
	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return result_len;
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_write
 *	  write len bytes of buf into the large object fd
 *
 * returns the number of bytes written, or -1 on failure.
 */
int
lo_write(PGconn *conn, int fd, const char *buf, size_t len)
{
	PQArgBlock	argv[2];
	PGresult   *res;
	int			result_len;
	int			retval;

	if (lo_initialize(conn) < 0)
		return -1;

	/*
	 * Long ago, somebody thought it'd be a good idea to declare this function
	 * as taking size_t ... but the underlying backend function only accepts a
	 * signed int32 length.  So throw error if the given value overflows
	 * int32.
	 */
	if (len > (size_t) INT_MAX)
	{
		libpq_append_conn_error(conn, "argument of lo_write exceeds integer range");
		return -1;
	}

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = fd;

	argv[1].isint = 0;
	argv[1].len = (int) len;
	argv[1].u.ptr = (int *) unconstify(char *, buf);

	res = PQfn(conn, conn->lobjfuncs->fn_lo_write,
			   &retval, &result_len, 1, argv, 2);
	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return retval;
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_lseek
 *	  change the current read or write location on a large object
 */
int
lo_lseek(PGconn *conn, int fd, int offset, int whence)
{
	PQArgBlock	argv[3];
	PGresult   *res;
	int			retval;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return -1;

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = fd;

	argv[1].isint = 1;
	argv[1].len = 4;
	argv[1].u.integer = offset;

	argv[2].isint = 1;
	argv[2].len = 4;
	argv[2].u.integer = whence;

	res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek,
			   &retval, &result_len, 1, argv, 3);
	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return retval;
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_lseek64
 *	  change the current read or write location on a large object
 */
pg_int64
lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
{
	PQArgBlock	argv[3];
	PGresult   *res;
	pg_int64	retval;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return -1;

	if (conn->lobjfuncs->fn_lo_lseek64 == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_lseek64");
		return -1;
	}

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = fd;

	offset = lo_hton64(offset);
	argv[1].isint = 0;
	argv[1].len = 8;
	argv[1].u.ptr = (int *) &offset;

	argv[2].isint = 1;
	argv[2].len = 4;
	argv[2].u.integer = whence;

	res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek64,
			   (void *) &retval, &result_len, 0, argv, 3);
	if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
	{
		PQclear(res);
		return lo_ntoh64(retval);
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_creat
 *	  create a new large object
 * the mode is ignored (once upon a time it had a use)
 *
 * returns the oid of the large object created or
 * InvalidOid upon failure
 */
Oid
lo_creat(PGconn *conn, int mode)
{
	PQArgBlock	argv[1];
	PGresult   *res;
	int			retval;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return InvalidOid;

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = mode;
	res = PQfn(conn, conn->lobjfuncs->fn_lo_creat,
			   &retval, &result_len, 1, argv, 1);
	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return (Oid) retval;
	}
	else
	{
		PQclear(res);
		return InvalidOid;
	}
}

/*
 * lo_create
 *	  create a new large object
 * if lobjId isn't InvalidOid, it specifies the OID to (attempt to) create
 *
 * returns the oid of the large object created or
 * InvalidOid upon failure
 */
Oid
lo_create(PGconn *conn, Oid lobjId)
{
	PQArgBlock	argv[1];
	PGresult   *res;
	int			retval;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return InvalidOid;

	/* Must check this on-the-fly because it's not there pre-8.1 */
	if (conn->lobjfuncs->fn_lo_create == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_create");
		return InvalidOid;
	}

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = lobjId;
	res = PQfn(conn, conn->lobjfuncs->fn_lo_create,
			   &retval, &result_len, 1, argv, 1);
	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return (Oid) retval;
	}
	else
	{
		PQclear(res);
		return InvalidOid;
	}
}


/*
 * lo_tell
 *	  returns the current seek location of the large object
 */
int
lo_tell(PGconn *conn, int fd)
{
	int			retval;
	PQArgBlock	argv[1];
	PGresult   *res;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return -1;

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = fd;

	res = PQfn(conn, conn->lobjfuncs->fn_lo_tell,
			   &retval, &result_len, 1, argv, 1);
	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return retval;
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_tell64
 *	  returns the current seek location of the large object
 */
pg_int64
lo_tell64(PGconn *conn, int fd)
{
	pg_int64	retval;
	PQArgBlock	argv[1];
	PGresult   *res;
	int			result_len;

	if (lo_initialize(conn) < 0)
		return -1;

	if (conn->lobjfuncs->fn_lo_tell64 == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_tell64");
		return -1;
	}

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = fd;

	res = PQfn(conn, conn->lobjfuncs->fn_lo_tell64,
			   (void *) &retval, &result_len, 0, argv, 1);
	if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8)
	{
		PQclear(res);
		return lo_ntoh64(retval);
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_unlink
 *	  delete a file
 */

int
lo_unlink(PGconn *conn, Oid lobjId)
{
	PQArgBlock	argv[1];
	PGresult   *res;
	int			result_len;
	int			retval;

	if (lo_initialize(conn) < 0)
		return -1;

	argv[0].isint = 1;
	argv[0].len = 4;
	argv[0].u.integer = lobjId;

	res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink,
			   &retval, &result_len, 1, argv, 1);
	if (PQresultStatus(res) == PGRES_COMMAND_OK)
	{
		PQclear(res);
		return retval;
	}
	else
	{
		PQclear(res);
		return -1;
	}
}

/*
 * lo_import -
 *	  imports a file as an (inversion) large object.
 *
 * returns the oid of that object upon success,
 * returns InvalidOid upon failure
 */

Oid
lo_import(PGconn *conn, const char *filename)
{
	return lo_import_internal(conn, filename, InvalidOid);
}

/*
 * lo_import_with_oid -
 *	  imports a file as an (inversion) large object.
 *	  large object id can be specified.
 *
 * returns the oid of that object upon success,
 * returns InvalidOid upon failure
 */

Oid
lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId)
{
	return lo_import_internal(conn, filename, lobjId);
}

static Oid
lo_import_internal(PGconn *conn, const char *filename, Oid oid)
{
	int			fd;
	int			nbytes,
				tmp;
	char		buf[LO_BUFSIZE];
	Oid			lobjOid;
	int			lobj;
	char		sebuf[PG_STRERROR_R_BUFLEN];

	if (conn == NULL)
		return InvalidOid;

	/* Since this is the beginning of a query cycle, reset the error state */
	pqClearConnErrorState(conn);

	/*
	 * open the file to be read in
	 */
	fd = open(filename, O_RDONLY | PG_BINARY, 0666);
	if (fd < 0)
	{							/* error */
		libpq_append_conn_error(conn, "could not open file \"%s\": %s",
								filename, strerror_r(errno, sebuf, sizeof(sebuf)));
		return InvalidOid;
	}

	/*
	 * create an inversion object
	 */
	if (oid == InvalidOid)
		lobjOid = lo_creat(conn, INV_READ | INV_WRITE);
	else
		lobjOid = lo_create(conn, oid);

	if (lobjOid == InvalidOid)
	{
		/* we assume lo_create() already set a suitable error message */
		(void) close(fd);
		return InvalidOid;
	}

	lobj = lo_open(conn, lobjOid, INV_WRITE);
	if (lobj == -1)
	{
		/* we assume lo_open() already set a suitable error message */
		(void) close(fd);
		return InvalidOid;
	}

	/*
	 * read in from the file and write to the large object
	 */
	while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0)
	{
		tmp = lo_write(conn, lobj, buf, nbytes);
		if (tmp != nbytes)
		{
			/*
			 * If lo_write() failed, we are now in an aborted transaction so
			 * there's no need for lo_close(); furthermore, if we tried it
			 * we'd overwrite the useful error result with a useless one. So
			 * just nail the doors shut and get out of town.
			 */
			(void) close(fd);
			return InvalidOid;
		}
	}

	if (nbytes < 0)
	{
		/* We must do lo_close before setting the errorMessage */
		int			save_errno = errno;

		(void) lo_close(conn, lobj);
		(void) close(fd);
		/* deliberately overwrite any error from lo_close */
		pqClearConnErrorState(conn);
		libpq_append_conn_error(conn, "could not read from file \"%s\": %s",
								filename,
								strerror_r(save_errno, sebuf, sizeof(sebuf)));
		return InvalidOid;
	}

	(void) close(fd);

	if (lo_close(conn, lobj) != 0)
	{
		/* we assume lo_close() already set a suitable error message */
		return InvalidOid;
	}

	return lobjOid;
}

/*
 * lo_export -
 *	  exports an (inversion) large object.
 * returns -1 upon failure, 1 if OK
 */
int
lo_export(PGconn *conn, Oid lobjId, const char *filename)
{
	int			result = 1;
	int			fd;
	int			nbytes,
				tmp;
	char		buf[LO_BUFSIZE];
	int			lobj;
	char		sebuf[PG_STRERROR_R_BUFLEN];

	/*
	 * open the large object.
	 */
	lobj = lo_open(conn, lobjId, INV_READ);
	if (lobj == -1)
	{
		/* we assume lo_open() already set a suitable error message */
		return -1;
	}

	/*
	 * create the file to be written to
	 */
	fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
	if (fd < 0)
	{
		/* We must do lo_close before setting the errorMessage */
		int			save_errno = errno;

		(void) lo_close(conn, lobj);
		/* deliberately overwrite any error from lo_close */
		pqClearConnErrorState(conn);
		libpq_append_conn_error(conn, "could not open file \"%s\": %s",
								filename,
								strerror_r(save_errno, sebuf, sizeof(sebuf)));
		return -1;
	}

	/*
	 * read in from the large object and write to the file
	 */
	while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0)
	{
		tmp = write(fd, buf, nbytes);
		if (tmp != nbytes)
		{
			/* We must do lo_close before setting the errorMessage */
			int			save_errno = errno;

			(void) lo_close(conn, lobj);
			(void) close(fd);
			/* deliberately overwrite any error from lo_close */
			pqClearConnErrorState(conn);
			libpq_append_conn_error(conn, "could not write to file \"%s\": %s",
									filename,
									strerror_r(save_errno, sebuf, sizeof(sebuf)));
			return -1;
		}
	}

	/*
	 * If lo_read() failed, we are now in an aborted transaction so there's no
	 * need for lo_close(); furthermore, if we tried it we'd overwrite the
	 * useful error result with a useless one. So skip lo_close() if we got a
	 * failure result.
	 */
	if (nbytes < 0 ||
		lo_close(conn, lobj) != 0)
	{
		/* assume lo_read() or lo_close() left a suitable error message */
		result = -1;
	}

	/* if we already failed, don't overwrite that msg with a close error */
	if (close(fd) != 0 && result >= 0)
	{
		libpq_append_conn_error(conn, "could not write to file \"%s\": %s",
								filename, strerror_r(errno, sebuf, sizeof(sebuf)));
		result = -1;
	}

	return result;
}


/*
 * lo_initialize
 *
 * Initialize for a new large-object operation on an existing connection.
 * Return 0 if OK, -1 on failure.
 *
 * If we haven't previously done so, we collect the function OIDs from
 * pg_proc for all functions that are required for large object operations.
 */
static int
lo_initialize(PGconn *conn)
{
	PGresult   *res;
	PGlobjfuncs *lobjfuncs;
	int			n;
	const char *query;
	const char *fname;
	Oid			foid;

	/* Nothing we can do with no connection */
	if (conn == NULL)
		return -1;

	/* Since this is the beginning of a query cycle, reset the error state */
	pqClearConnErrorState(conn);

	/* Nothing else to do if we already collected info */
	if (conn->lobjfuncs != NULL)
		return 0;

	/*
	 * Allocate the structure to hold the function OIDs.  We don't store it
	 * into the PGconn until it's successfully filled.
	 */
	lobjfuncs = (PGlobjfuncs *) malloc(sizeof(PGlobjfuncs));
	if (lobjfuncs == NULL)
	{
		libpq_append_conn_error(conn, "out of memory");
		return -1;
	}
	MemSet((char *) lobjfuncs, 0, sizeof(PGlobjfuncs));

	/*
	 * Execute the query to get all the functions at once.  (Not all of them
	 * may exist in older server versions.)
	 */
	query = "select proname, oid from pg_catalog.pg_proc "
		"where proname in ("
		"'lo_open', "
		"'lo_close', "
		"'lo_creat', "
		"'lo_create', "
		"'lo_unlink', "
		"'lo_lseek', "
		"'lo_lseek64', "
		"'lo_tell', "
		"'lo_tell64', "
		"'lo_truncate', "
		"'lo_truncate64', "
		"'loread', "
		"'lowrite') "
		"and pronamespace = (select oid from pg_catalog.pg_namespace "
		"where nspname = 'pg_catalog')";

	res = PQexec(conn, query);
	if (res == NULL)
	{
		free(lobjfuncs);
		return -1;
	}

	if (res->resultStatus != PGRES_TUPLES_OK)
	{
		free(lobjfuncs);
		PQclear(res);
		libpq_append_conn_error(conn, "query to initialize large object functions did not return data");
		return -1;
	}

	/*
	 * Examine the result and put the OID's into the struct
	 */
	for (n = 0; n < PQntuples(res); n++)
	{
		fname = PQgetvalue(res, n, 0);
		foid = (Oid) atoi(PQgetvalue(res, n, 1));
		if (strcmp(fname, "lo_open") == 0)
			lobjfuncs->fn_lo_open = foid;
		else if (strcmp(fname, "lo_close") == 0)
			lobjfuncs->fn_lo_close = foid;
		else if (strcmp(fname, "lo_creat") == 0)
			lobjfuncs->fn_lo_creat = foid;
		else if (strcmp(fname, "lo_create") == 0)
			lobjfuncs->fn_lo_create = foid;
		else if (strcmp(fname, "lo_unlink") == 0)
			lobjfuncs->fn_lo_unlink = foid;
		else if (strcmp(fname, "lo_lseek") == 0)
			lobjfuncs->fn_lo_lseek = foid;
		else if (strcmp(fname, "lo_lseek64") == 0)
			lobjfuncs->fn_lo_lseek64 = foid;
		else if (strcmp(fname, "lo_tell") == 0)
			lobjfuncs->fn_lo_tell = foid;
		else if (strcmp(fname, "lo_tell64") == 0)
			lobjfuncs->fn_lo_tell64 = foid;
		else if (strcmp(fname, "lo_truncate") == 0)
			lobjfuncs->fn_lo_truncate = foid;
		else if (strcmp(fname, "lo_truncate64") == 0)
			lobjfuncs->fn_lo_truncate64 = foid;
		else if (strcmp(fname, "loread") == 0)
			lobjfuncs->fn_lo_read = foid;
		else if (strcmp(fname, "lowrite") == 0)
			lobjfuncs->fn_lo_write = foid;
	}

	PQclear(res);

	/*
	 * Finally check that we got all required large object interface functions
	 * (ones that have been added later than the stone age are instead checked
	 * only if used)
	 */
	if (lobjfuncs->fn_lo_open == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_open");
		free(lobjfuncs);
		return -1;
	}
	if (lobjfuncs->fn_lo_close == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_close");
		free(lobjfuncs);
		return -1;
	}
	if (lobjfuncs->fn_lo_creat == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_creat");
		free(lobjfuncs);
		return -1;
	}
	if (lobjfuncs->fn_lo_unlink == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_unlink");
		free(lobjfuncs);
		return -1;
	}
	if (lobjfuncs->fn_lo_lseek == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_lseek");
		free(lobjfuncs);
		return -1;
	}
	if (lobjfuncs->fn_lo_tell == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lo_tell");
		free(lobjfuncs);
		return -1;
	}
	if (lobjfuncs->fn_lo_read == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"loread");
		free(lobjfuncs);
		return -1;
	}
	if (lobjfuncs->fn_lo_write == 0)
	{
		libpq_append_conn_error(conn, "cannot determine OID of function %s",
								"lowrite");
		free(lobjfuncs);
		return -1;
	}

	/*
	 * Put the structure into the connection control
	 */
	conn->lobjfuncs = lobjfuncs;
	return 0;
}

/*
 * lo_hton64
 *	  converts a 64-bit integer from host byte order to network byte order
 */
static pg_int64
lo_hton64(pg_int64 host64)
{
	union
	{
		pg_int64	i64;
		uint32		i32[2];
	}			swap;
	uint32		t;

	/* High order half first, since we're doing MSB-first */
	t = (uint32) (host64 >> 32);
	swap.i32[0] = pg_hton32(t);

	/* Now the low order half */
	t = (uint32) host64;
	swap.i32[1] = pg_hton32(t);

	return swap.i64;
}

/*
 * lo_ntoh64
 *	  converts a 64-bit integer from network byte order to host byte order
 */
static pg_int64
lo_ntoh64(pg_int64 net64)
{
	union
	{
		pg_int64	i64;
		uint32		i32[2];
	}			swap;
	pg_int64	result;

	swap.i64 = net64;

	result = (uint32) pg_ntoh32(swap.i32[0]);
	result <<= 32;
	result |= (uint32) pg_ntoh32(swap.i32[1]);

	return result;
}
