This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

expand.c

By: a guest on Nov 19th, 2012  |  syntax: C  |  size: 9.14 KB  |  views: 61  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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. }
clone this paste RAW Paste Data