1b725ae77Skettenis /*
2b725ae77Skettenis * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3b725ae77Skettenis *
4b725ae77Skettenis * This software may be freely used, copied, modified, and distributed
5b725ae77Skettenis * provided that the above copyright notice is preserved in all copies of the
6b725ae77Skettenis * software.
7b725ae77Skettenis */
8b725ae77Skettenis
9b725ae77Skettenis /*
10b725ae77Skettenis * Host C Library support functions.
11b725ae77Skettenis *
12*63addd46Skettenis * $Revision: 1.3 $
13*63addd46Skettenis * $Date: 2004/12/27 14:00:54 $
14b725ae77Skettenis */
15b725ae77Skettenis
16b725ae77Skettenis #ifdef DEBUG
17b725ae77Skettenis # include <ctype.h>
18b725ae77Skettenis #endif
19b725ae77Skettenis
20b725ae77Skettenis #include <stdio.h>
21b725ae77Skettenis #include <stdlib.h>
22b725ae77Skettenis #include <string.h>
23b725ae77Skettenis #include <stdarg.h>
24b725ae77Skettenis #include <errno.h>
25b725ae77Skettenis #include <time.h>
26b725ae77Skettenis
27b725ae77Skettenis #include "adp.h"
28b725ae77Skettenis #include "host.h"
29b725ae77Skettenis #include "ardi.h"
30b725ae77Skettenis #include "buffers.h"
31b725ae77Skettenis #include "channels.h" /* Channel interface. */
32b725ae77Skettenis #include "angel_endian.h"
33b725ae77Skettenis #include "logging.h" /* Angel support functions. */
34b725ae77Skettenis #include "msgbuild.h"
35b725ae77Skettenis #include "sys.h"
36b725ae77Skettenis #include "hsys.h" /* Function and structure declarations. */
37b725ae77Skettenis #include "hostchan.h"
38b725ae77Skettenis
39b725ae77Skettenis #define FILEHANDLE int
40b725ae77Skettenis
41b725ae77Skettenis /* Note: no statics allowed. All globals must be malloc()ed on the heap.
42b725ae77Skettenis The state struct is used for this purpose. See 'hsys.h'. */
43b725ae77Skettenis /* This is the message handler function passed to the channel manager in
44b725ae77Skettenis HostSysInit. It is called whenever a message is received. 'buffptr'
45b725ae77Skettenis points to the message body. Functionality is provided by the debugger
46b725ae77Skettenis toolkit. The routine is very loosely based on the HandleSWI routine from
47b725ae77Skettenis armos.c in the armulator source. */
48b725ae77Skettenis /* These routines could be tested by providing a simple interface to armsd,
49b725ae77Skettenis and running them in that. */
50b725ae77Skettenis
51b725ae77Skettenis
52b725ae77Skettenis /* taken staight from armulator source */
53b725ae77Skettenis #ifdef __riscos
54b725ae77Skettenis extern int _fisatty(FILE *);
55b725ae77Skettenis # define isatty_(f) _fisatty(f)
56b725ae77Skettenis # define EMFILE -1
57b725ae77Skettenis # define EBADF -1
_kernel_escape_seen(void)58b725ae77Skettenis int _kernel_escape_seen(void) { return 0 ;}
59b725ae77Skettenis #else
60b725ae77Skettenis # if defined(_WINDOWS) || defined(_CONSOLE)
61b725ae77Skettenis # define isatty_(f) (f == stdin || f == stdout)
62b725ae77Skettenis # else
63b725ae77Skettenis # ifdef __ZTC__
64b725ae77Skettenis # include <io.h>
65b725ae77Skettenis # define isatty_(f) isatty((f)->_file)
66b725ae77Skettenis # else
67b725ae77Skettenis # ifdef macintosh
68b725ae77Skettenis # include <ioctl.h>
69b725ae77Skettenis # define isatty_(f) (~ioctl((f)->_file,FIOINTERACTIVE,NULL))
70b725ae77Skettenis # else
71b725ae77Skettenis # define isatty_(f) isatty(fileno(f))
72b725ae77Skettenis # endif
73b725ae77Skettenis # endif
74b725ae77Skettenis # endif
75b725ae77Skettenis #endif
76b725ae77Skettenis
77b725ae77Skettenis /* Set up the state block, filetable and register the C lib callback fn */
HostSysInit(const struct Dbg_HostosInterface * hostif,char ** cmdline,hsys_state ** stateptr)78b725ae77Skettenis int HostSysInit(const struct Dbg_HostosInterface *hostif, char **cmdline,
79b725ae77Skettenis hsys_state **stateptr)
80b725ae77Skettenis {
81b725ae77Skettenis ChannelCallback HandleMessageFPtr = (ChannelCallback) HandleSysMessage;
82b725ae77Skettenis int i;
83b725ae77Skettenis *stateptr = (hsys_state *)malloc(sizeof(hsys_state));
84b725ae77Skettenis
85b725ae77Skettenis if (*stateptr == NULL) return RDIError_OutOfStore;
86b725ae77Skettenis
87b725ae77Skettenis (*stateptr)->hostif=hostif;
88b725ae77Skettenis (*stateptr)->last_errno=0;
89b725ae77Skettenis (*stateptr)->OSptr=(OSblock *)malloc(sizeof(OSblock));
90b725ae77Skettenis if ((*stateptr)->OSptr == NULL) return RDIError_OutOfStore;
91b725ae77Skettenis for (i=0; i<UNIQUETEMPS; i++) (*stateptr)->OSptr->TempNames[i]=NULL;
92b725ae77Skettenis for (i=0; i<HSYS_FOPEN_MAX; i++) {
93b725ae77Skettenis (*stateptr)->OSptr->FileTable[i]=NULL;
94b725ae77Skettenis (*stateptr)->OSptr->FileFlags[i]=0;
95b725ae77Skettenis }
96b725ae77Skettenis (*stateptr)->CommandLine=cmdline;
97b725ae77Skettenis
98b725ae77Skettenis return Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleMessageFPtr,
99b725ae77Skettenis *stateptr);
100b725ae77Skettenis }
101b725ae77Skettenis
102b725ae77Skettenis /* Shut down the Clib support, this will probably never get called though */
HostSysExit(hsys_state * stateptr)103b725ae77Skettenis int HostSysExit(hsys_state *stateptr)
104b725ae77Skettenis {
105b725ae77Skettenis free(stateptr->OSptr);
106b725ae77Skettenis free(stateptr);
107b725ae77Skettenis return RDIError_NoError;
108b725ae77Skettenis }
109b725ae77Skettenis
110b725ae77Skettenis #ifdef DEBUG
DebugCheckNullTermString(char * prefix,bool nl,unsigned int len,unsigned char * strp)111b725ae77Skettenis static void DebugCheckNullTermString(char *prefix, bool nl,
112b725ae77Skettenis unsigned int len, unsigned char *strp)
113b725ae77Skettenis {
114b725ae77Skettenis printf("%s: %d: ", prefix, len);
115b725ae77Skettenis if (strp[len]=='\0')
116b725ae77Skettenis printf("\"%s\"", strp);
117b725ae77Skettenis else
118b725ae77Skettenis printf("NOT NULL TERMINATED");
119b725ae77Skettenis if (nl)
120b725ae77Skettenis printf("\n");
121b725ae77Skettenis else
122b725ae77Skettenis {
123b725ae77Skettenis printf(" ");
124b725ae77Skettenis fflush(stdout);
125b725ae77Skettenis }
126b725ae77Skettenis }
127b725ae77Skettenis
128b725ae77Skettenis #ifdef NEED_SYSERRLIST
129b725ae77Skettenis extern int sys_nerr;
130b725ae77Skettenis extern char *sys_errlist[];
131b725ae77Skettenis #endif
132b725ae77Skettenis
DebugStrError(int last_errno)133b725ae77Skettenis static char *DebugStrError(int last_errno)
134b725ae77Skettenis {
135b725ae77Skettenis if (last_errno < sys_nerr)
136b725ae77Skettenis return sys_errlist[last_errno];
137b725ae77Skettenis else
138b725ae77Skettenis return "NO MSG (errno>sys_nerr)";
139b725ae77Skettenis }
140b725ae77Skettenis
DebugCheckErr(char * prefix,bool nl,int err,int last_errno)141b725ae77Skettenis static void DebugCheckErr(char *prefix, bool nl, int err, int last_errno)
142b725ae77Skettenis {
143b725ae77Skettenis printf("\t%s: returned ", prefix);
144b725ae77Skettenis if (err == 0)
145b725ae77Skettenis printf("okay");
146b725ae77Skettenis else
147b725ae77Skettenis printf("%d, errno = %d \"%s\"", err, last_errno,
148b725ae77Skettenis DebugStrError(last_errno));
149b725ae77Skettenis if (nl)
150b725ae77Skettenis printf("\n");
151b725ae77Skettenis else
152b725ae77Skettenis {
153b725ae77Skettenis printf(" ");
154b725ae77Skettenis fflush(stdout);
155b725ae77Skettenis }
156b725ae77Skettenis }
157b725ae77Skettenis
DebugCheckNonNull(char * prefix,bool nl,void * handle,int last_errno)158b725ae77Skettenis static void DebugCheckNonNull(char *prefix, bool nl,
159b725ae77Skettenis void *handle, int last_errno)
160b725ae77Skettenis {
161b725ae77Skettenis printf("\t%s: returned ", prefix);
162b725ae77Skettenis if (handle != NULL)
163b725ae77Skettenis printf("okay [%08x]", (unsigned int)handle);
164b725ae77Skettenis else
165b725ae77Skettenis printf("NULL, errno = %d \"%s\"", last_errno,
166b725ae77Skettenis DebugStrError(last_errno));
167b725ae77Skettenis if (nl)
168b725ae77Skettenis printf("\n");
169b725ae77Skettenis else
170b725ae77Skettenis {
171b725ae77Skettenis printf(" ");
172b725ae77Skettenis fflush(stdout);
173b725ae77Skettenis }
174b725ae77Skettenis }
175b725ae77Skettenis
176b725ae77Skettenis #define DebugPrintF(c) printf c;
177b725ae77Skettenis
178b725ae77Skettenis #else
179b725ae77Skettenis
180b725ae77Skettenis #define DebugCheckNullTermString(p, n, l, s) ((void)(0))
181b725ae77Skettenis #define DebugCheckErr(p, n, e, l) ((void)(0))
182b725ae77Skettenis #define DebugCheckNonNull(p, n, h, l) ((void)(0))
183b725ae77Skettenis #define DebugPrintF(c) ((void)(0))
184b725ae77Skettenis
185b725ae77Skettenis #endif /* ifdef DEBUG ... else */
186b725ae77Skettenis
hsysGetRealFileHandle(hsys_state * stateptr,int fh,char * flags)187b725ae77Skettenis static FILE *hsysGetRealFileHandle(hsys_state *stateptr, int fh, char *flags)
188b725ae77Skettenis {
189b725ae77Skettenis FILE *file_p = NULL;
190b725ae77Skettenis
191b725ae77Skettenis if (fh < 0 || fh >= HSYS_FOPEN_MAX)
192b725ae77Skettenis {
193b725ae77Skettenis stateptr->last_errno = EBADF;
194b725ae77Skettenis DebugPrintF(("\tfh %d out-of-bounds!\n", fh));
195b725ae77Skettenis return NULL;
196b725ae77Skettenis }
197b725ae77Skettenis else
198b725ae77Skettenis {
199b725ae77Skettenis file_p = stateptr->OSptr->FileTable[fh];
200b725ae77Skettenis if (file_p != NULL) {
201b725ae77Skettenis if (flags != NULL)
202b725ae77Skettenis *flags = stateptr->OSptr->FileFlags[fh];
203b725ae77Skettenis }
204b725ae77Skettenis else {
205b725ae77Skettenis stateptr->last_errno = EBADF;
206b725ae77Skettenis DebugPrintF(("\tFileTable[%d] is NULL\n", fh));
207b725ae77Skettenis }
208b725ae77Skettenis
209b725ae77Skettenis return file_p;
210b725ae77Skettenis }
211b725ae77Skettenis }
212b725ae77Skettenis
HandleSysMessage(Packet * packet,hsys_state * stateptr)213b725ae77Skettenis int HandleSysMessage(Packet *packet, hsys_state *stateptr)
214b725ae77Skettenis {
215b725ae77Skettenis unsigned int reason_code, mode, len, c, nbytes, nbtotal, nbtogo = 0;
216b725ae77Skettenis long posn, fl;
217b725ae77Skettenis char character;
218b725ae77Skettenis int err;
219b725ae77Skettenis
220b725ae77Skettenis /* Note: We must not free the buffer passed in as the callback handler */
221b725ae77Skettenis /* expects to do this. Freeing any other buffers we have malloced */
222b725ae77Skettenis /* ourselves is acceptable */
223b725ae77Skettenis
224b725ae77Skettenis unsigned char *buffp = ((unsigned char *)BUFFERDATA(packet->pk_buffer))+16;
225b725ae77Skettenis /* buffp points to the parameters*/
226b725ae77Skettenis /* the invidual messages, excluding*/
227b725ae77Skettenis /* standard SYS fields (debugID, */
228b725ae77Skettenis /* osinfo and reasoncode) */
229b725ae77Skettenis unsigned char *buffhead = (unsigned char *)(packet->pk_buffer);
230b725ae77Skettenis
231b725ae77Skettenis int DebugID, OSInfo1, OSInfo2, count;
232b725ae77Skettenis
233b725ae77Skettenis const char* fmode[] = {"r","rb","r+","r+b",
234b725ae77Skettenis "w","wb","w+","w+b",
235b725ae77Skettenis "a","ab","a+","a+b",
236b725ae77Skettenis "r","r","r","r"} /* last 4 are illegal */ ;
237b725ae77Skettenis
238b725ae77Skettenis FILEHANDLE fh; /* fh is used as an index to the real file handle
239b725ae77Skettenis * in OSptr */
240b725ae77Skettenis FILE *fhreal;
241b725ae77Skettenis unpack_message(BUFFERDATA(buffhead), "%w%w%w%w", &reason_code,
242b725ae77Skettenis &DebugID, &OSInfo1, &OSInfo2);
243b725ae77Skettenis /* Extract reason code from buffer. */
244b725ae77Skettenis reason_code &= 0xFFFF; /* Strip away direction bit, OSInfo and */
245b725ae77Skettenis /* DebugInfo fields. Will want to do some */
246b725ae77Skettenis /* sort of validation on this later. */
247b725ae77Skettenis
248b725ae77Skettenis switch(reason_code)
249b725ae77Skettenis {
250b725ae77Skettenis
251b725ae77Skettenis case CL_WriteC: /* Write a character to the terminal. */
252b725ae77Skettenis /* byte data -> word status */
253b725ae77Skettenis {
254b725ae77Skettenis #ifdef DEBUG
255b725ae77Skettenis int c = (int)(*buffp);
256b725ae77Skettenis printf("CL_WriteC: [%02x]>%c<", c, isprint(c) ? c : '.');
257b725ae77Skettenis #endif
258b725ae77Skettenis stateptr->hostif->writec(stateptr->hostif->hostosarg, (int)(*buffp));
259b725ae77Skettenis DevSW_FreePacket(packet);
260b725ae77Skettenis return msgsend(CI_CLIB,"%w%w%w%w%w", CL_WriteC|HtoT,
261b725ae77Skettenis DebugID, OSInfo1, OSInfo2, NoError);
262b725ae77Skettenis }
263b725ae77Skettenis
264b725ae77Skettenis case CL_Write0: /* Write a null terminated string to the terminal. */
265b725ae77Skettenis {
266b725ae77Skettenis unpack_message(buffp, "%w", &len);
267b725ae77Skettenis DebugCheckNullTermString("CL_Write0", TRUE, len, buffp+4);
268b725ae77Skettenis stateptr->hostif->write(stateptr->hostif->hostosarg,
269b725ae77Skettenis (char *) buffp+4, len);
270b725ae77Skettenis DevSW_FreePacket(packet);
271b725ae77Skettenis return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Write0|HtoT, DebugID,
272b725ae77Skettenis OSInfo1, OSInfo2, NoError);
273b725ae77Skettenis }
274b725ae77Skettenis
275b725ae77Skettenis case CL_ReadC: /* Read a byte from the terminal */
276b725ae77Skettenis {
277b725ae77Skettenis DebugPrintF(("CL_ReadC: "));
278b725ae77Skettenis DevSW_FreePacket(packet);
279b725ae77Skettenis
280b725ae77Skettenis character = stateptr->hostif->readc(stateptr->hostif->hostosarg);
281b725ae77Skettenis DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character,
282b725ae77Skettenis isprint(character) ? character : '.'));
283b725ae77Skettenis
284b725ae77Skettenis return msgsend(CI_CLIB, "%w%w%w%w%w%b", CL_ReadC|HtoT,
285b725ae77Skettenis DebugID, OSInfo1, OSInfo2, NoError, character);
286b725ae77Skettenis }
287b725ae77Skettenis
288b725ae77Skettenis case CL_System: /* Pass NULL terminated string to the hosts command
289b725ae77Skettenis * interpreter. As it is nULL terminated we dont need
290b725ae77Skettenis * the length
291b725ae77Skettenis */
292b725ae77Skettenis {
293b725ae77Skettenis unpack_message(buffp, "%w", &len);
294b725ae77Skettenis DebugCheckNullTermString("CL_System", TRUE, len, buffp+4);
295b725ae77Skettenis
296b725ae77Skettenis err = system((char *)buffp+4); /* Use the string in the buffer */
297b725ae77Skettenis stateptr->last_errno = errno;
298b725ae77Skettenis DebugCheckErr("system", TRUE, err, stateptr->last_errno);
299b725ae77Skettenis
300b725ae77Skettenis err = msgsend(CI_CLIB, "%w%w%w%w%w%w", CL_System|HtoT,
301b725ae77Skettenis DebugID, OSInfo1, OSInfo2, NoError, err);
302b725ae77Skettenis DevSW_FreePacket(packet);
303b725ae77Skettenis return err;
304b725ae77Skettenis }
305b725ae77Skettenis
306b725ae77Skettenis case CL_GetCmdLine: /* Returns the command line used to call the program */
307b725ae77Skettenis {
308b725ae77Skettenis /* Note: we reuse the packet here, this may not always be desirable */
309b725ae77Skettenis /* /* TODO: Use long buffers if possible */
310b725ae77Skettenis DebugPrintF(("CL_GetCmdLine: \"%s\"\n", *(stateptr->CommandLine)));
311b725ae77Skettenis
312b725ae77Skettenis if (buffhead!=NULL) {
313b725ae77Skettenis len = strlen(*(stateptr->CommandLine));
314b725ae77Skettenis if (len > Armsd_BufferSize-24) len = Armsd_BufferSize-24;
315b725ae77Skettenis packet->pk_length = len + msgbuild(BUFFERDATA(buffhead),
316b725ae77Skettenis "%w%w%w%w%w%w", CL_GetCmdLine|HtoT,
317b725ae77Skettenis DebugID, OSInfo1, OSInfo2,
318b725ae77Skettenis NoError, len);
319b725ae77Skettenis strncpy((char *) BUFFERDATA(buffhead)+24,*(stateptr->CommandLine),
320b725ae77Skettenis len);
321b725ae77Skettenis
322b725ae77Skettenis Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
323b725ae77Skettenis return 0;
324b725ae77Skettenis }
325b725ae77Skettenis else return -1;
326b725ae77Skettenis }
327b725ae77Skettenis
328b725ae77Skettenis case CL_Clock: /* Return the number of centiseconds since the support */
329b725ae77Skettenis /* code started executing */
330b725ae77Skettenis {
331b725ae77Skettenis time_t retTime = time(NULL);
332b725ae77Skettenis if (retTime == (time_t)-1)
333b725ae77Skettenis stateptr->last_errno = errno;
334b725ae77Skettenis else
335b725ae77Skettenis retTime *=100;
336b725ae77Skettenis
337b725ae77Skettenis DebugPrintF(("CL_Clock: %lu\n", retTime));
338b725ae77Skettenis DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
339b725ae77Skettenis stateptr->last_errno);
340b725ae77Skettenis
341b725ae77Skettenis DevSW_FreePacket(packet);
342b725ae77Skettenis return msgsend(CI_CLIB, "%w%w%w%w%w%w",CL_Clock|HtoT,
343b725ae77Skettenis DebugID, OSInfo1, OSInfo2, NoError, retTime);
344b725ae77Skettenis }
345b725ae77Skettenis
346b725ae77Skettenis case CL_Time: /* return time, in seconds since the start of 1970 */
347b725ae77Skettenis {
348b725ae77Skettenis time_t retTime = time(NULL);
349b725ae77Skettenis if (retTime == (time_t)-1)
350b725ae77Skettenis stateptr->last_errno = errno;
351b725ae77Skettenis
352b725ae77Skettenis DebugPrintF(("CL_Time: %lu\n", retTime));
353b725ae77Skettenis DebugCheckErr("time", TRUE, (retTime == (time_t)-1),
354b725ae77Skettenis stateptr->last_errno);
355b725ae77Skettenis
356b725ae77Skettenis DevSW_FreePacket(packet);
357b725ae77Skettenis return msgsend(CI_CLIB,"%w%w%w%w%w%w",CL_Time|HtoT,
358b725ae77Skettenis DebugID, OSInfo1, OSInfo2, NoError, retTime);
359b725ae77Skettenis }
360b725ae77Skettenis
361b725ae77Skettenis case CL_Remove: /* delete named in the null terminated string */
362b725ae77Skettenis {
363b725ae77Skettenis /* Removing an open file will cause problems but once again
364b725ae77Skettenis * its not our problem, likely result is a tangled FileTable */
365b725ae77Skettenis /* As the filename is passed with a null terminator we can use it
366b725ae77Skettenis * straight out of the buffer without copying it.*/
367b725ae77Skettenis
368b725ae77Skettenis unpack_message(buffp, "%w", &len);
369b725ae77Skettenis DebugCheckNullTermString("CL_Remove", TRUE, len, buffp+4);
370b725ae77Skettenis
371b725ae77Skettenis err=remove((char *)buffp+4);
372b725ae77Skettenis stateptr->last_errno = errno;
373b725ae77Skettenis DevSW_FreePacket(packet);
374b725ae77Skettenis DebugCheckErr("remove", TRUE, err, stateptr->last_errno);
375b725ae77Skettenis
376b725ae77Skettenis return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Remove|HtoT,
377b725ae77Skettenis DebugID, OSInfo1, OSInfo2, err?-1:NoError);
378b725ae77Skettenis }
379b725ae77Skettenis
380b725ae77Skettenis case CL_Rename: /* rename file */
381b725ae77Skettenis {
382b725ae77Skettenis /* Rename(word nbytes, bytes oname, word nbytes, bytes nname)
383b725ae77Skettenis * return(byte status)
384b725ae77Skettenis */
385b725ae77Skettenis unsigned int len2;
386b725ae77Skettenis
387b725ae77Skettenis unpack_message(buffp, "%w", &len);
388b725ae77Skettenis DebugCheckNullTermString("CL_Rename", FALSE, len, buffp+4);
389b725ae77Skettenis unpack_message(buffp+5+len, "%w", &len2);
390b725ae77Skettenis DebugCheckNullTermString("to", TRUE, len2, buffp+9+len);
391b725ae77Skettenis
392b725ae77Skettenis /* Both names are passed with null terminators so we can use them
393b725ae77Skettenis * directly from the buffer. */
394b725ae77Skettenis err = rename((char *)buffp+4, (char *)buffp+9+len);
395b725ae77Skettenis stateptr->last_errno = errno;
396b725ae77Skettenis DebugCheckErr("rename", TRUE, err, stateptr->last_errno);
397b725ae77Skettenis DevSW_FreePacket(packet);
398b725ae77Skettenis
399b725ae77Skettenis return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Rename|HtoT,
400b725ae77Skettenis DebugID, OSInfo1, OSInfo2, (err==0)? NoError : -1);
401b725ae77Skettenis }
402b725ae77Skettenis
403b725ae77Skettenis case CL_Open: /* open the file */
404b725ae77Skettenis {
405b725ae77Skettenis /* Open(word nbytes, bytes name, byte mode)
406b725ae77Skettenis * return(word handle)
407b725ae77Skettenis */
408b725ae77Skettenis unpack_message(buffp, "%w", &len);
409b725ae77Skettenis /* get the open mode */
410b725ae77Skettenis unpack_message((buffp)+4+len+1, "%w", &mode);
411b725ae77Skettenis DebugCheckNullTermString("CL_Open", FALSE, len, buffp+4);
412b725ae77Skettenis DebugPrintF(("mode: %d\n", mode));
413b725ae77Skettenis
414b725ae77Skettenis /* do some checking on the file first? */
415b725ae77Skettenis /* check if its a tty */
416b725ae77Skettenis if (strcmp((char *)buffp+4, ":tt")==0 && (mode==0||mode==1)) {
417b725ae77Skettenis /* opening tty "r" */
418b725ae77Skettenis fhreal = stdin;
419b725ae77Skettenis stateptr->last_errno = errno;
420b725ae77Skettenis DebugPrintF(("\tstdin "));
421b725ae77Skettenis }
422b725ae77Skettenis else if (strcmp((char *)buffp+4, ":tt")== 0 && (mode==4||mode==5)) {
423b725ae77Skettenis /* opening tty "w" */
424b725ae77Skettenis fhreal = stdout;
425b725ae77Skettenis stateptr->last_errno = errno;
426b725ae77Skettenis DebugPrintF(("\tstdout "));
427b725ae77Skettenis }
428b725ae77Skettenis else
429b725ae77Skettenis {
430b725ae77Skettenis fhreal = fopen((char *)buffp+4, fmode[mode&0xFF]);
431b725ae77Skettenis stateptr->last_errno = errno;
432b725ae77Skettenis DebugCheckNonNull("fopen", FALSE, fhreal, stateptr->last_errno);
433b725ae77Skettenis }
434b725ae77Skettenis DevSW_FreePacket(packet);
435b725ae77Skettenis
436b725ae77Skettenis c = NONHANDLE;
437b725ae77Skettenis if (fhreal != NULL) {
438b725ae77Skettenis /* update filetable */
439b725ae77Skettenis for (c=3; c < HSYS_FOPEN_MAX; c++) {
440b725ae77Skettenis /* allow for stdin, stdout, stderr (!!! WHY? MJG) */
441b725ae77Skettenis if (stateptr->OSptr->FileTable[c] == NULL) {
442b725ae77Skettenis stateptr->OSptr->FileTable[c]= fhreal;
443b725ae77Skettenis stateptr->OSptr->FileFlags[c]= mode & 1;
444b725ae77Skettenis DebugPrintF(("fh: %d\n", c));
445b725ae77Skettenis break;
446b725ae77Skettenis }
447b725ae77Skettenis else if (c == HSYS_FOPEN_MAX) {
448b725ae77Skettenis /* no filehandles free */
449b725ae77Skettenis DebugPrintF(("no free fh: %d\n", c));
450b725ae77Skettenis stateptr->last_errno = EMFILE;
451b725ae77Skettenis }
452b725ae77Skettenis }
453b725ae77Skettenis }
454b725ae77Skettenis else {
455b725ae77Skettenis /* c = NULL;*/
456b725ae77Skettenis DebugPrintF(("error fh: %d\n", c));
457b725ae77Skettenis }
458b725ae77Skettenis (void) msgsend(CI_CLIB, "%w%w%w%w%w", CL_Open|HtoT,
459b725ae77Skettenis DebugID, OSInfo1, OSInfo2, c);
460b725ae77Skettenis return 0;
461b725ae77Skettenis }
462b725ae77Skettenis
463b725ae77Skettenis case CL_Close: /* close the file pointed to by the filehandle */
464b725ae77Skettenis {
465b725ae77Skettenis unpack_message(buffp, "%w", &fh);
466b725ae77Skettenis DebugPrintF(("CL_Close: fh %d\n", fh));
467b725ae77Skettenis DevSW_FreePacket(packet);
468b725ae77Skettenis
469b725ae77Skettenis fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
470b725ae77Skettenis if (fhreal == NULL)
471b725ae77Skettenis err = -1;
472b725ae77Skettenis else {
473b725ae77Skettenis if (fhreal == stdin || fhreal == stdout || fhreal == stderr) {
474b725ae77Skettenis stateptr->last_errno = errno;
475b725ae77Skettenis DebugPrintF(("\tskipping close of std*\n"));
476b725ae77Skettenis err = 0;
477b725ae77Skettenis }
478b725ae77Skettenis else {
479b725ae77Skettenis err = fclose(fhreal);
480b725ae77Skettenis if (err == 0)
481b725ae77Skettenis stateptr->OSptr->FileTable[fh]=NULL;
482b725ae77Skettenis stateptr->last_errno = errno;
483b725ae77Skettenis DebugCheckErr("fclose", TRUE, err, stateptr->last_errno);
484b725ae77Skettenis }
485b725ae77Skettenis }
486b725ae77Skettenis return msgsend(CI_CLIB,"%w%w%w%w%w", CL_Close|HtoT, DebugID,
487b725ae77Skettenis OSInfo1, OSInfo2, err);
488b725ae77Skettenis }
489b725ae77Skettenis
490b725ae77Skettenis case CL_Write:
491b725ae77Skettenis {
492b725ae77Skettenis /* Write(word handle, word nbtotal, word nbytes, bytes data)
493b725ae77Skettenis * return(word nbytes)
494b725ae77Skettenis * WriteX(word nbytes, bytes data)
495b725ae77Skettenis * return(word nbytes)
496b725ae77Skettenis */
497b725ae77Skettenis unsigned char *rwdata = NULL, *rwhead = NULL;
498b725ae77Skettenis unsigned char *write_source = NULL;
499b725ae77Skettenis char flags;
500b725ae77Skettenis FILE *fhreal;
501b725ae77Skettenis unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */
502b725ae77Skettenis
503b725ae77Skettenis err = -1; /* err == 0 is fwrite() error indication */
504b725ae77Skettenis unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes);
505b725ae77Skettenis DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n",
506b725ae77Skettenis fh, nbtotal, nbytes));
507b725ae77Skettenis
508b725ae77Skettenis fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
509b725ae77Skettenis nbtogo = nbtotal;
510b725ae77Skettenis
511b725ae77Skettenis /* deal with the file handle */
512b725ae77Skettenis if (fhreal == NULL)
513b725ae77Skettenis err = 0;
514b725ae77Skettenis else {
515b725ae77Skettenis if (flags & READOP)
516b725ae77Skettenis fseek(fhreal,0,SEEK_CUR);
517b725ae77Skettenis stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
518b725ae77Skettenis
519b725ae77Skettenis nbtogo -= nbytes;
520b725ae77Skettenis
521b725ae77Skettenis if (nbtogo > 0) {
522b725ae77Skettenis write_source = rwdata = rwhead = (unsigned char *)malloc(nbtotal);
523b725ae77Skettenis if (rwhead == NULL) {
524b725ae77Skettenis fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
525b725ae77Skettenis __LINE__, __FILE__);
526b725ae77Skettenis return -1;
527b725ae77Skettenis }
528b725ae77Skettenis memcpy(rwdata, buffp+12, nbytes);
529b725ae77Skettenis rwdata += nbytes;
530b725ae77Skettenis }
531b725ae77Skettenis else
532b725ae77Skettenis write_source = buffp+12;
533b725ae77Skettenis }
534b725ae77Skettenis
535b725ae77Skettenis do {
536b725ae77Skettenis /* at least once!! */
537b725ae77Skettenis
538b725ae77Skettenis if (nbtogo == 0 && err != 0) {
539b725ae77Skettenis /* Do the actual write! */
540b725ae77Skettenis if (fhreal == stdout || fhreal == stderr) {
541b725ae77Skettenis stateptr->hostif->write(stateptr->hostif->hostosarg,
542b725ae77Skettenis (char *)write_source, nbtotal);
543b725ae77Skettenis }
544b725ae77Skettenis else
545b725ae77Skettenis err = fwrite(write_source, 1, nbtotal, fhreal);
546b725ae77Skettenis stateptr->last_errno = errno;
547b725ae77Skettenis DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno);
548b725ae77Skettenis }
549b725ae77Skettenis
550b725ae77Skettenis DevSW_FreePacket(packet);
551b725ae77Skettenis if (msgsend(CI_CLIB,"%w%w%w%w%w%w", ack_reason|HtoT,
552b725ae77Skettenis DebugID, OSInfo1, OSInfo2, (err == 0), nbtogo))
553b725ae77Skettenis {
554b725ae77Skettenis fprintf(stderr, "COULD NOT REPLY at line %d in %s\n",
555b725ae77Skettenis __LINE__, __FILE__);
556b725ae77Skettenis if (rwhead != NULL)
557b725ae77Skettenis free(rwhead);
558b725ae77Skettenis return -1;
559b725ae77Skettenis }
560b725ae77Skettenis
561b725ae77Skettenis if (nbtogo == 0 || err == 0) {
562b725ae77Skettenis DebugPrintF(("\twrite complete - returning\n"));
563b725ae77Skettenis if (rwhead != NULL)
564b725ae77Skettenis free(rwhead);
565b725ae77Skettenis return 0;
566b725ae77Skettenis }
567b725ae77Skettenis else {
568b725ae77Skettenis /* await extension */
569b725ae77Skettenis ack_reason = CL_WriteX;
570b725ae77Skettenis
571b725ae77Skettenis packet = DevSW_AllocatePacket(Armsd_BufferSize);
572b725ae77Skettenis if (packet == NULL)
573b725ae77Skettenis {
574b725ae77Skettenis fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
575b725ae77Skettenis __LINE__, __FILE__);
576b725ae77Skettenis if (rwhead != NULL)
577b725ae77Skettenis free(rwhead);
578b725ae77Skettenis return -1;
579b725ae77Skettenis }
580b725ae77Skettenis Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
581b725ae77Skettenis Adp_ChannelRead(CI_CLIB, &packet);
582b725ae77Skettenis Adp_ChannelRegisterRead(CI_CLIB,
583b725ae77Skettenis (ChannelCallback)HandleSysMessage,
584b725ae77Skettenis stateptr);
585b725ae77Skettenis
586b725ae77Skettenis buffhead = packet->pk_buffer;
587b725ae77Skettenis unpack_message(BUFFERDATA(buffhead), "%w%w%w%w%w", &reason_code,
588b725ae77Skettenis &DebugID, &OSInfo1, &OSInfo2, &nbytes);
589b725ae77Skettenis if (reason_code != (CL_WriteX|TtoH)) {
590b725ae77Skettenis DevSW_FreePacket(packet);
591b725ae77Skettenis free(rwhead);
592b725ae77Skettenis fprintf(stderr, "EXPECTING CL_WriteX GOT %u at line %d in %s\n",
593b725ae77Skettenis reason_code, __LINE__, __FILE__);
594b725ae77Skettenis return -1;
595b725ae77Skettenis }
596b725ae77Skettenis
597b725ae77Skettenis DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes));
598b725ae77Skettenis memcpy(rwdata, BUFFERDATA(buffhead)+20, nbytes);
599b725ae77Skettenis rwdata += nbytes;
600b725ae77Skettenis nbtogo -= nbytes;
601b725ae77Skettenis }
602b725ae77Skettenis
603b725ae77Skettenis } while (TRUE); /* will return when done */
604b725ae77Skettenis }
605b725ae77Skettenis
606b725ae77Skettenis case CL_WriteX: /*
607b725ae77Skettenis * NOTE: if we've got here something has gone wrong
608b725ae77Skettenis * CL_WriteX's should all be picked up within the
609b725ae77Skettenis * CL_Write loop, probably best to return an error here
610b725ae77Skettenis * do this for the moment just so we do actually return
611b725ae77Skettenis */
612b725ae77Skettenis fprintf(stderr, "ERROR: unexpected CL_WriteX message received\n");
613b725ae77Skettenis return -1;
614b725ae77Skettenis
615b725ae77Skettenis case CL_Read:
616b725ae77Skettenis {
617b725ae77Skettenis /* Read(word handle, word nbtotal)
618b725ae77Skettenis * return(word nbytes, word nbmore, bytes data)
619b725ae77Skettenis */
620b725ae77Skettenis /* ReadX()
621b725ae77Skettenis * return(word nbytes, word nbmore, bytes data) */
622b725ae77Skettenis unsigned char *rwdata, *rwhead;
623b725ae77Skettenis int gotlen;
624b725ae77Skettenis unsigned int max_data_in_buffer=Armsd_BufferSize-28;
625b725ae77Skettenis char flags;
626b725ae77Skettenis FILE *fhreal;
627b725ae77Skettenis unsigned int nbleft = 0, reason = CL_Read;
628b725ae77Skettenis
629b725ae77Skettenis err = NoError;
630b725ae77Skettenis
631b725ae77Skettenis unpack_message(buffp, "%w%w", &fh, &nbtotal);
632b725ae77Skettenis DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh, nbtotal));
633b725ae77Skettenis
634b725ae77Skettenis rwdata = rwhead = (unsigned char *)malloc(nbtotal);
635b725ae77Skettenis if (rwdata == NULL) {
636b725ae77Skettenis fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
637b725ae77Skettenis __LINE__, __FILE__);
638b725ae77Skettenis DevSW_FreePacket(packet);
639b725ae77Skettenis return -1;
640b725ae77Skettenis }
641b725ae77Skettenis
642b725ae77Skettenis /* perform the actual read */
643b725ae77Skettenis fhreal = hsysGetRealFileHandle(stateptr, fh, &flags);
644b725ae77Skettenis if (fhreal == NULL)
645b725ae77Skettenis {
646b725ae77Skettenis /* bad file handle */
647b725ae77Skettenis err = -1;
648b725ae77Skettenis nbytes = 0;
649b725ae77Skettenis gotlen = 0;
650b725ae77Skettenis }
651b725ae77Skettenis else
652b725ae77Skettenis {
653b725ae77Skettenis if (flags & WRITEOP)
654b725ae77Skettenis fseek(fhreal,0,SEEK_CUR);
655b725ae77Skettenis stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP;
656b725ae77Skettenis if (isatty_(fhreal)) {
657b725ae77Skettenis /* reading from a tty, so do some nasty stuff, reading into rwdata */
658b725ae77Skettenis if (angel_hostif->gets(stateptr->hostif->hostosarg, (char *)rwdata,
659b725ae77Skettenis nbtotal) != 0)
660b725ae77Skettenis gotlen = strlen((char *)rwdata);
661b725ae77Skettenis else
662b725ae77Skettenis gotlen = 0;
663b725ae77Skettenis stateptr->last_errno = errno;
664b725ae77Skettenis DebugPrintF(("ttyread %d\n", gotlen));
665b725ae77Skettenis }
666b725ae77Skettenis else {
667b725ae77Skettenis /* not a tty, reading from a real file */
668b725ae77Skettenis gotlen = fread(rwdata, 1, nbtotal, fhreal);
669b725ae77Skettenis stateptr->last_errno = errno;
670b725ae77Skettenis DebugCheckErr("fread", FALSE, (gotlen == 0), stateptr->last_errno);
671b725ae77Skettenis DebugPrintF(("(%d)\n", gotlen));
672b725ae77Skettenis }
673b725ae77Skettenis }
674b725ae77Skettenis
675b725ae77Skettenis nbtogo = gotlen;
676b725ae77Skettenis
677b725ae77Skettenis do {
678b725ae77Skettenis /* at least once */
679b725ae77Skettenis
680b725ae77Skettenis if ((unsigned int) nbtogo <= max_data_in_buffer)
681b725ae77Skettenis nbytes = nbtogo;
682b725ae77Skettenis else
683b725ae77Skettenis nbytes = max_data_in_buffer;
684b725ae77Skettenis nbtogo -= nbytes;
685b725ae77Skettenis
686b725ae77Skettenis /* last ReadX needs subtle adjustment to returned nbtogo */
687b725ae77Skettenis if (nbtogo == 0 && err == NoError && reason == CL_ReadX)
688b725ae77Skettenis nbleft = nbtotal - gotlen;
689b725ae77Skettenis else
690b725ae77Skettenis nbleft = nbtogo;
691b725ae77Skettenis
692b725ae77Skettenis count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w%w",
693b725ae77Skettenis reason|HtoT, 0, ADP_HandleUnknown,
694b725ae77Skettenis ADP_HandleUnknown, err, nbytes, nbleft);
695b725ae77Skettenis
696b725ae77Skettenis if (err == NoError) {
697b725ae77Skettenis /* copy data into buffptr */
698b725ae77Skettenis memcpy(BUFFERDATA(buffhead)+28, rwdata, nbytes);
699b725ae77Skettenis rwdata += nbytes;
700b725ae77Skettenis count += nbytes;
701b725ae77Skettenis }
702b725ae77Skettenis
703b725ae77Skettenis DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n",
704b725ae77Skettenis err, nbytes, nbtogo));
705b725ae77Skettenis
706b725ae77Skettenis packet->pk_length = count;
707b725ae77Skettenis Adp_ChannelWrite(CI_CLIB, packet);
708b725ae77Skettenis
709b725ae77Skettenis if (nbtogo == 0 || err != NoError) {
710b725ae77Skettenis /* done */
711b725ae77Skettenis free(rwhead);
712b725ae77Skettenis return 0;
713b725ae77Skettenis }
714b725ae77Skettenis else {
715b725ae77Skettenis /* await extension */
716b725ae77Skettenis reason = CL_ReadX;
717b725ae77Skettenis
718b725ae77Skettenis packet = DevSW_AllocatePacket(Armsd_BufferSize);
719b725ae77Skettenis if (packet == NULL) {
720b725ae77Skettenis fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
721b725ae77Skettenis __LINE__, __FILE__);
722b725ae77Skettenis free(rwhead);
723b725ae77Skettenis return -1;
724b725ae77Skettenis }
725b725ae77Skettenis Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL);
726b725ae77Skettenis Adp_ChannelRead(CI_CLIB, &packet);
727b725ae77Skettenis Adp_ChannelRegisterRead(CI_CLIB,
728b725ae77Skettenis (ChannelCallback)HandleSysMessage,
729b725ae77Skettenis stateptr);
730b725ae77Skettenis buffhead = packet->pk_buffer;
731b725ae77Skettenis unpack_message(BUFFERDATA(buffhead),"%w", &reason_code);
732b725ae77Skettenis if (reason_code != (CL_ReadX|TtoH)) {
733b725ae77Skettenis fprintf(stderr, "EXPECTING CL_ReadX GOT %u at line %d in %s\n",
734b725ae77Skettenis reason_code, __LINE__, __FILE__);
735b725ae77Skettenis DevSW_FreePacket(packet);
736b725ae77Skettenis free(rwdata);
737b725ae77Skettenis return -1;
738b725ae77Skettenis }
739b725ae77Skettenis }
740b725ae77Skettenis
741b725ae77Skettenis } while (TRUE); /* will return above on error or when done */
742b725ae77Skettenis }
743b725ae77Skettenis
744b725ae77Skettenis case CL_ReadX: /* If we're here something has probably gone wrong */
745b725ae77Skettenis fprintf(stderr, "ERROR: Got unexpected CL_ReadX message\n");
746b725ae77Skettenis return -1;
747b725ae77Skettenis
748b725ae77Skettenis case CL_Seek:
749b725ae77Skettenis {
750b725ae77Skettenis unpack_message(buffp, "%w%w", &fh, &posn);
751b725ae77Skettenis DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh, posn));
752b725ae77Skettenis DevSW_FreePacket(packet);
753b725ae77Skettenis
754b725ae77Skettenis fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
755b725ae77Skettenis if (fhreal == NULL)
756b725ae77Skettenis err = -1;
757b725ae77Skettenis else {
758b725ae77Skettenis err = fseek(fhreal, posn, SEEK_SET);
759b725ae77Skettenis stateptr->last_errno = errno;
760b725ae77Skettenis DebugCheckErr("fseek", TRUE, err, stateptr->last_errno);
761b725ae77Skettenis }
762b725ae77Skettenis
763b725ae77Skettenis return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Seek|HtoT,
764b725ae77Skettenis DebugID, OSInfo1, OSInfo2, err);
765b725ae77Skettenis }
766b725ae77Skettenis
767b725ae77Skettenis case CL_Flen:
768b725ae77Skettenis {
769b725ae77Skettenis unpack_message(buffp, "%w", &fh);
770b725ae77Skettenis DebugPrintF(("CL_Flen: fh %d ", fh));
771b725ae77Skettenis DevSW_FreePacket(packet);
772b725ae77Skettenis
773b725ae77Skettenis fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
774b725ae77Skettenis if (fhreal == NULL)
775b725ae77Skettenis fl = -1;
776b725ae77Skettenis else {
777b725ae77Skettenis posn = ftell(fhreal);
778b725ae77Skettenis if (fseek(fhreal, 0L, SEEK_END) < 0) {
779b725ae77Skettenis fl=-1;
780b725ae77Skettenis }
781b725ae77Skettenis else {
782b725ae77Skettenis fl = ftell(fhreal);
783b725ae77Skettenis fseek(fhreal, posn, SEEK_SET);
784b725ae77Skettenis }
785b725ae77Skettenis stateptr->last_errno = errno;
786b725ae77Skettenis }
787b725ae77Skettenis DebugPrintF(("returning len %ld\n", fl));
788b725ae77Skettenis return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Flen|HtoT, DebugID, OSInfo1,
789b725ae77Skettenis OSInfo2, fl);
790b725ae77Skettenis }
791b725ae77Skettenis
792b725ae77Skettenis case CL_IsTTY:
793b725ae77Skettenis {
794b725ae77Skettenis int ttyOrNot;
795b725ae77Skettenis unpack_message(buffp, "%w", &fh);
796b725ae77Skettenis DebugPrintF(("CL_IsTTY: fh %d ", fh));
797b725ae77Skettenis DevSW_FreePacket(packet);
798b725ae77Skettenis
799b725ae77Skettenis fhreal = hsysGetRealFileHandle(stateptr, fh, NULL);
800b725ae77Skettenis if (fhreal == NULL)
801b725ae77Skettenis ttyOrNot = FALSE;
802b725ae77Skettenis else {
803b725ae77Skettenis ttyOrNot = isatty_(fhreal);
804b725ae77Skettenis stateptr->last_errno = errno;
805b725ae77Skettenis }
806b725ae77Skettenis DebugPrintF(("returning %s\n", ttyOrNot ? "tty (1)" : "not (0)"));
807b725ae77Skettenis
808b725ae77Skettenis return msgsend(CI_CLIB, "%w%w%w%w%w",CL_IsTTY|HtoT,
809b725ae77Skettenis DebugID, OSInfo1, OSInfo2, ttyOrNot);
810b725ae77Skettenis }
811b725ae77Skettenis
812b725ae77Skettenis case CL_TmpNam:
813b725ae77Skettenis {
814b725ae77Skettenis char *name;
815b725ae77Skettenis unsigned int tnamelen, TargetID;
816b725ae77Skettenis unpack_message(buffp, "%w%w", &tnamelen, &TargetID);
817b725ae77Skettenis DebugPrintF(("CL_TmpNam: tnamelen %d TargetID %d: ",
818b725ae77Skettenis tnamelen, TargetID));
819b725ae77Skettenis DevSW_FreePacket(packet);
820b725ae77Skettenis
821b725ae77Skettenis TargetID = TargetID & 0xFF;
822b725ae77Skettenis if (stateptr->OSptr->TempNames[TargetID] == NULL) {
823b725ae77Skettenis if ((stateptr->OSptr->TempNames[TargetID] =
824b725ae77Skettenis (char *)malloc(L_tmpnam)) == NULL)
825b725ae77Skettenis {
826b725ae77Skettenis fprintf(stderr, "OUT OF MEMORY at line %d in %s\n",
827b725ae77Skettenis __LINE__, __FILE__);
828b725ae77Skettenis return -1;
829b725ae77Skettenis }
830b725ae77Skettenis tmpnam(stateptr->OSptr->TempNames[TargetID]);
831b725ae77Skettenis }
832b725ae77Skettenis name = stateptr->OSptr->TempNames[TargetID];
833b725ae77Skettenis len = strlen(name) + 1;
834b725ae77Skettenis packet = DevSW_AllocatePacket(Armsd_BufferSize);
835b725ae77Skettenis if (packet == NULL)
836b725ae77Skettenis {
837b725ae77Skettenis fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n",
838b725ae77Skettenis __LINE__, __FILE__);
839b725ae77Skettenis return -1;
840b725ae77Skettenis }
841b725ae77Skettenis buffhead = packet->pk_buffer;
842b725ae77Skettenis if (len > tnamelen) {
843b725ae77Skettenis DebugPrintF(("TMPNAME TOO LONG!\n"));
844b725ae77Skettenis count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w",
845b725ae77Skettenis CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, -1);
846b725ae77Skettenis }
847b725ae77Skettenis else {
848b725ae77Skettenis DebugPrintF(("returning \"%s\"\n", name));
849b725ae77Skettenis count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_TmpNam|HtoT,
850b725ae77Skettenis DebugID, OSInfo1, OSInfo2, 0, len);
851b725ae77Skettenis strcpy((char *)BUFFERDATA(buffhead)+count, name);
852b725ae77Skettenis count +=len+1;
853b725ae77Skettenis }
854b725ae77Skettenis packet->pk_length = count;
855b725ae77Skettenis Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */
856b725ae77Skettenis return 0;
857b725ae77Skettenis }
858b725ae77Skettenis
859b725ae77Skettenis case CL_Unrecognised:
860b725ae77Skettenis DebugPrintF(("CL_Unrecognised!!\n"));
861b725ae77Skettenis return 0;
862b725ae77Skettenis
863b725ae77Skettenis default:
864b725ae77Skettenis fprintf(stderr, "UNRECOGNISED CL code %08x\n", reason_code);
865b725ae77Skettenis break;
866b725ae77Skettenis /* Need some sort of error handling here. */
867b725ae77Skettenis /* A call to CL_Unrecognised should suffice */
868b725ae77Skettenis }
869b725ae77Skettenis return -1; /* Stop a potential compiler warning */
870b725ae77Skettenis }
871b725ae77Skettenis
872b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
873b725ae77Skettenis
874b725ae77Skettenis #include <windows.h>
875b725ae77Skettenis
876b725ae77Skettenis extern HWND hwndParent;
877b725ae77Skettenis
panic(const char * format,...)878b725ae77Skettenis void panic(const char *format, ...)
879b725ae77Skettenis {
880b725ae77Skettenis char buf[2048];
881b725ae77Skettenis va_list args;
882b725ae77Skettenis
883b725ae77Skettenis Adp_CloseDevice();
884b725ae77Skettenis
885b725ae77Skettenis va_start(args, format);
886b725ae77Skettenis vsprintf(buf, format, args);
887b725ae77Skettenis
888b725ae77Skettenis MessageBox(hwndParent, (LPCTSTR)buf, (LPCTSTR)"Fatal Error:", MB_OK);
889b725ae77Skettenis
890b725ae77Skettenis /* SJ - Not the proper way to shutdown the app */
891b725ae77Skettenis exit(EXIT_FAILURE);
892b725ae77Skettenis
893b725ae77Skettenis /*
894b725ae77Skettenis if (hwndParent != NULL)
895b725ae77Skettenis SendMessage(hwndParent, WM_QUIT, 0, 0);
896b725ae77Skettenis */
897b725ae77Skettenis
898b725ae77Skettenis va_end(args);
899b725ae77Skettenis }
900b725ae77Skettenis
901b725ae77Skettenis #else
902b725ae77Skettenis
panic(const char * format,...)903b725ae77Skettenis void panic(const char *format, ...)
904b725ae77Skettenis {
905b725ae77Skettenis va_list args;
906b725ae77Skettenis
907b725ae77Skettenis va_start(args, format);
908b725ae77Skettenis fprintf(stderr, "Fatal error: ");
909b725ae77Skettenis vfprintf(stderr, format, args);
910b725ae77Skettenis fprintf(stderr,"\n");
911b725ae77Skettenis
912b725ae77Skettenis exit(EXIT_FAILURE);
913b725ae77Skettenis }
914b725ae77Skettenis
915b725ae77Skettenis #endif
916b725ae77Skettenis
917b725ae77Skettenis /* EOF hsys.c */
918