Fixed compatibility of output.
[AROS.git] / external / openurl / library / utils.c
blobea478055b65469b48bb5752da1d26ee7a276aaba
1 /***************************************************************************
3 openurl.library - universal URL display and browser launcher library
4 Copyright (C) 1998-2005 by Troels Walsted Hansen, et al.
5 Copyright (C) 2005-2013 by openurl.library Open Source Team
7 This library is free software; it has been placed in the public domain
8 and you can freely redistribute it and/or modify it. Please note, however,
9 that some components may be under the LGPL or GPL license.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 openurl.library project: http://sourceforge.net/projects/openurllib/
17 $Id$
19 ***************************************************************************/
21 #include "lib.h"
23 #include <proto/dos.h>
24 #include <proto/exec.h>
25 #include <proto/utility.h>
27 #include <stdio.h>
29 #if !defined(__amigaos4__)
30 #include <dos/dostags.h>
31 #include <exec/execbase.h>
32 #endif
34 #include "debug.h"
36 /**************************************************************************/
38 #define FINDPORT_NUM 100 /* how many FindPort() to do while waiting */
39 #define FINDPORT_TIME 10 /* how many seconds to spread those FindPort() over */
40 #define FINDPORT_DTIME ((FINDPORT_TIME * TICKS_PER_SECOND)/FINDPORT_NUM)
42 struct placeHolder
44 TEXT ph_Char;
45 STRPTR ph_String;
48 #define PH_COUNT_BROWSER 2
49 #define PH_COUNT_MAILER 6
50 #define PH_COUNT_FTP 2
52 /**************************************************************************/
54 static STRPTR expandPlaceHolders(STRPTR template, struct placeHolder *ph, int num)
56 STRPTR p, res = NULL;
57 int i, length = 0;
59 ENTER();
61 for (p = template; *p; p++)
63 for (i = 0; i<num; i++)
65 if ((*p=='%') && (*(p+1)== ph[i].ph_Char))
66 length += strlen(ph[i].ph_String);
69 length++;
72 if ((res = allocArbitrateVecPooled(length+1)) != NULL)
74 for (p = res; *template; template++)
76 for (i = 0; i<num; i++)
77 if ((*template=='%') && (*(template+1)== ph[i].ph_Char))
78 break;
80 if (i<num)
82 strcpy(p,ph[i].ph_String);
83 p += strlen(ph[i].ph_String);
84 template++;
85 continue;
88 *p++ = *template;
91 *p = '\0';
94 RETURN(res);
95 return res;
98 /**************************************************************************/
100 static BOOL writeToFile(STRPTR fileName, STRPTR str)
102 BOOL res = FALSE;
103 BPTR fh;
105 ENTER();
107 if((fh = Open(fileName, MODE_NEWFILE)))
109 LONG len = strlen(str);
111 if(Write(fh, str, len)==len)
112 res = TRUE;
114 Close(fh);
117 RETURN(res);
118 return res;
121 /**************************************************************************/
123 static STRPTR findRexxPort(struct List *list,STRPTR name)
125 STRPTR portName = NULL;
127 ENTER();
129 /* find a rexx port, allowing a .<number> extension */
131 // avoid empty port names
132 if(name != NULL && name[0] != '\0')
134 ULONG len;
135 struct Node *n;
137 len = strlen(name);
139 for(n = list->lh_Head; n->ln_Succ; n = n->ln_Succ)
141 if(n->ln_Name != NULL && strncmp(n->ln_Name, name, len) == 0 &&
142 (n->ln_Name[len] == '\0' || (n->ln_Name[len] == '.' && isdigits(&n->ln_Name[len+1]))))
144 portName = n->ln_Name;
145 break;
150 RETURN(portName);
151 return portName;
154 /**************************************************************************/
156 static STRPTR waitForRexxPort(STRPTR port)
158 STRPTR name = NULL;
159 int i;
161 ENTER();
163 /* (busy) wait for the port to appear */
165 // avoid empty port names
166 if(port != NULL && port[0] != '\0')
168 for(i = 0; i<FINDPORT_NUM; i++)
170 STRPTR rxport;
172 Forbid();
173 rxport = findRexxPort(&((struct ExecBase *)SysBase)->PortList, port);
174 Permit();
176 if(rxport != NULL)
178 name = rxport;
179 break;
182 if(SetSignal(0, 0) & SIGBREAKF_CTRL_C)
184 name = NULL;
185 break;
188 Delay(FINDPORT_DTIME);
192 RETURN(name);
193 return name;
196 /**************************************************************************/
198 static BOOL sendRexxMsg(STRPTR rxport, STRPTR rxcmd)
200 BOOL res = FALSE;
201 struct Process *proc;
203 ENTER();
205 D(DBF_STARTUP, "sending command '%s' to port '%s'", rxcmd, rxport);
207 #if defined(__MORPHOS__)
208 proc = CreateNewProcTags(NP_Entry, handler,
209 NP_CodeType, CODETYPE_PPC,
210 NP_PPCStackSize, 8192,
211 NP_StackSize, 4096,
212 NP_Name, "OpenURL - Handler",
213 NP_CopyVars, FALSE,
214 NP_Input, NULL,
215 NP_CloseInput, FALSE,
216 NP_Output, NULL,
217 NP_CloseOutput, FALSE,
218 NP_Error, NULL,
219 NP_CloseError, FALSE,
220 TAG_DONE);
221 #else
222 proc = CreateNewProcTags(NP_Entry, handler,
223 NP_StackSize, 4096,
224 NP_Name, "OpenURL - Handler",
225 NP_CopyVars, FALSE,
226 NP_Input, NULL,
227 NP_CloseInput, FALSE,
228 NP_Output, NULL,
229 NP_CloseOutput, FALSE,
230 NP_Error, NULL,
231 NP_CloseError, FALSE,
232 TAG_DONE);
233 #endif
235 if(proc != NULL)
237 struct MsgPort *port;
239 #if defined(__amigaos4__)
240 port = AllocSysObjectTags(ASOT_PORT, TAG_DONE);
241 #else
242 port = CreateMsgPort();
243 #endif
245 if(port != NULL)
247 struct startMsg *smsg;
249 #if defined(__amigaos4__)
250 smsg = AllocSysObjectTags(ASOT_MESSAGE, ASOMSG_Size, sizeof(*smsg),
251 ASOMSG_ReplyPort, port,
252 TAG_DONE);
253 #else
254 smsg = allocArbitrateVecPooled(sizeof(*smsg));
255 #endif
257 if(smsg != NULL)
259 #if !defined(__amigaos4__)
260 INITMESSAGE(smsg, port, sizeof(*smsg));
261 #endif
263 smsg->port = rxport;
264 smsg->cmd = rxcmd;
266 ObtainSemaphore(&OpenURLBase->libSem);
267 OpenURLBase->rexx_use++;
268 ReleaseSemaphore(&OpenURLBase->libSem);
270 PutMsg(&proc->pr_MsgPort, (struct Message *)smsg);
271 WaitPort(port);
272 GetMsg(port);
274 res = smsg->res;
276 #if defined(__amigaos4__)
277 FreeSysObject(ASOT_MESSAGE, smsg);
278 #else
279 freeArbitrateVecPooled(smsg);
280 #endif
283 #if defined(__amigaos4__)
284 FreeSysObject(ASOT_PORT, port);
285 #else
286 DeleteMsgPort(port);
287 #endif
291 RETURN(res);
292 return res;
295 /****************************************************************************/
297 BOOL sendToBrowser(STRPTR URL, struct List *portlist, ULONG flags, STRPTR pubScreenName)
299 BOOL res = FALSE;
300 STRPTR cmd = NULL;
301 struct placeHolder ph[PH_COUNT_BROWSER];
302 struct URL_BrowserNode *bn;
304 ENTER();
306 /* set up the placeholder mapping */
308 ph[0].ph_Char = 'u'; ph[0].ph_String = URL;
309 ph[1].ph_Char = 'p'; ph[1].ph_String = pubScreenName ? pubScreenName : (STRPTR)"Workbench";
311 /* try to find one of the browsers in the list */
313 for (bn = (struct URL_BrowserNode *)OpenURLBase->prefs->up_BrowserList.mlh_Head;
314 bn->ubn_Node.mln_Succ;
315 bn = (struct URL_BrowserNode *)bn->ubn_Node.mln_Succ)
317 STRPTR port;
319 if(isFlagSet(bn->ubn_Flags, UNF_DISABLED))
320 continue;
321 if(bn->ubn_Path[0] == '\0')
322 continue;
324 port = findRexxPort(portlist,bn->ubn_Port);
326 if (port)
328 /* send uniconify msg */
330 if (isFlagSet(flags, SENDTOF_SHOW) && *bn->ubn_ShowCmd)
331 sendRexxMsg(port,bn->ubn_ShowCmd);
333 /* send screentofront command */
335 if (isFlagSet(flags, SENDTOF_TOFRONT) && *bn->ubn_ToFrontCmd)
336 sendRexxMsg(port,bn->ubn_ToFrontCmd);
338 /* try sending openurl msg */
340 if (!(cmd = expandPlaceHolders(isFlagSet(flags, SENDTOF_NEWWINDOW) ? bn->ubn_OpenURLWCmd : bn->ubn_OpenURLCmd,ph,PH_COUNT_BROWSER)))
341 goto done;
343 if (!(res = sendRexxMsg(port,cmd)))
345 freeArbitrateVecPooled(cmd);
346 cmd = NULL;
348 else goto done;
352 /* no running browser, launch a new one */
354 if (isFlagClear(flags, SENDTOF_LAUNCH))
355 goto done;
357 for (bn = (struct URL_BrowserNode *)OpenURLBase->prefs->up_BrowserList.mlh_Head;
358 bn->ubn_Node.mln_Succ;
359 bn = (struct URL_BrowserNode *)bn->ubn_Node.mln_Succ)
361 ULONG startOnly;
362 STRPTR filePart;
363 TEXT c = '\0';
364 BPTR lock;
365 LONG error;
367 if(isFlagSet(bn->ubn_Flags, UNF_DISABLED))
368 continue;
369 if(bn->ubn_Path[0] == '\0')
370 continue;
372 /* compose commandline */
374 if (strstr(bn->ubn_Path,"%u")) startOnly = TRUE;
375 else startOnly = FALSE;
377 if (!(cmd = expandPlaceHolders(bn->ubn_Path,ph,PH_COUNT_BROWSER)))
378 goto done;
380 filePart = FilePart(bn->ubn_Path);
382 if (filePart)
384 c = *filePart;
385 *filePart = '\0';
388 lock = Lock(bn->ubn_Path,ACCESS_READ);
390 if (filePart) *filePart = c;
392 /* start the browser */
394 error = SystemTags(cmd,SYS_Asynch, TRUE,
395 SYS_Input, Open("NIL:",MODE_NEWFILE),
396 SYS_Output, NULL,
397 SYS_Error, NULL,
398 lock ? NP_CurrentDir : TAG_IGNORE, lock,
399 TAG_DONE);
401 freeArbitrateVecPooled(cmd);
402 cmd = NULL;
404 if (error)
406 if (lock) UnLock(lock);
407 continue;
410 if (!startOnly)
412 STRPTR rxport;
414 /* send urlopen command */
416 if (!(cmd = expandPlaceHolders(bn->ubn_OpenURLCmd,ph,PH_COUNT_BROWSER)))
417 goto done;
419 /* wait for the port to appear */
421 if ((rxport = waitForRexxPort(bn->ubn_Port)))
422 res = sendRexxMsg(rxport,cmd);
424 break;
426 else
428 res = TRUE;
429 break;
433 done:
434 if(cmd)
435 freeArbitrateVecPooled(cmd);
437 RETURN(res);
438 return res;
441 /**************************************************************************/
443 BOOL sendToFTP(STRPTR URL, struct List *portlist, ULONG flags, STRPTR pubScreenName)
445 BOOL res = FALSE;
446 STRPTR cmd = NULL;
447 struct placeHolder ph[PH_COUNT_FTP];
448 struct URL_FTPNode *fn;
450 ENTER();
452 /* set up the placeholder mapping */
454 ph[0].ph_Char = 'u'; /*ph[0].ph_String = URL;*/
455 ph[1].ph_Char = 'p'; ph[1].ph_String = pubScreenName ? pubScreenName : (STRPTR)"Workbench";
457 /* try to find one of the ftp client in the list */
459 for (fn = (struct URL_FTPNode *)OpenURLBase->prefs->up_FTPList.mlh_Head;
460 fn->ufn_Node.mln_Succ;
461 fn = (struct URL_FTPNode *)fn->ufn_Node.mln_Succ)
463 STRPTR port;
465 if(isFlagSet(fn->ufn_Flags, UNF_DISABLED))
466 continue;
468 port = findRexxPort(portlist,fn->ufn_Port);
470 if (port)
472 /* send uniconify msg */
474 if (isFlagSet(flags, SENDTOF_SHOW) && *fn->ufn_ShowCmd)
475 sendRexxMsg(port,fn->ufn_ShowCmd);
477 /* send screentofront command */
479 if (isFlagSet(flags, SENDTOF_TOFRONT) && *fn->ufn_ToFrontCmd)
480 sendRexxMsg(port,fn->ufn_ToFrontCmd);
482 /* try sending openurl msg */
484 if(isFlagSet(fn->ufn_Flags, UFNF_REMOVEFTP) && !Strnicmp(URL,"ftp://",6))
485 ph[0].ph_String = URL+6;
486 else
487 ph[0].ph_String = URL+6;
489 if (!(cmd = expandPlaceHolders(isFlagSet(flags, SENDTOF_NEWWINDOW) ? fn->ufn_OpenURLWCmd : fn->ufn_OpenURLCmd,ph,PH_COUNT_FTP)))
490 goto done;
492 if (!(res = sendRexxMsg(port,cmd)))
494 freeArbitrateVecPooled(cmd);
495 cmd = NULL;
497 else goto done;
501 /* no running ftp client, launch a new one */
503 if (isFlagClear(flags, SENDTOF_LAUNCH))
504 goto done;
506 for (fn = (struct URL_FTPNode *)OpenURLBase->prefs->up_FTPList.mlh_Head;
507 fn->ufn_Node.mln_Succ;
508 fn = (struct URL_FTPNode *)fn->ufn_Node.mln_Succ)
510 ULONG startOnly;
511 STRPTR filePart;
512 TEXT c = '\0';
513 BPTR lock;
514 LONG error;
516 if(isFlagSet(fn->ufn_Flags, UNF_DISABLED))
517 continue;
518 if(fn->ufn_Path[0] == '\0')
519 continue;
521 /* compose commandline */
523 if (strstr(fn->ufn_Path,"%u"))
524 startOnly = TRUE;
525 else
526 startOnly = FALSE;
528 if(isFlagSet(fn->ufn_Flags, UFNF_REMOVEFTP) && !Strnicmp(URL,"ftp://",6))
529 ph[0].ph_String = URL+6;
530 else
531 ph[0].ph_String = URL+6;
533 if (!(cmd = expandPlaceHolders(fn->ufn_Path,ph,PH_COUNT_FTP)))
534 goto done;
536 filePart = FilePart(fn->ufn_Path);
538 if (filePart)
540 c = *filePart;
541 *filePart = '\0';
544 lock = Lock(fn->ufn_Path,ACCESS_READ);
546 if (filePart) *filePart = c;
548 /* start the ftp client */
550 error = SystemTags(cmd,SYS_Asynch, TRUE,
551 SYS_Input, Open("NIL:",MODE_NEWFILE),
552 SYS_Output, NULL,
553 SYS_Error, NULL,
554 lock ? NP_CurrentDir : TAG_IGNORE, lock,
555 TAG_DONE);
557 freeArbitrateVecPooled(cmd);
558 cmd = NULL;
560 if (error)
562 if (lock) UnLock(lock);
563 continue;
566 if (!startOnly)
568 STRPTR rxport;
570 /* send urlopen command */
572 if (!(cmd = expandPlaceHolders(fn->ufn_OpenURLCmd,ph,PH_COUNT_FTP)))
573 goto done;
575 /* wait for the port to appear */
577 if ((rxport = waitForRexxPort(fn->ufn_Port)))
578 res = sendRexxMsg(rxport,cmd);
580 break;
582 else
584 res = TRUE;
585 break;
589 done:
590 if(cmd)
591 freeArbitrateVecPooled(cmd);
593 RETURN(res);
594 return res;
597 /**************************************************************************/
599 static WORD trans[256];
601 BOOL sendToMailer(STRPTR URL, struct List *portlist, ULONG flags, STRPTR pubScreenName)
603 struct placeHolder ph[PH_COUNT_MAILER];
604 struct URL_MailerNode *mn;
605 STRPTR start, end, data, address = NULL, subject = NULL, body = NULL,
606 cmd = NULL, *tag;
607 TEXT fileName[32];
608 BOOL res = FALSE, written = FALSE;
609 UWORD offset, len;
611 ENTER();
613 /* setup trans */
614 ObtainSemaphore(&OpenURLBase->libSem);
615 if(isFlagClear(OpenURLBase->flags, BASEFLG_Trans))
617 for (len = 0; len<256; len++) trans[len] = -1;
619 trans['0'] = 0;
620 trans['1'] = 1;
621 trans['2'] = 2;
622 trans['3'] = 3;
623 trans['4'] = 4;
624 trans['5'] = 5;
625 trans['6'] = 6;
626 trans['7'] = 7;
627 trans['8'] = 8;
628 trans['9'] = 9;
629 trans['A'] = trans['a'] = 10;
630 trans['B'] = trans['b'] = 11;
631 trans['C'] = trans['c'] = 12;
632 trans['D'] = trans['d'] = 13;
633 trans['E'] = trans['e'] = 14;
634 trans['F'] = trans['f'] = 15;
636 SET_FLAG(OpenURLBase->flags, BASEFLG_Trans);
638 ReleaseSemaphore(&OpenURLBase->libSem);
640 /* parse the URL "mailto:user@host.domain?subject=Subject&body=Body" */
642 start = URL;
643 while (start)
645 tag = NULL;
646 end = NULL;
647 offset = 1;
649 /* Use utility.library - Piru */
651 if (!Strnicmp(start,"mailto:",7))
653 tag = &address;
654 offset = 7;
655 end = strchr(start+offset,'?');
657 else if ((!Strnicmp(start,"?subject=",9)) || (!Strnicmp(start,"&subject=",9)))
659 tag = &subject;
660 offset = 9;
661 end = strchr(start+offset,'&');
663 else if ((!Strnicmp(start,"?body=",6)) || (!Strnicmp(start,"&body=",6)))
665 tag = &body;
666 offset = 6;
667 end = strchr(start+offset,'&');
670 /* if we found some data && we even found it the first time ! */
671 if (tag && !*tag)
673 data=start+offset;
675 if (end) len=end-data;
676 else len=strlen(data);
678 if(!(*tag = allocArbitrateVecPooled(len+1)))
679 goto done;
681 strncpy(*tag,data,len);
682 *((*tag)+len)='\0';
684 /* decode %XX sequences in urls */
685 data=*tag;
686 while (data)
688 if ((data=strchr(data,'%')) && (trans[(int)data[1]]!=-1) && (trans[(int)data[2]]!=-1))
690 *data=(trans[(int)data[1]]<<4)|trans[(int)data[2]];
691 data++;
692 memmove(data,data+2,strlen(data+2)+1);
697 start = end;
700 if(body)
701 snprintf(fileName, sizeof(fileName), "T:OpenURL-MailBody.%016lx", (IPTR)FindTask(NULL));
702 else
704 written = TRUE;
705 strlcpy(fileName, "NIL:", sizeof(fileName));
708 /* set up the placeholder mapping */
710 ph[0].ph_Char = 'a'; ph[0].ph_String = address ? address : (STRPTR)"";
711 ph[1].ph_Char = 's'; ph[1].ph_String = subject ? subject : (STRPTR)"";//URL;
712 ph[2].ph_Char = 'b'; ph[2].ph_String = body ? body : (STRPTR)"";
713 ph[3].ph_Char = 'f'; ph[3].ph_String = fileName;
714 ph[4].ph_Char = 'u'; ph[4].ph_String = URL;
715 ph[5].ph_Char = 'p'; ph[5].ph_String = pubScreenName ? pubScreenName : (STRPTR)"Workbench";
717 /* try to find one of the mailers in the list */
719 for (mn = (struct URL_MailerNode *)OpenURLBase->prefs->up_MailerList.mlh_Head;
720 mn->umn_Node.mln_Succ;
721 mn = (struct URL_MailerNode *)mn->umn_Node.mln_Succ)
723 STRPTR rxport;
725 if(isFlagSet(mn->umn_Flags, UNF_DISABLED))
726 continue;
728 rxport = findRexxPort(portlist,mn->umn_Port);
730 if (rxport)
732 /* send uniconify msg */
734 if (isFlagSet(flags, SENDTOF_SHOW) && *mn->umn_ShowCmd)
735 sendRexxMsg(rxport,mn->umn_ShowCmd);
737 /* send screentofront command */
739 if (isFlagSet(flags, SENDTOF_TOFRONT) && *mn->umn_ToFrontCmd)
740 sendRexxMsg(rxport,mn->umn_ToFrontCmd);
742 /* write to temp file */
744 if (!written && strstr(mn->umn_WriteMailCmd,"%f"))
745 written = writeToFile(fileName,body);
747 /* try sending writemail msg */
749 if (!(cmd = expandPlaceHolders(mn->umn_WriteMailCmd,ph,PH_COUNT_MAILER)))
750 goto done;
752 /* now split each message at the ';' and send fragments */
753 start = end = cmd;
754 while (*start)
756 while ((*end) && (*end!=';'))
758 end++;
759 /* skip data, which is enclosed in "" */
760 if (*end=='"')
762 end++;
763 while ((*end) && (*end!='"')) end++;
764 if (*end=='"') end++;
767 /* are there more commands */
768 if (*end==';')
770 *end='\0';
771 end++;
773 if (!(res = sendRexxMsg(rxport,start)))
775 /* send failed, try next mailer */
776 freeArbitrateVecPooled(cmd);
777 start = cmd = NULL;
779 else start=end;
781 /* cmd processed succesfully, return */
782 if (cmd) goto done;
786 /* no running ftp client, launch a new one */
788 if (isFlagClear(flags, SENDTOF_LAUNCH))
789 goto done;
791 for (mn = (struct URL_MailerNode *)OpenURLBase->prefs->up_MailerList.mlh_Head;
792 mn->umn_Node.mln_Succ;
793 mn = (struct URL_MailerNode *)mn->umn_Node.mln_Succ)
795 ULONG startOnly;
796 STRPTR filePart;
797 TEXT c = '\0';
798 BPTR lock;
799 LONG error;
801 if(isFlagSet(mn->umn_Flags, UNF_DISABLED))
802 continue;
803 if(mn->umn_Path[0] == '\0')
804 continue;
806 /* compose commandline */
808 if (strstr(mn->umn_Path,"%a"))
809 startOnly = TRUE;
810 else
811 startOnly = FALSE;
813 if (!written && strstr(mn->umn_Path,"%f"))
814 written = writeToFile(fileName,body);
816 if (!(cmd = expandPlaceHolders(mn->umn_Path,ph,PH_COUNT_MAILER)))
817 goto done;
819 filePart = FilePart(mn->umn_Path);
821 if (filePart)
823 c = *filePart;
824 *filePart = '\0';
827 lock = Lock(mn->umn_Path,ACCESS_READ);
829 if (filePart) *filePart = c;
831 /* start the mailer */
833 error = SystemTags(cmd,SYS_Asynch, TRUE,
834 SYS_Input, Open("NIL:", MODE_NEWFILE),
835 SYS_Output, NULL,
836 SYS_Error, NULL,
837 lock ? NP_CurrentDir : TAG_IGNORE, lock,
838 TAG_DONE);
840 freeArbitrateVecPooled(cmd);
841 cmd = NULL;
843 if (error)
845 if (lock) UnLock(lock);
846 continue;
849 if (!startOnly)
851 STRPTR rxport;
853 /* send write mail command */
855 if (!written && strstr(mn->umn_WriteMailCmd,"%f"))
856 /*written = */writeToFile(fileName,body);
858 if (!(cmd = expandPlaceHolders(mn->umn_WriteMailCmd,ph,PH_COUNT_MAILER)))
859 goto done;
861 /* wait for the port to appear */
863 if ((rxport = waitForRexxPort(mn->umn_Port)))
865 start = end = cmd;
866 while (*start)
868 while ((*end) && (*end!=';'))
870 end++;
871 /* skip data, which is enclosed in "" */
872 if (*end=='"')
874 end++;
875 while ((*end) && (*end!='"')) end++;
876 if (*end=='"') end++;
879 /* are there more commands */
880 if (*end==';')
882 *end='\0';
883 end++;
885 if (!(res = sendRexxMsg(rxport,start)))
887 /* send failed, try next mailer */
888 freeArbitrateVecPooled(cmd);
889 start = cmd = NULL;
891 else start=end;
894 break;
896 else
898 res = TRUE;
899 break;
903 done:
904 if (cmd) freeArbitrateVecPooled(cmd);
905 if (body) freeArbitrateVecPooled(body);
906 if (subject) freeArbitrateVecPooled(subject);
907 if (address) freeArbitrateVecPooled(address);
909 RETURN(res);
910 return res;
913 /**************************************************************************/
915 BOOL copyList(struct List *dst, struct List *src, ULONG size)
917 BOOL success = TRUE;
918 struct Node *n, *new;
920 ENTER();
922 /* copy src list into dst, and return success */
924 for(n = src->lh_Head; n->ln_Succ; n = n->ln_Succ)
926 if((new = allocArbitrateVecPooled(size)) == NULL)
928 freeList(dst);
929 success = FALSE;
930 break;
933 CopyMem(n,new,size);
934 AddTail(dst,new);
937 RETURN(success);
938 return success;
941 /**************************************************************************/
943 void freeList(struct List *list)
945 struct Node *n;
947 ENTER();
949 while((n = RemHead(list)) != NULL)
950 freeArbitrateVecPooled(n);
952 LEAVE();
955 /**************************************************************************/
957 BOOL isdigits(STRPTR str)
959 BOOL result = FALSE;
961 ENTER();
963 for(;;)
965 if(*str == '\0')
967 result = TRUE;
968 break;
970 else if(!isdigit(*str))
971 break;
973 str++;
976 RETURN(result);
977 return result;
980 #if !defined(HAVE_ALLOCVECPOOLED)
981 APTR allocVecPooled(APTR pool, ULONG size)
983 ULONG *mem;
985 ENTER();
987 size += sizeof(ULONG);
988 if((mem = AllocPooled(pool, size)))
989 *mem++ = size;
991 RETURN(mem);
992 return mem;
994 #endif
996 /****************************************************************************/
998 #if !defined(HAVE_FREEVECPOOLED)
999 void freeVecPooled(APTR pool,APTR mem)
1001 ENTER();
1003 FreePooled(pool,(LONG *)mem - 1,*((LONG *)mem - 1));
1005 LEAVE();
1007 #endif
1009 /****************************************************************************/
1011 APTR reallocVecPooled(APTR pool, APTR mem, ULONG oldSize, ULONG newSize)
1013 ULONG *newMem;
1015 ENTER();
1017 if((newMem = allocVecPooled(pool, newSize)) != NULL)
1019 memcpy(newMem, mem, (oldSize < newSize) ? oldSize : newSize);
1021 freeVecPooled(pool, mem);
1024 RETURN(newMem);
1025 return newMem;
1028 /****************************************************************************/
1030 APTR allocArbitrateVecPooled(ULONG size)
1032 ULONG *mem;
1034 ENTER();
1036 ObtainSemaphore(&OpenURLBase->poolSem);
1037 mem = allocVecPooled(OpenURLBase->pool, size);
1038 ReleaseSemaphore(&OpenURLBase->poolSem);
1040 RETURN(mem);
1041 return mem;
1044 /****************************************************************************/
1046 void freeArbitrateVecPooled(APTR mem)
1048 ENTER();
1050 ObtainSemaphore(&OpenURLBase->poolSem);
1051 freeVecPooled(OpenURLBase->pool, mem);
1052 ReleaseSemaphore(&OpenURLBase->poolSem);
1054 LEAVE();
1057 /****************************************************************************/
1059 APTR reallocArbitrateVecPooled(APTR mem, ULONG oldSize, ULONG newSize)
1061 ENTER();
1063 ObtainSemaphore(&OpenURLBase->poolSem);
1064 mem = reallocVecPooled(OpenURLBase->pool, mem, oldSize, newSize);
1065 ReleaseSemaphore(&OpenURLBase->poolSem);
1067 RETURN(mem);
1068 return mem;
1071 /****************************************************************************/