Fix for a crash which happened when a document couldn't be opened.
[AROS-Contrib.git] / rexx / src / address.c
blobfd0e55695cf1a08d72f2411e90c3634399a66bf2
1 /*
2 * $Header$
3 * $Log$
4 * Revision 1.2 2001/04/05 16:58:26 stegerg
5 * AROS does not have system() and chmod() functions, so for now #if 0 them out
7 * Revision 1.1 2001/04/04 05:43:38 wang
8 * First commit: compiles on Linux, Amiga, Windows, Windows CE, generic gcc
10 * Revision 1.3 1999/11/26 13:13:02 bnv
11 * Added: Windows CE support.
13 * Revision 1.2 1999/03/10 16:53:32 bnv
14 * Added MSC support
16 * Revision 1.1 1998/07/02 17:34:50 bnv
17 * Initial revision
21 #include <string.h>
22 #include <stdlib.h>
23 #include <lstring.h>
25 #include <rexx.h>
26 #include <trace.h>
27 #include <stack.h>
28 #include <compile.h>
29 #include <interpre.h>
31 #ifndef WIN
33 #if defined(MSDOS) || defined(__WIN32__)
34 # include <io.h>
35 #ifndef _MSC_VER
36 # include <dir.h>
37 #endif
38 # include <process.h>
39 # if defined(__BORLANDC__) && !defined(__WIN32__)
40 # include <systemx.h>
41 # endif
42 #elif defined(__MPW__)
43 #elif defined(_MSC_VER)
44 #else
45 # include <fcntl.h>
46 # include <unistd.h>
47 #endif
49 #include <sys/stat.h>
50 #include <string.h>
52 #ifndef S_IREAD
53 # define S_IREAD 0
54 # define S_IWRITE 1
55 #endif
57 #define NOSTACK 0
58 #define FIFO 1
59 #define LIFO 2
60 #define STACK 3
62 #define LOW_STDIN 0
63 #define LOW_STDOUT 1
65 /* ---------------------- chkcmd4stack ---------------------- */
66 static void
67 chkcmd4stack(PLstr cmd, int *in, int *out )
69 Lstr Ucmd;
71 *in = *out = 0;
72 if (LLEN(*cmd)<7) return;
74 LINITSTR(Ucmd);
76 /* Search for string "STACK>" in front of command
77 or for strings "(STACK", "(FIFO", "(LIFO"
78 ">STACK", ">FIFO", ">LIFO" at the end */
80 if (LLEN(*cmd)<=5) return;
82 Lstrcpy(&Ucmd,cmd); Lupper(&Ucmd);
84 if (!MEMCMP(LSTR(Ucmd),"STACK>",6)) *in=FIFO;
85 if (!MEMCMP(LSTR(Ucmd)+LLEN(Ucmd)-5,"STACK",5)) *out = STACK;
86 if (!MEMCMP(LSTR(Ucmd)+LLEN(Ucmd)-4,"FIFO",4)) *out = FIFO;
87 if (!MEMCMP(LSTR(Ucmd)+LLEN(Ucmd)-4,"LIFO",4)) *out = LIFO;
88 if (*out)
89 if (LSTR(Ucmd)[LLEN(Ucmd)-((*out==STACK)?6:5)]!='(' &&
90 LSTR(Ucmd)[LLEN(Ucmd)-((*out==STACK)?6:5)]!='>') *out = 0;
91 LFREESTR(Ucmd);
93 if (*in) {
94 MEMMOVE(LSTR(*cmd),LSTR(*cmd)+6,LLEN(*cmd)-6);
95 LLEN(*cmd) -= 6;
97 if (*out)
98 LLEN(*cmd) -= (*out==STACK)?6:5;
100 if (*out==STACK)
101 *out = FIFO;
102 } /* chkcmd4stack */
104 /* ------------------ RxRedirectCmd ----------------- */
106 RxRedirectCmd(PLstr cmd, int in, int out, PLstr resultstr)
108 char fnin[250], fnout[250];
109 int old_stdin, old_stdout;
110 int filein, fileout;
111 FILE *f;
112 int l;
113 char *c;
114 PLstr str;
116 /* --- redirect input --- */
117 if (in) {
118 fnin[0] = '\0'; c = getenv("TEMP");
119 if (c) STRCPY(fnin,c);
120 l = STRLEN(fnin);
121 if (l)
122 if (fnin[l-1] != FILESEP) {
123 fnin[l] = FILESEP;
124 fnin[l+1] = '\0';
126 STRCAT(fnin,"OXXXXXX");
127 mktemp(fnin);
129 if ((f=fopen(fnin,"w"))!=NULL) {
130 while (StackQueued()>0) {
131 str = PullFromStack();
132 L2STR(str); LASCIIZ(*str);
133 fputs(LSTR(*str),f); fputc('\n',f);
134 LPFREE(str);
136 fclose(f);
138 old_stdin = dup(LOW_STDIN);
139 filein = open(fnin,S_IREAD);
140 dup2(filein,LOW_STDIN);
141 close(filein);
142 } else
143 in = FALSE;
146 /* --- redirect output --- */
147 if (out) {
148 fnout[0] = '\0'; c = getenv("TEMP");
149 if (c) STRCPY(fnout,c);
150 l = STRLEN(fnout);
151 if (l)
152 if (fnout[l-1] != FILESEP) {
153 fnout[l] = FILESEP;
154 fnout[l+1] = '\0';
156 STRCAT(fnout,"OXXXXXX");
157 mktemp(fnout);
158 old_stdout = dup(LOW_STDOUT);
159 fileout = creat(fnout,S_IWRITE);
160 dup2(fileout,LOW_STDOUT);
161 close(fileout);
164 /* --- Execute the command --- */
165 LASCIIZ(*cmd);
166 #if defined(__BORLANDC__) && !defined(__WIN32__)
167 RxReturnCode = systemx(LSTR(*cmd));
168 #else
169 RxReturnCode = system(LSTR(*cmd));
170 #endif
172 /* --- restore input --- */
173 if (in) {
174 close(LOW_STDIN);
175 dup2(old_stdin,LOW_STDIN);
176 close(old_stdin);
177 remove(fnin);
180 /* --- restore output --- */
181 if (out) {
182 close(LOW_STDOUT);
183 dup2(old_stdout,LOW_STDOUT); /* restore stdout */
184 close(old_stdout);
185 #if !defined(MSDOS) && !defined(AROS)
186 chmod(fnout,0666);
187 #endif
188 if ((f=fopen(fnout,"r"))!=NULL) {
189 if (resultstr) {
190 Lread(f,resultstr,LREADFILE);
191 #ifdef RMLAST
192 if (LSTR(*resultstr)[LLEN(*resultstr)-1]=='\n')
193 LLEN(*resultstr)--;
194 #endif
195 } else /* push it to stack */
196 while (!feof(f)) {
197 LPMALLOC(str);
198 Lread(f,str,LREADLINE);
199 if (LLEN(*str)==0 && feof(f)) {
200 LPFREE(str);
201 break;
203 if (out==FIFO)
204 Queue2Stack(str);
205 else
206 Push2Stack(str);
209 fclose(f);
210 remove(fnout);
214 return RxReturnCode;
215 } /* RxRedirectCmd */
216 #endif
218 /* ------------------ RxExecuteCmd ----------------- */
220 RxExecuteCmd( PLstr cmd, PLstr env )
222 #ifndef WIN
223 int in,out;
224 Lstr cmdN;
226 LINITSTR(cmdN); Lfx(&cmdN,1);
227 Lstrcpy(&cmdN,cmd);
228 L2STR(&cmdN);
230 LASCIIZ(cmdN);
231 if (env==NULL) {
232 chkcmd4stack(&cmdN,&in,&out);
233 RxReturnCode = RxRedirectCmd(&cmdN,in,out,FALSE);
234 } else
235 if ( !Lcmp(env,"COMMAND") ||
236 !Lcmp(env,"DOS") ||
237 !Lcmp(env,"CMS") ||
238 !Lstrcmp(env,&(SystemStr->key))) {
239 chkcmd4stack(&cmdN,&in,&out);
240 RxReturnCode = RxRedirectCmd(&cmdN,in,out,FALSE);
242 #if defined(__BORLANDC__) && !defined(__WIN32__)
243 else
244 if (!Lcmp(env,"INT2E"))
245 int2e(LSTR(cmdN));
246 #endif
247 else
248 if (!Lcmp(env,"EXEC")) ; /*execl(...); */
249 else
250 RxReturnCode = -3;
252 /* free string */
253 LFREESTR(cmdN);
255 RxSetSpecialVar(RCVAR,RxReturnCode);
256 if (RxReturnCode) {
257 if (_Proc[_rx_proc].trace & (error_trace | normal_trace)) {
258 TraceCurline(NULL,TRUE);
259 fprintf(STDERR," +++ RC(%d) +++\n",RxReturnCode);
260 if (_Proc[_rx_proc].interactive_trace)
261 TraceInteractive(FALSE);
263 if (_Proc[_rx_proc].condition & SC_ERROR)
264 RxSignalCondition(SC_ERROR);
266 #else
267 size_t len;
268 char *ch;
269 Lstr file, args;
270 TCHAR *uFile, *uArgs;
271 PROCESS_INFORMATION p;
273 LINITSTR(file);
274 LINITSTR(args);
276 ch = LSTR(*cmd);
277 if ((*ch=='\'') || (*ch=='\"')) {
278 ch = STRCHR(ch+1,*ch);
279 if (ch)
280 len = (DWORD)ch - (DWORD)LSTR(*cmd);
281 else
282 len = LLEN(*cmd);
283 Lsubstr(&file, cmd, 2, len-1, ' ');
284 Lsubstr(&args, cmd, len+3, LREST, ' ');
285 } else {
286 Lword(&file, cmd, 1);
287 Lsubword(&args, cmd, 2, LREST);
290 uFile = (TCHAR*)MALLOC(sizeof(TCHAR)*LLEN(file)+2,NULL);
291 uArgs = (TCHAR*)MALLOC(sizeof(TCHAR)*LLEN(args)+2,NULL);
292 mbstowcs(uFile,LSTR(file),LLEN(file)); uFile[LLEN(file)] = (TCHAR)0;
293 mbstowcs(uArgs,LSTR(args),LLEN(args)); uArgs[LLEN(args)] = (TCHAR)0;
295 CreateProcess(uFile, uArgs, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &p);
296 CloseHandle(p.hProcess);
297 CloseHandle(p.hThread);
299 FREE(uFile);
300 FREE(uArgs);
301 LFREESTR(file);
302 LFREESTR(args);
303 #endif
304 return RxReturnCode;
305 } /* RxExecuteCmd */