1 /*  C K C S I G . H  */
2 
3 /*  Definitions and prototypes for signal handling  */
4 
5 /*
6   Author: Jeffrey E Altman (jaltman@secure-endpoints.com),
7   Secure Endpoints Inc., New York City.
8 
9   Copyright (C) 1985, 2013
10     Trustees of Columbia University in the City of New York.
11     All rights reserved.  See the C-Kermit COPYING.TXT file or the
12     copyright text in the ckcmai.c module for disclaimer and permissions.
13 */
14 #ifdef OS2
15 #ifndef NT
16 #ifndef __HEV__                 /* INCL_SEMAPHORE may also define HEV */
17 #define __HEV__
18 typedef  ULONG    HEV;                  /* hev */
19 typedef  HEV      *PHEV;
20 #endif /* __HEV__ */
21 #endif /* NT */
22 struct _threadinfo {
23     int inuse;
24     int child;
25     int sibling;
26 #ifdef NT
27     HANDLE id;
28     HANDLE handle;
29     HANDLE parent;
30     HANDLE CompletionSem ;
31     HANDLE DieSem ;
32 #else /* NT */
33     TID id;
34     TID parent;
35     HEV CompletionSem;
36     HEV DieSem;
37 #endif /* NT */
38 };
39 #endif /* OS2 */
40 
41 #ifdef CK_ANSIC
42 typedef SIGTYP (*ck_sigfunc)(void *);
43 typedef SIGTYP (*ck_sighand)(int);
44 #else
45 typedef SIGTYP (*ck_sigfunc)();
46 typedef SIGTYP (*ck_sighand)();
47 #endif /* CK_ANSIC */
48 
49 /* Macros for POSIX vs old-style signal handling. */
50 
51 #ifdef CK_POSIX_SIG
52 typedef sigjmp_buf ckjmpbuf;
53 #else
54 #ifdef NT
55 #define NOCRYPT
56 #include <windows.h>
57 #ifdef NTASM
58 typedef struct {
59     CONTEXT context;
60     DWORD retcode;
61 } ckjmpbuf;
62 #else /* NTASM */
63 typedef jmp_buf ckjmpbuf;
64 #endif /* NTASM */
65 #else
66 typedef jmp_buf ckjmpbuf;
67 #endif
68 #endif /* CK_POSIX_SIG */
69 /*
70   Suppose you want to pass the address of a jmp_buf bar to a function foo.
71   Since jmp_buf is normally defined (typedef'd) as an array, you would do
72   it like this:  foo(bar), where foo = foo(jmp_buf bar).  But suppose a
73   jmp_buf is (say) a struct rather than an array.  Then you must do
74   foo(&bar) where foo is foo(jmp_buf * bar).  This is controlled here in
75   the traditional fashion, by ifdefs.  By default, we assume that jmp_buf
76   is an array.  Define the symbol JBNOTARRAY if jmp_buf is not an array.
77 */
78 #ifndef JBNOTARRAY
79 #ifdef NT
80 #define JBNOTARRAY
81 #endif /* NT */
82 #endif /* JBNOTARRAY */
83 
84 #ifdef JBNOTARRAY
85 typedef ckjmpbuf * ckjptr;
86 #define ckjaddr(x) & x
87 #define ckjdref(x) * x
88 #ifdef CK_POSIX_SIG
89 #define cksetjmp(x) sigsetjmp(x,1)
90 #define cklongjmp(x,y) siglongjmp(x,y)
91 #else
92 #ifdef NT
93 #ifdef COMMENT
94 __inline int
95 #else
96 static __inline int /* duplicate definition issue */
97 #endif /* COMMENT */
98 
ck_ih(void)99 ck_ih(void) {
100     extern int TlsIndex;
101 #ifdef NTSIG
102     struct _threadinfo * threadinfo;
103     threadinfo = (struct _threadinfo *) TlsGetValue(TlsIndex);
104     if (threadinfo) {
105         if (WaitAndResetSem(threadinfo->DieSem,0)) {
106             ckThreadDie(threadinfo);
107             return 1;                   /* This should never execute */
108         }
109     }
110 #ifdef COMMENT
111     else debug( F100, "ck_ih() threadinfo is NULL","",0);
112 #endif /* COMMENT */
113 #endif /* NTSIG */
114     return 0;
115 }
116 #ifdef NTSIG
117 #define cksetjmp(x) setjmp(x)
118 #define cklongjmp(x,y) longjmp(x,y)
119 #else /* NTSIG */
120 #ifdef NTASM
121 __inline DWORD
cksetjmp(ckjptr jmp)122 cksetjmp( ckjptr jmp ) {
123     extern int isinterrupted;
124     jmp->retcode = 0;
125     memset( &jmp->context, 0, sizeof(CONTEXT) );
126     jmp->context.ContextFlags = CONTEXT_FULL ;
127     if ( !GetThreadContext( GetCurrentThread(), &jmp->context ) )
128       debug( F101, "cksetjmp GetThreadContext failed","",GetLastError());
129     debug(F101,"cksetjmp returns","",jmp->retcode);
130     isinterrupted = 0;
131     return (jmp->retcode);
132 }
133 
134 __inline void
cklongjmp(ckjptr jmp,int retval)135 cklongjmp( ckjptr jmp, int retval ) {
136     extern HANDLE tidCommand;
137     extern int ttyfd, mdmtyp ;
138     extern DWORD CommandID;
139     extern int isinterrupted;
140 
141     connoi();
142     isinterrupted = 1;
143     jmp->retcode = ( retval ? retval : 1 );
144     debug(F101,"about to SetThreadContext for thread","", CommandID);
145     debug(F101,"from Thread","",GetCurrentThreadId());
146     if ( mdmtyp >= 0 ) {
147         PurgeComm( (HANDLE) ttyfd, PURGE_TXABORT | PURGE_RXABORT );
148     }
149     if (SetThreadContext( tidCommand, &jmp->context ))
150       debug(F100,"cklongjmp SetThreadContext success","",0);
151     else
152       debug(F101,"cklongjmp SetThreadContext failed","",GetLastError());
153     msleep(50);
154     cmini(1);                           /* Reset command parser */
155     putkey(13);                         /* Stuff a carriage return */
156    /* PostEventAvailSem(); */
157 }
158 #else /* NTASM */
159 void crash( void ) ;
160 #define cksetjmp(x) setjmp(x)
161 __inline void
cklongjmp(ckjptr jmp,int retval)162 cklongjmp( ckjptr jmp, int retval ) {
163     extern HANDLE tidCommand;
164     extern int ttyfd, mdmtyp;
165     extern DWORD CommandID;
166     CONTEXT context;
167 
168     if ( mdmtyp >= 0 ) {
169         PurgeComm( (HANDLE) ttyfd, PURGE_TXABORT | PURGE_RXABORT ) ;
170     }
171     memset( &context, 0, sizeof(CONTEXT) );
172     context.ContextFlags = CONTEXT_FULL;
173     if ( !GetThreadContext( tidCommand, &context ) )
174       debug( F101, "cklongjmp GetThreadContext failed","",GetLastError());
175 
176     /* Invalidate the instruction pointer */
177     context.Eip =  (unsigned long) crash;
178 
179     debug(F101,"about to SetThreadContext for thread","", CommandID);
180     debug(F101,"from Thread","",GetCurrentThreadId());
181     if (SetThreadContext( tidCommand, &context ))
182       debug(F100,"cklongjmp SetThreadContext success","",0);
183     else
184       debug(F101,"cklongjmp SetThreadContext failed","",GetLastError());
185 }
186 #endif /* NTASM */
187 #endif /* NTSIG */
188 #else /* NT */
189 #define cksetjmp(x) setjmp(x)
190 #define cklongjmp(x,y) longjmp(x,y)
191 #endif /* NT */
192 #endif /* CK_POSIX_SIG */
193 #else  /* jmp_buf is an array */
194 typedef ckjmpbuf ckjptr;
195 #define ckjaddr(x) x
196 #define ckjdref(x) x
197 #ifdef CK_POSIX_SIG
198 #define cksetjmp(x) sigsetjmp(x,1)
199 #define cklongjmp(x,y) siglongjmp(x,y)
200 #else
201 #define cksetjmp(x) setjmp(x)
202 #define cklongjmp(x,y) longjmp(x,y)
203 #endif /* CK_POSIX_SIG */
204 #endif /* JBNOTARRAY */
205 
206 _PROTOTYP( int cc_execute, (ckjptr, ck_sigfunc, ck_sigfunc) );
207 _PROTOTYP( int alrm_execute,
208           (ckjptr,
209            int /* timo */,
210            ck_sighand /* handler */,
211            ck_sigfunc, ck_sigfunc) );
212 _PROTOTYP( int cc_alrm_execute,
213           (ckjptr,
214            int /* timo */,
215            ck_sighand /* handler */,
216            ck_sigfunc,
217            ck_sigfunc) );
218 
219 /* End of ckusig.h */
220