Commit 55fe0b61c0e3ea3c7ccab86fcb0b2030dcd120f6

Authored by Perry Werneck
1 parent 6f550f75
Exists in master and in 2 other branches develop, macos

Working on log/trace files.

src/core/linux/log.c
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 42
43 int use_syslog = 0; 43 int use_syslog = 0;
44 44
45 -void default_log_writer(H3270 GNUC_UNUSED(*session), const char *module, int GNUC_UNUSED(rc), const char *fmt, va_list arg_ptr) { 45 +int default_log_writer(H3270 GNUC_UNUSED(*session), const char *module, int GNUC_UNUSED(rc), const char *fmt, va_list arg_ptr) {
46 #ifdef HAVE_SYSLOG 46 #ifdef HAVE_SYSLOG
47 if(use_syslog) { 47 if(use_syslog) {
48 vsyslog(LOG_INFO, fmt, arg_ptr); 48 vsyslog(LOG_INFO, fmt, arg_ptr);
@@ -58,6 +58,7 @@ void default_log_writer(H3270 GNUC_UNUSED(*session), const char *module, int GNU @@ -58,6 +58,7 @@ void default_log_writer(H3270 GNUC_UNUSED(*session), const char *module, int GNU
58 printf("\n"); 58 printf("\n");
59 fflush(stdout); 59 fflush(stdout);
60 #endif 60 #endif
  61 + return 0;
61 } 62 }
62 63
63 LIB3270_EXPORT int lib3270_set_syslog(int flag) { 64 LIB3270_EXPORT int lib3270_set_syslog(int flag) {
src/core/log.c
@@ -47,98 +47,100 @@ @@ -47,98 +47,100 @@
47 47
48 /*---[ Constants ]------------------------------------------------------------------------------------------*/ 48 /*---[ Constants ]------------------------------------------------------------------------------------------*/
49 49
50 -static void (*loghandler)(H3270 *session, const char *module, int rc, const char *fmt, va_list arg_ptr) = default_log_writer; 50 +LIB3270_LOG_HANDLER loghandler = default_log_writer;
51 51
52 /*---[ Implementacao ]--------------------------------------------------------------------------------------*/ 52 /*---[ Implementacao ]--------------------------------------------------------------------------------------*/
53 53
54 -static void logfile(H3270 *session, const char *module, int rc, const char *fmt, va_list arg_ptr) { 54 +static void write_log(const H3270 *session, const char *module, int rc, const char *fmt, va_list arg_ptr) {
55 55
56 - FILE *f = fopen(session->file.log, "a"); 56 + if(session) {
57 57
58 - if(f) { 58 + if(session->log.file) {
59 59
60 - time_t ltime = time(0); 60 + // Has log file. Use it if possible.
  61 + FILE *f = fopen(session->log.file, "a");
61 62
62 - char timestamp[80];  
63 -#ifdef HAVE_LOCALTIME_R  
64 - struct tm tm;  
65 - strftime(timestamp, 79, "%x %X", localtime_r(&ltime,&tm));  
66 -#else  
67 - strftime(timestamp, 79, "%x %X", localtime(&ltime));  
68 -#endif // HAVE_LOCALTIME_R 63 + if(f) {
69 64
70 - fprintf(f,"%s %s\t",timestamp,module);  
71 - vfprintf(f,fmt,arg_ptr);  
72 - fprintf(f,"\n"); 65 + time_t ltime = time(0);
73 66
74 - fclose(f); 67 + char timestamp[80];
  68 + #ifdef HAVE_LOCALTIME_R
  69 + struct tm tm;
  70 + strftime(timestamp, 79, "%x %X", localtime_r(&ltime,&tm));
  71 + #else
  72 + strftime(timestamp, 79, "%x %X", localtime(&ltime));
  73 + #endif // HAVE_LOCALTIME_R
  74 +
  75 + fprintf(f,"%s %s\t",timestamp,module);
  76 + vfprintf(f,fmt,arg_ptr);
  77 + fprintf(f,"\n");
  78 +
  79 + fclose(f);
  80 +
  81 + }
  82 +
  83 + }
  84 +
  85 + session->log.handler(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),rc,fmt,arg_ptr);
75 86
76 } else { 87 } else {
77 88
78 - loghandler(session,module,rc,fmt,arg_ptr); 89 + loghandler(session, (module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME)),rc,fmt,arg_ptr);
79 90
80 } 91 }
81 92
82 } 93 }
83 94
84 LIB3270_EXPORT const char * lib3270_get_log_filename(const H3270 * hSession) { 95 LIB3270_EXPORT const char * lib3270_get_log_filename(const H3270 * hSession) {
85 - return hSession->file.log; 96 + return hSession->log.file;
86 } 97 }
87 98
88 LIB3270_EXPORT int lib3270_set_log_filename(H3270 * hSession, const char *filename) { 99 LIB3270_EXPORT int lib3270_set_log_filename(H3270 * hSession, const char *filename) {
89 100
90 - if(hSession->file.log) {  
91 - lib3270_free(hSession->file.log);  
92 - hSession->file.log = NULL; 101 + if(!hSession) {
  102 + return EINVAL;
93 } 103 }
94 104
  105 + if(hSession->log.file) {
  106 + lib3270_free(hSession->log.file);
  107 + }
  108 +
  109 + hSession->log.file = NULL;
  110 +
95 if(filename && *filename) { 111 if(filename && *filename) {
96 - hSession->file.log = lib3270_strdup(filename);  
97 - } else {  
98 - hSession->file.log = NULL; 112 + hSession->log.file = lib3270_strdup(filename);
99 } 113 }
100 114
101 return 0; 115 return 0;
102 116
103 } 117 }
104 118
105 -LIB3270_EXPORT void lib3270_set_log_handler(void (*handler)(H3270 *, const char *, int, const char *, va_list)) {  
106 - loghandler = handler ? handler : default_log_writer; 119 +LIB3270_EXPORT void lib3270_set_log_handler(H3270 *session, const LIB3270_LOG_HANDLER handler) {
  120 + if(session) {
  121 + session->log.handler = (handler ? handler : default_log_writer);
  122 + } else {
  123 + loghandler = (handler ? handler : default_log_writer);
  124 + }
107 } 125 }
108 126
109 -LIB3270_EXPORT int lib3270_write_log(H3270 *session, const char *module, const char *fmt, ...) { 127 +LIB3270_EXPORT int lib3270_write_log(const H3270 *session, const char *module, const char *fmt, ...) {
110 va_list arg_ptr; 128 va_list arg_ptr;
111 va_start(arg_ptr, fmt); 129 va_start(arg_ptr, fmt);
112 -  
113 - if(session && session->file.log) {  
114 - logfile(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),0,fmt,arg_ptr);  
115 - } else {  
116 - loghandler(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),0,fmt,arg_ptr);  
117 - }  
118 - 130 + write_log(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),0,fmt,arg_ptr);
119 va_end(arg_ptr); 131 va_end(arg_ptr);
120 return 0; 132 return 0;
121 } 133 }
122 134
123 -LIB3270_EXPORT int lib3270_write_rc(H3270 *session, const char *module, int rc, const char *fmt, ...) { 135 +LIB3270_EXPORT int lib3270_write_rc(const H3270 *session, const char *module, int rc, const char *fmt, ...) {
124 va_list arg_ptr; 136 va_list arg_ptr;
125 va_start(arg_ptr, fmt); 137 va_start(arg_ptr, fmt);
126 -  
127 - if(session && session->file.log) {  
128 - logfile(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),rc,fmt,arg_ptr);  
129 - } else {  
130 - loghandler(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),rc,fmt,arg_ptr);  
131 - }  
132 - 138 + write_log(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),rc,fmt,arg_ptr);
133 va_end(arg_ptr); 139 va_end(arg_ptr);
134 return rc; 140 return rc;
135 } 141 }
136 142
137 -LIB3270_EXPORT void lib3270_write_va_log(H3270 *session, const char *module, const char *fmt, va_list arg) {  
138 - if(session && session->file.log) {  
139 - logfile(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),0,fmt,arg);  
140 - } else {  
141 - loghandler(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),0,fmt,arg);  
142 - } 143 +LIB3270_EXPORT void lib3270_write_va_log(const H3270 *session, const char *module, const char *fmt, va_list arg) {
  144 + write_log(session,module ? module : LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),0,fmt,arg);
143 } 145 }
144 146
src/core/properties/string.c
@@ -36,6 +36,7 @@ @@ -36,6 +36,7 @@
36 #include <lib3270/keyboard.h> 36 #include <lib3270/keyboard.h>
37 #include <lib3270/log.h> 37 #include <lib3270/log.h>
38 #include <lib3270/ssl.h> 38 #include <lib3270/ssl.h>
  39 +#include <lib3270/trace.h>
39 40
40 static const char * get_version(const H3270 GNUC_UNUSED(*hSession)) { 41 static const char * get_version(const H3270 GNUC_UNUSED(*hSession)) {
41 return lib3270_get_version(); 42 return lib3270_get_version();
src/core/session.c
@@ -148,8 +148,8 @@ void lib3270_session_free(H3270 *h) { @@ -148,8 +148,8 @@ void lib3270_session_free(H3270 *h) {
148 lib3270_linked_list_free(&h->input.list); 148 lib3270_linked_list_free(&h->input.list);
149 149
150 // Release logfile 150 // Release logfile
151 - release_pointer(h->file.log);  
152 - release_pointer(h->file.trace); 151 + release_pointer(h->log.file);
  152 + release_pointer(h->trace.file);
153 lib3270_free(h); 153 lib3270_free(h);
154 154
155 } 155 }
@@ -199,9 +199,10 @@ static int load(H3270 *session, const char GNUC_UNUSED(*filename)) { @@ -199,9 +199,10 @@ static int load(H3270 *session, const char GNUC_UNUSED(*filename)) {
199 return errno = ENOTSUP; 199 return errno = ENOTSUP;
200 } 200 }
201 201
202 -static void def_trace(H3270 GNUC_UNUSED(*session), void GNUC_UNUSED(*userdata), const char *fmt, va_list args) { 202 +static int def_trace(const H3270 GNUC_UNUSED(*session), void GNUC_UNUSED(*userdata), const char *fmt, va_list args) {
203 vfprintf(stdout,fmt,args); 203 vfprintf(stdout,fmt,args);
204 fflush(stdout); 204 fflush(stdout);
  205 + return 0;
205 } 206 }
206 207
207 static void update_ssl(H3270 GNUC_UNUSED(*session), LIB3270_SSL_STATE GNUC_UNUSED(state)) { 208 static void update_ssl(H3270 GNUC_UNUSED(*session), LIB3270_SSL_STATE GNUC_UNUSED(state)) {
@@ -279,6 +280,9 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char @@ -279,6 +280,9 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char
279 // Trace management. 280 // Trace management.
280 hSession->trace.handler = def_trace; 281 hSession->trace.handler = def_trace;
281 282
  283 + // Log management.
  284 + hSession->log.handler = loghandler;
  285 +
282 // Set the defaults. 286 // Set the defaults.
283 hSession->extended = 1; 287 hSession->extended = 1;
284 hSession->typeahead = 1; 288 hSession->typeahead = 1;
@@ -489,7 +493,7 @@ LIB3270_EXPORT char lib3270_get_session_id(H3270 *hSession) { @@ -489,7 +493,7 @@ LIB3270_EXPORT char lib3270_get_session_id(H3270 *hSession) {
489 493
490 struct lib3270_session_callbacks * lib3270_get_session_callbacks(H3270 *hSession, const char *revision, unsigned short sz) { 494 struct lib3270_session_callbacks * lib3270_get_session_callbacks(H3270 *hSession, const char *revision, unsigned short sz) {
491 495
492 - #define REQUIRED_REVISION "20210619" 496 + #define REQUIRED_REVISION "20210818"
493 497
494 if(revision && strcasecmp(revision,REQUIRED_REVISION) < 0) { 498 if(revision && strcasecmp(revision,REQUIRED_REVISION) < 0) {
495 errno = EINVAL; 499 errno = EINVAL;
src/core/trace_ds.c
@@ -348,21 +348,19 @@ void lib3270_trace_data(H3270 *hSession, const char *msg, const unsigned char *d @@ -348,21 +348,19 @@ void lib3270_trace_data(H3270 *hSession, const char *msg, const unsigned char *d
348 348
349 } 349 }
350 350
351 -LIB3270_EXPORT const char * lib3270_get_trace_filename(H3270 * hSession) {  
352 - return hSession->file.trace; 351 +LIB3270_EXPORT const char * lib3270_get_trace_filename(const H3270 * hSession) {
  352 + return hSession->trace.file;
353 } 353 }
354 354
355 LIB3270_EXPORT int lib3270_set_trace_filename(H3270 * hSession, const char *filename) { 355 LIB3270_EXPORT int lib3270_set_trace_filename(H3270 * hSession, const char *filename) {
356 356
357 - if(hSession->file.trace) {  
358 - lib3270_free(hSession->file.trace);  
359 - hSession->file.trace = NULL; 357 + if(hSession->trace.file) {
  358 + lib3270_free(hSession->trace.file);
360 } 359 }
  360 + hSession->trace.file = NULL;
361 361
362 if(filename && *filename) { 362 if(filename && *filename) {
363 - hSession->file.trace = lib3270_strdup(filename);  
364 - } else {  
365 - hSession->file.trace = NULL; 363 + hSession->trace.file = lib3270_strdup(filename);
366 } 364 }
367 365
368 return 0; 366 return 0;
src/core/windows/log.c
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 41
42 /*---[ Implement ]------------------------------------------------------------------------------------------*/ 42 /*---[ Implement ]------------------------------------------------------------------------------------------*/
43 43
44 -void default_log_writer(H3270 GNUC_UNUSED(*session), const char *module, int rc, const char *fmt, va_list arg_ptr) { 44 +int default_log_writer(H3270 GNUC_UNUSED(*session), const char *module, int rc, const char *fmt, va_list arg_ptr) {
45 lib3270_autoptr(char) msg = lib3270_vsprintf(fmt,arg_ptr); 45 lib3270_autoptr(char) msg = lib3270_vsprintf(fmt,arg_ptr);
46 46
47 debug("%s",msg); 47 debug("%s",msg);
@@ -74,6 +74,7 @@ void default_log_writer(H3270 GNUC_UNUSED(*session), const char *module, int rc, @@ -74,6 +74,7 @@ void default_log_writer(H3270 GNUC_UNUSED(*session), const char *module, int rc,
74 74
75 } 75 }
76 76
  77 + return 0;
77 } 78 }
78 79
79 LIB3270_EXPORT int lib3270_set_syslog(int GNUC_UNUSED(flag)) { 80 LIB3270_EXPORT int lib3270_set_syslog(int GNUC_UNUSED(flag)) {
src/include/internals.h
@@ -41,6 +41,8 @@ @@ -41,6 +41,8 @@
41 #include <lib3270/popup.h> 41 #include <lib3270/popup.h>
42 #include <networking.h> 42 #include <networking.h>
43 #include <lib3270/os.h> 43 #include <lib3270/os.h>
  44 +#include <lib3270/log.h>
  45 +#include <lib3270/trace.h>
44 46
45 #if defined(HAVE_LDAP) && defined (HAVE_LIBSSL) 47 #if defined(HAVE_LDAP) && defined (HAVE_LIBSSL)
46 #include <openssl/x509.h> 48 #include <openssl/x509.h>
@@ -625,11 +627,17 @@ struct _h3270 { @@ -625,11 +627,17 @@ struct _h3270 {
625 627
626 // Trace methods. 628 // Trace methods.
627 struct { 629 struct {
628 - void (*handler)(H3270 *session, void *userdata, const char *fmt, va_list args); 630 + char *file; ///< @brief Trace file name (if set).
  631 + LIB3270_TRACE_HANDLER handler;
629 void *userdata; 632 void *userdata;
630 } trace; 633 } trace;
631 634
632 struct { 635 struct {
  636 + char *file; ///< @brief Log file name (if set).
  637 + LIB3270_LOG_HANDLER handler;
  638 + } log;
  639 +
  640 + struct {
633 unsigned int host : 1; ///< @brief Non zero if host requires SSL. 641 unsigned int host : 1; ///< @brief Non zero if host requires SSL.
634 unsigned int download_crl : 1; ///< @brief Non zero to download CRL. 642 unsigned int download_crl : 1; ///< @brief Non zero to download CRL.
635 LIB3270_SSL_STATE state; 643 LIB3270_SSL_STATE state;
@@ -653,11 +661,6 @@ struct _h3270 { @@ -653,11 +661,6 @@ struct _h3270 {
653 661
654 unsigned int tasks; 662 unsigned int tasks;
655 663
656 - struct {  
657 - char *log; ///< @brief Log file name (if set).  
658 - char *trace; ///< @brief Trace file name (if set).  
659 - } file;  
660 -  
661 }; 664 };
662 665
663 #define SELECTION_LEFT 0x01 666 #define SELECTION_LEFT 0x01
@@ -736,7 +739,10 @@ LIB3270_INTERNAL void clear_chr(H3270 *hSession, int baddr); @@ -736,7 +739,10 @@ LIB3270_INTERNAL void clear_chr(H3270 *hSession, int baddr);
736 LIB3270_INTERNAL unsigned char get_field_attribute(H3270 *session, int baddr); 739 LIB3270_INTERNAL unsigned char get_field_attribute(H3270 *session, int baddr);
737 740
738 /// @brief Default log writer. 741 /// @brief Default log writer.
739 -LIB3270_INTERNAL void default_log_writer(H3270 *session, const char *module, int rc, const char *fmt, va_list arg_ptr); 742 +LIB3270_INTERNAL int default_log_writer(H3270 *session, const char *module, int rc, const char *fmt, va_list arg_ptr);
  743 +
  744 +/// @brief The active log handler.
  745 +LIB3270_INTERNAL LIB3270_LOG_HANDLER loghandler;
740 746
741 LIB3270_INTERNAL char * lib3270_get_user_name(); 747 LIB3270_INTERNAL char * lib3270_get_user_name();
742 748
src/include/lib3270/log.h
@@ -52,16 +52,16 @@ @@ -52,16 +52,16 @@
52 extern "C" { 52 extern "C" {
53 #endif 53 #endif
54 54
55 -LIB3270_EXPORT void lib3270_set_log_handler(void (*loghandler)(H3270 *, const char *, int, const char *, va_list));  
56 -LIB3270_EXPORT int lib3270_write_log(H3270 *session, const char *module, const char *fmt, ...) LIB3270_GNUC_FORMAT(3,4);  
57 -LIB3270_EXPORT int lib3270_write_rc(H3270 *session, const char *module, int rc, const char *fmt, ...) LIB3270_GNUC_FORMAT(4,5);  
58 -LIB3270_EXPORT void lib3270_write_va_log(H3270 *session, const char *module, const char *fmt, va_list arg); 55 +typedef int (*LIB3270_LOG_HANDLER)(const H3270 *, const char *, int, const char *, va_list);
59 56
  57 +LIB3270_EXPORT void lib3270_set_log_handler(H3270 *session, const LIB3270_LOG_HANDLER loghandler);
60 LIB3270_EXPORT int lib3270_set_log_filename(H3270 * hSession, const char *name); 58 LIB3270_EXPORT int lib3270_set_log_filename(H3270 * hSession, const char *name);
61 LIB3270_EXPORT const char * lib3270_get_log_filename(const H3270 * hSession); 59 LIB3270_EXPORT const char * lib3270_get_log_filename(const H3270 * hSession);
62 60
63 -LIB3270_EXPORT int lib3270_set_trace_filename(H3270 * hSession, const char *name);  
64 -LIB3270_EXPORT const char * lib3270_get_trace_filename(const H3270 * hSession); 61 +LIB3270_EXPORT int lib3270_write_log(const H3270 *session, const char *module, const char *fmt, ...) LIB3270_GNUC_FORMAT(3,4);
  62 +LIB3270_EXPORT int lib3270_write_rc(const H3270 *session, const char *module, int rc, const char *fmt, ...) LIB3270_GNUC_FORMAT(4,5);
  63 +LIB3270_EXPORT void lib3270_write_va_log(const H3270 *session, const char *module, const char *fmt, va_list arg);
  64 +
65 65
66 /** 66 /**
67 * @brief Send logs to system log (if available) 67 * @brief Send logs to system log (if available)
src/include/lib3270/trace.h
@@ -45,7 +45,25 @@ extern &quot;C&quot; { @@ -45,7 +45,25 @@ extern &quot;C&quot; {
45 #define LIB3270_AS_PRINTF(a,b) __attribute__((format(printf, a, b))) 45 #define LIB3270_AS_PRINTF(a,b) __attribute__((format(printf, a, b)))
46 #endif 46 #endif
47 47
48 -typedef void (*LIB3270_TRACE_HANDLER)(H3270 *, void *, const char *, va_list); 48 +typedef int (*LIB3270_TRACE_HANDLER)(const H3270 *, void *, const char *, va_list);
  49 +
  50 +/**
  51 + * @brief Set trace filename.
  52 + *
  53 + * @param hSession TN3270 Session handle.
  54 + * @param name The trace file name (null to disable).
  55 + *
  56 + */
  57 +LIB3270_EXPORT int lib3270_set_trace_filename(H3270 * hSession, const char *name);
  58 +
  59 +/**
  60 + * @brief Get trace file name.
  61 + *
  62 + * @param hSession TN3270 Session handle.
  63 + * @return The trace file name or NULL if disabled.
  64 + *
  65 + */
  66 +LIB3270_EXPORT const char * lib3270_get_trace_filename(const H3270 * hSession);
49 67
50 /** 68 /**
51 * @brief Set trace handle callback. 69 * @brief Set trace handle callback.
src/testprogram/testprogram.c
@@ -50,13 +50,14 @@ @@ -50,13 +50,14 @@
50 50
51 const char *trace_file = "test.trace"; 51 const char *trace_file = "test.trace";
52 52
53 -static void write_trace(H3270 GNUC_UNUSED(*session), void GNUC_UNUSED(*userdata), const char *fmt, va_list args) { 53 +static int write_trace(const H3270 GNUC_UNUSED(*session), void GNUC_UNUSED(*userdata), const char *fmt, va_list args) {
54 FILE *out = fopen(trace_file,"a"); 54 FILE *out = fopen(trace_file,"a");
55 if(out) { 55 if(out) {
56 56
57 vfprintf(out,fmt,args); 57 vfprintf(out,fmt,args);
58 fclose(out); 58 fclose(out);
59 } 59 }
  60 + return 0;
60 } 61 }
61 62
62 static void online_group_state_changed(H3270 GNUC_UNUSED(*hSession), void GNUC_UNUSED(*dunno)) { 63 static void online_group_state_changed(H3270 GNUC_UNUSED(*hSession), void GNUC_UNUSED(*dunno)) {
@@ -96,11 +97,11 @@ int main(int argc, char *argv[]) { @@ -96,11 +97,11 @@ int main(int argc, char *argv[]) {
96 { 0, 0, 0, 0} 97 { 0, 0, 0, 0}
97 98
98 }; 99 };
99 -// #pragma GCC diagnostic pop  
100 100
101 H3270 * h = lib3270_session_new(""); 101 H3270 * h = lib3270_session_new("");
102 int rc = 0; 102 int rc = 0;
103 103
  104 + lib3270_set_log_filename(h,"testprogram.log");
104 lib3270_write_log(h,"TEST","Testprogram %s starts (%s)",argv[0],LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME)); 105 lib3270_write_log(h,"TEST","Testprogram %s starts (%s)",argv[0],LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME));
105 106
106 lib3270_autoptr(char) version_info = lib3270_get_version_info(); 107 lib3270_autoptr(char) version_info = lib3270_get_version_info();