2 Copyright © 2012, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
8 #include <proto/exec.h>
19 #define ARG_TEMPLATE "FILENAME,PROFILE/K,NOGUI/S,ARGUMENTS/F"
20 #define CMD_TMPLATE_SIZE (2000)
34 static void clean_exit(struct Req
*req
, CONST_STRPTR s
)
36 LONG retval
= RETURN_OK
;
45 if (req
->rda
) FreeArgs(req
->rda
);
52 static struct Req
*alloc_req(void)
54 return AllocPooled(poolmem
, sizeof (struct Req
));
57 static BOOL
handle_args(struct Req
*req
, int argc
, char **argv
)
61 IPTR args
[ARG_COUNT
] = {0};
63 req
->rda
= ReadArgs(ARG_TEMPLATE
, args
, NULL
);
66 PrintFault(IoErr(), argv
[0]);
70 req
->filename
= (STRPTR
)args
[ARG_FILENAME
];
71 req
->profile
= (STRPTR
)args
[ARG_PROFILE
];
72 req
->nogui
= args
[ARG_NOGUI
] ? TRUE
: FALSE
;
73 req
->arguments
= (STRPTR
)args
[ARG_ARGUMENTS
];
78 // FIXME: it should be possible to use R as default tool
85 // return TRUE if name exists and is not a directory
86 static BOOL
is_file(CONST_STRPTR name
)
92 struct FileInfoBlock
*fib
= AllocDosObject(DOS_FIB
, NULL
);
95 BPTR lock
= Lock(name
, SHARED_LOCK
);
98 if (Examine(lock
, fib
))
100 if (fib
->fib_DirEntryType
< 0)
107 FreeDosObject(DOS_FIB
, fib
);
114 // search for the command. It must
115 // be an absolute path, exist in the current directory
117 static BOOL
check_exist(struct Req
*req
)
121 if (req
->filename
== NULL
)
124 if (strchr(req
->filename
, ':')) // absolute path
126 if (is_file(req
->filename
))
128 D(bug("[R] command found by absolute path\n"));
132 else if (strchr(req
->filename
, '/') == NULL
) // not in a sub-dir
134 if (is_file(req
->filename
)) // in current directory
136 D(bug("[R] command found in current directory\n"));
141 BPTR lock
= Lock("C:", SHARED_LOCK
);
144 BPTR olddir
= CurrentDir(lock
);
145 if (is_file(req
->filename
))
147 D(bug("[R] command found in C:\n"));
161 // execute the command with "?" option and read the command template
162 static BOOL
get_template(struct Req
*req
)
166 BPTR input_fh
= BNULL
;
167 BPTR output_fh
= BNULL
;
169 TEXT out_file_name
[30];
170 TEXT in_file_name
[30];
175 __unused LONG cmd_res
= 0;
177 if (req
->filename
== NULL
)
182 cmd_len
= strlen(req
->filename
) + 20;
183 cmd
= AllocPooled(poolmem
, cmd_len
);
189 for (i
= 0; i
< 20 && output_fh
== BNULL
; i
++)
191 sprintf(out_file_name
, "t:%08u.request.outfile", (unsigned int)i
);
192 output_fh
= Open(out_file_name
, MODE_NEWFILE
);
194 if (output_fh
== BNULL
)
199 for (i
= 0; i
< 20 && input_fh
== BNULL
; i
++)
201 sprintf(in_file_name
, "t:%08u.request.infile", (unsigned int)i
);
202 input_fh
= Open(in_file_name
, MODE_NEWFILE
);
204 if (input_fh
== BNULL
)
209 input_fh
= Open(in_file_name
, MODE_OLDFILE
);
210 if (input_fh
== BNULL
)
215 // append "!GETTEMPLATE!" to the command
216 strlcpy(cmd
, req
->filename
, cmd_len
);
217 strlcat(cmd
, " !GETTEMPLATE!", cmd_len
);
219 // shut up DOS error message
220 struct Process
*me
= (struct Process
*)FindTask(NULL
);
221 APTR oldwin
= me
->pr_WindowPtr
;
222 me
->pr_WindowPtr
= (APTR
)-1;
224 // Execute the command
225 cmd_res
= Execute(cmd
, input_fh
, output_fh
);
226 D(bug("[R] Execute() returned: %d\n", cmd_res
));
228 // restore window ptr
229 me
->pr_WindowPtr
= oldwin
;
231 req
->cmd_template
= AllocPooled(poolmem
, CMD_TMPLATE_SIZE
); // FIXME get mem size from file size
232 if (req
->cmd_template
== NULL
)
237 // go to the beginning of the output file and read the template
238 Seek(output_fh
, 0, OFFSET_BEGINNING
);
239 if (FGets(output_fh
, req
->cmd_template
, CMD_TMPLATE_SIZE
))
241 D(bug("[R] template read: %s\n", req
->cmd_template
));
249 DeleteFile(in_file_name
);
254 DeleteFile(out_file_name
);
257 FreePooled(poolmem
, cmd
, cmd_len
);
263 static BOOL
parse_template(struct Req
*req
)
269 if (req
->cmd_template
[0] == '\0')
272 // count number of arguments
275 req
->arg_cnt
= 1, chr
= req
->cmd_template
;
276 *chr
!= '\0' && req
->arg_cnt
< 50;
286 D(bug("[R/parse_template args found %d\n", req
->arg_cnt
));
288 req
->cargs
= AllocPooled(poolmem
, sizeof (struct CArg
) * req
->arg_cnt
);
289 if (req
->cargs
== NULL
)
296 arg
= 0, chr
= req
->cmd_template
;
302 TEXT
*name_start
= chr
;
310 else if (*chr
== '=')
312 // we are only interested in the part after the "=".
320 len
= chr
- name_start
;
327 req
->cargs
[arg
].argname
= AllocPooled(poolmem
, len
+ 1);
328 if (req
->cargs
[arg
].argname
== NULL
)
332 memcpy(req
->cargs
[arg
].argname
, name_start
, len
);
333 req
->cargs
[arg
].argname
[len
] = '\0';
341 req
->cargs
[arg
].a_flag
= TRUE
;
345 req
->cargs
[arg
].f_flag
= TRUE
;
349 req
->cargs
[arg
].k_flag
= TRUE
;
353 req
->cargs
[arg
].m_flag
= TRUE
;
357 req
->cargs
[arg
].n_flag
= TRUE
;
361 req
->cargs
[arg
].s_flag
= TRUE
;
365 req
->cargs
[arg
].t_flag
= TRUE
;
382 // create the command line from the selected options
383 static void execute_command(struct Req
*req
)
389 ULONG cmd_size
= strlen(req
->filename
) + 5;
390 for (i
= 0; i
< req
->arg_cnt
; i
++)
392 cmd_size
+= strlen(req
->cargs
[i
].argname
) + 5;
393 if (!req
->cargs
[i
].s_flag
&& !req
->cargs
[i
].t_flag
)
395 cmd_size
+= strlen(get_gui_string(&req
->cargs
[i
])) + 5;
399 cmd
= AllocPooled(poolmem
, cmd_size
);
405 strcpy(cmd
, req
->filename
);
407 for (i
= 0; i
< req
->arg_cnt
; i
++)
409 if (req
->cargs
[i
].s_flag
|| req
->cargs
[i
].t_flag
)
411 if (get_gui_bool(&req
->cargs
[i
]))
414 strcat(cmd
, req
->cargs
[i
].argname
);
417 else if (req
->cargs
[i
].n_flag
)
419 str
= get_gui_string(&req
->cargs
[i
]);
423 strcat(cmd
, req
->cargs
[i
].argname
);
431 str
= get_gui_string(&req
->cargs
[i
]);
434 // do we have a space character in the string?
436 // For /M the quotes are already set by the GUI
437 if (!req
->cargs
[i
].m_flag
&& strchr(str
, ' ') && str
[0] != '\"')
442 strcat(cmd
, req
->cargs
[i
].argname
);
457 D(bug("[R] executing command %s\n", cmd
));
465 Printf(_(MSG_ERROR_RETURN
), req
->filename
, result
);
470 int main(int argc
, char **argv
)
472 poolmem
= CreatePool(MEMF_ANY
| MEMF_CLEAR
, 2000, 2000);
474 clean_exit(NULL
, _(MSG_ERROR_POOL
));
476 struct Req
*req
= alloc_req();
478 clean_exit(req
, _(MSG_ERROR_STRUCT
));
480 D(bug("[R/main] req %p\n", req
));
482 if (! handle_args(req
, argc
, argv
))
483 clean_exit(req
, _(MSG_ERROR_ARGS
));
485 if (! check_exist(req
))
486 clean_exit(req
, _(MSG_ERROR_NOTFOUND
));
488 if (! get_template(req
))
489 clean_exit(req
, _(MSG_ERROR_TMPLT_GET
));
491 if (! parse_template(req
))
492 clean_exit(req
, _(MSG_ERROR_TMPLT_PARSE
));
494 if (! create_gui(req
))
495 clean_exit(req
, _(MSG_ERROR_GUI
));
499 execute_command(req
);
502 clean_exit(req
, NULL
);