2
* Copyright 1999-2006 University of Chicago
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
#include "globus_i_gridftp_server.h"
20
* should select logging based on configuration. log output funcs should
21
* still be usable before this and will output to stderr.
23
* if this fails, just print to stderr.
27
static globus_logging_handle_t globus_l_gfs_log_handle = NULL;
28
static globus_list_t * globus_l_gfs_log_usage_handle_list = NULL;
29
static FILE * globus_l_gfs_log_file = NULL;
30
static FILE * globus_l_gfs_transfer_log_file = NULL;
31
static globus_bool_t globus_l_gfs_log_events = GLOBUS_FALSE;
33
#define GLOBUS_L_GFS_USAGE_ID 0
34
#define GLOBUS_L_GFS_USAGE_VER 0
36
#define GLOBUS_GFS_DEFAULT_TAGLIST "eEvbBNsStcDATaV"
37
#define GLOBUS_GFS_ALL_TAGLIST "eEvbBNsStcfiIudCDATaVU"
38
#define GLOBUS_GFS_MAX_TAGCOUNT 25
40
typedef enum globus_i_gfs_log_usage_tag_e
42
GLOBUS_I_GFS_USAGE_START = 'e',
43
GLOBUS_I_GFS_USAGE_END = 'E',
44
GLOBUS_I_GFS_USAGE_VER = 'v',
45
GLOBUS_I_GFS_USAGE_BUFFER = 'b',
46
GLOBUS_I_GFS_USAGE_BLOCK = 'B',
47
GLOBUS_I_GFS_USAGE_NBYTES = 'N',
48
GLOBUS_I_GFS_USAGE_STREAMS = 's',
49
GLOBUS_I_GFS_USAGE_STRIPES = 'S',
50
GLOBUS_I_GFS_USAGE_TYPE = 't',
51
GLOBUS_I_GFS_USAGE_CODE = 'c',
52
GLOBUS_I_GFS_USAGE_FILE = 'f',
53
GLOBUS_I_GFS_USAGE_CLIENTIP = 'i',
54
GLOBUS_I_GFS_USAGE_DATAIP = 'I',
55
GLOBUS_I_GFS_USAGE_USER = 'u',
56
GLOBUS_I_GFS_USAGE_USERDN = 'd',
57
GLOBUS_I_GFS_USAGE_CONFID = 'C',
58
GLOBUS_I_GFS_USAGE_DSI = 'D',
59
GLOBUS_I_GFS_USAGE_EM = 'A',
60
GLOBUS_I_GFS_USAGE_SCHEME = 'T',
61
GLOBUS_I_GFS_USAGE_APP = 'a',
62
GLOBUS_I_GFS_USAGE_APPVER = 'V',
63
GLOBUS_I_GFS_USAGE_SESSID = 'U'
64
/* !! ADD to ALL_TAGLIST above when adding here */
65
} globus_i_gfs_log_usage_tag_t;
67
typedef struct globus_l_gfs_log_usage_ent_s
69
globus_usage_stats_handle_t handle;
72
} globus_l_gfs_log_usage_ent_t;
76
globus_l_gfs_log_matchlevel(
80
GlobusGFSName(globus_l_gfs_log_matchlevel);
81
GlobusGFSDebugEnter();
83
if(strcasecmp(tag, "ERROR") == 0)
85
out = GLOBUS_GFS_LOG_ERR;
87
else if(strcasecmp(tag, "WARN") == 0)
89
out = GLOBUS_GFS_LOG_WARN;
91
else if(strcasecmp(tag, "INFO") == 0)
93
out = GLOBUS_GFS_LOG_INFO;
95
else if(strcasecmp(tag, "STATUS") == 0)
97
out = GLOBUS_GFS_LOG_STATUS;
99
else if(strcasecmp(tag, "DUMP") == 0)
101
out = GLOBUS_GFS_LOG_DUMP;
103
else if(strcasecmp(tag, "ALL") == 0)
105
out = GLOBUS_GFS_LOG_ALL;
108
GlobusGFSDebugExit();
115
globus_l_gfs_log_usage_stats_init()
117
globus_result_t result;
122
globus_list_t * list;
123
globus_l_gfs_log_usage_ent_t * usage_ent;
125
target_str = globus_libc_strdup(
126
globus_i_gfs_config_string("usage_stats_target"));
128
if(target_str && strchr(target_str, '!'))
131
while((ptr = strchr(target, ',')) != NULL)
133
usage_ent = (globus_l_gfs_log_usage_ent_t *)
134
globus_malloc(sizeof(globus_l_gfs_log_usage_ent_t));
137
entry = globus_libc_strdup(target);
140
if((ptr = strchr(entry, '!')) != NULL)
143
usage_ent->taglist = globus_libc_strdup(ptr + 1);
144
if(strlen(usage_ent->taglist) > GLOBUS_GFS_MAX_TAGCOUNT)
146
usage_ent->taglist[GLOBUS_GFS_MAX_TAGCOUNT + 1] = '\0';
152
globus_libc_strdup(GLOBUS_GFS_DEFAULT_TAGLIST);
155
if(strcasecmp(usage_ent->taglist, "default") == 0)
157
globus_free(usage_ent->taglist);
159
globus_libc_strdup(GLOBUS_GFS_DEFAULT_TAGLIST);
161
else if(strcasecmp(usage_ent->taglist, "all") == 0)
163
globus_free(usage_ent->taglist);
165
globus_libc_strdup(GLOBUS_GFS_ALL_TAGLIST);
168
usage_ent->target = entry;
170
globus_list_insert(&globus_l_gfs_log_usage_handle_list, usage_ent);
174
usage_ent = (globus_l_gfs_log_usage_ent_t *)
175
globus_malloc(sizeof(globus_l_gfs_log_usage_ent_t));
177
entry = globus_libc_strdup(target);
180
if((ptr = strchr(entry, '!')) != NULL)
183
usage_ent->taglist = globus_libc_strdup(ptr + 1);
184
if(strlen(usage_ent->taglist) > GLOBUS_GFS_MAX_TAGCOUNT)
186
usage_ent->taglist[GLOBUS_GFS_MAX_TAGCOUNT + 1] = '\0';
192
globus_libc_strdup(GLOBUS_GFS_DEFAULT_TAGLIST);
195
if(strcasecmp(usage_ent->taglist, "default") == 0)
197
globus_free(usage_ent->taglist);
199
globus_libc_strdup(GLOBUS_GFS_DEFAULT_TAGLIST);
201
else if(strcasecmp(usage_ent->taglist, "all") == 0)
203
globus_free(usage_ent->taglist);
205
globus_libc_strdup(GLOBUS_GFS_ALL_TAGLIST);
208
usage_ent->target = entry;
210
globus_list_insert(&globus_l_gfs_log_usage_handle_list, usage_ent);
213
globus_free(target_str);
217
usage_ent = (globus_l_gfs_log_usage_ent_t *)
218
globus_malloc(sizeof(globus_l_gfs_log_usage_ent_t));
220
usage_ent->target = target_str;
221
usage_ent->taglist = globus_libc_strdup(GLOBUS_GFS_DEFAULT_TAGLIST);
223
globus_list_insert(&globus_l_gfs_log_usage_handle_list, usage_ent);
227
for(list = globus_l_gfs_log_usage_handle_list;
228
!globus_list_empty(list);
229
list = globus_list_rest(list))
231
usage_ent = (globus_l_gfs_log_usage_ent_t *) globus_list_first(list);
233
usage_ent->handle = NULL;
234
result = globus_usage_stats_handle_init(
236
GLOBUS_L_GFS_USAGE_ID,
237
GLOBUS_L_GFS_USAGE_VER,
246
globus_i_gfs_log_open()
250
globus_logging_module_t * log_mod;
251
void * log_arg = NULL;
252
char * logfilename = NULL;
253
char * log_filemode = NULL;
254
char * logunique = NULL;
255
char * log_level = NULL;
261
globus_result_t result;
262
globus_reltime_t flush_interval;
263
globus_size_t buffer;
264
GlobusGFSName(globus_i_gfs_log_open);
265
GlobusGFSDebugEnter();
267
GlobusTimeReltimeSet(flush_interval, 5, 0);
270
/* parse user supplied log level string */
271
log_level = globus_libc_strdup(globus_i_gfs_config_string("log_level"));
272
if(log_level != NULL)
274
len = strlen(log_level);
275
for(ctr = 0; ctr < len && isdigit(log_level[ctr]); ctr++);
276
/* just a number, set log level to the supplied level || every level
280
log_mask = atoi(log_level);
283
log_mask |= (log_mask >> 1) | ((log_mask >> 1) - 1);
289
while((ptr = strchr(tag, ',')) != NULL)
292
log_mask |= globus_l_gfs_log_matchlevel(tag);
297
log_mask |= globus_l_gfs_log_matchlevel(tag);
300
globus_free(log_level);
303
module_str = globus_libc_strdup(globus_i_gfs_config_string("log_module"));
305
if(module_str != NULL)
309
globus_off_t tmp_off;
312
end = module_str + strlen(module_str);
313
ptr = strchr(module_str, ':');
322
ptr = strchr(opts, ':');
332
if(strncasecmp(opts, "buffer=", 7) == 0)
334
rc = globus_args_bytestr_to_num(
338
fprintf(stderr, "Invalid value for log buffer\n");
342
log_mask |= GLOBUS_LOGGING_INLINE;
350
buffer = (globus_size_t) tmp_off;
353
else if(strncasecmp(opts, "interval=", 9) == 0)
355
rc = globus_args_bytestr_to_num(
360
"Invalid value for log flush interval\n");
362
GlobusTimeReltimeSet(flush_interval, (int) tmp_off, 0);
366
fprintf(stderr, "Invalid log module option: %s\n", opts);
370
} while(ptr && *ptr);
374
if(module == NULL || strcmp(module, "stdio") == 0)
376
log_mod = &globus_logging_stdio_module;
378
else if(strcmp(module, "syslog") == 0)
380
log_mod = &globus_logging_syslog_module;
382
else if(strcmp(module, "stdio_ng") == 0)
384
log_mod = &globus_logging_stdio_ng_module;
385
globus_l_gfs_log_events = GLOBUS_TRUE;
386
log_mask |= GLOBUS_GFS_LOG_INFO |
387
GLOBUS_GFS_LOG_WARN | GLOBUS_GFS_LOG_ERR;
389
else if(strcmp(module, "syslog_ng") == 0)
391
log_mod = &globus_logging_syslog_ng_module;
392
globus_l_gfs_log_events = GLOBUS_TRUE;
393
log_mask |= GLOBUS_GFS_LOG_INFO |
394
GLOBUS_GFS_LOG_WARN | GLOBUS_GFS_LOG_ERR;
398
globus_libc_fprintf(stderr,
399
"Invalid logging module specified, using stdio.\n");
400
log_mod = &globus_logging_stdio_module;
403
if(log_mod == &globus_logging_stdio_module ||
404
log_mod == &globus_logging_stdio_ng_module )
406
logfilename = globus_i_gfs_config_string("log_single");
407
if(logfilename == NULL)
409
logunique = globus_i_gfs_config_string("log_unique");
410
if(logunique != NULL)
412
logfilename = globus_common_create_string(
413
"%sgridftp.%d.log", logunique, getpid());
416
if(logfilename != NULL)
418
globus_l_gfs_log_file = fopen(logfilename, "a");
419
if(globus_l_gfs_log_file == NULL)
421
if(!globus_i_gfs_config_bool("inetd"))
423
globus_libc_fprintf(stderr,
424
"Unable to open %s for logging. "
425
"Using stderr instead.\n", logfilename);
426
globus_l_gfs_log_file = stderr;
431
setvbuf(globus_l_gfs_log_file, NULL, _IOLBF, 0);
433
globus_i_gfs_config_string("log_filemode")) != NULL)
436
mode = strtoul(log_filemode, NULL, 0);
437
chmod(logfilename, mode);
442
if(globus_l_gfs_log_file == NULL)
444
globus_l_gfs_log_file = stderr;
447
log_arg = globus_l_gfs_log_file;
449
if(logunique != NULL)
451
globus_free(logfilename);
455
if(!((log_mod == &globus_logging_stdio_module ||
456
log_mod == &globus_logging_stdio_ng_module) && log_arg == NULL))
459
&globus_l_gfs_log_handle,
467
if((logfilename = globus_i_gfs_config_string("log_transfer")) != NULL)
469
globus_l_gfs_transfer_log_file = fopen(logfilename, "a");
470
if(globus_l_gfs_transfer_log_file == NULL)
472
if(!globus_i_gfs_config_bool("inetd"))
474
globus_libc_fprintf(stderr,
475
"Unable to open %s for transfer logging.\n", logfilename);
480
setvbuf(globus_l_gfs_transfer_log_file, NULL, _IOLBF, 0);
481
if((log_filemode = globus_i_gfs_config_string("log_filemode")) != 0)
484
mode = strtoul(log_filemode, NULL, 0);
485
chmod(logfilename, mode);
490
if(!globus_i_gfs_config_bool("disable_usage_stats"))
492
result = globus_l_gfs_log_usage_stats_init();
498
globus_free(module_str);
501
GlobusGFSDebugExit();
505
globus_i_gfs_log_close(void)
507
globus_list_t * list;
508
GlobusGFSName(globus_i_gfs_log_close);
509
GlobusGFSDebugEnter();
511
if(globus_l_gfs_log_handle != NULL)
513
globus_logging_flush(globus_l_gfs_log_handle);
514
globus_logging_destroy(globus_l_gfs_log_handle);
516
if(globus_l_gfs_log_file != stderr && globus_l_gfs_log_file != NULL)
518
fclose(globus_l_gfs_log_file);
519
globus_l_gfs_log_file = NULL;
521
if(globus_l_gfs_transfer_log_file != NULL)
523
fclose(globus_l_gfs_transfer_log_file);
524
globus_l_gfs_transfer_log_file = NULL;
527
list = globus_l_gfs_log_usage_handle_list;
529
while(!globus_list_empty(list))
531
globus_l_gfs_log_usage_ent_t * usage_ent;
533
usage_ent = (globus_l_gfs_log_usage_ent_t *)
534
globus_list_remove(&list, list);
538
if(usage_ent->handle)
540
globus_usage_stats_handle_destroy(usage_ent->handle);
542
if(usage_ent->target)
544
globus_free(usage_ent->target);
546
if(usage_ent->taglist)
548
globus_free(usage_ent->taglist);
550
globus_free(usage_ent);
554
GlobusGFSDebugExit();
558
globus_gfs_log_message(
559
globus_gfs_log_type_t type,
564
GlobusGFSName(globus_gfs_log_message);
565
GlobusGFSDebugEnter();
567
if(globus_l_gfs_log_handle != NULL && !globus_l_gfs_log_events)
569
va_start(ap, format);
570
globus_logging_vwrite(globus_l_gfs_log_handle, type, format, ap);
574
GlobusGFSDebugExit();
578
globus_gfs_log_result(
579
globus_gfs_log_type_t type,
581
globus_result_t result)
584
GlobusGFSName(globus_gfs_log_result);
585
GlobusGFSDebugEnter();
587
if(result != GLOBUS_SUCCESS)
589
message = globus_error_print_friendly(globus_error_peek(result));
593
message = globus_libc_strdup("(unknown error)");
595
globus_gfs_log_message(type, "%s:\n%s\n", lead, message);
596
globus_free(message);
598
GlobusGFSDebugExit();
609
GlobusGFSName(globus_l_gfs_log_tr);
610
GlobusGFSDebugEnter();
612
ptr = strchr(msg, from);
616
ptr = strchr(ptr, from);
618
GlobusGFSDebugExit();
623
globus_gfs_log_event(
624
globus_gfs_log_type_t type,
625
globus_gfs_log_event_type_t event_type,
626
const char * event_name,
627
globus_result_t result,
636
char * message = NULL;
637
GlobusGFSName(globus_gfs_log_message);
638
GlobusGFSDebugEnter();
640
if(globus_l_gfs_log_handle != NULL && globus_l_gfs_log_events)
644
va_start(ap, format);
645
tmp = globus_common_v_create_string(format, ap);
648
globus_i_gfs_log_tr(tmp, '\n', ' ');
651
if(result != GLOBUS_SUCCESS)
653
message = globus_error_print_friendly(globus_error_peek(result));
654
globus_i_gfs_log_tr(message, '\n', ' ');
655
globus_i_gfs_log_tr(message, '\"', '\'');
660
case GLOBUS_GFS_LOG_EVENT_START:
664
case GLOBUS_GFS_LOG_EVENT_END:
666
if(result == GLOBUS_SUCCESS)
668
status = " status=0";
672
status = " status=-1";
675
case GLOBUS_GFS_LOG_EVENT_MESSAGE:
676
startend = "message";
681
status = " status=-1";
685
msg = globus_common_create_string(
686
"event=globus-gridftp-server%s%s.%s%s%s%s%s%s%s\n",
687
event_name ? "." : "",
688
event_name ? event_name : "",
692
message ? " msg=\"" : "",
693
message ? message : "",
695
status ? status : "");
697
globus_logging_write(globus_l_gfs_log_handle, type, msg);
706
globus_free(message);
710
GlobusGFSDebugExit();
714
globus_i_gfs_log_create_transfer_event_msg(
718
globus_size_t blksize,
719
globus_size_t tcp_bs,
726
GlobusGFSName(globus_i_gfs_log_transfer);
727
GlobusGFSDebugEnter();
729
transfermsg = globus_common_create_string(
734
"bytes=%"GLOBUS_OFF_T_FORMAT" "
749
GlobusGFSDebugExit();
754
globus_i_gfs_log_transfer(
757
struct timeval * start_gtd_time,
758
struct timeval * end_gtd_time,
760
globus_size_t blksize,
761
globus_size_t tcp_bs,
769
time_t start_time_time;
770
time_t end_time_time;
771
struct tm * tmp_tm_time;
772
struct tm start_tm_time;
773
struct tm end_tm_time;
776
GlobusGFSName(globus_i_gfs_log_transfer);
777
GlobusGFSDebugEnter();
779
if(globus_l_gfs_transfer_log_file == NULL)
784
start_time_time = (time_t)start_gtd_time->tv_sec;
785
tmp_tm_time = gmtime(&start_time_time);
786
if(tmp_tm_time == NULL)
790
start_tm_time = *tmp_tm_time;
792
end_time_time = (time_t)end_gtd_time->tv_sec;
793
tmp_tm_time = gmtime(&end_time_time);
794
if(tmp_tm_time == NULL)
798
end_tm_time = *tmp_tm_time;
807
if(strcmp(type, "RETR") == 0 || strcmp(type, "ERET") == 0)
810
sock = STDOUT_FILENO;
817
opt_len = sizeof(win_size);
818
getsockopt(sock, SOL_SOCKET, opt_dir, &win_size, &opt_len);
827
"DATE=%04d%02d%02d%02d%02d%02d.%d "
831
"START=%04d%02d%02d%02d%02d%02d.%d "
836
"NBYTES=%"GLOBUS_OFF_T_FORMAT" "
844
end_tm_time.tm_year + 1900,
845
end_tm_time.tm_mon + 1,
850
(int) end_gtd_time->tv_usec,
851
globus_i_gfs_config_string("fqdn"),
852
"globus-gridftp-server",
854
start_tm_time.tm_year + 1900,
855
start_tm_time.tm_mon + 1,
856
start_tm_time.tm_mday,
857
start_tm_time.tm_hour,
858
start_tm_time.tm_min,
859
start_tm_time.tm_sec,
860
(int) start_gtd_time->tv_usec,
874
fwrite(out_buf, 1, strlen(out_buf), globus_l_gfs_transfer_log_file);
876
GlobusGFSDebugExit();
880
GlobusGFSDebugExitWithError();
885
globus_i_gfs_log_usage_stats(
886
struct timeval * start_gtd_time,
887
struct timeval * end_gtd_time,
890
globus_size_t blksize,
891
globus_size_t tcp_bs,
904
time_t start_time_time;
905
time_t end_time_time;
906
struct tm * tmp_tm_time;
907
struct tm start_tm_time;
908
struct tm end_tm_time;
918
globus_result_t result;
919
globus_list_t * list;
920
globus_l_gfs_log_usage_ent_t * usage_ent;
921
char * keys[GLOBUS_GFS_MAX_TAGCOUNT];
922
char * values[GLOBUS_GFS_MAX_TAGCOUNT];
928
char * save_taglist = NULL;
929
GlobusGFSName(globus_i_gfs_log_usage_stats);
930
GlobusGFSDebugEnter();
933
for(list = globus_l_gfs_log_usage_handle_list;
934
!globus_list_empty(list);
935
list = globus_list_rest(list))
937
usage_ent = (globus_l_gfs_log_usage_ent_t *) globus_list_first(list);
939
if(!usage_ent || usage_ent->handle == NULL)
944
if(save_taglist == NULL ||
945
strcmp(save_taglist, usage_ent->taglist) != 0)
947
save_taglist = usage_ent->taglist;
949
ptr = usage_ent->taglist;
955
case GLOBUS_I_GFS_USAGE_START:
957
start_time_time = (time_t)start_gtd_time->tv_sec;
958
tmp_tm_time = gmtime(&start_time_time);
959
if(tmp_tm_time == NULL)
963
start_tm_time = *tmp_tm_time;
964
sprintf(start_b, "%04d%02d%02d%02d%02d%02d.%d",
965
start_tm_time.tm_year + 1900,
966
start_tm_time.tm_mon + 1,
967
start_tm_time.tm_mday,
968
start_tm_time.tm_hour,
969
start_tm_time.tm_min,
970
start_tm_time.tm_sec,
971
(int) start_gtd_time->tv_usec);
975
case GLOBUS_I_GFS_USAGE_END:
977
end_time_time = (time_t)end_gtd_time->tv_sec;
978
tmp_tm_time = gmtime(&end_time_time);
979
if(tmp_tm_time == NULL)
983
end_tm_time = *tmp_tm_time;
984
sprintf(end_b, "%04d%02d%02d%02d%02d%02d.%d",
985
end_tm_time.tm_year + 1900,
986
end_tm_time.tm_mon + 1,
991
(int) end_gtd_time->tv_usec);
995
case GLOBUS_I_GFS_USAGE_VER:
997
value = globus_i_gfs_config_string("version_string");
1000
case GLOBUS_I_GFS_USAGE_BUFFER:
1002
sprintf(buffer_b, "%ld", (long) tcp_bs);
1006
case GLOBUS_I_GFS_USAGE_BLOCK:
1008
sprintf(block_b, "%ld",(long) blksize);
1012
case GLOBUS_I_GFS_USAGE_NBYTES:
1014
sprintf(nbytes_b, "%"GLOBUS_OFF_T_FORMAT, nbytes);
1018
case GLOBUS_I_GFS_USAGE_STREAMS:
1020
sprintf(streams_b, "%d", stream_count);
1024
case GLOBUS_I_GFS_USAGE_STRIPES:
1026
sprintf(stripes_b, "%d", stripe_count);
1030
case GLOBUS_I_GFS_USAGE_TYPE:
1035
case GLOBUS_I_GFS_USAGE_CODE:
1037
sprintf(code_b, "%d", code);
1041
case GLOBUS_I_GFS_USAGE_FILE:
1046
case GLOBUS_I_GFS_USAGE_CLIENTIP:
1051
case GLOBUS_I_GFS_USAGE_DATAIP:
1056
case GLOBUS_I_GFS_USAGE_USER:
1061
case GLOBUS_I_GFS_USAGE_USERDN:
1066
case GLOBUS_I_GFS_USAGE_CONFID:
1068
value = globus_i_gfs_config_string("usage_stats_id");
1071
case GLOBUS_I_GFS_USAGE_DSI:
1073
tmp = globus_i_gfs_config_string("load_dsi_module");
1074
strncpy(dsi_b, tmp, sizeof(dsi_b));
1075
dsi_b[sizeof(dsi_b - 1)] = '\0';
1076
if((tmp = strchr(dsi_b, ':')) != NULL)
1083
case GLOBUS_I_GFS_USAGE_EM:
1085
value = globus_i_gfs_config_string("acl");
1088
case GLOBUS_I_GFS_USAGE_SCHEME:
1093
case GLOBUS_I_GFS_USAGE_APP:
1098
case GLOBUS_I_GFS_USAGE_APPVER:
1103
case GLOBUS_I_GFS_USAGE_SESSID:
1114
if(key != NULL && value != NULL)
1125
result = globus_usage_stats_send_array(
1126
usage_ent->handle, i, keys, values);
1130
GlobusGFSDebugExit();
1134
GlobusGFSDebugExitWithError();