Fixed compatibility of output.
[AROS.git] / test / misc / hostcb.c
blob4d101525cd2253c588f8acbcf11686a67bed6ad1
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Tool to access host clipboard, when using a hosted version of AROS.
6 */
9 #include <dos/dos.h>
10 #include <libraries/iffparse.h>
11 #include <datatypes/textclass.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
14 #include <proto/iffparse.h>
15 #include <aros/debug.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
20 /****************************************************************************************/
22 #define ARG_TEMPLATE "TOSTDOUT=OUT/S,TOAROSCLIP=TOAROS/S,TOFILE=TO/K," \
23 "FROMAROSCLIP=FROMAROS/S,FROMSTRING=STRING/K," \
24 "FROMFILE=FROM/K,AROSCLIPUNIT=AROSUNIT/N/K,QUIET/S"
26 #define ARG_TOSTDOUT 0
27 #define ARG_TOAROSCLIP 1
28 #define ARG_TOFILE 2
29 #define ARG_FROMAROSCLIP 3
30 #define ARG_FROMSTRING 4
31 #define ARG_FROMFILE 5
32 #define ARG_AROSCLIPUNIT 6
33 #define ARG_QUIET 7
34 #define NUM_ARGS 8
36 #define CMD(msg) ((msg)->mn_Node.ln_Pri)
37 #define PARAM(msg) ((msg)->mn_Node.ln_Name)
38 #define RETVAL(msg) ((msg)->mn_Node.ln_Name)
39 #define SUCCESS(msg) ((msg)->mn_Node.ln_Pri)
41 /****************************************************************************************/
43 struct Library *IFFParseBase;
44 struct MsgPort *replyport;
45 struct Message msg;
46 struct RDArgs *myargs;
47 BPTR fh;
48 ULONG arosclipunit;
49 STRPTR filebuffer, hostbuffer;
50 IPTR args[NUM_ARGS];
51 UBYTE s[256];
53 /****************************************************************************************/
55 static void cleanup(char *msg, ULONG retcode)
57 if (msg && !args[ARG_QUIET])
59 fprintf(stderr, "hostcb: %s\n", msg);
62 if (fh) Close(fh);
63 FreeVec(hostbuffer);
64 FreeVec(filebuffer);
65 if (myargs) FreeArgs(myargs);
67 if (IFFParseBase) CloseLibrary(IFFParseBase);
68 if (replyport) DeleteMsgPort(replyport);
70 exit(retcode);
73 /****************************************************************************************/
75 static void noport(void)
77 cleanup("HOST_CLIPBOARD port not found!", RETURN_ERROR);
80 /****************************************************************************************/
82 static void cmdfailed(void)
84 cleanup("HOST_CLIPBOARD cmd failure!", RETURN_ERROR);
87 /****************************************************************************************/
89 static void init(void)
91 replyport = CreateMsgPort();
92 if (!replyport) cleanup("Out of memory", RETURN_ERROR);
94 msg.mn_ReplyPort = replyport;
96 IFFParseBase = OpenLibrary("iffparse.library", 36);
99 /****************************************************************************************/
101 static void getarguments(void)
103 if (!(myargs = ReadArgs(ARG_TEMPLATE, args, 0)))
105 Fault(IoErr(), 0, s, 255);
106 cleanup(s, RETURN_FAIL);
109 if (args[ARG_AROSCLIPUNIT]) arosclipunit = *(IPTR *)args[ARG_AROSCLIPUNIT];
112 /****************************************************************************************/
114 static BOOL sendclipboardmsg(struct Message *msg, char command, void *param)
116 struct MsgPort *port;
118 Forbid();
119 port = FindPort("HOST_CLIPBOARD");
120 if (port)
122 CMD(msg) = command;
123 PARAM(msg) = param;
125 PutMsg(port, msg);
127 Permit();
129 return port ? TRUE : FALSE;
132 /****************************************************************************************/
134 static void toarosclip(void)
136 struct IFFHandle *iff;
137 BOOL sent;
139 if (!IFFParseBase) cleanup("Failed to open iffparse.library!", RETURN_FAIL);
141 sent = sendclipboardmsg(&msg, 'R', NULL);
142 if (sent)
144 WaitPort(replyport);
145 GetMsg(replyport);
147 if (SUCCESS(&msg) && RETVAL(&msg))
149 BOOL ok = FALSE;
151 iff = AllocIFF();
152 if (iff)
154 if ((iff->iff_Stream = (IPTR)OpenClipboard(arosclipunit)))
156 InitIFFasClip(iff);
158 if (!OpenIFF(iff, IFFF_WRITE))
160 if (!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN))
162 if (!PushChunk(iff, 0, ID_CHRS, IFFSIZE_UNKNOWN))
164 ULONG len = strlen(RETVAL(&msg));
166 if (WriteChunkBytes(iff, RETVAL(&msg), len) == len)
168 ok = TRUE;
170 PopChunk(iff);
172 } /* if (!PushChunk(iff, 0, ID_CHRS, IFFSIZE_UNKNOWN)) */
174 PopChunk(iff);
176 } /* if (!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) */
178 CloseIFF(iff);
180 } /* if (!OpenIFF(iff, IFFF_WRITE)) */
182 CloseClipboard((struct ClipboardHandle*)iff->iff_Stream);
184 } /* if ((iff->iff_Stream = (IPTR)OpenClipboard(arosclipunit))) */
186 FreeIFF(iff);
188 } /* if (iff) */
190 FreeVec(RETVAL(&msg));
192 if (!ok) cleanup("Error writing to AROS clipboard!", RETURN_ERROR);
194 } /* if (SUCCESS(&msg) && RETVAL(&msg)) */
195 else
197 cmdfailed();
200 } /* if (sent) */
201 else
203 noport();
208 /****************************************************************************************/
210 static void fromarosclip(void)
212 struct IFFHandle *iff;
213 BOOL sent, ok = FALSE;
215 if (!IFFParseBase) cleanup("Failed to open iffparse.library!", RETURN_FAIL);
217 iff = AllocIFF();
218 if (iff)
220 if ((iff->iff_Stream = (IPTR)OpenClipboard(arosclipunit)))
222 InitIFFasClip(iff);
224 if (!OpenIFF(iff, IFFF_READ))
226 if (!StopChunk(iff, ID_FTXT, ID_CHRS))
228 ULONG filebuffer_size = 0;
230 for(;;)
232 struct ContextNode *cn;
233 LONG error;
235 error = ParseIFF(iff, IFFPARSE_SCAN);
236 if ((error != 0) && (error != IFFERR_EOC)) break;
238 cn = CurrentChunk(iff);
239 if (!cn)
241 kprintf(" [ZERO CONTEXTNODE]\n\n");
242 continue;
245 if ((cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS))
247 if (!filebuffer)
249 filebuffer = AllocVec(cn->cn_Size + 1, MEMF_ANY);
250 if (!filebuffer) break;
252 ok = TRUE;
254 else
256 STRPTR new_filebuffer;
258 new_filebuffer = AllocVec(filebuffer_size + cn->cn_Size + 1, MEMF_ANY);
259 if (!new_filebuffer)
261 ok = FALSE;
262 break;
265 CopyMem(filebuffer, new_filebuffer, filebuffer_size);
266 FreeVec(filebuffer);
267 filebuffer = new_filebuffer;
270 if (ReadChunkBytes(iff, filebuffer + filebuffer_size, cn->cn_Size) != cn->cn_Size)
272 ok = FALSE;
273 break;
276 filebuffer_size += cn->cn_Size;
277 filebuffer[filebuffer_size] = '\0';
279 } /* if ((cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS)) */
281 } /* for(;;) */
283 } /* if (!StopChunk(iff, ID_FTXT, ID_CHRS)) */
285 CloseIFF(iff);
287 } /* if (!OpenIFF(iff, IFFF_READ)) */
289 CloseClipboard((struct ClipboardHandle*)iff->iff_Stream);
291 } /* if ((iff->iff_Stream = (IPTR)OpenClipboard(arosclipunit))) */
292 FreeIFF(iff);
294 } /* if (iff) */
296 if (!ok)
298 cleanup("Error reading from AROS clipboard!", RETURN_ERROR);
301 sent = sendclipboardmsg(&msg, 'W', filebuffer);
302 if (sent)
304 WaitPort(replyport);
305 GetMsg(replyport);
307 if (SUCCESS(&msg))
309 FreeVec(filebuffer),
310 filebuffer = 0;
312 else
314 cmdfailed();
317 else
319 noport();
324 /****************************************************************************************/
326 static void tostdout(void)
328 BOOL sent;
330 sent = sendclipboardmsg(&msg, 'R', NULL);
331 if (sent)
333 WaitPort(replyport);
334 GetMsg(replyport);
336 if (SUCCESS(&msg) && RETVAL(&msg))
338 printf("%s", RETVAL(&msg));
339 FreeVec(RETVAL(&msg));
341 else
343 cmdfailed();
346 else
348 noport();
353 /****************************************************************************************/
355 static void tofile(char *filename)
357 BOOL sent;
359 sent = sendclipboardmsg(&msg, 'R', NULL);
360 if (sent)
362 WaitPort(replyport);
363 GetMsg(replyport);
365 if (SUCCESS(&msg) && RETVAL(&msg))
367 ULONG len;
369 hostbuffer = RETVAL(&msg);
370 len = strlen(hostbuffer);
372 fh = Open(filename, MODE_NEWFILE);
373 if (!fh)
375 Fault(IoErr(), 0, s, 255);
376 cleanup(s, RETURN_ERROR);
379 if (Write(fh, hostbuffer, len) != len)
381 Fault(IoErr(), 0, s, 255);
382 cleanup(s, RETURN_ERROR);
385 Close(fh);
386 fh = 0;
388 FreeVec(hostbuffer);
389 hostbuffer = 0;
391 else
393 cmdfailed();
396 else
398 noport();
403 /****************************************************************************************/
405 static void fromstring(char *s)
407 BOOL sent;
409 sent = sendclipboardmsg(&msg, 'W', s);
410 if (sent)
412 WaitPort(replyport);
413 GetMsg(replyport);
415 if (!SUCCESS(&msg))
417 cmdfailed();
420 else
422 noport();
427 /****************************************************************************************/
429 static void fromfile(char *filename)
431 BOOL sent;
432 LONG len;
434 fh = Open(filename, MODE_OLDFILE);
435 if (!fh)
437 Fault(IoErr(), 0, s, 255);
438 cleanup(s, RETURN_ERROR);
441 len = Seek(fh, 0, OFFSET_END);
442 if (len != -1) len = Seek(fh, 0, OFFSET_BEGINNING);
444 if (len == -1)
446 Fault(IoErr(), 0, s, 255);
447 cleanup(s, RETURN_ERROR);
450 filebuffer = AllocVec(len + 1, MEMF_ANY);
451 if (!filebuffer)
453 cleanup("Out of memory!", RETURN_ERROR);
456 if (Read(fh, filebuffer, len) != len)
458 Fault(IoErr(), 0, s, 255);
459 cleanup(s, RETURN_ERROR);
462 Close(fh);
463 fh = 0;
465 filebuffer[len] = '\0';
467 sent = sendclipboardmsg(&msg, 'W', filebuffer);
468 if (sent)
470 WaitPort(replyport);
471 GetMsg(replyport);
473 if (!SUCCESS(&msg))
475 cmdfailed();
478 else
480 noport();
483 FreeVec(filebuffer);
484 filebuffer = 0;
488 /****************************************************************************************/
490 int main(void)
492 init();
493 getarguments();
494 if (args[ARG_TOAROSCLIP]) toarosclip();
495 if (args[ARG_FROMAROSCLIP]) fromarosclip();
496 if (args[ARG_TOSTDOUT]) tostdout();
497 if (args[ARG_TOFILE]) tofile((char *)args[ARG_TOFILE]);
498 if (args[ARG_FROMSTRING]) fromstring((char *)args[ARG_FROMSTRING]);
499 if (args[ARG_FROMFILE]) fromfile((char *)args[ARG_FROMFILE]);
501 cleanup(0, RETURN_OK);
503 return 0;
506 /****************************************************************************************/