Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <ctype.h>
- #include <dirent.h>
- #include <pwd.h>
- #include <errno.h>
- #include "proto.h"
- #define BUF_SIZE 256
- static int expLiteralChars(char *orig, char *new, int *oldl_ind, int *newl_ind, int *insideQuoteFlag)
- {
- if(orig[*oldl_ind] == '"') *insideQuoteFlag = !(*insideQuoteFlag);
- new[*newl_ind] = orig[*oldl_ind];
- (*newl_ind)++;
- (*oldl_ind)++;
- return 0;
- }
- static int expEnvVars(char *orig, char *new, int *oldl_ind, int *newl_ind)
- {
- char *envValue;
- int envNameLen = 0;
- (*oldl_ind)++;
- while(orig[*oldl_ind + envNameLen] != '}')
- {
- if(orig[*oldl_ind + envNameLen] == 0 || orig[*oldl_ind + envNameLen] == '$')
- {
- fprintf(stderr, "msh: no matching }\n");
- return 1;
- }
- envNameLen++;
- }
- orig[*oldl_ind + envNameLen] = 0;
- envValue = getenv(&(orig[*oldl_ind]));
- if(envValue != NULL)
- {
- strcpy(&(new[*newl_ind]), envValue);
- *newl_ind = *newl_ind + strlen(envValue);
- }
- *oldl_ind = *oldl_ind + envNameLen + 1;
- // envNameLen = 0;
- return 0;
- }
- static int expShPid(char *orig, char *new, int *oldl_ind, int *newl_ind)
- {
- char pidBuff[8];
- int pid = (int)getpid();
- int i = 0;
- if(sprintf(pidBuff, "%d", pid) > -1)
- {
- while(pidBuff[i])
- {
- new[*newl_ind] = pidBuff[i++];
- (*newl_ind)++;
- }
- (*oldl_ind)++;
- return 0;
- }
- return 1;
- }
- static int expMainArgs(char *orig, char *new, int *oldl_ind, int *newl_ind) //, int mainargc, char **mainargv, char **shiftedMArgV)
- {
- int argInd;
- int argLen;
- char tempChar;
- char *argIndStr = &(orig[*oldl_ind]);
- while(isdigit(orig[*oldl_ind])) (*oldl_ind)++;
- tempChar = orig[(*oldl_ind)];
- orig[*oldl_ind] = 0;
- argInd = atoi(argIndStr);
- orig[*oldl_ind] = tempChar;
- if(m_argc == 1)
- {
- if(argInd >= m_shifted_argc) return 0;
- argLen = strlen(m_argv[0]);
- strcpy(&(new[*newl_ind]), m_argv[0]);
- }
- else
- {
- if((argInd+1) >= m_shifted_argc) return 0;
- if(argInd == 0)
- {
- argLen = strlen(m_argv[1]);
- strcpy(&(new[*newl_ind]), m_argv[1]);
- }
- else
- {
- argLen = strlen(m_shifted_argv[argInd+1]);
- strcpy(&(new[*newl_ind]), m_shifted_argv[argInd+1]);
- }
- }
- *newl_ind = *newl_ind + argLen;
- return 0;
- }
- static int expMainCount(char *new, int *newl_ind) //, int mainargc)
- {
- int argStrLen;
- int offset = 1;
- if(m_argc == 1) offset = 0;
- argStrLen = sprintf(&(new[*newl_ind]), "%d", (m_shifted_argc - offset));
- *newl_ind = *newl_ind + argStrLen;
- return 0;
- }
- static int expLastExitS(char *new, int *newl_ind)
- {
- int exStatStrLen = sprintf(&(new[*newl_ind]), "%d", (last_exit_status));
- *newl_ind = *newl_ind + exStatStrLen;
- return 0;
- }
- static int expWildCard(char *orig, char *new, int *oldl_ind, int *newl_ind, int filterFlag)
- {
- int i;
- int dirLen;
- int matchCount = 0;
- int passedFilterFlag = 0;
- int dirNameStrLen;
- char *dirName;
- char *filterStr;
- char tempChar;
- struct dirent **namelist;
- /* GET ALL THE DIRECTORIES AND PUT THEM IN namelist */
- dirLen = scandir(".", &namelist, 0, alphasort);
- if(dirLen < 0)
- {
- perror("scandir");
- return 1;
- }
- (*oldl_ind)++;
- if(filterFlag)
- {
- filterStr = &(orig[*oldl_ind]);
- while(orig[*oldl_ind] != ' ' && orig[*oldl_ind] != '"' && orig[*oldl_ind] != 0)
- {
- if(orig[*oldl_ind] == '/')
- {
- fprintf(stderr, "./msh: no match\n");
- return 1;
- }
- (*oldl_ind)++;
- }
- tempChar = orig[*oldl_ind];
- orig[*oldl_ind] = 0;
- }
- for(i = 0; i < dirLen; i++)
- {
- dirName = namelist[i]->d_name;
- dirNameStrLen = strlen(dirName);
- if(dirName[0] == '.')
- {
- passedFilterFlag = 0;
- }
- else if(filterFlag)
- {
- if(strlen(filterStr) > dirNameStrLen) passedFilterFlag = 0;
- else
- {
- if(!strcmp(filterStr, &(dirName[dirNameStrLen - strlen(filterStr)]))) passedFilterFlag = 1;
- else passedFilterFlag = 0;
- }
- }
- else passedFilterFlag = 1;
- if(passedFilterFlag)
- {
- matchCount++;
- strcpy(&(new[*newl_ind]), dirName);
- if(i != (dirLen -1))
- {
- *newl_ind = *newl_ind + dirNameStrLen + 1;
- new[*newl_ind - 1] = ' ';
- }
- else *newl_ind = *newl_ind + dirNameStrLen;
- }
- free(namelist[i]);
- }
- if(!matchCount)
- {
- new[*newl_ind] = '*';
- (*newl_ind)++;
- if(filterFlag)
- {
- strcpy(&(new[*newl_ind]), filterStr);
- *newl_ind = *newl_ind + strlen(filterStr);
- }
- }
- if(filterFlag) orig[*oldl_ind] = tempChar;
- free(namelist);
- return 0;
- }
- static int expHomeDir(char *orig, char *new, int *oldl_ind, int *newl_ind)
- {
- int i = 1;
- char temp;
- char *name = 0;
- char *hdir;
- struct passwd *pwResult;
- /* SEE IF NAME PRESENT AFTER ~ AND PUT NULL TERMINATOR AT END IF THERE IS
- IF NOT USE getlogin */
- while(orig[*oldl_ind + i] != ' ' && orig[*oldl_ind + i] != '/' && orig[*oldl_ind + i] != 0) i++;
- temp = orig[*oldl_ind +i];
- if(i == 1) name = getlogin();
- else
- {
- orig[*oldl_ind + i] = 0;
- name = &(orig[*oldl_ind + 1]);
- }
- /* GET PASSWD RESULTS, REPLACE NULL(OR NOTHING) WITH TEMP */
- pwResult = getpwnam(name);
- orig[*oldl_ind + i] = temp;
- /* UPDATE IND'S. IF THERE ARE NO PASSWD RESULTS, LEAVE LITERAL
- TILDA, OTHERWISE COPY HOME FOLDER TO NEW. */
- if(!pwResult)
- {
- new[*newl_ind] = '~';
- *oldl_ind = *oldl_ind + 1;
- *newl_ind = *newl_ind + 1;
- }
- else
- {
- hdir = pwResult->pw_dir;
- strcpy(&(new[*newl_ind]), hdir);
- *oldl_ind = *oldl_ind + i;
- *newl_ind = *newl_ind + strlen(hdir);
- }
- return 0;
- }
- static int expCmdOutput(char *orig, char *new, int *oldl_ind, int *newl_ind)
- {
- char buf[BUF_SIZE];
- int bytes_read;
- int total_bytes_read = 0;
- int fd[2];
- int parenthCount = 1;
- int i = *oldl_ind + 1;
- /* ENSURE MATCHING PARENS - REPLACE LAST PAREN WITH 0 */
- while(parenthCount > 0)
- {
- if(orig[i] == '(') parenthCount++;
- else if(orig[i] == ')') parenthCount--;
- else if(orig[i] == 0)
- {
- fprintf(stderr, "./msh: missing )\n");
- return 1;
- }
- i++;
- }
- orig[i-1] = 0;
- /* PIPE, RECURSIVELY CALL PROCESSLINE(should pass 0 for 3rd arg), AND CLOSE WRITE END */
- if(pipe (fd) < 0) perror("pipe");
- processline(&(orig[*oldl_ind + 1]), fd[1], 0);
- close(fd[1]);
- /* READ OUTPUT OF COMMAND FROM READ END OF PIPE, THEN CLOSE READ END */
- while((bytes_read = read(fd[0],buf,BUF_SIZE-1)))
- {
- if(bytes_read < 0)
- {
- if(errno == EWOULDBLOCK || errno == EAGAIN) continue;
- else if(errno == EINTR) fprintf(stderr, "WE GOT AN EINTR SIGNAL\n");
- else
- {
- perror("read");
- break; // Or should this be exit?
- }
- }
- else if(bytes_read > 0) total_bytes_read += bytes_read;
- }
- buf[total_bytes_read] = 0;
- close(fd[0]);
- /* REPLACE ORIGINAL MATCHING PAREN, UPDATE oldl_ind */
- orig[i-1] = ')';
- *oldl_ind = i;
- /* COPY OUTPUT OF COMMAND TO EXPANDED LINE, UPDATE newl_ind */
- i = 0;
- while(buf[i] != 0)// && buf[i] != '\n')
- {
- new[*newl_ind + i] = buf[i];
- i++;
- }
- *newl_ind = *newl_ind + i;
- /* REMOVING EXTRA LINES */
- i = 0;
- while(new[i])
- {
- if(new[i] == '\n') new[i] = ' ';// && new[i+1] != 0) new[i] = ' ';
- i++;
- }
- return 0;
- }
- int expand(char *orig, char *new, int newsize) //, int mainargc, char **mainargv, char **shiftedMArgV)
- {
- int newl_ind = 0;
- int oldl_ind = 0;
- int insideQuoteFlag = 0;
- while(orig[oldl_ind] && newl_ind < newsize)
- {
- if(orig[oldl_ind] == '$')
- {
- if(orig[++oldl_ind] == '{') { if(expEnvVars(orig, new, &oldl_ind, &newl_ind)) return 1; }
- else if(orig[oldl_ind] == '(') { if(expCmdOutput(orig, new, &oldl_ind, &newl_ind)) return 1; }
- else if(orig[oldl_ind] == '$') { if(expShPid(orig, new, &oldl_ind, &newl_ind)) return 1; }
- else if(isdigit(orig[oldl_ind])) { if(expMainArgs(orig, new, &oldl_ind, &newl_ind)) return 1; } //, mainargc, mainargv, shiftedMArgV)) return 1; }
- else if(orig[oldl_ind] == '#') {
- if(expMainCount(new, &newl_ind)) return 1;
- oldl_ind++;
- }
- else if(orig[oldl_ind] == '?') {
- if(expLastExitS(new, &newl_ind)) return 1;
- oldl_ind++;
- }
- else
- {
- new[newl_ind] = orig[oldl_ind - 1];
- newl_ind++;
- }
- }
- else if(orig[oldl_ind] == '*')
- {
- if(orig[oldl_ind-1] == ' ' || orig[oldl_ind-1] == '"' || oldl_ind == 0)
- {
- if(orig[oldl_ind+1] == ' ' || orig[oldl_ind+1] == '"' || orig[oldl_ind+1] == 0)
- {
- if(expWildCard(orig, new, &oldl_ind, &newl_ind, 0)) return 1;
- }
- else
- {
- if(expWildCard(orig, new, &oldl_ind, &newl_ind, 1)) return 1;
- }
- }
- else if(orig[oldl_ind-1] == '\\')
- {
- new[newl_ind-1] = '*';
- oldl_ind++;
- }
- else
- {
- /*new[newl_ind] = '*';
- newl_ind++;
- oldl_ind++;*/
- if(expLiteralChars(orig, new, &oldl_ind, &newl_ind, &insideQuoteFlag)) return 1;
- }
- }
- else if(orig[oldl_ind] == '#' && !insideQuoteFlag) break;
- else if(orig[oldl_ind] == '~' && orig[oldl_ind-1] == ' ')
- {
- if(expHomeDir(orig, new, &oldl_ind, &newl_ind)) return 1;
- }
- else
- {
- /*if(orig[oldl_ind] == '"') insideQuoteFlag = !insideQuoteFlag;
- new[newl_ind] = orig[oldl_ind];
- newl_ind++;
- oldl_ind++;*/
- if(expLiteralChars(orig, new, &oldl_ind, &newl_ind, &insideQuoteFlag)) return 1;
- }
- }
- new[newl_ind] = 0;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement