Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/input.c

    r5db9084 reff10e03  
    1 /* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
     1/*
     2 * Copyright (c) 2008 Tim Post
     3 * Copyright (c) 2011 Jiri Svoboda
    24 * All rights reserved.
    35 *
    46 * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions are met:
     7 * modification, are permitted provided that the following conditions
     8 * are met:
    69 *
    7  * Redistributions of source code must retain the above copyright notice, this
    8  * list of conditions and the following disclaimer.
     10 * - Redistributions of source code must retain the above copyright
     11 *   notice, this list of conditions and the following disclaimer.
     12 * - Redistributions in binary form must reproduce the above copyright
     13 *   notice, this list of conditions and the following disclaimer in the
     14 *   documentation and/or other materials provided with the distribution.
     15 * - The name of the author may not be used to endorse or promote products
     16 *   derived from this software without specific prior written permission.
    917 *
    10  * Redistributions in binary form must reproduce the above copyright notice,
    11  * this list of conditions and the following disclaimer in the documentation
    12  * and/or other materials provided with the distribution.
    13  *
    14  * Neither the name of the original program's authors nor the names of its
    15  * contributors may be used to endorse or promote products derived from this
    16  * software without specific prior written permission.
    17  *
    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    28  * POSSIBILITY OF SUCH DAMAGE.
     18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2928 */
    3029
     
    4544
    4645#include "config.h"
     46#include "compl.h"
    4747#include "util.h"
    4848#include "scli.h"
     
    5050#include "errors.h"
    5151#include "exec.h"
     52#include "tok.h"
    5253
    5354extern volatile unsigned int cli_quit;
     
    5556/** Text input field. */
    5657static tinput_t *tinput;
     58
     59/* Private helpers */
     60static int run_command(char **, cliuser_t *, iostate_t *);
     61static void print_pipe_usage(void);
    5762
    5863/* Tokenizes input from console, sees if the first word is a built-in, if so
    5964 * invokes the built-in entry point (a[0]) passing all arguments in a[] to
    6065 * the handler */
    61 int tok_input(cliuser_t *usr)
     66int process_input(cliuser_t *usr)
    6267{
    6368        char *cmd[WORD_MAX];
    64         int n = 0, i = 0;
    6569        int rc = 0;
    66         char *tmp;
     70        tokenizer_t tok;
     71        int i, pipe_count, processed_pipes;
     72        int pipe_pos[2];
     73        char **actual_cmd;
     74        char *redir_from = NULL;
     75        char *redir_to = NULL;
    6776
    6877        if (NULL == usr->line)
    6978                return CL_EFAIL;
    7079
    71         tmp = str_dup(usr->line);
    72 
    73         cmd[n] = strtok(tmp, " ");
    74         while (cmd[n] && n < WORD_MAX) {
    75                 cmd[++n] = strtok(NULL, " ");
    76         }
    77 
    78         /* We have rubbish */
    79         if (NULL == cmd[0]) {
    80                 rc = CL_ENOENT;
    81                 goto finit;
    82         }
    83 
    84         /* Its a builtin command ? */
    85         if ((i = (is_builtin(cmd[0]))) > -1) {
    86                 rc = run_builtin(i, cmd, usr);
    87                 goto finit;
    88         /* Its a module ? */
    89         } else if ((i = (is_module(cmd[0]))) > -1) {
    90                 rc = run_module(i, cmd);
    91                 goto finit;
    92         }
    93 
    94         /* See what try_exec thinks of it */
    95         rc = try_exec(cmd[0], cmd);
    96 
     80        rc = tok_init(&tok, usr->line, cmd, WORD_MAX);
     81        if (rc != EOK) {
     82                goto finit;
     83        }
     84       
     85        rc = tok_tokenize(&tok);
     86        if (rc != EOK) {
     87                goto finit;
     88        }
     89       
     90        /* Until full support for pipes is implemented, allow for a simple case:
     91         * [from <file> |] command [| to <file>]
     92         *
     93         * First find the pipes and check that there are no more
     94         */
     95        int cmd_length = 0;
     96        for (i = 0, pipe_count = 0; cmd[i] != NULL; i++, cmd_length++) {
     97                if (cmd[i][0] == '|') {
     98                        if (pipe_count >= 2) {
     99                                print_pipe_usage();
     100                                rc = ENOTSUP;
     101                                goto finit;
     102                        }
     103                        pipe_pos[pipe_count] = i;
     104                        pipe_count++;
     105                }
     106        }
     107       
     108        actual_cmd = cmd;
     109        processed_pipes = 0;
     110       
     111        /* Check if the first part (from <file> |) is present */
     112        if (pipe_count > 0 && pipe_pos[0] == 2 && str_cmp(cmd[0], "from") == 0) {
     113                /* Ignore the first three tokens (from, file, pipe) and set from */
     114                redir_from = cmd[1];
     115                actual_cmd = cmd + 3;
     116                processed_pipes++;
     117        }
     118       
     119        /* Check if the second part (| to <file>) is present */
     120        if ((pipe_count - processed_pipes) > 0 &&
     121            pipe_pos[processed_pipes] == cmd_length - 3 &&
     122            str_cmp(cmd[cmd_length-2], "to") == 0) {
     123                /* Ignore the last three tokens (pipe, to, file) and set to */
     124                redir_to = cmd[cmd_length-1];
     125                cmd[cmd_length-3] = NULL;
     126                cmd_length -= 3;
     127                processed_pipes++;
     128        }
     129       
     130        if (processed_pipes != pipe_count) {
     131                print_pipe_usage();
     132                rc = ENOTSUP;
     133                goto finit;
     134        }
     135       
     136        if (actual_cmd[0] == NULL) {
     137                print_pipe_usage();
     138                rc = ENOTSUP;
     139                goto finit;
     140        }
     141       
     142        iostate_t new_iostate = {
     143                .stdin = stdin,
     144                .stdout = stdout,
     145                .stderr = stderr
     146        };
     147       
     148        FILE *from = NULL;
     149        FILE *to = NULL;
     150       
     151        if (redir_from) {
     152                from = fopen(redir_from, "r");
     153                if (from == NULL) {
     154                        printf("Cannot open file %s\n", redir_from);
     155                        rc = errno;
     156                        goto finit_with_files;
     157                }
     158                new_iostate.stdin = from;
     159        }
     160       
     161       
     162        if (redir_to) {
     163                to = fopen(redir_to, "w");
     164                if (to == NULL) {
     165                        printf("Cannot open file %s\n", redir_to);
     166                        rc = errno;
     167                        goto finit_with_files;
     168                }
     169                new_iostate.stdout = to;
     170        }
     171       
     172        rc = run_command(actual_cmd, usr, &new_iostate);
     173       
     174finit_with_files:
     175        if (from != NULL) {
     176                fclose(from);
     177        }
     178        if (to != NULL) {
     179                fclose(to);
     180        }
     181       
    97182finit:
    98183        if (NULL != usr->line) {
     
    100185                usr->line = (char *) NULL;
    101186        }
    102         if (NULL != tmp)
    103                 free(tmp);
     187        tok_fini(&tok);
    104188
    105189        return rc;
     190}
     191
     192void print_pipe_usage()
     193{
     194        printf("Invalid syntax!\n");
     195        printf("Usage of redirection (pipes in the future):\n");
     196        printf("from filename | command ...\n");
     197        printf("from filename | command ... | to filename\n");
     198        printf("command ... | to filename\n");
     199       
     200}
     201
     202int run_command(char **cmd, cliuser_t *usr, iostate_t *new_iostate)
     203{
     204        int id = 0;
     205       
     206        /* We have rubbish */
     207        if (NULL == cmd[0]) {
     208                return CL_ENOENT;
     209        }
     210       
     211        /* Is it a builtin command ? */
     212        if ((id = (is_builtin(cmd[0]))) > -1) {
     213                return run_builtin(id, cmd, usr, new_iostate);
     214        }
     215       
     216        /* Is it a module ? */
     217        if ((id = (is_module(cmd[0]))) > -1) {
     218                return run_module(id, cmd, new_iostate);
     219        }
     220
     221        /* See what try_exec thinks of it */
     222        return try_exec(cmd[0], cmd, new_iostate);
    106223}
    107224
     
    110227        char *str;
    111228        int rc;
    112 
    113         fflush(stdout);
    114         console_set_style(fphone(stdout), STYLE_EMPHASIS);
    115         printf("%s", usr->prompt);
    116         fflush(stdout);
    117         console_set_style(fphone(stdout), STYLE_NORMAL);
     229       
     230        tinput_set_prompt(tinput, usr->prompt);
    118231
    119232        rc = tinput_read(tinput, &str);
     
    148261        }
    149262
     263        tinput_set_compl_ops(tinput, &compl_ops);
     264
    150265        return 0;
    151266}
Note: See TracChangeset for help on using the changeset viewer.