xref: /nrf52832-nimble/rt-thread/components/finsh/msh_file.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2015-09-25     Bernard      the first verion for FinSH
9  */
10 
11 #include <rtthread.h>
12 
13 #if defined(FINSH_USING_MSH) && defined(RT_USING_DFS)
14 
15 #include <finsh.h>
16 #include "msh.h"
17 #include <dfs_posix.h>
18 
msh_readline(int fd,char * line_buf,int size)19 static int msh_readline(int fd, char *line_buf, int size)
20 {
21     char ch;
22     int index = 0;
23 
24     do
25     {
26         if (read(fd, &ch, 1) != 1)
27         {
28             /* nothing in this file */
29             return 0;
30         }
31     }
32     while (ch == '\n' || ch == '\r');
33 
34     /* set the first character */
35     line_buf[index ++] = ch;
36 
37     while (index < size)
38     {
39         if (read(fd, &ch, 1) == 1)
40         {
41             if (ch == '\n' || ch == '\r')
42             {
43                 line_buf[index] = '\0';
44                 break;
45             }
46 
47             line_buf[index++] = ch;
48         }
49         else
50         {
51             line_buf[index] = '\0';
52             break;
53         }
54     }
55 
56     return index;
57 }
58 
msh_exec_script(const char * cmd_line,int size)59 int msh_exec_script(const char *cmd_line, int size)
60 {
61     int ret;
62     int fd = -1;
63     char *pg_name;
64     int length, cmd_length = 0;
65 
66     if (size == 0) return -RT_ERROR;
67 
68     /* get the length of command0 */
69     while ((cmd_line[cmd_length] != ' ' && cmd_line[cmd_length] != '\t') && cmd_length < size)
70         cmd_length ++;
71 
72     /* get name length */
73     length = cmd_length + 32;
74 
75     /* allocate program name memory */
76     pg_name = (char *) rt_malloc(length);
77     if (pg_name == RT_NULL) return -RT_ENOMEM;
78 
79     /* copy command0 */
80     memcpy(pg_name, cmd_line, cmd_length);
81     pg_name[cmd_length] = '\0';
82 
83     if (strstr(pg_name, ".sh") != RT_NULL || strstr(pg_name, ".SH") != RT_NULL)
84     {
85         /* try to open program */
86         fd = open(pg_name, O_RDONLY, 0);
87 
88         /* search in /bin path */
89         if (fd < 0)
90         {
91             rt_snprintf(pg_name, length - 1, "/bin/%.*s", cmd_length, cmd_line);
92             fd = open(pg_name, O_RDONLY, 0);
93         }
94     }
95 
96     rt_free(pg_name);
97     if (fd >= 0)
98     {
99         /* found script */
100         char *line_buf;
101         int length;
102 
103         line_buf = (char *) rt_malloc(RT_CONSOLEBUF_SIZE);
104 
105         /* read line by line and then exec it */
106         do
107         {
108             length = msh_readline(fd, line_buf, RT_CONSOLEBUF_SIZE);
109             if (length > 0)
110             {
111                 char ch = '\0';
112                 int index;
113 
114                 for (index = 0; index < length; index ++)
115                 {
116                     ch = line_buf[index];
117                     if (ch == ' ' || ch == '\t') continue;
118                     else break;
119                 }
120 
121                 if (ch != '#') /* not a comment */
122                     msh_exec(line_buf, length);
123             }
124         }
125         while (length > 0);
126 
127         close(fd);
128         rt_free(line_buf);
129 
130         ret = 0;
131     }
132     else
133     {
134         ret = -1;
135     }
136 
137     return ret;
138 }
139 
140 #endif /* defined(FINSH_USING_MSH) && defined(RT_USING_DFS) */
141 
142