Advertisement
Guest User

expand.c

a guest
Nov 19th, 2012
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.14 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <ctype.h>
  6. #include <dirent.h>
  7. #include <pwd.h>
  8. #include <errno.h>
  9. #include "proto.h"
  10.  
  11. #define BUF_SIZE 256
  12.  
  13. static int expLiteralChars(char *orig, char *new, int *oldl_ind, int *newl_ind, int *insideQuoteFlag)
  14. {
  15.     if(orig[*oldl_ind] == '"') *insideQuoteFlag = !(*insideQuoteFlag);
  16.     new[*newl_ind] = orig[*oldl_ind];
  17.     (*newl_ind)++;
  18.     (*oldl_ind)++;
  19.     return 0;
  20. }
  21.  
  22. static int expEnvVars(char *orig, char *new, int *oldl_ind, int *newl_ind)
  23. {
  24.     char *envValue;
  25.     int envNameLen = 0;
  26.  
  27.     (*oldl_ind)++;
  28.     while(orig[*oldl_ind + envNameLen] != '}')
  29.     {
  30.         if(orig[*oldl_ind + envNameLen] == 0 || orig[*oldl_ind + envNameLen] == '$')
  31.         {
  32.             fprintf(stderr, "msh: no matching }\n");
  33.             return 1;
  34.         }
  35.         envNameLen++;
  36.     }
  37.  
  38.     orig[*oldl_ind + envNameLen] = 0;
  39.     envValue = getenv(&(orig[*oldl_ind]));
  40.  
  41.  
  42.     if(envValue != NULL)
  43.     {
  44.         strcpy(&(new[*newl_ind]), envValue);
  45.         *newl_ind = *newl_ind + strlen(envValue);
  46.     }
  47.    
  48.     *oldl_ind = *oldl_ind + envNameLen + 1;
  49.     // envNameLen = 0;
  50.     return 0;
  51. }
  52.  
  53. static int expShPid(char *orig, char *new, int *oldl_ind, int *newl_ind)
  54. {
  55.     char pidBuff[8];
  56.     int pid = (int)getpid();
  57.     int i = 0;
  58.  
  59.     if(sprintf(pidBuff, "%d", pid) > -1)
  60.     {
  61.         while(pidBuff[i])
  62.         {
  63.             new[*newl_ind] = pidBuff[i++];
  64.             (*newl_ind)++;
  65.         }
  66.         (*oldl_ind)++;
  67.         return 0;
  68.     }
  69.     return 1;
  70. }
  71.  
  72. static int expMainArgs(char *orig, char *new, int *oldl_ind, int *newl_ind) //, int mainargc, char **mainargv, char **shiftedMArgV)
  73. {
  74.     int argInd;
  75.     int argLen;
  76.     char tempChar;
  77.     char *argIndStr = &(orig[*oldl_ind]);
  78.  
  79.     while(isdigit(orig[*oldl_ind])) (*oldl_ind)++;
  80.  
  81.     tempChar = orig[(*oldl_ind)];
  82.     orig[*oldl_ind] = 0;
  83.     argInd = atoi(argIndStr);
  84.     orig[*oldl_ind] = tempChar;
  85.  
  86.  
  87.     if(m_argc == 1)
  88.     {
  89.         if(argInd >= m_shifted_argc) return 0;
  90.         argLen = strlen(m_argv[0]);
  91.         strcpy(&(new[*newl_ind]), m_argv[0]);
  92.     }
  93.     else
  94.     {
  95.         if((argInd+1) >= m_shifted_argc) return 0;
  96.         if(argInd == 0)
  97.         {
  98.             argLen = strlen(m_argv[1]);
  99.             strcpy(&(new[*newl_ind]), m_argv[1]);
  100.         }
  101.         else
  102.         {
  103.             argLen = strlen(m_shifted_argv[argInd+1]);
  104.             strcpy(&(new[*newl_ind]), m_shifted_argv[argInd+1]);
  105.         }
  106.     }
  107.  
  108.     *newl_ind = *newl_ind + argLen;
  109.     return 0;
  110. }
  111.  
  112. static int expMainCount(char *new, int *newl_ind) //, int mainargc)
  113. {
  114.     int argStrLen;
  115.     int offset = 1;
  116.  
  117.     if(m_argc == 1) offset = 0;
  118.  
  119.     argStrLen = sprintf(&(new[*newl_ind]), "%d", (m_shifted_argc - offset));
  120.  
  121.     *newl_ind = *newl_ind + argStrLen;
  122.  
  123.     return 0;
  124. }
  125.  
  126. static int expLastExitS(char *new, int *newl_ind)
  127. {
  128.     int exStatStrLen = sprintf(&(new[*newl_ind]), "%d", (last_exit_status));
  129.  
  130.     *newl_ind = *newl_ind + exStatStrLen;
  131.  
  132.     return 0;
  133. }
  134.  
  135. static int expWildCard(char *orig, char *new, int *oldl_ind, int *newl_ind, int filterFlag)
  136. {
  137.     int i;
  138.     int dirLen;
  139.     int matchCount = 0;
  140.     int passedFilterFlag = 0;
  141.     int dirNameStrLen;
  142.     char *dirName;
  143.     char *filterStr;
  144.     char tempChar;
  145.     struct dirent **namelist;
  146.  
  147.     /* GET ALL THE DIRECTORIES AND PUT THEM IN namelist */
  148.     dirLen = scandir(".", &namelist, 0, alphasort);
  149.     if(dirLen < 0)
  150.     {
  151.         perror("scandir");
  152.         return 1;
  153.     }
  154.  
  155.     (*oldl_ind)++;
  156.     if(filterFlag)
  157.     {
  158.         filterStr = &(orig[*oldl_ind]);
  159.         while(orig[*oldl_ind] != ' ' && orig[*oldl_ind] != '"' && orig[*oldl_ind] != 0)
  160.         {
  161.             if(orig[*oldl_ind] == '/')
  162.             {
  163.                 fprintf(stderr, "./msh: no match\n");
  164.                 return 1;
  165.             }
  166.             (*oldl_ind)++;
  167.         }
  168.         tempChar = orig[*oldl_ind];
  169.         orig[*oldl_ind] = 0;
  170.     }
  171.  
  172.     for(i = 0; i < dirLen; i++)
  173.     {
  174.         dirName = namelist[i]->d_name;
  175.         dirNameStrLen = strlen(dirName);
  176.  
  177.         if(dirName[0] == '.')
  178.         {
  179.             passedFilterFlag = 0;
  180.         }
  181.         else if(filterFlag)
  182.         {
  183.             if(strlen(filterStr) > dirNameStrLen) passedFilterFlag = 0;
  184.             else
  185.             {
  186.                 if(!strcmp(filterStr, &(dirName[dirNameStrLen - strlen(filterStr)]))) passedFilterFlag = 1;
  187.                 else passedFilterFlag = 0;
  188.             }
  189.         }
  190.         else passedFilterFlag = 1;
  191.  
  192.         if(passedFilterFlag)
  193.         {
  194.             matchCount++;
  195.             strcpy(&(new[*newl_ind]), dirName);
  196.             if(i != (dirLen -1))
  197.             {
  198.                 *newl_ind = *newl_ind + dirNameStrLen + 1;
  199.                 new[*newl_ind - 1] = ' ';
  200.             }
  201.             else *newl_ind = *newl_ind + dirNameStrLen;
  202.         }
  203.  
  204.         free(namelist[i]);
  205.     }
  206.  
  207.     if(!matchCount)
  208.     {
  209.         new[*newl_ind] = '*';
  210.         (*newl_ind)++;
  211.         if(filterFlag)
  212.         {
  213.             strcpy(&(new[*newl_ind]), filterStr);
  214.             *newl_ind = *newl_ind + strlen(filterStr);
  215.         }
  216.     }
  217.  
  218.     if(filterFlag) orig[*oldl_ind] = tempChar;
  219.     free(namelist);
  220.     return 0;
  221. }
  222.  
  223. static int expHomeDir(char *orig, char *new, int *oldl_ind, int *newl_ind)
  224. {
  225.     int i = 1;
  226.     char temp;
  227.     char *name = 0;
  228.     char *hdir;
  229.     struct passwd *pwResult;
  230.    
  231.     /* SEE IF NAME PRESENT AFTER ~ AND PUT NULL TERMINATOR AT END IF THERE IS
  232.        IF NOT USE getlogin */
  233.     while(orig[*oldl_ind + i] != ' ' && orig[*oldl_ind + i] != '/' && orig[*oldl_ind + i] != 0) i++;
  234.     temp = orig[*oldl_ind +i];
  235.     if(i == 1) name = getlogin();
  236.     else
  237.     {
  238.         orig[*oldl_ind + i] = 0;
  239.         name = &(orig[*oldl_ind + 1]);
  240.     }
  241.    
  242.     /* GET PASSWD RESULTS, REPLACE NULL(OR NOTHING) WITH TEMP */
  243.     pwResult = getpwnam(name);
  244.     orig[*oldl_ind + i] = temp;
  245.    
  246.     /* UPDATE IND'S. IF THERE ARE NO PASSWD RESULTS, LEAVE LITERAL
  247.        TILDA, OTHERWISE COPY HOME FOLDER TO NEW. */
  248.     if(!pwResult)
  249.     {
  250.         new[*newl_ind] = '~';
  251.         *oldl_ind = *oldl_ind + 1;
  252.         *newl_ind = *newl_ind + 1;
  253.     }
  254.     else
  255.     {
  256.         hdir = pwResult->pw_dir;
  257.         strcpy(&(new[*newl_ind]), hdir);
  258.        
  259.         *oldl_ind = *oldl_ind + i;
  260.         *newl_ind = *newl_ind + strlen(hdir);
  261.     }
  262.    
  263.     return 0;
  264. }
  265.  
  266. static int expCmdOutput(char *orig, char *new, int *oldl_ind, int *newl_ind)
  267. {
  268.     char buf[BUF_SIZE];
  269.     int bytes_read;
  270.     int total_bytes_read = 0;
  271.     int fd[2];
  272.     int parenthCount = 1;
  273.     int i = *oldl_ind + 1;
  274.    
  275.     /* ENSURE MATCHING PARENS - REPLACE LAST PAREN WITH 0 */
  276.     while(parenthCount > 0)
  277.     {
  278.         if(orig[i] == '(') parenthCount++;
  279.         else if(orig[i] == ')') parenthCount--;
  280.         else if(orig[i] == 0)
  281.         {
  282.             fprintf(stderr, "./msh: missing )\n");
  283.             return 1;
  284.         }
  285.         i++;
  286.     }
  287.     orig[i-1] = 0;
  288.    
  289.     /* PIPE, RECURSIVELY CALL PROCESSLINE(should pass 0 for 3rd arg), AND CLOSE WRITE END */
  290.     if(pipe (fd) < 0) perror("pipe");
  291.     processline(&(orig[*oldl_ind + 1]), fd[1], 0);
  292.     close(fd[1]);
  293.    
  294.     /* READ OUTPUT OF COMMAND FROM READ END OF PIPE, THEN CLOSE READ END */
  295.     while((bytes_read = read(fd[0],buf,BUF_SIZE-1)))
  296.     {
  297.         if(bytes_read < 0)
  298.         {
  299.             if(errno == EWOULDBLOCK || errno == EAGAIN) continue;
  300.             else if(errno == EINTR) fprintf(stderr, "WE GOT AN EINTR SIGNAL\n");
  301.             else
  302.             {
  303.                 perror("read");
  304.                 break; // Or should this be exit?
  305.             }
  306.         }
  307.         else if(bytes_read > 0) total_bytes_read += bytes_read;
  308.     }
  309.     buf[total_bytes_read] = 0;
  310.     close(fd[0]);
  311.    
  312.     /* REPLACE ORIGINAL MATCHING PAREN, UPDATE oldl_ind */
  313.     orig[i-1] = ')';
  314.     *oldl_ind = i;
  315.    
  316.     /* COPY OUTPUT OF COMMAND TO EXPANDED LINE, UPDATE newl_ind */
  317.     i = 0;
  318.     while(buf[i] != 0)// && buf[i] != '\n')
  319.     {
  320.         new[*newl_ind + i] = buf[i];
  321.         i++;
  322.     }
  323.     *newl_ind = *newl_ind + i;
  324.    
  325.     /* REMOVING EXTRA LINES */
  326.     i = 0;
  327.     while(new[i])
  328.     {
  329.         if(new[i] == '\n') new[i] = ' ';// && new[i+1] != 0) new[i] = ' ';
  330.         i++;
  331.     }
  332.    
  333.     return 0;
  334. }
  335.  
  336. int expand(char *orig, char *new, int newsize) //, int mainargc, char **mainargv, char **shiftedMArgV)
  337. {
  338.     int newl_ind = 0;
  339.     int oldl_ind = 0;
  340.     int insideQuoteFlag = 0;
  341.  
  342.     while(orig[oldl_ind] && newl_ind < newsize)
  343.     {
  344.         if(orig[oldl_ind] == '$')
  345.         {
  346.             if(orig[++oldl_ind] == '{') { if(expEnvVars(orig, new, &oldl_ind, &newl_ind)) return 1; }
  347.             else if(orig[oldl_ind] == '(') { if(expCmdOutput(orig, new, &oldl_ind, &newl_ind)) return 1; }
  348.             else if(orig[oldl_ind] == '$') { if(expShPid(orig, new, &oldl_ind, &newl_ind)) return 1; }
  349.             else if(isdigit(orig[oldl_ind])) { if(expMainArgs(orig, new, &oldl_ind, &newl_ind)) return 1; } //, mainargc, mainargv, shiftedMArgV)) return 1; }
  350.             else if(orig[oldl_ind] == '#') {
  351.                 if(expMainCount(new, &newl_ind)) return 1;
  352.                 oldl_ind++;
  353.             }
  354.             else if(orig[oldl_ind] == '?') {
  355.                 if(expLastExitS(new, &newl_ind)) return 1;
  356.                 oldl_ind++;
  357.             }
  358.             else
  359.             {
  360.                 new[newl_ind] = orig[oldl_ind - 1];
  361.                 newl_ind++;
  362.             }
  363.         }
  364.         else if(orig[oldl_ind] == '*')
  365.         {
  366.             if(orig[oldl_ind-1] == ' ' || orig[oldl_ind-1] == '"' || oldl_ind == 0)
  367.             {
  368.                 if(orig[oldl_ind+1] == ' ' || orig[oldl_ind+1] == '"' || orig[oldl_ind+1] == 0)
  369.                 {
  370.                     if(expWildCard(orig, new, &oldl_ind, &newl_ind, 0)) return 1;
  371.                 }
  372.                 else
  373.                 {
  374.                     if(expWildCard(orig, new, &oldl_ind, &newl_ind, 1)) return 1;
  375.                 }
  376.             }
  377.             else if(orig[oldl_ind-1] == '\\')
  378.             {
  379.                 new[newl_ind-1] = '*';
  380.                 oldl_ind++;
  381.             }
  382.             else
  383.             {
  384.                 /*new[newl_ind] = '*';
  385.                 newl_ind++;
  386.                 oldl_ind++;*/
  387.                 if(expLiteralChars(orig, new, &oldl_ind, &newl_ind, &insideQuoteFlag)) return 1;
  388.             }
  389.         }
  390.         else if(orig[oldl_ind] == '#' && !insideQuoteFlag) break;
  391.         else if(orig[oldl_ind] == '~' && orig[oldl_ind-1] == ' ')
  392.         {
  393.             if(expHomeDir(orig, new, &oldl_ind, &newl_ind)) return 1;
  394.         }
  395.         else
  396.         {
  397.             /*if(orig[oldl_ind] == '"') insideQuoteFlag = !insideQuoteFlag;
  398.             new[newl_ind] = orig[oldl_ind];
  399.             newl_ind++;
  400.             oldl_ind++;*/
  401.             if(expLiteralChars(orig, new, &oldl_ind, &newl_ind, &insideQuoteFlag)) return 1;
  402.         }
  403.     }
  404.     new[newl_ind] = 0;
  405.     return 0;
  406. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement