home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2002 April / VPR0204A.ISO / OLS / SHELL002 / shell002.lzh / shell.cpp next >
C/C++ Source or Header  |  2000-12-29  |  5KB  |  197 lines

  1. /******************************************************************************
  2.     似非 command.com ver0.00 copyright (c) 2000 t_kumagai
  3.  
  4.     shell.txc からシェルに command.com を使う場合の不安定さに耐え切れずに作成。
  5.     make が使えればいいやという考えで作っているので、超低機能です。
  6.     組み込みコマンドとして、dir, cd しか使えません。オプションもありません。
  7.  
  8.     高機能なシェルが必要な場合は別のシェルを使ってください。
  9.     (それでも &, ; は欲しいかも)
  10.  
  11. v0.00    2000/12/30
  12.     ・shell.txc から安定して make が使えるシェルが欲しいということで新規作成。
  13.       tcsh, zsh, sh は makeから呼び出すコマンドが実行できず。command.com は
  14.       強制終了させた場合、後の動作が耐えられないほど不安定になった。
  15. ******************************************************************************/
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <windows.h>
  19.  
  20. void show_prompt()
  21. {
  22.     char s[MAX_PATH];
  23.     GetCurrentDirectory(MAX_PATH, s);
  24.     printf("%s>" , s);
  25.     fflush(stdout);
  26. }
  27.  
  28. // src のポイント先の文字列から空白または '"' で区切られた部分を
  29. // dst 以下に格納して src, dst を更新する。
  30. // .str      .      ->  str.    arg.
  31. // |         |             |       |
  32. // (src)     (dst)  ->   (src)  (dst)
  33. //
  34. // str:    \s*\S+\s*|\s*"[^\"]+"\s
  35. // arg: \S*|[^\"]*
  36. int parse_command(char** dst, char** src)
  37. {
  38.     int ret;
  39.     char* s = *src;
  40.     char* d = *dst;
  41.     // 空白読み飛ばし
  42.     while (*s == ' ')
  43.         *s++;
  44.     while (*s == '"') {
  45.         s++;
  46.         do {
  47.             *d++ = *s++;
  48.         } while (*s && *s != '"');
  49.     }
  50.     while (*s && *s != ' ')
  51.         *d++ = *s++;
  52.  
  53.     ret = (d - *dst);
  54.     *d++ = '\0';
  55.     *src = s;
  56.     *dst = d;
  57.     
  58.     return ret;
  59. }
  60.  
  61. void get_command(char* cmdline, char* avs, int* ac, char** av)
  62. {
  63.     char* p = avs;
  64.     char* prev = avs;
  65.     show_prompt();
  66.     gets(cmdline);
  67.     *ac = 0;
  68.     
  69.     while (parse_command(&p, &cmdline)) {
  70.         av[(*ac)++] = prev;
  71.         prev = p;
  72.     }
  73. }
  74.  
  75. DWORD call_command(char* cmdline)
  76. {
  77.     PROCESS_INFORMATION pi;
  78.     STARTUPINFO si;
  79.     GetStartupInfo(&si);
  80.     DWORD ret;
  81.  
  82.     if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE,
  83.         CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi)) {
  84.         printf("%s: Command not found.\n", cmdline);
  85.         fflush(stdout);
  86.     }
  87.     WaitForSingleObject(pi.hProcess, INFINITE);
  88.     GetExitCodeProcess(pi.hProcess, &ret);
  89.  
  90.     CloseHandle(pi.hThread);
  91.     CloseHandle(pi.hProcess);
  92.  
  93.     return ret;
  94. }
  95.  
  96. void print_attr(char c, DWORD attr)
  97. {
  98.     if (attr) {
  99.         putchar(c);
  100.     } else {
  101.         putchar('-');
  102.     }
  103. }
  104.  
  105. int is_execute(char* fname)
  106. {
  107.     char s[MAX_PATH];
  108.     char* p = s;
  109.     char* f = fname;
  110.     while ((*p++ = toupper(*f++)) != '\0')
  111.         ;
  112.     // 拡張子以外でもマッチしてしまう。
  113.     if (strstr(s, ".EXE") || strstr(s, ".BAT") || strstr(s, ".COM"))
  114.         return 1;
  115.     
  116.     return 0;
  117. }
  118.  
  119. void on_dir(char* mask)
  120. {
  121.     HANDLE hFind;
  122.     WIN32_FIND_DATA fd;
  123.     FILETIME ft;
  124.     SYSTEMTIME st;
  125.     
  126.     if ((hFind = FindFirstFile(mask, &fd)) == INVALID_HANDLE_VALUE) {
  127.         printf("%s : not found\n", mask);
  128.         return;
  129.     }
  130.     do {
  131.         FileTimeToLocalFileTime(&fd.ftLastWriteTime, &ft);
  132.         FileTimeToSystemTime(&ft, &st);
  133.         print_attr('d', fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
  134.         print_attr('r', fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY);
  135.         print_attr('s', fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM);
  136.         print_attr('h', fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN);
  137.         print_attr('a', fd.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE);
  138.         print_attr('x', is_execute(fd.cFileName));
  139.  
  140.           printf(" %10d", fd.nFileSizeLow);
  141.         printf(" %02d/%02d/%02d %02d:%02d:%02d",
  142.             st.wYear % 100, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
  143.           printf(" %s\n", fd.cFileName);
  144.           fflush(stdout);
  145.     } while (FindNextFile(hFind, &fd));
  146.     FindClose(hFind);
  147. }
  148.  
  149. void on_cd(char* dir)
  150. {
  151.     if (SetCurrentDirectory(dir) == 0) {
  152.         printf("%s : No Such file or directory.\n", dir);
  153.         fflush(stdout);
  154.     }
  155. }
  156.  
  157. int main(int argc, char** argv)
  158. {
  159.     const MAX_ARG = 64;
  160.     char cmdline[MAX_PATH];
  161.     int ac;
  162.     char* av[MAX_ARG];
  163.     char avs[MAX_PATH];
  164.     int i;
  165.     
  166.     argc;
  167.     argv;
  168.     puts("似非 command.com ver0.00 copyright (c) 2000 t_kumagai");
  169.     puts("組み込みコマンドとして以下のコマンドが使えます");
  170.     puts("    cd [ディレクトリ]");
  171.     puts("    dir [ファイル名(デフォルト*.*)]");
  172.     puts("    (オプションはありません)");
  173.     fflush(stdout);
  174.     for (;;) {
  175.         get_command(cmdline, avs, &ac, av);
  176.         if (ac <= 0)
  177.             continue;
  178.  
  179.         if (strcmp(av[0], "exit") == 0) {
  180.             break;
  181.         } else if (strcmp(av[0], "dir") == 0) {
  182.             if (ac > 1)
  183.                 for (i=1; i<ac; i++) {
  184.                     on_dir(av[i]);
  185.                 }
  186.             else
  187.                 on_dir("*.*");
  188.         } else if (strcmp(av[0], "cd") == 0) {
  189.             if (ac > 1) {
  190.                 on_cd(av[1]);
  191.             }
  192.         } else call_command(cmdline);
  193.     }
  194.  
  195.     return 0;
  196. }
  197.