home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2002 April
/
VPR0204A.ISO
/
OLS
/
SHELL002
/
shell002.lzh
/
shell.cpp
next >
Wrap
C/C++ Source or Header
|
2000-12-29
|
5KB
|
197 lines
/******************************************************************************
似非 command.com ver0.00 copyright (c) 2000 t_kumagai
shell.txc からシェルに command.com を使う場合の不安定さに耐え切れずに作成。
make が使えればいいやという考えで作っているので、超低機能です。
組み込みコマンドとして、dir, cd しか使えません。オプションもありません。
高機能なシェルが必要な場合は別のシェルを使ってください。
(それでも &, ; は欲しいかも)
v0.00 2000/12/30
・shell.txc から安定して make が使えるシェルが欲しいということで新規作成。
tcsh, zsh, sh は makeから呼び出すコマンドが実行できず。command.com は
強制終了させた場合、後の動作が耐えられないほど不安定になった。
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
void show_prompt()
{
char s[MAX_PATH];
GetCurrentDirectory(MAX_PATH, s);
printf("%s>" , s);
fflush(stdout);
}
// src のポイント先の文字列から空白または '"' で区切られた部分を
// dst 以下に格納して src, dst を更新する。
// .str . -> str. arg.
// | | | |
// (src) (dst) -> (src) (dst)
//
// str: \s*\S+\s*|\s*"[^\"]+"\s
// arg: \S*|[^\"]*
int parse_command(char** dst, char** src)
{
int ret;
char* s = *src;
char* d = *dst;
// 空白読み飛ばし
while (*s == ' ')
*s++;
while (*s == '"') {
s++;
do {
*d++ = *s++;
} while (*s && *s != '"');
}
while (*s && *s != ' ')
*d++ = *s++;
ret = (d - *dst);
*d++ = '\0';
*src = s;
*dst = d;
return ret;
}
void get_command(char* cmdline, char* avs, int* ac, char** av)
{
char* p = avs;
char* prev = avs;
show_prompt();
gets(cmdline);
*ac = 0;
while (parse_command(&p, &cmdline)) {
av[(*ac)++] = prev;
prev = p;
}
}
DWORD call_command(char* cmdline)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
GetStartupInfo(&si);
DWORD ret;
if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE,
CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi)) {
printf("%s: Command not found.\n", cmdline);
fflush(stdout);
}
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &ret);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return ret;
}
void print_attr(char c, DWORD attr)
{
if (attr) {
putchar(c);
} else {
putchar('-');
}
}
int is_execute(char* fname)
{
char s[MAX_PATH];
char* p = s;
char* f = fname;
while ((*p++ = toupper(*f++)) != '\0')
;
// 拡張子以外でもマッチしてしまう。
if (strstr(s, ".EXE") || strstr(s, ".BAT") || strstr(s, ".COM"))
return 1;
return 0;
}
void on_dir(char* mask)
{
HANDLE hFind;
WIN32_FIND_DATA fd;
FILETIME ft;
SYSTEMTIME st;
if ((hFind = FindFirstFile(mask, &fd)) == INVALID_HANDLE_VALUE) {
printf("%s : not found\n", mask);
return;
}
do {
FileTimeToLocalFileTime(&fd.ftLastWriteTime, &ft);
FileTimeToSystemTime(&ft, &st);
print_attr('d', fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
print_attr('r', fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY);
print_attr('s', fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM);
print_attr('h', fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN);
print_attr('a', fd.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE);
print_attr('x', is_execute(fd.cFileName));
printf(" %10d", fd.nFileSizeLow);
printf(" %02d/%02d/%02d %02d:%02d:%02d",
st.wYear % 100, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
printf(" %s\n", fd.cFileName);
fflush(stdout);
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
}
void on_cd(char* dir)
{
if (SetCurrentDirectory(dir) == 0) {
printf("%s : No Such file or directory.\n", dir);
fflush(stdout);
}
}
int main(int argc, char** argv)
{
const MAX_ARG = 64;
char cmdline[MAX_PATH];
int ac;
char* av[MAX_ARG];
char avs[MAX_PATH];
int i;
argc;
argv;
puts("似非 command.com ver0.00 copyright (c) 2000 t_kumagai");
puts("組み込みコマンドとして以下のコマンドが使えます");
puts(" cd [ディレクトリ]");
puts(" dir [ファイル名(デフォルト*.*)]");
puts(" (オプションはありません)");
fflush(stdout);
for (;;) {
get_command(cmdline, avs, &ac, av);
if (ac <= 0)
continue;
if (strcmp(av[0], "exit") == 0) {
break;
} else if (strcmp(av[0], "dir") == 0) {
if (ac > 1)
for (i=1; i<ac; i++) {
on_dir(av[i]);
}
else
on_dir("*.*");
} else if (strcmp(av[0], "cd") == 0) {
if (ac > 1) {
on_cd(av[1]);
}
} else call_command(cmdline);
}
return 0;
}