home *** CD-ROM | disk | FTP | other *** search
/ Media Depot 5 / mediadepotvolume51993.iso / FILES / 16 / FREEDOS.ZIP / COM050.ZIP / INTERNAL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-18  |  13.4 KB  |  611 lines

  1. /*
  2.  *  INTERNAL.C - command.com internal commands.
  3.  *
  4.  *  Comments:
  5.  *
  6.  *  17/08/94 (Tim Norman) ---------------------------------------------------
  7.  *    started.
  8.  *
  9.  *  08/08/95 (Matt Rains) ---------------------------------------------------
  10.  *    i have cleaned up the source code. changes now bring this source into
  11.  *    guidelines for recommended programming practice.
  12.  *
  13.  *  cd()
  14.  *    started.
  15.  *
  16.  *  dir()
  17.  *    i have added support for file attributes to the DIR() function. the
  18.  *    routine adds "d" (directory) and "r" (read only) output. files with the
  19.  *    system attribute have the filename converted to lowercase. files with
  20.  *    the hidden attribute are not displayed.
  21.  *
  22.  *    i have added support for directorys. now if the directory attribute is
  23.  *    detected the file size if replaced with the string "<dir>".
  24.  *
  25.  *  ver()
  26.  *    started.
  27.  *
  28.  *  md()
  29.  *    started.
  30.  *
  31.  *  rd()
  32.  *    started.
  33.  *
  34.  *  del()
  35.  *    started.
  36.  *
  37.  *  does not support wildcard selection.
  38.  *
  39.  *  todo: add delete directory support.
  40.  *        add recursive directory delete support.
  41.  *
  42.  *  ren()
  43.  *    started.
  44.  *
  45.  *  does not support wildcard selection.
  46.  *
  47.  *    todo: add rename directory support.
  48.  *
  49.  *  a general structure has been used for the cd, rd and md commands. this
  50.  *  will be better in the long run. it is too hard to maintain such diverse
  51.  *  functions when you are involved in a group project like this.
  52.  *
  53.  *  12/14/95 (Tim Norman) -----------------------------------------------------
  54.  *    fixed DIR so that it will stick \*.* if a directory is specified and
  55.  *    that it will stick on .* if a file with no extension is specified or
  56.  *    *.* if it ends in a \
  57.  *
  58.  *  1/6/96 (Tim Norman) -----------------------------------------------------
  59.  *    added an isatty call to DIR so it won't prompt for keypresses unless
  60.  *    stdin and stdout are the console.
  61.  *
  62.  *    changed parameters to be mutually consistent to make calling the
  63.  *    functions easier
  64.  *
  65.  *  rem()
  66.  *    started.
  67.  *
  68.  *  doskey()
  69.  *    started.
  70.  *
  71.  */
  72.  
  73. #include <stdlib.h>
  74. #include <dos.h>
  75. #include <stdio.h>
  76. #include <ctype.h>
  77. #include <string.h>
  78. #include <dir.h>
  79. #include <conio.h>
  80. #include <io.h>
  81.  
  82. #define SHELLINFO    "FreeDOS Command Line Interface"
  83. #define SHELLVER     "version 0.50"
  84. #define BADCMDLINE   "bad or incorrect commandline"
  85. #define USAGE        "usage"
  86. #define CD           "change to directory   cd [d:][path]"
  87. #define MD           "make directory   md [d:]path"
  88. #define RD           "remove directory   rd [d:]path"
  89. #define DIR          "display directory listing   dir [d:][path][filespec]"
  90. #define VER          "display shell version info   ver"
  91. #define DEL          "delete file   del [d:][path]filespec"
  92. #define REN          "rename file   ren [d:][path]filespec1 [d:][path]filespec2"
  93. #define SETPROMPT    "SET PROMPT="
  94.  
  95. /*
  96.  * set environment variables
  97.  *
  98.  *
  99.  */
  100. #pragma argsused
  101. void set(int argc, char *argv[], char *commandline)
  102. {
  103.    int r;
  104.    unsigned char count;
  105.    static char env_temp[128]; /* must be static to use putenv() */
  106.    char *command;
  107.  
  108.    if (argc == 1)
  109.    {
  110.       void show_environment (void);
  111.  
  112.       show_environment ();
  113.       return;
  114.    }
  115.  
  116.    command = commandline;
  117.  
  118.    while(isspace(*command)) /* skip over "set" and whitespace */
  119.    {
  120.       command++;
  121.    }
  122.  
  123.    while(!isspace(*command))
  124.    {
  125.       command++;
  126.    }
  127.  
  128.    while(isspace(*command))
  129.    {
  130.       command++;
  131.    }
  132.  
  133.    strcpy(env_temp, command);
  134.    count = strlen (env_temp) - 1; /* remove trailing spaces */
  135.  
  136.    while(env_temp[count] == ' ')
  137.    {
  138.       env_temp[count--] = 0;
  139.    }
  140.  
  141.    if(strstr(env_temp, "=") == NULL)
  142.    {
  143.       puts("Syntax error");
  144.       return;
  145.    }
  146.  
  147.    /* capitalize name of env. var. */
  148.    for(count = 0; env_temp[count] != '=' && env_temp[count] != 0; count++)
  149.    {
  150.       env_temp[count] = toupper(env_temp[count]);
  151.    }
  152.  
  153.    r = putenv(env_temp);
  154.  
  155.    if(r == -1)
  156.    {
  157.       puts("Environment error");
  158.    }
  159.  
  160.    return;
  161. }
  162.  
  163. /*
  164.  *  simple change to directory internal command.
  165.  *
  166.  *
  167.  */
  168. #pragma argsused
  169. void cd(int args, char *p[128], char *commandline)
  170. {
  171.    int errnum;
  172.    char dir[128];
  173.  
  174.    if (args == 1)
  175.    {
  176.       strcpy (dir, &p[0][2]);
  177.    }
  178.    else if (args == 2)
  179.    {
  180.       strcpy (dir, p[1]);
  181.    }
  182.    else
  183.    {
  184.       printf("%s\n", BADCMDLINE);
  185.       printf("%s: %s\n", USAGE, CD);
  186.       return;
  187.    }
  188.  
  189.    /* if no parameters given, print out the current directory */
  190.    if (!dir[0])
  191.    {
  192.       char direc[128];
  193.       char temp[128];
  194.  
  195.       direc[0] = getdisk() + 'A';
  196.       direc[1] = ':';
  197.       getcurdir(0, temp);
  198.  
  199.       if(temp[0] == '\\')
  200.       {
  201.      strcpy(&direc[2], temp);
  202.       }
  203.       else
  204.       {
  205.      direc[2] = '\\';
  206.      strcpy(&direc[3], temp);
  207.       }
  208.  
  209.       printf("%s\n", direc);
  210.  
  211.       return;
  212.    }
  213.  
  214.    /* take off trailing \ if any... */
  215.    if (strlen (dir) > 1 && dir[strlen (dir) - 1] == '\\')
  216.       dir[strlen (dir) - 1] = 0;
  217.  
  218.    if((errnum = chdir(dir)) != 0)
  219.    {
  220.       printf("cd() : error %d\n\n", errnum);
  221.    }
  222.  
  223.    return;
  224. }
  225.  
  226. /*
  227.  *  simple make directory internal command.
  228.  *
  229.  *
  230.  */
  231. #pragma argsused
  232. void md(int args, char *p[128], char *commandline)
  233. {
  234.    int errnum;
  235.    char dir[128];
  236.  
  237.    if (args == 1)
  238.    {
  239.       strcpy (dir, &p[0][2]);
  240.    }
  241.    else if (args == 2)
  242.    {
  243.       strcpy (dir, p[1]);
  244.    }
  245.    else
  246.    {
  247.       printf("%s\n", BADCMDLINE);
  248.       printf("%s: %s\n", USAGE, MD);
  249.       return;
  250.    }
  251.  
  252.    if((errnum = mkdir(dir)) != 0)
  253.    {
  254.       printf("md() : error %d\n\n", errnum);
  255.    }
  256. }
  257.  
  258. /*
  259.  *  simple remove directory internal command.
  260.  *
  261.  *
  262.  */
  263. #pragma argsused
  264. void rd(int args, char *p[128], char *commandline)
  265. {
  266.    int errnum;
  267.    char dir[128];
  268.  
  269.    if (args == 1)
  270.    {
  271.       strcpy (dir, &p[0][2]);
  272.    }
  273.    else if (args == 2)
  274.    {
  275.       strcpy (dir, p[1]);
  276.    }
  277.    else
  278.    {
  279.       printf("%s\n", BADCMDLINE);
  280.       printf("%s: %s\n", USAGE, RD);
  281.       return;
  282.    }
  283.  
  284.    if((errnum = rmdir(dir)) != 0)
  285.    {
  286.       printf("rd() : error %d\n\n", errnum);
  287.    }
  288. }
  289.  
  290. /*
  291.  *  simple display directory internal command.
  292.  *
  293.  *
  294.  */
  295. #pragma argsused
  296. void dir(int args, char *p[128], char *commandline)
  297. {
  298.    struct ffblk file;
  299.    union REGS regs;
  300.  
  301.    long bytes = 0;
  302.    int count;
  303.    int dirs = 0;
  304.    int done;
  305.    int files = 0;
  306.    int i;
  307.    int len;
  308.    int wildcards;
  309.    char fattrib[4];
  310.    char fname[13];
  311.    char searchname[128], lastchar;
  312.  
  313.    if(args > 2)
  314.    {
  315.       printf("%s\n", BADCMDLINE);
  316.       printf("%s: %s\n", USAGE, DIR);
  317.  
  318.       return;
  319.    }
  320.  
  321.    /* set up search name and see if we have wildcards */
  322.    if (args == 1)
  323.      {
  324.        /* find all files if nothing specified */
  325.        strcpy (searchname, "*.*");
  326.        wildcards = 1;
  327.      }
  328.    else
  329.      {
  330.        /* get the filename specified and find the last character */
  331.        strcpy (searchname, p[1]);
  332.  
  333.        len = strlen (searchname);
  334.        lastchar = searchname[len - 1];
  335.  
  336.        wildcards = 0;
  337.  
  338.        /* search for wildcards */
  339.        for (count = 0; count < len; count++)
  340.      if (searchname[count] == '*' || searchname[count] == '?')
  341.        {
  342.          wildcards = 1;
  343.          break;
  344.        }
  345.      }
  346.  
  347.    /* check if filename ends in : or \ */
  348.    if (!wildcards && (lastchar == ':' || lastchar == '\\'))
  349.        strcpy (&searchname[len], "*.*");
  350.    else
  351.    {
  352.       /* see if this file is a directory */
  353.       if (!wildcards)
  354.      done = findfirst (searchname, &file, 0xff);
  355.       else
  356.      done = 1;
  357.  
  358.       /* if we found a directory */
  359.       if (!done && (file.ff_attrib & 0x10))
  360.      strcpy (&searchname[len], "\\*.*");
  361.       else
  362.       {
  363.      /* search for a . before a \ */
  364.      for (count = len - 1; count >= 0; count--)
  365.         if (searchname[count] == '.' || searchname[count] == '\\')
  366.            break;
  367.  
  368.      /* if the filename has no extension, add a .* */
  369.      if (count < 0 || (count >= 0 && searchname[count] == '\\'))
  370.         strcpy (&searchname[len], ".*");
  371.       }
  372.    }
  373.  
  374.    /* scan through all the files */
  375.    done = findfirst(searchname, &file, 0xff);
  376.  
  377.    if (done)
  378.    {
  379.       printf ("File not found.\n");
  380.       return;
  381.    }
  382.  
  383.    do
  384.      {
  385.        /* check file attributes */
  386.        fattrib[0] = file.ff_attrib & 0x10 ? 'd' : '-'; /* 'd' = directory */
  387.        fattrib[1] = file.ff_attrib & 0x01 ? 'r' : '-'; /* 'r' = read only */
  388.        fattrib[2] = 0; /* terminate string */
  389.        fattrib[3] = file.ff_attrib & 0x02 ? 'h' : '-'; /* 'h' = hidden */
  390.        fattrib[4] = file.ff_attrib & 0x04 ? 's' : '-'; /* 's' = system file */
  391.  
  392.        /* convert filename to lowercase if it has the system attribute */
  393.        if(fattrib[4] == 's')
  394.          {
  395.        for(i = 0;i <= strlen(file.ff_name); i++)
  396.          {
  397.                fname[i] = tolower(file.ff_name[i]);
  398.          }
  399.          }
  400.        else
  401.          {
  402.        strcpy(fname, file.ff_name);
  403.          }
  404.        
  405.        /* honor hidden attribute by ignoring files with this attribute */
  406.        /* why not just set the mask right in findfirst/findnext? */
  407.        if(fattrib[3] != 'h')
  408.          {
  409.        if(fattrib[0] == 'd')
  410.          {
  411.            /* entry found is a directory */
  412.                dirs++;
  413.                printf("%s  %-12s           <dir>\n", fattrib, fname);
  414.          }
  415.        else
  416.          {
  417.                /* entry found is a file */
  418.                files++;
  419.                bytes += file.ff_fsize;
  420.                printf("%s  %-12s %15ld\n", fattrib, fname, file.ff_fsize);
  421.          }
  422.        
  423.        /* only prompt for keypress if stdin & stdout are console */
  424.        if(isatty (0) && isatty (1) && (files + dirs) % 20 == 0)
  425.          {
  426.                puts("[press any key to continue]");
  427.                getch();
  428.          }
  429.          }
  430.        
  431.        done = findnext(&file);
  432.      }
  433.    while(!done);
  434.    
  435.    printf("    %d file%s\n", files, files == 1 ? "" : "s");
  436.    printf("    %d dir%s\n", dirs, dirs == 1 ? "" : "s");
  437.    
  438.    /* get free bytes */
  439.    regs.h.ah = 0x36;
  440.    regs.h.dl = 0;
  441.    int86(0x21, ®s, ®s);
  442.    
  443.    printf("      %15ld byte%s used\n", bytes, bytes == 1 ? "" : "s");
  444.    printf("      %15ld bytes free\n", (long) regs.x.ax * regs.x.cx * regs.x.bx);
  445. }
  446.  
  447. /*
  448.  *  display shell version info internal command.
  449.  *
  450.  *
  451.  */
  452. #pragma argsused
  453. void ver(int args, char *p[128], char *commandline)
  454. {
  455.    if(args != 1)
  456.    {
  457.       printf("%s\n", BADCMDLINE);
  458.       printf("%s: %s\n", USAGE, VER);
  459.    }
  460.    else
  461.    {
  462.       printf("License:\n");
  463.       printf(" This program is free software; you can redistribute it and/or modify\n");
  464.       printf(" it under the terms of the GNU General Public License as published by\n");
  465.       printf(" the Free Software Foundation; either version 2 of the License, or\n");
  466.       printf(" (at your option) any later version.\n\n");
  467.       printf(" This program is distributed in the hope that it will be useful,\n");
  468.       printf(" but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
  469.       printf(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
  470.       printf(" GNU General Public License for more details.\n\n");
  471.       printf(" You should have received a copy of the GNU General Public License\n");
  472.       printf(" along with this program; if not, write to the Free Software\n");
  473.       printf(" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n");
  474.  
  475.       printf("%s %s\n\n", SHELLINFO, SHELLVER);
  476.  
  477.       printf("developed by: Tim Norman\n");
  478.       printf("              Matt Rains\n");
  479.       printf("              Evan Jeffrey\n");
  480.       printf("              Steffen Kaiser\n");
  481.    }
  482.  
  483.    return;
  484. }
  485.  
  486. /*
  487.  *
  488.  *  simple file delete internal command.
  489.  *
  490.  */
  491. #pragma argsused
  492. void del(int args, char *p[128], char *commandline)
  493. {
  494.    int errnum;
  495.  
  496.    if(args != 2)
  497.    {
  498.       printf("%s\n", BADCMDLINE);
  499.       printf("%s: %s\n", USAGE, DEL);
  500.    }
  501.    else
  502.    {
  503.       if((errnum = remove(p[1])) != 0)
  504.       {
  505.      printf("del() : error %d\n\n", errnum);
  506.       }
  507.    }
  508.  
  509.    return;
  510. }
  511.  
  512. /*
  513.  *
  514.  *  simple file rename internal command.
  515.  *
  516.  */
  517. #pragma argsused
  518. void ren(int args, char *p[128], char *commandline)
  519. {
  520.    int errnum;
  521.  
  522.    if(args == 1 || args >= 4)
  523.    {
  524.       printf("%s\n", BADCMDLINE);
  525.       printf("%s: %s\n", USAGE, REN);
  526.    }
  527.    else
  528.    {
  529.       if((errnum = rename(p[1], p[2])) != 0)
  530.       {
  531.      printf("ren() : error %d\n\n", errnum);
  532.       }
  533.    }
  534.  
  535.    return;
  536. }
  537.  
  538. extern char exitflag;
  539.  
  540. /*
  541.  *
  542.  * set the exitflag to true
  543.  *
  544.  */
  545. #pragma argsused
  546. void internal_exit (int args, char *p[128], char *commandline)
  547. {
  548.    exitflag = 1;
  549. }
  550.  
  551. /*
  552.  *
  553.  * does nothing
  554.  *
  555.  */
  556. #pragma argsused
  557. void rem (int args, char *p[128], char *commandline)
  558. {
  559. }
  560.  
  561. /*
  562.  *
  563.  * prints DOSKEY message...  will soon emulate DOSKEY macros
  564.  *
  565.  */
  566. #pragma argsused
  567. void doskey (int args, char *p[128], char *commandline)
  568. {
  569.    printf ("DOSKEY features are already enabled in the shell.\n");
  570. }
  571.  
  572. /*
  573.  *
  574.  * changes the PROMPT env. var.
  575.  *
  576.  */
  577. #pragma argsused
  578. void prompt (int args, char *p[128], char *commandline)
  579. {
  580.    char *from, *to, tempcommand[256];
  581.  
  582.    from = commandline;
  583.    to = tempcommand + 11;
  584.    strcpy(tempcommand, SETPROMPT);
  585.  
  586.    while(isspace(*from))
  587.    {
  588.       from++;
  589.    }
  590.  
  591.    from += 6;
  592.  
  593.    while(isspace(*from))
  594.    {
  595.       from++;
  596.    }
  597.  
  598.    if(*from == '=')
  599.    {
  600.       from++;
  601.  
  602.       while(isspace(*from))
  603.       {
  604.      from++;
  605.       }
  606.    }
  607.  
  608.    strcpy(to, from);
  609.    set(2, p, tempcommand);   /* force 2 so that SET won't dump environment */
  610. }
  611.