Commit 2790e55cab84666ee1d7586589048abad973f671

Authored by Perry Werneck
2 parents eed25f55 91a01b45

Merge branch 'develop' of https://github.com/PerryWerneck/lib3270 into develop

src/core/ctlr.c
@@ -2696,101 +2696,3 @@ enum dbcs_state ctlr_dbcs_state(int baddr) @@ -2696,101 +2696,3 @@ enum dbcs_state ctlr_dbcs_state(int baddr)
2696 return dbcs? ea_buf[baddr].db: DBCS_NONE; 2696 return dbcs? ea_buf[baddr].db: DBCS_NONE;
2697 } 2697 }
2698 #endif /*]*/ 2698 #endif /*]*/
2699 -  
2700 -/*  
2701 - * Transaction timing. The time between sending an interrupt (PF, PA, Enter,  
2702 - * Clear) and the host unlocking the keyboard is indicated on the status line  
2703 - * to an accuracy of 0.1 seconds. If we don't repaint the screen before we see  
2704 - * the unlock, the time should be fairly accurate.  
2705 - */  
2706 -//static struct timeval t_start;  
2707 -// static Boolean ticking = False;  
2708 -//static Boolean mticking = False;  
2709 -//static void * tick_id;  
2710 -//static struct timeval t_want;  
2711 -  
2712 -/*  
2713 -/// @brief Return the difference in milliseconds between two timevals.  
2714 -static long delta_msec(struct timeval *t1, struct timeval *t0)  
2715 -{  
2716 - return (t1->tv_sec - t0->tv_sec) * 1000 +  
2717 - (t1->tv_usec - t0->tv_usec + 500) / 1000;  
2718 -}  
2719 -  
2720 -static int keep_ticking(H3270 *hSession)  
2721 -{  
2722 - struct timeval t1;  
2723 - long msec;  
2724 -  
2725 - do  
2726 - {  
2727 - (void) gettimeofday(&t1, (struct timezone *) 0);  
2728 - hSession->t_want.tv_sec++;  
2729 - msec = delta_msec(&hSession->t_want, &t1);  
2730 - } while (msec <= 0);  
2731 -  
2732 - status_timing(hSession,&hSession->t_start, &t1);  
2733 -  
2734 - return 1;  
2735 -}  
2736 -*/  
2737 -  
2738 -/*  
2739 -void ticking_start(H3270 *hSession, Boolean anyway)  
2740 -{  
2741 - CHECK_SESSION_HANDLE(hSession);  
2742 -  
2743 - if(hSession->cbk.set_timer)  
2744 - {  
2745 - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SHOW_TIMING) || anyway)  
2746 - hSession->cbk.set_timer(hSession,1);  
2747 - }  
2748 - else  
2749 - {  
2750 - (void) gettimeofday(&hSession->t_start, (struct timezone *) 0);  
2751 -  
2752 - hSession->mticking = 1;  
2753 -  
2754 - if (!lib3270_get_toggle(hSession,LIB3270_TOGGLE_SHOW_TIMING) && !anyway)  
2755 - return;  
2756 -  
2757 - status_untiming(hSession);  
2758 -  
2759 - if (hSession->ticking)  
2760 - RemoveTimer(hSession, hSession->tick_id);  
2761 -  
2762 - hSession->ticking = 1;  
2763 - hSession->tick_id = AddTimer(1000, hSession, keep_ticking);  
2764 - hSession->t_want = hSession->t_start;  
2765 - }  
2766 -  
2767 -}  
2768 -*/  
2769 -  
2770 -/*  
2771 -static void ticking_stop(H3270 *hSession)  
2772 -{  
2773 - CHECK_SESSION_HANDLE(hSession);  
2774 -  
2775 - if(hSession->cbk.set_timer)  
2776 - {  
2777 - hSession->cbk.set_timer(hSession,0);  
2778 - }  
2779 - else  
2780 - {  
2781 - struct timeval t1;  
2782 -  
2783 - (void) gettimeofday(&t1, (struct timezone *) 0);  
2784 - if (hSession->mticking)  
2785 - hSession->mticking = 0;  
2786 - else  
2787 - return;  
2788 -  
2789 - if (!hSession->ticking)  
2790 - return;  
2791 - RemoveTimer(hSession, hSession->tick_id);  
2792 - hSession->ticking = 0;  
2793 - status_timing(hSession,&hSession->t_start, &t1);  
2794 - }  
2795 -}  
2796 -*/  
src/core/host.c
@@ -64,7 +64,7 @@ @@ -64,7 +64,7 @@
64 /** 64 /**
65 * @brief Called from timer to attempt an automatic reconnection. 65 * @brief Called from timer to attempt an automatic reconnection.
66 */ 66 */
67 -static int check_for_auto_reconnect(H3270 *hSession) 67 +static int check_for_auto_reconnect(H3270 *hSession, void GNUC_UNUSED(*userdata))
68 { 68 {
69 69
70 if(hSession->auto_reconnect_inprogress) 70 if(hSession->auto_reconnect_inprogress)
@@ -94,7 +94,7 @@ int lib3270_activate_auto_reconnect(H3270 *hSession, unsigned long msec) @@ -94,7 +94,7 @@ int lib3270_activate_auto_reconnect(H3270 *hSession, unsigned long msec)
94 return EBUSY; 94 return EBUSY;
95 95
96 hSession->auto_reconnect_inprogress = 1; 96 hSession->auto_reconnect_inprogress = 1;
97 - (void) AddTimer(msec, hSession, check_for_auto_reconnect); 97 + (void) AddTimer(msec, hSession, check_for_auto_reconnect, NULL);
98 98
99 return 0; 99 return 0;
100 } 100 }
src/core/iocalls.c
@@ -63,7 +63,7 @@ @@ -63,7 +63,7 @@
63 63
64 // Timeout calls 64 // Timeout calls
65 static void internal_remove_timer(H3270 *session, void *timer); 65 static void internal_remove_timer(H3270 *session, void *timer);
66 - static void * internal_add_timer(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session)); 66 + static void * internal_add_timer(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session, void *userdata), void *userdata);
67 67
68 static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata ); 68 static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata );
69 static void internal_remove_poll(H3270 *session, void *id); 69 static void internal_remove_poll(H3270 *session, void *id);
@@ -78,7 +78,7 @@ @@ -78,7 +78,7 @@
78 78
79 /*---[ Active callbacks ]-----------------------------------------------------------------------------------*/ 79 /*---[ Active callbacks ]-----------------------------------------------------------------------------------*/
80 80
81 - static void * (*add_timer)(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session)) 81 + static void * (*add_timer)(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session, void *userdata), void *userdata)
82 = internal_add_timer; 82 = internal_add_timer;
83 83
84 static void (*remove_timer)(H3270 *session, void *timer) 84 static void (*remove_timer)(H3270 *session, void *timer)
@@ -128,7 +128,7 @@ static void ms_ts(unsigned long long *u) @@ -128,7 +128,7 @@ static void ms_ts(unsigned long long *u)
128 } 128 }
129 #endif 129 #endif
130 130
131 -static void * internal_add_timer(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session)) 131 +static void * internal_add_timer(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session, void *userdata), void *userdata)
132 { 132 {
133 timeout_t *t_new; 133 timeout_t *t_new;
134 timeout_t *t; 134 timeout_t *t;
@@ -139,6 +139,7 @@ static void * internal_add_timer(H3270 *session, unsigned long interval_ms, int @@ -139,6 +139,7 @@ static void * internal_add_timer(H3270 *session, unsigned long interval_ms, int
139 t_new = (timeout_t *) lib3270_malloc(sizeof(timeout_t)); 139 t_new = (timeout_t *) lib3270_malloc(sizeof(timeout_t));
140 140
141 t_new->proc = proc; 141 t_new->proc = proc;
  142 + t_new->userdata = userdata;
142 t_new->in_play = False; 143 t_new->in_play = False;
143 144
144 #if defined(_WIN32) 145 #if defined(_WIN32)
@@ -207,28 +208,6 @@ static void internal_remove_timer(H3270 *session, void * timer) @@ -207,28 +208,6 @@ static void internal_remove_timer(H3270 *session, void * timer)
207 if(!st->in_play) 208 if(!st->in_play)
208 lib3270_linked_list_delete_node(&session->timeouts,timer); 209 lib3270_linked_list_delete_node(&session->timeouts,timer);
209 210
210 - /*  
211 - timeout_t *t;  
212 - timeout_t *prev = TN;  
213 -  
214 -  
215 - if (st->in_play)  
216 - return;  
217 -  
218 - for (t = session->timeouts; t != TN; t = t->next)  
219 - {  
220 - if (t == st)  
221 - {  
222 - if (prev != TN)  
223 - prev->next = t->next;  
224 - else  
225 - session->timeouts = t->next;  
226 - lib3270_free(t);  
227 - return;  
228 - }  
229 - prev = t;  
230 - }  
231 - */  
232 } 211 }
233 212
234 /* I/O events. */ 213 /* I/O events. */
@@ -250,35 +229,7 @@ static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, vo @@ -250,35 +229,7 @@ static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, vo
250 static void internal_remove_poll(H3270 *session, void *id) 229 static void internal_remove_poll(H3270 *session, void *id)
251 { 230 {
252 lib3270_linked_list_delete_node(&session->input.list,id); 231 lib3270_linked_list_delete_node(&session->input.list,id);
253 -  
254 session->input.changed = 1; 232 session->input.changed = 1;
255 -  
256 - /*  
257 - input_t *ip;  
258 - input_t *prev = (input_t *)NULL;  
259 -  
260 - for (ip = session->inputs; ip != (input_t *) NULL; ip = (input_t *) ip->next)  
261 - {  
262 - if (ip == (input_t *)id)  
263 - break;  
264 -  
265 - prev = ip;  
266 - }  
267 -  
268 - if (ip == (input_t *)NULL)  
269 - {  
270 - lib3270_write_log(session,"lib3270","Invalid call to (%s): Input %p wasnt found in the list",__FUNCTION__,id);  
271 - return;  
272 - }  
273 -  
274 - if (prev != (input_t *)NULL)  
275 - prev->next = ip->next;  
276 - else  
277 - session->inputs = (input_t *) ip->next;  
278 -  
279 - lib3270_free(ip);  
280 - session->inputs_changed = 1;  
281 - */  
282 } 233 }
283 234
284 static void internal_set_poll_state(H3270 *session, void *id, int enabled) 235 static void internal_set_poll_state(H3270 *session, void *id, int enabled)
@@ -372,11 +323,14 @@ static void internal_ring_bell(H3270 GNUC_UNUSED(*session)) @@ -372,11 +323,14 @@ static void internal_ring_bell(H3270 GNUC_UNUSED(*session))
372 323
373 /* External entry points */ 324 /* External entry points */
374 325
375 -void * AddTimer(unsigned long interval_ms, H3270 *session, int (*proc)(H3270 *session)) 326 +void * AddTimer(unsigned long interval_ms, H3270 *session, int (*proc)(H3270 *session, void *userdata), void *userdata)
376 { 327 {
377 - void *timer;  
378 - CHECK_SESSION_HANDLE(session);  
379 - timer = add_timer(session,interval_ms,proc); 328 + void *timer = add_timer(
  329 + session,
  330 + interval_ms ? interval_ms : 100, // Prevents a zero-value timer.
  331 + proc,
  332 + userdata
  333 + );
380 trace("Timeout %p created with %ld ms",timer,interval_ms); 334 trace("Timeout %p created with %ld ms",timer,interval_ms);
381 return timer; 335 return timer;
382 } 336 }
@@ -427,7 +381,7 @@ void remove_input_calls(H3270 *session) @@ -427,7 +381,7 @@ void remove_input_calls(H3270 *session)
427 } 381 }
428 } 382 }
429 383
430 -LIB3270_EXPORT void lib3270_register_timer_handlers(void * (*add)(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session)), void (*rm)(H3270 *session, void *timer)) 384 +LIB3270_EXPORT void lib3270_register_timer_handlers(void * (*add)(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session,void *userdata), void *userdata), void (*rm)(H3270 *session, void *timer))
431 { 385 {
432 if(add) 386 if(add)
433 add_timer = add; 387 add_timer = add;
src/core/keyboard/kybd.c
@@ -1009,7 +1009,7 @@ LIB3270_EXPORT int lib3270_clear_operator_error(H3270 *hSession) @@ -1009,7 +1009,7 @@ LIB3270_EXPORT int lib3270_clear_operator_error(H3270 *hSession)
1009 /** 1009 /**
1010 * @brief Deferred keyboard unlock. 1010 * @brief Deferred keyboard unlock.
1011 */ 1011 */
1012 -static int defer_unlock(H3270 *hSession) 1012 +static int defer_unlock(H3270 *hSession, void GNUC_UNUSED(*userdata))
1013 { 1013 {
1014 lib3270_kybdlock_clear(hSession,KL_DEFERRED_UNLOCK); 1014 lib3270_kybdlock_clear(hSession,KL_DEFERRED_UNLOCK);
1015 status_reset(hSession); 1015 status_reset(hSession);
@@ -1067,12 +1067,12 @@ void do_reset(H3270 *hSession, Boolean explicit) @@ -1067,12 +1067,12 @@ void do_reset(H3270 *hSession, Boolean explicit)
1067 1067
1068 if(hSession->unlock_delay_ms) 1068 if(hSession->unlock_delay_ms)
1069 { 1069 {
1070 - hSession->unlock_id = AddTimer(hSession->unlock_delay_ms, hSession, defer_unlock); 1070 + hSession->unlock_id = AddTimer(hSession->unlock_delay_ms, hSession, defer_unlock, NULL);
1071 } 1071 }
1072 else 1072 else
1073 { 1073 {
1074 hSession->unlock_id = 0; 1074 hSession->unlock_id = 0;
1075 - defer_unlock(hSession); 1075 + defer_unlock(hSession, NULL);
1076 } 1076 }
1077 1077
1078 } 1078 }
src/core/linux/connect.c
@@ -245,6 +245,15 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -245,6 +245,15 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
245 245
246 if(seconds) 246 if(seconds)
247 { 247 {
  248 + int rc = lib3270_wait_for_cstate(hSession,LIB3270_CONNECTED_TN3270E,seconds);
  249 + if(rc)
  250 + {
  251 + lib3270_disconnect(hSession);
  252 + lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(ETIMEDOUT));
  253 + return errno = rc;
  254 + }
  255 +
  256 + /*
248 time_t end = time(0)+seconds; 257 time_t end = time(0)+seconds;
249 258
250 while(time(0) < end) 259 while(time(0) < end)
@@ -282,6 +291,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG @@ -282,6 +291,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
282 lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(ETIMEDOUT)); 291 lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(ETIMEDOUT));
283 292
284 return errno = ETIMEDOUT; 293 return errno = ETIMEDOUT;
  294 + */
285 } 295 }
286 296
287 return 0; 297 return 0;
src/core/linux/event_dispatcher.c
@@ -188,11 +188,13 @@ retry: @@ -188,11 +188,13 @@ retry:
188 if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec)) 188 if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec))
189 { 189 {
190 t->in_play = True; 190 t->in_play = True;
191 - (*t->proc)(hSession);  
192 - processed_any = True;  
193 191
  192 + (*t->proc)(hSession,t->userdata);
194 lib3270_linked_list_delete_node(&hSession->timeouts,t); 193 lib3270_linked_list_delete_node(&hSession->timeouts,t);
195 194
  195 + processed_any = True;
  196 +
  197 +
196 } 198 }
197 else 199 else
198 { 200 {
src/core/properties/boolean.c
@@ -45,10 +45,13 @@ @@ -45,10 +45,13 @@
45 return hSession->starting != 0; 45 return hSession->starting != 0;
46 } 46 }
47 47
48 - void lib3270_disable_crl_download(H3270 *hSession) 48 + int lib3270_disable_crl_download(H3270 *hSession, int enabled)
49 { 49 {
50 #ifdef SSL_ENABLE_CRL_CHECK 50 #ifdef SSL_ENABLE_CRL_CHECK
51 - hSession->ssl.crl.download = 0; 51 + hSession->ssl.crl.download = enabled ? 1 : 0;
  52 + return 0;
  53 +#else
  54 + return errno = ENOTSUP;
52 #endif // SSL_ENABLE_CRL_CHECK 55 #endif // SSL_ENABLE_CRL_CHECK
53 } 56 }
54 57
src/core/wait.c
@@ -31,9 +31,16 @@ @@ -31,9 +31,16 @@
31 #include <lib3270/log.h> 31 #include <lib3270/log.h>
32 #include <lib3270/trace.h> 32 #include <lib3270/trace.h>
33 #include "kybdc.h" 33 #include "kybdc.h"
  34 +#include "utilc.h"
34 35
35 /*---[ Implement ]------------------------------------------------------------------------------------------*/ 36 /*---[ Implement ]------------------------------------------------------------------------------------------*/
36 37
  38 +static int timer_expired(H3270 GNUC_UNUSED(*hSession), void *userdata)
  39 +{
  40 + *((int *) userdata) = 1;
  41 + return 0;
  42 +}
  43 +
37 LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNUC_UNUSED(seconds)) 44 LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNUC_UNUSED(seconds))
38 { 45 {
39 return errno = ENOTSUP; 46 return errno = ENOTSUP;
@@ -41,57 +48,90 @@ LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNU @@ -41,57 +48,90 @@ LIB3270_EXPORT int lib3270_wait_for_update(H3270 GNUC_UNUSED(*hSession), int GNU
41 48
42 LIB3270_EXPORT int lib3270_wait_for_ready(H3270 *hSession, int seconds) 49 LIB3270_EXPORT int lib3270_wait_for_ready(H3270 *hSession, int seconds)
43 { 50 {
44 - time_t end = time(0)+seconds;  
45 -  
46 - if(lib3270_is_disconnected(hSession))  
47 - return errno = ENOTCONN; 51 + FAIL_IF_NOT_ONLINE(hSession);
48 52
49 - lib3270_main_iterate(hSession,0); 53 + debug("%s",__FUNCTION__);
  54 + debug("Session lock state is %d",lib3270_get_lock_status(hSession));
50 55
51 - // Keyboard is locked by operator error, fails!  
52 - if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))  
53 - return errno = EPERM; 56 + int rc = 0;
  57 + int timeout = 0;
  58 + void * timer = AddTimer(seconds * 1000, hSession, timer_expired, &timeout);
54 59
55 - do 60 + while(!rc)
56 { 61 {
57 - if(!lib3270_get_lock_status(hSession))  
58 - return 0; 62 + if(timeout) {
  63 + // Timeout! The timer was destroyed.
  64 + debug("%s exits with ETIMEDOUT",__FUNCTION__);
  65 + return errno = ETIMEDOUT;
  66 + }
  67 +
  68 + if(lib3270_get_lock_status(hSession) == LIB3270_MESSAGE_NONE)
  69 + {
  70 + // Is unlocked, break.
  71 +
  72 + break;
  73 + }
59 74
60 if(lib3270_is_disconnected(hSession)) 75 if(lib3270_is_disconnected(hSession))
61 - return errno = ENOTCONN; 76 + {
  77 + rc = errno = ENOTCONN;
  78 + break;
  79 + }
62 80
63 - lib3270_main_iterate(hSession,1); 81 + if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))
  82 + {
  83 + rc = errno = EPERM;
  84 + break;
  85 + }
64 86
  87 + debug("%s: Waiting",__FUNCTION__);
  88 + lib3270_main_iterate(hSession,1);
65 } 89 }
66 - while(time(0) < end); 90 + RemoveTimer(hSession,timer);
  91 +
  92 + debug("%s exits with rc=%d",__FUNCTION__,rc);
  93 + return rc;
67 94
68 - return errno = ETIMEDOUT;  
69 } 95 }
70 96
71 int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds) 97 int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds)
72 { 98 {
73 - time_t end = time(0)+seconds;  
74 -  
75 FAIL_IF_NOT_ONLINE(hSession); 99 FAIL_IF_NOT_ONLINE(hSession);
76 100
77 - lib3270_main_iterate(hSession,0); 101 + int rc = 0;
  102 + int timeout = 0;
  103 + void * timer = AddTimer(seconds * 1000, hSession, timer_expired, &timeout);
78 104
79 - do 105 + while(!rc)
80 { 106 {
  107 + if(timeout) {
  108 + // Timeout! The timer was destroyed.
  109 + return errno = ETIMEDOUT;
  110 + }
  111 +
81 // Keyboard is locked by operator error, fails! 112 // Keyboard is locked by operator error, fails!
82 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession)) 113 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))
83 - return errno = EPERM; 114 + {
  115 + rc = errno = EPERM;
  116 + break;
  117 + }
84 118
85 if(!lib3270_is_connected(hSession)) 119 if(!lib3270_is_connected(hSession))
86 - return errno = ENOTCONN; 120 + {
  121 + rc = errno = ENOTCONN;
  122 + break;
  123 + }
87 124
88 char * contents = lib3270_get_string_at_address(hSession, 0, -1, 0); 125 char * contents = lib3270_get_string_at_address(hSession, 0, -1, 0);
89 if(!contents) 126 if(!contents)
90 - return errno; 127 + {
  128 + rc = errno;
  129 + break;
  130 + }
91 131
92 if(strstr(contents,key)) { 132 if(strstr(contents,key)) {
93 lib3270_free(contents); 133 lib3270_free(contents);
94 - return 0; 134 + break;
95 } 135 }
96 136
97 lib3270_free(contents); 137 lib3270_free(contents);
@@ -99,44 +139,58 @@ int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds) @@ -99,44 +139,58 @@ int lib3270_wait_for_string(H3270 *hSession, const char *key, int seconds)
99 lib3270_main_iterate(hSession,1); 139 lib3270_main_iterate(hSession,1);
100 140
101 } 141 }
102 - while(time(0) < end); 142 + RemoveTimer(hSession,timer);
  143 +
  144 + return rc;
103 145
104 - return errno = ETIMEDOUT;  
105 } 146 }
106 147
107 int lib3270_wait_for_string_at_address(H3270 *hSession, int baddr, const char *key, int seconds) 148 int lib3270_wait_for_string_at_address(H3270 *hSession, int baddr, const char *key, int seconds)
108 { 149 {
109 - time_t end = time(0)+seconds;  
110 -  
111 FAIL_IF_NOT_ONLINE(hSession); 150 FAIL_IF_NOT_ONLINE(hSession);
112 151
113 - lib3270_main_iterate(hSession,0);  
114 -  
115 if(baddr < 0) 152 if(baddr < 0)
116 baddr = lib3270_get_cursor_address(hSession); 153 baddr = lib3270_get_cursor_address(hSession);
117 154
118 - do 155 + int rc = 0;
  156 + int timeout = 0;
  157 + void * timer = AddTimer(seconds * 1000, hSession, timer_expired, &timeout);
  158 +
  159 + while(!rc)
119 { 160 {
  161 + if(timeout) {
  162 + // Timeout! The timer was destroyed.
  163 + return errno = ETIMEDOUT;
  164 + }
  165 +
120 // Keyboard is locked by operator error, fails! 166 // Keyboard is locked by operator error, fails!
121 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession)) 167 if(hSession->kybdlock && KYBDLOCK_IS_OERR(hSession))
122 - return errno = EPERM; 168 + {
  169 + rc = errno = EPERM;
  170 + break;
  171 + }
123 172
124 if(!lib3270_is_connected(hSession)) 173 if(!lib3270_is_connected(hSession))
125 - return errno = ENOTCONN; 174 + {
  175 + rc = errno = ENOTCONN;
  176 + break;
  177 + }
126 178
127 if(lib3270_cmp_string_at_address(hSession, baddr, key, 0) == 0) 179 if(lib3270_cmp_string_at_address(hSession, baddr, key, 0) == 0)
128 - return 0; 180 + {
  181 + break;
  182 + }
129 183
130 lib3270_main_iterate(hSession,1); 184 lib3270_main_iterate(hSession,1);
131 185
132 } 186 }
133 - while(time(0) < end); 187 + RemoveTimer(hSession,timer);
134 188
135 - return errno = ETIMEDOUT; 189 + return rc;
136 190
137 } 191 }
138 192
139 -int lib3270_wait_for_string_at(H3270 *hSession, unsigned int row, unsigned int col, const char *key, int seconds) 193 +LIB3270_EXPORT int lib3270_wait_for_string_at(H3270 *hSession, unsigned int row, unsigned int col, const char *key, int seconds)
140 { 194 {
141 int baddr = lib3270_translate_to_address(hSession,row,col); 195 int baddr = lib3270_translate_to_address(hSession,row,col);
142 if(baddr < 0) 196 if(baddr < 0)
@@ -144,3 +198,37 @@ int lib3270_wait_for_string_at(H3270 *hSession, unsigned int row, unsigned int c @@ -144,3 +198,37 @@ int lib3270_wait_for_string_at(H3270 *hSession, unsigned int row, unsigned int c
144 198
145 return lib3270_wait_for_string_at_address(hSession,baddr,key,seconds); 199 return lib3270_wait_for_string_at_address(hSession,baddr,key,seconds);
146 } 200 }
  201 +
  202 +LIB3270_EXPORT int lib3270_wait_for_cstate(H3270 *hSession, LIB3270_CSTATE cstate, int seconds)
  203 +{
  204 +
  205 + int rc = -1;
  206 + int timeout = 0;
  207 + void * timer = AddTimer(seconds * 1000, hSession, timer_expired, &timeout);
  208 +
  209 + while(rc == -1)
  210 + {
  211 + if(timeout) {
  212 + // Timeout! The timer was destroyed.
  213 + return errno = ETIMEDOUT;
  214 + }
  215 +
  216 + if(hSession->connection.state == LIB3270_NOT_CONNECTED)
  217 + {
  218 + rc = ENOTCONN;
  219 + break;
  220 + }
  221 +
  222 + if(!hSession->starting && hSession->connection.state == cstate)
  223 + {
  224 + rc = 0;
  225 + break;
  226 + }
  227 +
  228 + lib3270_main_iterate(hSession,1);
  229 +
  230 + }
  231 + RemoveTimer(hSession,timer);
  232 +
  233 + return errno = rc;
  234 +}
src/core/windows/connect.c
@@ -347,6 +347,18 @@ int net_reconnect(H3270 *hSession, int seconds) @@ -347,6 +347,18 @@ int net_reconnect(H3270 *hSession, int seconds)
347 347
348 if(seconds) 348 if(seconds)
349 { 349 {
  350 + int rc = lib3270_wait_for_cstate(hSession,LIB3270_CONNECTED_TN3270E,seconds);
  351 + if(rc)
  352 + {
  353 + lib3270_disconnect(hSession);
  354 + lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(rc));
  355 + return errno = rc;
  356 + }
  357 + }
  358 +
  359 + /*
  360 + if(seconds)
  361 + {
350 time_t end = time(0)+seconds; 362 time_t end = time(0)+seconds;
351 363
352 while(time(0) < end) 364 while(time(0) < end)
@@ -382,6 +394,7 @@ int net_reconnect(H3270 *hSession, int seconds) @@ -382,6 +394,7 @@ int net_reconnect(H3270 *hSession, int seconds)
382 lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(ETIMEDOUT)); 394 lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(ETIMEDOUT));
383 return errno = ETIMEDOUT; 395 return errno = ETIMEDOUT;
384 } 396 }
  397 + */
385 398
386 return 0; 399 return 0;
387 400
src/include/internals.h
@@ -274,7 +274,7 @@ typedef struct timeout @@ -274,7 +274,7 @@ typedef struct timeout
274 struct timeval tv; 274 struct timeval tv;
275 #endif /*]*/ 275 #endif /*]*/
276 276
277 - int (*proc)(H3270 *session); 277 + int (*proc)(H3270 *session, void *userdata);
278 278
279 } timeout_t; 279 } timeout_t;
280 280
src/include/lib3270.h
@@ -970,7 +970,7 @@ @@ -970,7 +970,7 @@
970 { 970 {
971 unsigned short sz; 971 unsigned short sz;
972 972
973 - void * (*AddTimer)(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session)); 973 + void * (*AddTimer)(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session, void *userdata), void *userdata);
974 void (*RemoveTimer)(H3270 *session, void *timer); 974 void (*RemoveTimer)(H3270 *session, void *timer);
975 975
976 void * (*add_poll)(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata); 976 void * (*add_poll)(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata);
@@ -1001,7 +1001,7 @@ @@ -1001,7 +1001,7 @@
1001 * @param rm Callback for removing a timeout 1001 * @param rm Callback for removing a timeout
1002 * 1002 *
1003 */ 1003 */
1004 - LIB3270_EXPORT void lib3270_register_timer_handlers(void * (*add)(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session)), void (*rm)(H3270 *session, void *timer)); 1004 + LIB3270_EXPORT void lib3270_register_timer_handlers(void * (*add)(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session, void *userdata), void *userdata), void (*rm)(H3270 *session, void *timer));
1005 1005
1006 LIB3270_EXPORT void lib3270_register_fd_handlers(void * (*add)(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata), void (*rm)(H3270 *, void *id)); 1006 LIB3270_EXPORT void lib3270_register_fd_handlers(void * (*add)(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata), void (*rm)(H3270 *, void *id));
1007 1007
@@ -1111,7 +1111,7 @@ @@ -1111,7 +1111,7 @@
1111 LIB3270_EXPORT int lib3270_wait_for_update(H3270 *hSession, int seconds); 1111 LIB3270_EXPORT int lib3270_wait_for_update(H3270 *hSession, int seconds);
1112 1112
1113 /** 1113 /**
1114 - * Wait "N" seconds for "ready" state. 1114 + * @brief Wait "N" seconds for "ready" state.
1115 * 1115 *
1116 * @param seconds Number of seconds to wait. 1116 * @param seconds Number of seconds to wait.
1117 * 1117 *
@@ -1121,6 +1121,20 @@ @@ -1121,6 +1121,20 @@
1121 LIB3270_EXPORT int lib3270_wait_for_ready(H3270 *hSession, int seconds); 1121 LIB3270_EXPORT int lib3270_wait_for_ready(H3270 *hSession, int seconds);
1122 1122
1123 /** 1123 /**
  1124 + * @brief Wait "N" seconds for online state.
  1125 + *
  1126 + * @param seconds Number of seconds to wait.
  1127 + *
  1128 + * @return 0 if ok, errno code if not.
  1129 + *
  1130 + * @retval ETIMEDOUT Timeout waiting.
  1131 + * @retval ENOTCONN Not connected to host.
  1132 + * @retval 0 Session is online and in required state.
  1133 + *
  1134 + */
  1135 + LIB3270_EXPORT int lib3270_wait_for_cstate(H3270 *hSession, LIB3270_CSTATE cstate, int seconds);
  1136 +
  1137 + /**
1124 * "beep" to notify user. 1138 * "beep" to notify user.
1125 * 1139 *
1126 * If available play a sound signal do alert user. 1140 * If available play a sound signal do alert user.
src/include/lib3270/properties.h
@@ -216,9 +216,14 @@ @@ -216,9 +216,14 @@
216 * @brief Disable automatic download of the CRL. 216 * @brief Disable automatic download of the CRL.
217 * 217 *
218 * @param hSession Session handle. 218 * @param hSession Session handle.
  219 + * @param Value Non zero to enable automatic download of CRL.
219 * 220 *
  221 + * @return 0 if ok or error code if not (Sets errno).
  222 + *
  223 + * @retval 0 Download of the CRL was disabled.
  224 + * @retval ENOTSUP No SSL/TLS support.
220 */ 225 */
221 - LIB3270_EXPORT void lib3270_disable_crl_download(H3270 *hSession); 226 + LIB3270_EXPORT int lib3270_ssl_set_crl_download(H3270 *hSession, int enabled);
222 227
223 /** 228 /**
224 * @brief Get lib3270 version info. 229 * @brief Get lib3270 version info.
src/include/utilc.h
@@ -17,49 +17,20 @@ @@ -17,49 +17,20 @@
17 * @brief Global declarations for util.c. 17 * @brief Global declarations for util.c.
18 */ 18 */
19 19
20 -LIB3270_INTERNAL char *ctl_see(int c); 20 +LIB3270_INTERNAL char * ctl_see(int c);
21 21
22 - /*  
23 -LIB3270_INTERNAL void add_resource(const char *name, const char *value);  
24 -LIB3270_INTERNAL const char *get_message(const char *key);  
25 -LIB3270_INTERNAL const char *get_fresource(H3270 *hSession, const char *fmt, ...) LIB3270_GNUC_FORMAT(2, 3);  
26 -LIB3270_INTERNAL const char *get_resource(H3270 *hSession, const char *name);  
27 -LIB3270_INTERNAL int split_dbcs_resource(const char *value, char sep, char **part1, char **part2);  
28 -LIB3270_INTERNAL int split_dresource(char **st, char **left, char **right);  
29 -LIB3270_INTERNAL int split_lresource(char **st, char **value);  
30 -LIB3270_INTERNAL char *strip_whitespace(const char *s);  
31 -*/  
32 -  
33 -LIB3270_INTERNAL char *xs_buffer(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);  
34 -LIB3270_INTERNAL void xs_error(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);  
35 -LIB3270_INTERNAL void xs_warning(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2); 22 +LIB3270_INTERNAL char * xs_buffer(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);
  23 +LIB3270_INTERNAL void xs_error(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);
  24 +LIB3270_INTERNAL void xs_warning(const char *fmt, ...) LIB3270_GNUC_FORMAT(1, 2);
36 25
37 LIB3270_INTERNAL void * AddInput(int, H3270 *session, void (*fn)(H3270 *session)); 26 LIB3270_INTERNAL void * AddInput(int, H3270 *session, void (*fn)(H3270 *session));
38 LIB3270_INTERNAL void * AddOutput(int, H3270 *session, void (*fn)(H3270 *session)); 27 LIB3270_INTERNAL void * AddOutput(int, H3270 *session, void (*fn)(H3270 *session));
39 LIB3270_INTERNAL void * AddExcept(int, H3270 *session, void (*fn)(H3270 *session)); 28 LIB3270_INTERNAL void * AddExcept(int, H3270 *session, void (*fn)(H3270 *session));
40 29
41 LIB3270_INTERNAL void RemoveSource(H3270 *session, void *cookie); 30 LIB3270_INTERNAL void RemoveSource(H3270 *session, void *cookie);
42 -LIB3270_INTERNAL void * AddTimer(unsigned long msec, H3270 *session, int (*fn)(H3270 *session)); 31 +LIB3270_INTERNAL void * AddTimer(unsigned long msec, H3270 *session, int (*fn)(H3270 *session, void *userdata), void *userdata);
43 LIB3270_INTERNAL void RemoveTimer(H3270 *session, void *cookie); 32 LIB3270_INTERNAL void RemoveTimer(H3270 *session, void *cookie);
44 33
45 -// LIB3270_INTERNAL const char * KeysymToString(KeySym k);  
46 -  
47 -// LIB3270_INTERNAL int read_resource_file(const char *filename, Boolean fatal);  
48 -// LIB3270_INTERNAL Boolean split_hier(char *label, char **base, char ***parents);  
49 -  
50 -/*  
51 -typedef struct {  
52 - char *buf;  
53 - int alloc_len;  
54 - int cur_len;  
55 -} rpf_t;  
56 -  
57 -LIB3270_INTERNAL void rpf_init(rpf_t *r);  
58 -LIB3270_INTERNAL void rpf_reset(rpf_t *r);  
59 -LIB3270_INTERNAL void rpf(rpf_t *r, char *fmt, ...) LIB3270_GNUC_FORMAT(2, 3);  
60 -LIB3270_INTERNAL void rpf_free(rpf_t *r);  
61 -*/  
62 -  
63 /** 34 /**
64 * @brief "unescape" text (Replaces %value for corresponding character). 35 * @brief "unescape" text (Replaces %value for corresponding character).
65 * 36 *
@@ -71,7 +42,7 @@ LIB3270_INTERNAL void rpf_free(rpf_t *r); @@ -71,7 +42,7 @@ LIB3270_INTERNAL void rpf_free(rpf_t *r);
71 LIB3270_INTERNAL char * lib3270_unescape(const char *text); 42 LIB3270_INTERNAL char * lib3270_unescape(const char *text);
72 43
73 /** 44 /**
74 - * @brief Compare strings ignoring non alfanumeric chars. 45 + * @brief Compare strings ignoring non alphanumeric chars.
75 * 46 *
76 * @param s1 First string. 47 * @param s1 First string.
77 * @param s2 Second string. 48 * @param s2 Second string.
src/testprogram/testprogram.c
@@ -154,16 +154,39 @@ int main(int argc, char *argv[]) @@ -154,16 +154,39 @@ int main(int argc, char *argv[])
154 154
155 const void * online_listener = lib3270_register_action_group_listener(h,LIB3270_ACTION_GROUP_ONLINE,online_group_state_changed,NULL); 155 const void * online_listener = lib3270_register_action_group_listener(h,LIB3270_ACTION_GROUP_ONLINE,online_group_state_changed,NULL);
156 156
157 - rc = lib3270_reconnect(h,120); 157 + rc = lib3270_reconnect(h,0);
158 printf("\n\nConnect exits with rc=%d (%s)\n\n",rc,strerror(rc)); 158 printf("\n\nConnect exits with rc=%d (%s)\n\n",rc,strerror(rc));
159 159
160 if(!rc) 160 if(!rc)
161 { 161 {
  162 + rc = lib3270_wait_for_cstate(h,LIB3270_CONNECTED_TN3270E, 60);
  163 + printf("\n\nWait for LIB3270_CONNECTED_TN3270E exits with rc=%d (%s)\n\n",rc,strerror(rc));
  164 + }
  165 +
  166 + if(!rc)
  167 + {
  168 + rc = lib3270_wait_for_ready(h,60);
  169 + printf("\n\nWait for ready exits with rc=%d (%s)\n\n",rc,strerror(rc));
  170 + }
  171 +
  172 + if(!rc)
  173 + {
  174 +
162 printf("\n\nWaiting starts %u\n",(unsigned int) time(NULL)); 175 printf("\n\nWaiting starts %u\n",(unsigned int) time(NULL));
163 - lib3270_wait_for_ready(h,10); 176 +
  177 + {
  178 + // Performance checks
  179 + size_t f;
  180 + time_t start = time(0);
  181 + for(f=0;f < 1000; f++) {
  182 + lib3270_wait_for_ready(h,10);
  183 + }
  184 + printf("Time for 1000 iterations of wait_for_ready was %d\n",(int) (time(0) - start));
  185 +
  186 + }
  187 +
164 printf("Waiting ends %u\n\n",(unsigned int) time(NULL)); 188 printf("Waiting ends %u\n\n",(unsigned int) time(NULL));
165 189
166 - /*  
167 lib3270_enter(h); 190 lib3270_enter(h);
168 lib3270_wait(h,5); 191 lib3270_wait(h,5);
169 192
@@ -185,7 +208,6 @@ int main(int argc, char *argv[]) @@ -185,7 +208,6 @@ int main(int argc, char *argv[])
185 if(text) 208 if(text)
186 printf("Screen:\n[%s]\n",text); 209 printf("Screen:\n[%s]\n",text);
187 } 210 }
188 - */  
189 211
190 lib3270_disconnect(h); 212 lib3270_disconnect(h);
191 213