mshell/src/line_parce.c
Dm1tr1y147 885bd34da3 Added setting environment variables with APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL=trueCHROME_DESKTOP=code-oss.desktopCOLORTERM=truecolorDBUS_SESSION_BUS_ADDRESS='unix:path=/run/user/1000/bus'DISPLAY=:0GIT_ASKPASS=/usr/lib/code/extensions/git/dist/askpass.shGTK_MODULES=canberra-gtk-moduleHOME=/home/dshI3SOCK=/run/user/1000/i3/ipc-socket.521LANG=en_US.UTF-8LESS=-RLESSHISTFILE=-LESSPROMPT='?f%f .?ltLine %lt:?pt%pt\%:?btByte %bt:-...'LESS_TERMCAP_mb=$'\C-[[31m'LESS_TERMCAP_md=$'\C-[[31m'LESS_TERMCAP_me=$'\C-[[0m'LESS_TERMCAP_se=$'\C-[[0m'LESS_TERMCAP_so=$'\C-[[47;30m'LESS_TERMCAP_ue=$'\C-[[0m'LESS_TERMCAP_us=$'\C-[[32m'LOGNAME=dshLS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:'MAIL=/var/spool/mail/dshMANWIDTH=120MOZ_PLUGIN_PATH=/usr/lib/mozilla/pluginsNO_AT_BRIDGE=1OLDPWD=/mnt/hdd/Work/Development/C/myshellPATH=/home/dsh/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perlPWD=/mnt/hdd/Work/Development/C/myshellSHELL=/bin/zshSHLVL=3TERM=xterm-256colorTERM_PROGRAM=vscodeTERM_PROGRAM_VERSION=1.46.1USER=dshVSCODE_GIT_ASKPASS_MAIN=/usr/lib/code/extensions/git/dist/askpass-main.jsVSCODE_GIT_ASKPASS_NODE=/usr/lib/electron7/electronVSCODE_GIT_IPC_HANDLE=/run/user/1000/vscode-git-55765a537b.sockWINDOWPATH=1XAUTHORITY=/home/dsh/.XauthorityXDG_CONFIG_HOME=/home/dsh/.configXDG_RUNTIME_DIR=/run/user/1000XDG_SEAT=seat0XDG_SESSION_CLASS=userXDG_SESSION_ID=1XDG_SESSION_TYPE=ttyXDG_VTNR=1 and before command locally
2020-07-18 20:40:51 +05:00

341 lines
8.7 KiB
C

#include "../include/shell.h"
#include "../include/utils.h"
#include "../include/input.h"
/**
* @brief Extracts command and its arguments from line
*
* @param line
* @param args
*/
cmds_p *process_line(char *line)
{
int line_size = strlen(line);
if (line_size < 1)
return NULL;
char *tmp = strdup(line), *free_tmp = tmp;
cmds_p *coms = new_cmd();
cmds_p *curr_cmd = coms;
cmd_pipe *curr_pipe = curr_cmd->pipe;
curr_pipe->pipefd[0] = STDIN_FILENO;
for (int i = 0; i < line_size; i++)
{
if (line[i] == '"')
{
tmp++;
i++;
int j = i;
for (; j < line_size; j++)
if (line[j] == '"')
{
free_tmp[j] = '\0';
append_to_str_arr(&curr_pipe->args, &curr_pipe->args_am, trim_string(tmp, false));
tmp += strlen(curr_pipe->args[curr_pipe->args_am - 1]) + 1;
break;
}
if (j >= line_size)
{
char *ap_line = read_line();
line = realloc(line, strlen(line) + strlen(ap_line) + 1);
line = strcat(line, ap_line);
line_size = strlen(line);
free(ap_line);
i--;
continue;
}
i = j;
if (tmp[0] == ' ')
{
tmp++;
i++;
}
}
else if (line[i] == ';' || (line[i] == '&' && line[i + 1] == '&') || (line[i] == '|' && line[i + 1] == '|'))
{
free_tmp[i] = '\0';
if (line[i - 1] != ' ')
{
append_to_str_arr(&curr_pipe->args, &curr_pipe->args_am, trim_string(tmp, false));
tmp += strlen(curr_pipe->args[curr_pipe->args_am - 1]) + 1;
}
else
tmp++;
curr_pipe->args = realloc(curr_pipe->args, sizeof(char *) * (curr_pipe->args_am + 1));
curr_pipe->args[curr_pipe->args_am] = NULL;
switch (line[i])
{
case ';':
curr_cmd->sep_next = SEMICOLON_SEP;
break;
case '&':
curr_cmd->sep_next = AND_SEP;
i++;
tmp++;
break;
case '|':
curr_cmd->sep_next = OR_SEP;
i++;
tmp++;
break;
}
if (tmp[0] == ' ')
{
tmp++;
i++;
}
if (curr_pipe->args[0] != NULL)
{
if (strcmp(curr_pipe->args[0], "!") == 0)
{
curr_cmd->stat.invert = true;
}
}
cmds_p *next = new_cmd();
curr_cmd->next = next;
curr_cmd = curr_cmd->next;
curr_pipe = curr_cmd->pipe;
}
else if (line[i] == '|')
{
if (line[i - 1] != ' ')
{
append_to_str_arr(&curr_pipe->args, &curr_pipe->args_am, trim_string(tmp, false));
tmp += strlen(curr_pipe->args[curr_pipe->args_am - 1]) + 1;
}
else
tmp++;
curr_pipe->args = realloc(curr_pipe->args, sizeof(char *) * (curr_pipe->args_am + 1));
curr_pipe->args[curr_pipe->args_am] = NULL;
if (tmp[0] == ' ')
{
tmp++;
i++;
}
if (curr_pipe->args[0] != NULL)
{
if (strcmp(curr_pipe->args[0], "!") == 0)
{
curr_cmd->stat.invert = true;
}
}
cmd_pipe *next = new_cmd_pipe();
curr_pipe->next = next;
curr_cmd->pipes_am++;
curr_pipe = curr_pipe->next;
}
else if (line[i] == '>' || line[i] == '<')
{
int flags = 0;
int f = 0;
if (line[i] == '>' && line[i + 1] == '>')
{
flags = O_CREAT | O_APPEND | O_WRONLY;
i++;
tmp++;
f = 0;
}
else if (line[i] == '>')
{
flags = O_CREAT | O_TRUNC | O_WRONLY;
f = 0;
}
else if (line[i] == '<' && line[i + 1] == '>')
{
flags = O_CREAT | O_RDWR;
i++;
tmp++;
f = 1;
}
else if (line[i] == '<')
{
flags = O_RDONLY;
f = 2;
}
i++;
tmp++;
if (line[i] == ' ')
{
i++;
tmp++;
}
int j = i;
for (; j < line_size; j++)
if (line[j] == ' ' || line[j] == '|' || line[j] == '&' || line[j] == ';')
break;
free_tmp[j] = '\0';
if (tmp[0] == '"')
tmp++;
if (free_tmp[j - 1] == '"')
free_tmp[j - 1] = '\0';
int ffd;
if ((ffd = open(tmp, flags)) < 0)
{
perror("file redirection: open");
return NULL;
}
if (f == 0)
curr_pipe->pipefd[1] = ffd;
else if (f == 1)
for (int k = 0; k < 2; k++)
curr_pipe->pipefd[k] = ffd;
else if (f == 2)
curr_pipe->pipefd[0] = ffd;
tmp += j - i + 1;
i = j;
}
else if (line[i] == '$')
{
tmp++;
i++;
int j = i;
for (; j < line_size; j++)
if (line[j] == ' ' || line[j] == ';' || line[j] == '&' || line[j] == '|' || line[j] == '>' || line[j] == '<')
break;
free_tmp[j] = '\0';
char *msg = NULL;
for (int k = 0; k < curr_cmd->envs_am; k++)
if (strncmp(curr_cmd->envs[k], tmp, strlen(tmp)) == 0)
msg = strchr(curr_cmd->envs[k], '=') + 1;
if (msg == NULL)
{
msg = getenv(tmp);
if (msg == NULL)
msg = "\n";
}
append_to_str_arr(&curr_pipe->args, &curr_pipe->args_am, msg);
tmp += j - i + 1;
i = j;
}
else if (line[i] == ' ')
{
free_tmp[i] = '\0';
if (curr_cmd->pipe->args[0] == NULL && strchr(tmp, '='))
{
append_to_str_arr(&curr_cmd->envs, &curr_cmd->envs_am, tmp);
tmp += strlen(curr_cmd->envs[curr_cmd->envs_am - 1]) + 1;
continue;
}
char *ap_string = trim_string(tmp, false), **exp = calloc(0, sizeof(char *));
int sz = expand_wildcatrd(&exp, ap_string);
for (int l = 0; l < sz; l++)
append_to_str_arr(&curr_pipe->args, &curr_pipe->args_am, exp[l]);
tmp += strlen(ap_string) + 1;
}
else if (line[i] == '#')
{
break;
}
}
if (tmp[0] != '\0' && tmp[0] != '#')
{
if (tmp[strlen(tmp) - 1] != '"')
{
char *ap_string = trim_string(tmp, false), **exp = calloc(0, sizeof(char *));
int sz = expand_wildcatrd(&exp, ap_string);
for (int l = 0; l < sz; l++)
append_to_str_arr(&curr_pipe->args, &curr_pipe->args_am, exp[l]);
}
else
append_to_str_arr(&curr_pipe->args, &curr_pipe->args_am, trim_string(tmp, false));
}
if (curr_pipe->args[0] != NULL)
{
if (strcmp(curr_pipe->args[0], "!") == 0)
{
curr_cmd->stat.invert = true;
}
}
free(free_tmp);
if (curr_pipe->args[curr_pipe->args_am] != NULL)
{
curr_pipe->args = realloc(curr_pipe->args, sizeof(char *) * (curr_pipe->args_am + 1));
curr_pipe->args[curr_pipe->args_am] = NULL;
}
if (curr_pipe->pipefd[1] < 0)
curr_pipe->pipefd[1] = STDOUT_FILENO;
return coms;
}
/**
* @brief Expands wildcard in argument
*
* @param arr
* @param input
* @return int
*/
int expand_wildcatrd(char ***arr, char *input)
{
ssize_t size = 0;
if (strchr(input, '*') || strchr(input, '~') || strchr(input, '?'))
{
glob_t globbuf;
int t = glob(input, GLOB_TILDE, NULL, &globbuf);
if (t != 0)
perror("Glob");
for (int j = 0; j < globbuf.gl_pathc; j++)
append_to_str_arr(arr, &size, globbuf.gl_pathv[j]);
}
else
append_to_str_arr(arr, &size, input);
return size;
}