2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 //%% (c) Copyright 1993, 1994 Hewlett-Packard Company
24 //%% (c) Copyright 1993, 1994 International Business Machines Corp.
25 //%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
26 //%% (c) Copyright 1993, 1994 Novell, Inc.
27 //%% $TOG: tt_db_client.C /main/11 1999/10/14 18:40:38 mgreess $
29 * @(#)tt_db_client.C 1.54 95/09/26
31 * tt_db_client.C - Define the TT DB client class. This class defines a
32 * client interface to the DB server.
34 * Copyright (c) 1992 by Sun Microsystems, Inc.
36 * NOTE: Result fields need to be freed with xdr_free if they were
37 * allocated by XDR routines. When "faking" the new calls
38 * on an old DBserver, the results are allocated with malloc.
39 * the correspoding tt_free... or just plain free() call
41 * XXX: Pervasively, this code assumed freeing a null pointer is OK.
42 * While ANSI C specifies this is OK lots of platforms gag on it.
43 * rather than try to figure out which free() calls may have nulls, I
44 * just wrapped them all in "if (0!=ptr) {...}".
48 #include <sys/param.h>
49 #include <sys/socket.h>
51 #include "util/tt_port.h"
52 #include "util/tt_gettext.h"
53 #include "db/tt_db_client.h"
54 #include "db/tt_db_access.h"
55 #include "db/tt_db_rpc_message_routines.h"
56 #include "db/db_server.h"
57 #include "db/tt_db_rpc_routines.h"
58 #include "db/tt_old_db_partition_map_ref.h"
60 /* Included after "util/tt_string.h" to avoid index/strchr conflicts. */
61 #define X_INCLUDE_NETDB_H
62 #define XOS_USE_XT_LOCKING
63 #include <X11/Xos_r.h>
65 // Some old versions of RPC headers don\'t define AUTH_NONE but
66 // do define the older AUTH_NULL flavor.
68 #if !defined(AUTH_NONE)
69 #define AUTH_NONE AUTH_NULL
72 static const char TT_DB_RPC_PROTO[] = "tcp";
73 static const struct timeval TT_DB_RPC_NORMAL_TIMEOUT = {1000000, 0};
74 static const struct timeval TT_DB_RPC_QUICK_TIMEOUT = {4, 0};
75 const int TT_DB_RPC_RETRIES = 3;
77 // ********** Old DB Server Compatibility Include Files **********
78 #include "db/tt_db_client_consts.h"
79 // ********** Old DB Server Compatibility Include Files **********
81 _Tt_db_client::_Tt_db_client()
83 _Tt_string db_hostname = _tt_gethostname();
86 connectToDB(db_hostname);
91 dbSocket.sin_family = 0;
92 dbSocket.sin_port = 0;
96 _Tt_db_client::_Tt_db_client (_Tt_db_results & status)
98 _Tt_string db_hostname = _tt_gethostname();
101 connectToDB(db_hostname);
102 status = dbConnectionResults;
107 #if !defined(OPT_TLI)
108 dbSocket.sin_family = 0;
109 dbSocket.sin_port = 0;
113 _Tt_db_client::_Tt_db_client (const _Tt_string &hostname, _Tt_db_results & status)
116 connectToDB(hostname);
117 status = dbConnectionResults;
120 _Tt_db_results _Tt_db_client::connectToDB (const _Tt_string &hostname)
122 _tt_auth_level_results *auth_level_results = (_tt_auth_level_results *)NULL;
127 dbHostname = hostname;
129 // Connect to the dbserver on the specified host.
130 // If we don't have TI_RPC we cannot depend on CLGET_FD, so
131 // we have to use clnttcp_create so that we get the socket FD back
132 // in order to set close_on_exec.
136 #ifdef OPT_HAS_CLNT_CREATE_TIMED
138 struct timeval tv = { OPT_CLNT_CREATE_TIMEOUT, 0};
140 dbServer = clnt_create_timed((char *)dbHostname,
143 (char *)TT_DB_RPC_PROTO,
146 dbServer = clnt_create((char *)dbHostname,
149 (char *)TT_DB_RPC_PROTO);
153 clnt_control(dbServer, CLGET_FD, (char *)&_socket);
156 struct sockaddr_in server_addr;
157 struct hostent *host_ret;
158 _Xgethostbynameparams host_buf;
160 memset((char*) &host_buf, 0, sizeof(_Xgethostbynameparams));
161 if ((host_ret = _XGethostbyname((char *)dbHostname, host_buf)) != NULL) {
162 _socket = RPC_ANYSOCK;
163 memset(&server_addr, 0, sizeof(server_addr));
164 server_addr.sin_family = AF_INET;
165 server_addr.sin_port = htons(0);
166 memcpy(&server_addr.sin_addr.s_addr,
167 *(host_ret->h_addr_list),
168 sizeof(server_addr.sin_addr.s_addr));
170 dbServer = clnttcp_create(&server_addr,
177 // gethostbyname failed, fake RPC error
179 rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
183 // Connection failed.
186 _tt_syslog(0, LOG_ERR, catgets(_ttcatd, 1, 3,
187 "clnt_create for rpc.ttdbserverd on %s failed%s"),
188 (char *)dbHostname, clnt_spcreateerror(""));
190 // Set dbConnectionResults data member...
191 SetError(rpc_createerr.cf_stat);
193 return dbConnectionResults;
196 // Connection succeeded.
197 clnt_control(dbServer, CLSET_TIMEOUT, (char *)&TT_DB_RPC_QUICK_TIMEOUT);
199 dbConnectionResults = TT_DB_ERR_DB_CONNECTION_FAILED; // Default value.
202 for (;dbVersion > 0; dbVersion--) {
206 _tt_get_min_auth_level_1 ((void *)NULL, dbServer);
208 // If dbVersion == 1, then we are talking to an old DB server
209 static _tt_auth_level_results results;
212 clnt_stat rpc_status;
213 int *result = (int *)NULL;
214 result = _tt_min_auth_level_1(&path, dbServer, &rpc_status);
217 results.results = TT_DB_OK;
218 results.auth_level = *result;
219 auth_level_results = &results;
223 if ((auth_level_results) && (auth_level_results->results == TT_DB_OK)) {
225 clnt_control(dbServer, CLSET_TIMEOUT,
226 (char *)&TT_DB_RPC_NORMAL_TIMEOUT);
228 dbAuthLevel = auth_level_results->auth_level;
230 dbConnectionResults = TT_DB_OK; // Default return value.
232 switch (dbAuthLevel) {
235 dbServer->cl_auth = authunix_create_default();
238 #ifdef OPT_SECURE_RPC
240 char server_net_name [MAXNETNAMELEN+1];
241 struct hostent *host_ret;
242 _Xgethostbynameparams host_buf;
243 if (host2netname(server_net_name, dbHostname, 0) &&
244 ((host_ret = _XGethostbyname((char *)dbHostname, host_buf)) != NULL)) {
246 dbServerNetName = server_net_name;
248 memcpy((caddr_t) &dbSocket.sin_addr,
251 dbSocket.sin_family = AF_INET;
252 dbSocket.sin_port = 0;
255 dbConnectionResults =
256 TT_DB_ERR_DB_CONNECTION_FAILED;
260 #endif // OPT_SECURE_RPC
262 dbConnectionResults =
263 TT_DB_ERR_DB_CONNECTION_FAILED;
268 // If _tt_get_min_auth_level_1 is not available, then we are talking
269 // to an old DB server.
270 if (_tt_get_rpc_result() != RPC_AUTHERROR) {
272 _tt_syslog(0, LOG_ERR,
273 catgets(_ttcatd, 1, 4, "Error: rpc.ttdbserverd on %s is not running"),
276 SetError(_tt_get_rpc_result());
278 break; // Give up and return error code.
284 // Cleanup if failure.
286 if (dbConnectionResults != TT_DB_OK) {
288 clnt_destroy(dbServer);
289 dbServer = (CLIENT *)NULL;
293 // Set close-on-exec bit so a libtt client which forks and execs won't
294 // be short some fd's in the child.
295 if (-1 != _socket && -1 == fcntl(_socket, F_SETFD, 1)) {
296 _tt_syslog( 0, LOG_ERR, "_Tt_db_client::connectToDb(): "
297 "fcntl(F_SETFD): %m");
300 return dbConnectionResults;
304 SetError(enum clnt_stat cf_stat)
308 printf("DEBUG _Tt_db_client::SetError() -- cf_stat == %d\n", cf_stat);
312 case RPC_PROGNOTREGISTERED:
314 case RPC_VERSMISMATCH:
315 case RPC_PROGUNAVAIL:
316 case RPC_PROGVERSMISMATCH:
317 case RPC_PROCUNAVAIL:
318 dbConnectionResults = TT_DB_ERR_DB_OPEN_FAILED;
321 case RPC_CANTENCODEARGS:
322 case RPC_CANTDECODEARGS:
323 case RPC_CANTDECODERES:
327 dbConnectionResults = TT_DB_ERR_RPC_FAILED;
332 case RPC_SYSTEMERROR:
337 case RPC_UNKNOWNADDR:
339 case RPC_UNKNOWNHOST:
340 case RPC_UNKNOWNPROTO:
341 dbConnectionResults = TT_DB_ERR_RPC_CONNECTION_FAILED;
345 dbConnectionResults = TT_DB_ERR_DB_CONNECTION_FAILED;
348 } // end -SetError()-
350 void _Tt_db_client::setTtDBDefaults ()
352 dbAccess = new _Tt_db_access;
353 dbAuthLevel = AUTH_NONE;
354 dbConnectionResults = TT_DB_OK;
355 dbServer = (CLIENT *)NULL;
357 dbVersion = 2; // Initially assume version 2. If one of the new
358 // RPC calls cannot be found (RPC_PROCUNAVAIL),
359 // then downgrade the version to 1. This is only
360 // required for old DB server compatibility.
363 _Tt_db_client::~_Tt_db_client ()
366 if (dbServer->cl_auth) {
367 auth_destroy(dbServer->cl_auth);
369 clnt_destroy (dbServer);
373 void _Tt_db_client::setCurrentAccess (const _Tt_db_access_ptr &access)
378 _Tt_db_access_ptr _Tt_db_client::getCurrentAccess () const
384 _Tt_db_client::getFilePartition (const _Tt_string &file_path,
385 _Tt_string &partition,
386 _Tt_string &network_path)
388 _Tt_db_results retval;
389 char *temp_path = (char *)file_path;
390 char **temp_path_ptr = &temp_path;
394 _tt_file_partition_results *results =
396 _tt_get_file_partition_1(temp_path_ptr, dbServer) :
397 _tt_get_file_partition_1(temp_path_ptr, this));
400 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
403 partition = results->partition;
404 network_path = results->network_path;
405 retval = results->results;
408 if (0!=results->partition) {
409 free(results->partition);
412 if (0!=results->network_path) {
413 free(results->network_path);
416 xdr_free((xdrproc_t)xdr_tt_file_partition_results, (char *)results);
423 _Tt_db_client::createFile (const _Tt_string &file,
424 const _Tt_db_property_list_ptr &properties,
425 const _Tt_db_access_ptr &access,
428 _tt_create_file_args args;
430 args.file = (char *)file;
431 _tt_set_rpc_properties(properties, args.properties);
432 _tt_set_rpc_access(access, args.access);
435 _tt_db_cache_results *results =
437 _tt_create_file_1(&args, dbServer) :
438 _tt_create_file_1(&args, this));
439 _tt_free_rpc_properties(args.properties);
442 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
445 cache_level = results->cache_level;
446 return results->results;
450 _Tt_db_client::createObject (const _Tt_string &file,
451 const _Tt_string &objid,
452 const _Tt_string &otype,
453 const _Tt_db_property_list_ptr &properties,
454 const _Tt_db_access_ptr &access,
457 _tt_create_obj_args args;
459 args.file = (char *)file;
460 args.objid = (char *)objid;
461 args.otype = (char *)otype;
462 _tt_set_rpc_properties (properties, args.properties);
463 _tt_set_rpc_access(access, args.access);
466 _tt_db_cache_results *results =
468 _tt_create_obj_1(&args, dbServer) :
469 _tt_create_obj_1(&args, this));
470 _tt_free_rpc_properties(args.properties);
473 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
476 cache_level = results->cache_level;
477 return results->results;
481 _Tt_db_client::removeFile (const _Tt_string &file)
483 _tt_remove_file_args args;
484 _tt_set_rpc_access(dbAccess, args.access);
486 args.file = (char *)file;
488 _tt_db_results *results =
490 _tt_remove_file_1(&args, dbServer) :
491 _tt_remove_file_1(&args, this));
494 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
500 _Tt_db_client::removeObject (const _Tt_string &objid,
501 const _Tt_string &forward_pointer)
503 _tt_remove_obj_args args;
504 _tt_set_rpc_access(dbAccess, args.access);
506 args.objid = (char *)objid;
507 args.forward_pointer = (forward_pointer.len() ?
508 (char *)forward_pointer : (char *)NULL);
511 _tt_db_results *results =
513 _tt_remove_obj_1(&args, dbServer) :
514 _tt_remove_obj_1(&args, this));
517 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
523 _Tt_db_client::moveFile (const _Tt_string &file,
524 const _Tt_string &new_file)
526 _tt_move_file_args args;
527 _tt_set_rpc_access(dbAccess, args.access);
529 args.file = (char *)file;
530 args.new_file = (char *)new_file;
532 _tt_db_results *results =
534 _tt_move_file_1(&args, dbServer) :
535 _tt_move_file_1(&args, this));
538 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
544 _Tt_db_client::setFileProperty (const _Tt_string &file,
545 const _Tt_db_property_ptr &property,
548 _tt_set_file_prop_args args;
550 args.file = (char *)file;
551 _tt_set_rpc_property(property, args.property);
552 _tt_set_rpc_access(dbAccess, args.access);
555 _tt_db_cache_results *results =
557 _tt_set_file_prop_1(&args, dbServer) :
558 _tt_set_file_prop_1(&args, this));
559 _tt_free_rpc_property(args.property);
562 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
565 cache_level = results->cache_level;
566 return results->results;
569 _Tt_db_results _Tt_db_client
570 ::setFileProperties (const _Tt_string &file,
571 const _Tt_db_property_list_ptr &properties,
574 _tt_set_file_props_args args;
576 args.file = (char *)file;
577 _tt_set_rpc_properties (properties, args.properties);
578 _tt_set_rpc_access(dbAccess, args.access);
581 _tt_db_cache_results *results =
583 _tt_set_file_props_1(&args, dbServer) :
584 _tt_set_file_props_1(&args, this));
585 _tt_free_rpc_properties(args.properties);
588 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
591 cache_level = results->cache_level;
592 return results->results;
596 _Tt_db_client::addFileProperty (const _Tt_string &file,
597 const _Tt_db_property_ptr &property,
601 _tt_add_file_prop_args args;
603 args.file = (char *)file;
604 _tt_set_rpc_property(property, args.property);
605 args.unique = (int)unique;
606 _tt_set_rpc_access(dbAccess, args.access);
610 _tt_db_cache_results *results;
612 results = _tt_add_file_prop_1(&args, dbServer);
615 if (property->name == TT_DB_SESSION_PROPERTY) {
616 static _tt_db_cache_results rpc_results;
618 results = &rpc_results;
619 results->cache_level = cache_level+1;
620 results->results = addsession(file, (*property->values)[0]);
623 results = _tt_add_file_prop_1(&args, this);
626 _tt_free_rpc_property(args.property);
629 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
632 cache_level = results->cache_level;
633 return results->results;
637 _Tt_db_client::deleteFileProperty (const _Tt_string &file,
638 const _Tt_db_property_ptr &property,
641 _tt_del_file_prop_args args;
643 args.file = (char *)file;
644 _tt_set_rpc_property(property, args.property);
645 _tt_set_rpc_access(dbAccess, args.access);
648 _tt_db_cache_results *results;
650 results = _tt_delete_file_prop_1(&args, dbServer);
653 if (property->name == TT_DB_SESSION_PROPERTY) {
654 static _tt_db_cache_results rpc_results;
656 results = &rpc_results;
657 results->cache_level = cache_level+1;
658 results->results = delsession(file, (*property->values)[0]);
661 results = _tt_delete_file_prop_1(&args, this);
664 _tt_free_rpc_property(args.property);
667 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
670 cache_level = results->cache_level;
671 return results->results;
675 _Tt_db_client::getFileProperty (const _Tt_string &file,
676 const _Tt_string &name,
678 _Tt_db_property_ptr &property)
680 _Tt_db_results retval;
681 _tt_get_file_prop_args args;
683 args.file = (char *)file;
684 args.name = (char *)name;
685 _tt_set_rpc_access(dbAccess, args.access);
686 args.cache_level = cache_level;
689 _tt_file_prop_results *results =
691 _tt_get_file_prop_1(&args, dbServer) :
692 _tt_get_file_prop_1(&args, this));
695 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
698 cache_level = results->cache_level;
699 _tt_get_rpc_property(results->property, property);
700 retval = results->results;
702 _tt_free_rpc_property(results->property);
704 xdr_free((xdrproc_t)xdr_tt_file_prop_results, (char *)results);
709 _Tt_db_results _Tt_db_client::
710 getFileProperties (const _Tt_string &file,
712 _Tt_db_property_list_ptr &properties)
714 _Tt_db_results retval;
715 _tt_get_file_props_args args;
717 args.file = (char *)file;
718 _tt_set_rpc_access(dbAccess, args.access);
719 args.cache_level = cache_level;
722 _tt_file_props_results *results =
724 _tt_get_file_props_1(&args, dbServer) :
725 _tt_get_file_props_1(&args, this));
728 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
731 cache_level = results->cache_level;
732 retval = results->results;
733 _tt_get_rpc_properties(results->properties, properties);
735 _tt_free_rpc_properties(results->properties);
737 xdr_free((xdrproc_t)xdr_tt_file_props_results, (char *)results);
743 _Tt_db_client::getFileObjects (const _Tt_string &file,
745 _Tt_string_list_ptr &objids)
747 _Tt_db_results retval;
748 _tt_get_file_objs_args args;
750 args.file = (char *)file;
751 _tt_set_rpc_access(dbAccess, args.access);
752 args.cache_level = cache_level;
755 _tt_file_objs_results *results =
757 _tt_get_file_objs_1(&args, dbServer) :
758 _tt_get_file_objs_1(&args, this));
761 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
764 cache_level = results->cache_level;
765 retval = results->results;
766 _tt_get_rpc_strings(results->objids, objids);
768 _tt_free_rpc_strings(results->objids);
770 xdr_free((xdrproc_t)xdr_tt_file_objs_results, (char *)results);
776 _Tt_db_client::setFileAccess (const _Tt_string &file,
777 const _Tt_db_access_ptr &access)
779 _tt_set_file_access_args args;
781 args.file = (char *)file;
782 _tt_set_rpc_access(access, args.new_access);
783 _tt_set_rpc_access(dbAccess, args.access);
786 _tt_db_results *results =
788 _tt_set_file_access_1(&args, dbServer) :
789 _tt_set_file_access_1(&args, this));
792 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
798 _Tt_db_client::getFileAccess (const _Tt_string &file,
799 _Tt_db_access_ptr &access)
801 _tt_get_file_access_args args;
803 args.file = (char *)file;
804 _tt_set_rpc_access(dbAccess, args.access);
807 _tt_file_access_results *results =
809 _tt_get_file_access_1(&args, dbServer) :
810 _tt_get_file_access_1(&args, this));
813 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
816 _tt_get_rpc_access(results->access, access);
817 return results->results;
821 _Tt_db_client::setObjectProperty (const _Tt_string &objid,
822 const _Tt_db_property_ptr &property,
823 _Tt_db_property_list_ptr &properties,
826 _Tt_db_results retval;
827 _tt_set_obj_prop_args args;
829 args.objid = (char *)objid;
830 _tt_set_rpc_property(property, args.property);
831 _tt_set_rpc_access(dbAccess, args.access);
832 args.cache_level = cache_level;
835 _tt_obj_props_results *results =
837 _tt_set_obj_prop_1(&args, dbServer) :
838 _tt_set_obj_prop_1(&args, this));
839 _tt_free_rpc_property(args.property);
842 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
845 cache_level = results->cache_level;
846 retval = results->results;
847 _tt_get_rpc_properties(results->properties, properties);
849 _tt_free_rpc_properties(results->properties);
851 xdr_free((xdrproc_t)xdr_tt_obj_props_results, (char *)results);
856 _Tt_db_results _Tt_db_client::
857 setObjectProperties (const _Tt_string &objid,
858 const _Tt_db_property_list_ptr &in_properties,
859 _Tt_db_property_list_ptr &out_properties,
862 _Tt_db_results retval;
863 _tt_set_obj_props_args args;
865 args.objid = (char *)objid;
866 _tt_set_rpc_properties (in_properties, args.properties);
867 _tt_set_rpc_access(dbAccess, args.access);
868 args.cache_level = cache_level;
871 _tt_obj_props_results *results =
873 _tt_set_obj_props_1(&args, dbServer) :
874 _tt_set_obj_props_1(&args, this));
875 _tt_free_rpc_properties(args.properties);
878 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
881 cache_level = results->cache_level;
882 retval = results->results;
883 _tt_get_rpc_properties(results->properties, out_properties);
885 _tt_free_rpc_properties(results->properties);
887 xdr_free((xdrproc_t)xdr_tt_obj_props_results, (char *)results);
893 _Tt_db_client::addObjectProperty (const _Tt_string &objid,
894 const _Tt_db_property_ptr &property,
896 _Tt_db_property_list_ptr &properties,
899 _Tt_db_results retval;
900 _tt_add_obj_prop_args args;
902 args.objid = (char *)objid;
903 _tt_set_rpc_property(property, args.property);
904 args.unique = (int)unique;
905 _tt_set_rpc_access(dbAccess, args.access);
906 args.cache_level = cache_level;
909 _tt_obj_props_results *results =
911 _tt_add_obj_prop_1(&args, dbServer) :
912 _tt_add_obj_prop_1(&args, this));
913 _tt_free_rpc_property(args.property);
916 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
919 cache_level = results->cache_level;
920 retval = results->results;
921 _tt_get_rpc_properties(results->properties, properties);
923 _tt_free_rpc_properties(results->properties);
925 xdr_free((xdrproc_t)xdr_tt_obj_props_results, (char *)results);
930 _Tt_db_results _Tt_db_client::
931 deleteObjectProperty (const _Tt_string &objid,
932 const _Tt_db_property_ptr &property,
933 _Tt_db_property_list_ptr &properties,
936 _Tt_db_results retval;
937 _tt_del_obj_prop_args args;
939 args.objid = (char *)objid;
940 _tt_set_rpc_property(property, args.property);
941 _tt_set_rpc_access(dbAccess, args.access);
942 args.cache_level = cache_level;
945 _tt_obj_props_results *results =
947 _tt_delete_obj_prop_1(&args, dbServer) :
948 _tt_delete_obj_prop_1(&args, this));
949 _tt_free_rpc_property(args.property);
952 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
955 _tt_get_rpc_properties(results->properties, properties);
956 cache_level = results->cache_level;
957 retval = results->results;
959 _tt_free_rpc_properties(results->properties);
961 xdr_free((xdrproc_t)xdr_tt_obj_props_results, (char *)results);
967 _Tt_db_client::getObjectProperty (const _Tt_string &objid,
968 const _Tt_string &name,
970 _Tt_db_property_ptr &property)
972 _Tt_db_results retval;
973 _tt_get_obj_prop_args args;
975 args.objid = (char *)objid;
976 args.name = (char *)name;
977 _tt_set_rpc_access(dbAccess, args.access);
978 args.cache_level = cache_level;
981 _tt_obj_prop_results *results =
983 _tt_get_obj_prop_1(&args, dbServer) :
984 _tt_get_obj_prop_1(&args, this));
987 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
990 cache_level = results->cache_level;
991 retval = results->results;
992 _tt_get_rpc_property(results->property, property);
994 _tt_free_rpc_property(results->property);
996 xdr_free((xdrproc_t)xdr_tt_obj_prop_results, (char *)results);
1001 _Tt_db_results _Tt_db_client::
1002 getObjectProperties (const _Tt_string &objid,
1004 _Tt_db_property_list_ptr &properties)
1006 _Tt_db_results retval;
1007 _tt_get_obj_props_args args;
1009 args.objid = (char *)objid;
1010 _tt_set_rpc_access(dbAccess, args.access);
1011 args.cache_level = cache_level;
1014 _tt_obj_props_results *results =
1016 _tt_get_obj_props_1(&args, dbServer) :
1017 _tt_get_obj_props_1(&args, this));
1020 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1023 cache_level = results->cache_level;
1024 retval = results->results;
1025 _tt_get_rpc_properties(results->properties, properties);
1027 _tt_free_rpc_properties(results->properties);
1029 xdr_free((xdrproc_t)xdr_tt_obj_props_results, (char *)results);
1034 _Tt_db_results _Tt_db_client::setObjectType (const _Tt_string &objid,
1035 const _Tt_string &otype)
1037 _tt_set_obj_type_args args;
1039 args.objid = (char *)objid;
1040 args.otype = (char *)otype;
1041 _tt_set_rpc_access(dbAccess, args.access);
1044 _tt_db_results *results =
1046 _tt_set_obj_type_1(&args, dbServer) :
1047 _tt_set_obj_type_1(&args, this));
1050 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1055 _Tt_db_results _Tt_db_client::getObjectType (const _Tt_string &objid,
1058 _Tt_db_results retval;
1059 _tt_get_obj_type_args args;
1061 args.objid = (char *)objid;
1062 _tt_set_rpc_access(dbAccess, args.access);
1065 _tt_obj_type_results *results;
1066 if (dbVersion > 1) {
1067 results = _tt_get_obj_type_1(&args, dbServer);
1069 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1071 retval = results->results;
1072 otype = results->otype;
1073 xdr_free((xdrproc_t)xdr_tt_obj_type_results, (char *)results);
1075 retval = gettype(objid, otype);
1080 _Tt_db_results _Tt_db_client::setObjectFile (const _Tt_string &objid,
1081 const _Tt_string &file)
1083 _tt_set_obj_file_args args;
1085 args.objid = (char *)objid;
1086 args.file = (char *)file;
1087 _tt_set_rpc_access(dbAccess, args.access);
1090 _tt_db_results *results =
1092 _tt_set_obj_file_1(&args, dbServer) :
1093 _tt_set_obj_file_1(&args, this));
1096 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1102 _Tt_db_results _Tt_db_client::getObjectFile (const _Tt_string &objid,
1105 _Tt_db_results retval;
1106 _tt_get_obj_file_args args;
1108 args.objid = (char *)objid;
1109 _tt_set_rpc_access(dbAccess, args.access);
1112 _tt_obj_file_results *results =
1114 _tt_get_obj_file_1(&args, dbServer) :
1115 _tt_get_obj_file_1(&args, this));
1118 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1121 retval = results->results;
1122 file = results->file;
1124 if (0!=results->file) {
1125 free(results->file);
1128 xdr_free((xdrproc_t)xdr_tt_obj_file_results, (char *)results);
1134 _Tt_db_client::setObjectAccess (const _Tt_string &objid,
1135 const _Tt_db_access_ptr &access)
1137 _tt_set_obj_access_args args;
1139 args.objid = (char *)objid;
1140 _tt_set_rpc_access(access, args.new_access);
1141 _tt_set_rpc_access(dbAccess, args.access);
1144 _tt_db_results *results =
1146 _tt_set_obj_access_1(&args, dbServer) :
1147 _tt_set_obj_access_1(&args, this));
1150 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1156 _Tt_db_client::getObjectAccess (const _Tt_string &objid,
1157 _Tt_db_access_ptr &access)
1159 _tt_get_obj_access_args args;
1161 args.objid = (char *)objid;
1162 _tt_set_rpc_access(dbAccess, args.access);
1165 _tt_obj_access_results *results =
1167 _tt_get_obj_access_1(&args, dbServer) :
1168 _tt_get_obj_access_1(&args, this));
1171 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1174 _tt_get_rpc_access(results->access, access);
1175 return results->results;
1178 _Tt_db_results _Tt_db_client::
1179 isFileInDatabase (const _Tt_string &file,
1180 bool_t &directory_flag)
1182 _tt_is_file_in_db_args args;
1184 args.file = (char *)file;
1185 _tt_set_rpc_access(dbAccess, args.access);
1188 _tt_is_file_in_db_results *results =
1190 _tt_is_file_in_db_1(&args, dbServer) :
1191 _tt_is_file_in_db_1(&args, this));
1194 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1197 directory_flag = results->directory_flag;
1198 return results->results;
1201 _Tt_db_results _Tt_db_client::
1202 isObjectInDatabase (const _Tt_string &objid,
1203 _Tt_string &forward_pointer)
1205 _Tt_db_results retval;
1206 _tt_is_obj_in_db_args args;
1208 args.objid = (char *)objid;
1209 _tt_set_rpc_access(dbAccess, args.access);
1212 _tt_is_obj_in_db_results *results =
1214 _tt_is_obj_in_db_1(&args, dbServer) :
1215 _tt_is_obj_in_db_1(&args, this));
1218 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1221 forward_pointer = results->forward_pointer;
1222 retval = results->results;
1224 if (0!=results->forward_pointer) {
1225 free(results->forward_pointer);
1228 xdr_free((xdrproc_t)xdr_tt_is_obj_in_db_results, (char *)results);
1234 _Tt_db_client::queueMessage (const _Tt_string &file,
1235 const _Tt_string_list_ptr &ptypes,
1236 const _Tt_message_ptr &message)
1238 _tt_queue_msg_args args;
1240 args.file = (char *)file;
1241 _tt_set_rpc_strings(ptypes, args.ptypes);
1242 if (_tt_set_rpc_message(message, args.message) != TT_DB_OK) {
1243 return (TT_DB_ERR_ILLEGAL_MESSAGE);
1247 _tt_db_results *results =
1249 _tt_queue_message_1(&args, dbServer) :
1250 _tt_queue_message_1(&args, this));
1251 _tt_free_rpc_strings(args.ptypes);
1252 _tt_free_rpc_message(args.message);
1255 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1261 _Tt_db_client::dequeueMessages (const _Tt_string &file,
1262 const _Tt_string_list_ptr &ptypes,
1263 _Tt_message_list_ptr &messages)
1265 _tt_dequeue_msgs_args args;
1267 args.file = (char *)file;
1268 _tt_set_rpc_strings(ptypes, args.ptypes);
1271 _tt_dequeue_msgs_results *results =
1273 _tt_dequeue_messages_1(&args, dbServer) :
1274 _tt_dequeue_messages_1(&args, this));
1275 _tt_free_rpc_strings(args.ptypes);
1278 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1281 _tt_get_rpc_messages(results->messages, messages);
1283 _tt_free_rpc_messages(results->messages);
1285 xdr_free((xdrproc_t)xdr_tt_dequeue_msgs_results, (char *)results);
1287 return results->results;
1290 void _Tt_db_client::createAuth ()
1292 #ifdef OPT_SECURE_RPC
1293 if (dbAuthLevel == AUTH_DES) {
1294 if (dbServer->cl_auth) {
1295 auth_destroy(dbServer->cl_auth);
1297 const int CRED_EXPIRE = 10;
1299 dbServer->cl_auth = authdes_seccreate((char *)dbServerNetName,
1301 (char *)dbServerNetName,
1304 dbServer->cl_auth = authdes_create((char *)dbServerNetName,
1310 #endif // OPT_SECURE_RPC
1314 // Gets the remote ends' idea of what the netfile version of the specified
1316 _Tt_db_results _Tt_db_client ::
1317 file_netfile(const _Tt_string &file, _Tt_string &netfile)
1319 _Tt_db_results retval;
1320 _tt_file_netfile_args args;
1323 args.file_or_netfile = (char *)file;
1327 _tt_file_netfile_results *results = _tt_file_netfile_1(&args, dbServer);
1329 //XXX - this needs to detect that we tried contacting an old dbserver
1330 // so we can return TT_ERR_UNIMP
1332 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1335 // prepare what we're passing back to the caller.
1336 retval = results->results;
1337 netfile = results->result_string;
1339 xdr_free((xdrproc_t)xdr_tt_file_netfile_results, (char *)results);
1344 // Gets the remote ends' idea of what the file version of the specified
1346 _Tt_db_results _Tt_db_client ::
1347 netfile_file(const _Tt_string &netfile, _Tt_string &file)
1349 _Tt_db_results retval;
1350 _tt_file_netfile_args args;
1352 args.file_or_netfile = (char *)netfile;
1356 _tt_file_netfile_results *results = _tt_netfile_file_1(&args, dbServer);
1358 // XXX - this needs to detect that we tried contacting an old dbserver
1359 // so we can return TT_ERR_UNIMP
1361 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1364 // prepare what we're passing back to the caller.
1365 retval = results->results;
1366 file = results->result_string;
1368 xdr_free((xdrproc_t)xdr_tt_file_netfile_results, (char *)results);
1373 // ********** Old DB Server Compatibility Prototcol **********
1375 // The following member functions are used to provide compatibility
1376 // with old DB servers. All of these member functions map directly
1377 // to an old DB server RPC call. The names of these member functions
1378 // have been kept the same as the base name of the corresponding
1381 #include "db/tt_old_db_consts.h"
1383 _Tt_string _Tt_db_client::mfs(const _Tt_string &path)
1386 char *char_path = (char *)path;
1387 char **char_partition = _tt_mfs_1(&char_path, dbServer);
1389 if (char_partition) {
1390 retval = *char_partition;
1391 xdr_free((xdrproc_t)xdr_wrapstring, (char *)char_partition);
1394 // Theoretically "should not happen". If it does just use
1395 // the root partition which is our general fallback...
1396 return _Tt_string("/");
1401 _Tt_db_results _Tt_db_client::addsession(const _Tt_string &file,
1402 const _Tt_string &session)
1404 _Tt_isam_results *res;
1405 _Tt_session_args args;
1407 _Tt_string temp_string;
1408 _Tt_string path = file;
1409 path = path.split(':', temp_string);
1411 _Tt_string partition = mfs(path);
1412 _Tt_old_db_partition_map_ref map;
1413 _Tt_old_db_ptr old_db = map.getDB(partition, this);
1416 _Tt_db_results results = old_db->getFileKey(file, key);
1418 if (results == TT_DB_OK) {
1419 args.isfd = old_db->propertyTableFD;
1420 args.key = old_db->propertyTablePropertyKey->getKeyDescriptor();
1421 args.key_len = TT_OLD_DB_KEY_LENGTH + TT_OLD_DB_MAX_PROPERTY_NAME_LENGTH;
1422 args.oidkey.oidkey_len = TT_OLD_DB_KEY_LENGTH;
1423 args.oidkey.oidkey_val = (char *)key;
1424 args.session.session_len = session.len();
1425 args.session.session_val = (char *)session;
1426 res = _tt_addsession_1(&args, dbServer);
1427 return oldDBToNewDBResults((_Tt_old_db_results)res->result);
1433 _Tt_db_results _Tt_db_client::delsession(const _Tt_string &file,
1434 const _Tt_string &session)
1436 _Tt_isam_results *res;
1437 _Tt_session_args args;
1439 _Tt_string temp_string;
1440 _Tt_string path = file;
1441 path = path.split(':', temp_string);
1443 _Tt_string partition = mfs(path);
1444 _Tt_old_db_partition_map_ref map;
1445 _Tt_old_db_ptr old_db = map.getDB(partition, this);
1448 _Tt_db_results results = old_db->getFileKey(file, key);
1450 if (results == TT_DB_OK) {
1451 args.isfd = old_db->propertyTableFD;
1452 args.key = old_db->propertyTablePropertyKey->getKeyDescriptor();
1453 args.key_len = TT_OLD_DB_KEY_LENGTH + TT_OLD_DB_MAX_PROPERTY_NAME_LENGTH;
1454 args.oidkey.oidkey_len = TT_OLD_DB_KEY_LENGTH;
1455 args.oidkey.oidkey_val = (char *)key;
1456 args.session.session_len = session.len();
1457 args.session.session_val = (char *)session;
1458 res = _tt_delsession_1(&args, dbServer);
1459 if ((res->result == -1) && (res->iserrno == ENOREC)) { // XXX where else?
1460 return TT_DB_ERR_NO_SUCH_PROPERTY;
1462 return oldDBToNewDBResults((_Tt_old_db_results)res->result);
1468 _Tt_db_results _Tt_db_client::gettype(const _Tt_string &objid,
1471 _Tt_spec_props *res;
1472 _Tt_spec_props args;
1473 _Tt_prop props, *propp;
1474 _Tt_db_results retval;
1476 _Tt_string partition = objid;
1477 _Tt_string temp_string;
1479 // Get rid of file system type and hostname - the partition
1480 // is the only thing left
1481 partition = partition.split(':', temp_string);
1482 partition = partition.split(':', temp_string);
1483 partition = partition.split(':', temp_string);
1485 _Tt_old_db_partition_map_ref map;
1486 _Tt_old_db_ptr old_db = map.getDB(partition, this);
1487 _Tt_db_key object_key(objid);
1489 args.isfd = old_db->propertyTableFD;
1490 args.key = old_db->propertyTablePropertyKey->getKeyDescriptor();
1491 args.key_len = TT_OLD_DB_KEY_LENGTH + TT_OLD_DB_MAX_PROPERTY_NAME_LENGTH;
1492 args.oidkey.oidkey_len = TT_OLD_DB_KEY_LENGTH;
1493 args.oidkey.oidkey_val = (char *)object_key.binary();
1494 args.props.props_len = 1;
1495 args.props.props_val = &props;
1496 props.propname.propname_val = TT_OLD_DB_OBJECT_TYPE_PROPERTY;
1497 props.propname.propname_len = strlen(TT_OLD_DB_OBJECT_TYPE_PROPERTY);
1499 props.value.value_len = 0;
1500 props.value.value_val = 0;
1501 res = _tt_gettype_1(&args, dbServer);
1502 if (res->result == TT_DB_OK) {
1503 propp = &(res->props.props_val[0]);
1504 type.set((unsigned char *)propp->value.value_val,
1505 propp->value.value_len);
1507 retval = oldDBToNewDBResults((_Tt_old_db_results)res->result);
1508 xdr_free((xdrproc_t)xdr_Tt_spec_props, (char *)res);
1513 isaddindex(int isfd, struct keydesc *key)
1516 _Tt_isaddindex_args args;
1519 _Tt_isam_results *isresult = _tt_isaddindex_1(&args, dbServer);
1524 iserrno = isresult->iserrno;
1525 return isresult->result;
1529 isbuild(char *path, int reclen, struct keydesc *key, int mode)
1532 _Tt_isbuild_args args;
1534 args.reclen = reclen;
1537 args.isreclen = isreclen;
1538 _Tt_isam_results *isresult = _tt_isbuild_1(&args, dbServer);
1543 iserrno = isresult->iserrno;
1544 return isresult->result;
1551 _Tt_isam_results *isresult = _tt_isclose_1(&isfd, dbServer);
1556 iserrno = isresult->iserrno;
1557 return isresult->result;
1561 iscntl(int isfd, int func, char *arg)
1564 _Tt_iscntl_args args;
1567 args.arg.arg_len = ISAPPLMAGICLEN;
1568 args.arg.arg_val = arg;
1569 _Tt_iscntl_results *isresult = _tt_iscntl_1(&args, dbServer);
1574 iserrno = isresult->iserrno;
1575 memcpy(arg, isresult->arg.arg_val, isresult->arg.arg_len);
1576 if (isresult->arg.arg_val != 0) {
1577 xdr_free((xdrproc_t)xdr_Tt_iscntl_results, (char *)isresult);
1579 return isresult->result;
1583 isdelrec(int isfd, long recnum, char *rec)
1586 _Tt_isdelrec_args args;
1588 args.recnum = recnum;
1589 args.rec.rec_len = isreclen;
1590 args.rec.rec_val = rec;
1591 _Tt_isam_results *isresult = _tt_isdelrec_1(&args, dbServer);
1596 iserrno = isresult->iserrno;
1597 return isresult->result;
1604 _Tt_isam_results *isresult = _tt_iserase_1(&path, dbServer);
1609 iserrno = isresult->iserrno;
1610 return isresult->result;
1614 isopen(char *path, int mode)
1617 _Tt_isopen_args args;
1620 _Tt_isam_results *isresult = _tt_isopen_1(&args, dbServer);
1625 iserrno = isresult->iserrno;
1626 return isresult->result;
1630 isread(int isfd, char *rec, int mode)
1633 _Tt_isread_args args;
1635 args.rec.rec_len = isreclen;
1636 args.rec.rec_val = rec;
1639 _Tt_isread_results *isresult = _tt_isread_1(&args, dbServer);
1644 isreclen = isresult->isreclen;
1645 isrecnum = isresult->isrecnum;
1646 iserrno = isresult->isresult.iserrno;
1647 if (isresult->isresult.result != -1) {
1648 memcpy(rec, isresult->rec.rec_val, isresult->isreclen);
1650 if (isresult->rec.rec_val != 0) {
1651 xdr_free((xdrproc_t)xdr_Tt_isread_results, (char *)isresult);
1653 return isresult->isresult.result;
1657 isrewrec(int isfd, long recnum, char *rec)
1660 _Tt_isrewrec_args args;
1662 args.recnum = recnum;
1663 args.rec.rec_len = isreclen;
1664 args.rec.rec_val = rec;
1665 _Tt_isam_results *isresult = _tt_isrewrec_1(&args, dbServer);
1670 iserrno = isresult->iserrno;
1671 return isresult->result;
1675 isstart(int isfd, keydesc *key, int key_len, char *rec, int mode)
1678 _Tt_isstart_args args;
1681 args.key_len = key_len;
1682 args.rec.rec_len = rec ? isreclen : 0;
1683 args.rec.rec_val = rec ? rec : 0;
1685 _Tt_isam_results *isresult = _tt_isstart_1(&args, dbServer);
1690 iserrno = isresult->iserrno;
1691 return isresult->result;
1695 iswrite(int isfd, char *rec)
1698 _Tt_iswrite_args args;
1700 args.rec.rec_len = isreclen;
1701 args.rec.rec_val = rec;
1702 _Tt_isam_results *isresult = _tt_iswrite_1(&args, dbServer);
1707 iserrno = isresult->iserrno;
1708 return isresult->result;
1711 _Tt_db_results _Tt_db_client::
1712 oldDBToNewDBResults (_Tt_old_db_results old_db_results)
1714 switch (old_db_results) {
1718 case TT_OLD_DB_ERROR:
1719 case TT_OLD_DB_INIT_FAILED:
1720 return TT_DB_ERR_RPC_CONNECTION_FAILED;
1722 case TT_OLD_DB_DBDESC_EXISTS:
1723 case TT_OLD_DB_DB_EXISTS:
1724 case TT_OLD_DB_CREATE_FAILED:
1725 return TT_DB_ERR_CORRUPT_DB;
1727 case TT_OLD_DB_OPEN_FAILED:
1728 return TT_DB_ERR_DB_OPEN_FAILED;
1730 case TT_OLD_DB_NO_RECORD:
1731 case TT_OLD_DB_READ_FAILED:
1732 case TT_OLD_DB_WRITE_FAILED:
1733 case TT_OLD_DB_DELETE_FAILED:
1734 case TT_OLD_DB_CLOSE_FAILED:
1735 return TT_DB_ERR_CORRUPT_DB;
1737 case TT_OLD_DB_UNKNOWN_DBTABLE:
1738 case TT_OLD_DB_UNKNOWN_INDEX:
1739 case TT_OLD_DB_INVALID_VERSION_NUMBER:
1740 case TT_OLD_DB_PATHMAP_FAILED:
1741 case TT_OLD_DB_UPDATE_MFS_INFO_FAILED:
1742 case TT_OLD_DB_CLEAR_LOCKS_FAILED:
1743 return TT_DB_ERR_CORRUPT_DB;
1745 case TT_OLD_DB_RECORD_LOCKED:
1746 return TT_DB_ERR_DB_LOCKED;
1748 case TT_OLD_DB_NO_MFS:
1749 case TT_OLD_DB_UNKNOWN_FS:
1750 case TT_OLD_DB_CONVERSION_ERROR:
1751 case TT_OLD_DB_RECORD_SET:
1752 return TT_DB_ERR_CORRUPT_DB;
1754 case TT_OLD_DB_ACCESS_DENIED:
1755 return TT_DB_ERR_ACCESS_DENIED;
1761 return TT_DB_ERR_CORRUPT_DB;
1765 _Tt_db_client::get_all_sessions()
1768 static _Tt_string_list * results = NULL;
1770 if (results != NULL) {
1773 results = new _Tt_string_list;
1776 _tt_get_all_sessions_results *xdr_results;
1777 _tt_get_all_sessions_args args;
1781 // Clear out any old data.
1782 memset(&args, '\0', sizeof(args));
1786 xdr_results = _tt_get_all_sessions_1(&args, dbServer);
1787 if (xdr_results == NULL) {
1790 for (offset=0; offset<xdr_results->session_list.values_len; offset++){
1791 string = xdr_results->session_list.values_val[offset].value;
1792 results->append(string);
1795 xdr_free((xdrproc_t)xdr_tt_get_all_sessions_results,
1796 (char *)xdr_results);
1798 // Copy over any continuation key.
1799 memcpy(&xdr_results->oidkey, &args.oidkey, sizeof(args.oidkey));
1800 } while(xdr_results->oidkey.oidkey_len > 0);
1806 _Tt_db_client::delete_session(_Tt_string session)
1808 _tt_delete_session_results *res;
1809 _tt_delete_session_args args;
1811 args.session.value = session;
1813 res = _tt_delete_session_1(&args, dbServer);
1815 return (TT_DB_ERR_RPC_CONNECTION_FAILED);
1821 _Tt_db_client::garbage_collect_in_server()
1823 _tt_db_results results = TT_DB_OK;
1824 _tt_garbage_collect_results *res;
1826 res = _tt_garbage_collect_1(NULL, dbServer);
1828 return (TT_DB_ERR_RPC_CONNECTION_FAILED);