[Netadm-devel] gwc/gwcsh Makefile,NONE,1.1 gwcsh.c,NONE,1.1 input.c,NONE,1.1 input.h,NONE,1.1 ipccmd
Status: Beta
Brought to you by:
linuxpark
From: linuxpark <lin...@us...> - 2006-04-30 18:39:33
|
Update of /cvsroot/netadm/gwc/gwcsh In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3483/gwcsh Added Files: Makefile gwcsh.c input.c input.h ipccmd.c ipccmd.h kbhit.c kbhit.h Log Message: Initial check-in : gwcsh: gwc command shell This shell will replace with gwcguid daemon. --- NEW FILE: input.h --- /* Title : input.h Author : Jeho-Park <de...@sk...> Created date : 2006. 05. 01. (mon) 00:24:33 KST Description : header of input.c object */ #ident "@(#) $Header: /cvsroot/netadm/gwc/gwcsh/input.h,v 1.1 2006/04/30 18:39:28 linuxpark Exp $" #ifndef __GWCSH_INPUT_H #define __GWCSH_INPUT_H #define FN_PARAMS(paramlist) paramlist #ifndef NEWLINE #define NEWLINE '\n' #endif #ifndef RETURN #define RETURN CTRL('M') #endif #ifndef RUBOUT #define RUBOUT 0x7f #endif #ifndef TAB #define TAB '\t' #endif #ifdef ABORT_CHAR #undef ABORT_CHAR #endif #define ABORT_CHAR CTRL('G') #ifdef PAGE #undef PAGE #endif #define PAGE CTRL('L') #ifdef SPACE #undef SPACE #endif #define SPACE ' ' /* XXX - was 0x20 */ #ifdef ESC #undef ESC #endif #define ESC CTRL('[') /* Possible state values for rl_readline_state */ #define RL_STATE_NONE 0x00000 /* no state; before first call */ #define RL_STATE_INITIALIZING 0x00001 /* initializing */ #define RL_STATE_INITIALIZED 0x00002 /* initialization done */ #define RL_STATE_TERMPREPPED 0x00004 /* terminal is prepped */ #define RL_STATE_READCMD 0x00008 /* reading a command key */ #define RL_STATE_METANEXT 0x00010 /* reading input after ESC */ #define RL_STATE_DISPATCHING 0x00020 /* dispatching to a command */ #define RL_STATE_MOREINPUT 0x00040 /* reading more input in a command function */ #define RL_STATE_ISEARCH 0x00080 /* doing incremental search */ #define RL_STATE_NSEARCH 0x00100 /* doing non-inc search */ #define RL_STATE_SEARCH 0x00200 /* doing a history search */ #define RL_STATE_NUMERICARG 0x00400 /* reading numeric argument */ #define RL_STATE_MACROINPUT 0x00800 /* getting input from a macro */ #define RL_STATE_MACRODEF 0x01000 /* defining keyboard macro */ #define RL_STATE_OVERWRITE 0x02000 /* overwrite mode */ #define RL_STATE_COMPLETING 0x04000 /* doing completion */ #define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */ #define RL_STATE_UNDOING 0x10000 /* doing an undo */ #define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */ #define RL_STATE_TTYCSAVED 0x40000 /* tty special chars saved */ #define RL_STATE_DONE 0x80000 /* done; accepted line */ #define RL_SETSTATE(x) (rl_readline_state |= (x)) #define RL_UNSETSTATE(x) (rl_readline_state &= ~(x)) #define RL_ISSTATE(x) (rl_readline_state & (x)) extern FILE *rl_instream; extern FILE *rl_outstream; #if !defined (PARAMS) # define PARAMS(protos) protos #endif #if !defined (_RL_FUNCTION_TYPEDEF) #define _RL_FUNCTION_TYPEDEF /* Type for input and pre-read hook functions like rl_event_hook */ typedef int rl_hook_func_t PARAMS((void *)); /* Input function type */ typedef int rl_getc_func_t PARAMS((FILE *)); #endif extern rl_hook_func_t *rl_event_hook; extern rl_getc_func_t *rl_getc_function; /* Make this non-zero to return the current input_line. */ extern int rl_done; /* Non-zero makes this the next keystroke to read. */ extern int rl_pending_input; /* The number of characters read in order to type this complete command. */ extern int rl_key_sequence_length; /* Flags word encapsulating the current readline state. */ extern int rl_readline_state; extern int rl_stuff_char (int key); extern int rl_execute_next(int c); extern int rl_clear_pending_input(void); extern int _rl_unget_char (int key); extern int _rl_pushed_input_available (void); extern int rl_set_keyboard_input_timeout(int u); extern int rl_read_key (void); extern int rl_getc (FILE *stream); #endif /* __GWCSH_INPUT_H */ --- NEW FILE: input.c --- /* Title : input.c Author : Jeho-Park <de...@sk...> Created date : 2006. 05. 01. (mon) 00:24:33 KST Description : ported input.c of readline library. */ #ident "@(#) $Header: /cvsroot/netadm/gwc/gwcsh/input.c,v 1.1 2006/04/30 18:39:28 linuxpark Exp $" #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <sys/time.h> #include <sys/select.h> #include <sys/ioctl.h> #include <stdio.h> #include <errno.h> #include "sysnio.h" #include "input.h" /* Non-null means it is a pointer to a function to run while waiting for * character input. */ rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; rl_getc_func_t *rl_getc_function = rl_getc; /* The names of the streams that we do input and output to. */ FILE *rl_instream = (FILE *)NULL; FILE *rl_outstream = (FILE *)NULL; static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */ static int pop_index, push_index; static unsigned char ibuffer[512]; static int ibuffer_len = sizeof (ibuffer) - 1; /* Make this non-zero to return the current input_line. */ int rl_done; /* Non-zero makes this the next keystroke to read. */ int rl_pending_input = 0; /* The number of characters read in order to type this complete command. */ int rl_key_sequence_length = 0; /* Flags word encapsulating the current readline state. */ int rl_readline_state = RL_STATE_NONE; /* Get a key from the buffer of characters to be read. Return the key in KEY. Result is KEY if there was a key, or 0 if there wasn't. */ static int rl_get_char (key) int *key; { if (push_index == pop_index) return (0); *key = ibuffer[pop_index++]; if (pop_index >= ibuffer_len) pop_index = 0; return (1); } /* Return the amount of space available in the buffer for stuffing characters. */ static int ibuffer_space () { if (pop_index > push_index) return (pop_index - push_index - 1); else return (ibuffer_len - (push_index - pop_index)); } /* Add KEY to the buffer of characters to be read. Returns 1 if the character was stuffed correctly; 0 otherwise. */ int rl_stuff_char (key) int key; { if (ibuffer_space () == 0) return 0; if (key == EOF) { key = NEWLINE; rl_pending_input = EOF; RL_SETSTATE (RL_STATE_INPUTPENDING); } if (key == '\t') printf("good\n"); ibuffer[push_index++] = key; if (push_index >= ibuffer_len) push_index = 0; return 1; } /* Make C be the next command to be executed. */ int rl_execute_next (c) int c; { rl_pending_input = c; RL_SETSTATE (RL_STATE_INPUTPENDING); return 0; } /* Clear any pending input pushed with rl_execute_next() */ int rl_clear_pending_input () { rl_pending_input = 0; RL_UNSETSTATE (RL_STATE_INPUTPENDING); return 0; } /* If a character is available to be read, then read it and stuff it into IBUFFER. Otherwise, just return. Returns number of characters read (0 if none available) and -1 on error (EIO). */ static int rl_gather_tyi () { int tty; register int tem, result; int chars_avail, k; char input; fd_set readfds, exceptfds; struct timeval timeout; tty = fileno (rl_instream); FD_ZERO (&readfds); FD_ZERO (&exceptfds); FD_SET (tty, &readfds); FD_SET (tty, &exceptfds); timeout.tv_sec = 0; timeout.tv_usec = _keyboard_input_timeout; result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); if (result <= 0) return 0; /* Nothing to read. */ result = -1; errno = 0; result = ioctl (tty, FIONREAD, &chars_avail); if (result == -1 && errno == EIO) return -1; if (result == -1) { tem = fcntl (tty, F_GETFL, 0); //fcntl (tty, F_SETFL, (tem | O_NDELAY)); fcntl (tty, F_SETFL, (tem )); chars_avail = read (tty, &input, 1); fcntl (tty, F_SETFL, tem); if (chars_avail == -1 && errno == EAGAIN) return 0; if (chars_avail == 0) /* EOF */ { rl_stuff_char (EOF); return (0); } } /* If there's nothing available, don't waste time trying to read something. */ if (chars_avail <= 0) return 0; tem = ibuffer_space (); if (chars_avail > tem) chars_avail = tem; /* One cannot read all of the available input. I can only read a single character at a time, or else programs which require input can be thwarted. If the buffer is larger than one character, I lose. Damn! */ if (tem < ibuffer_len) chars_avail = 0; if (result != -1) { printf ("~~~~\n"); while (chars_avail--) { k = (*rl_getc_function) (rl_instream); rl_stuff_char (k); if ( k == '\t' || k == NEWLINE || k == RETURN) { break; } } } else { if (chars_avail) rl_stuff_char (input); } return 1; } /* Read a key, including pending input. */ int rl_read_key () { int c; rl_key_sequence_length++; if (rl_pending_input) { c = rl_pending_input; rl_clear_pending_input (); } else { #if 0 /* If input is coming from a macro, then use that. */ if (c = _rl_next_macro_key ()) return (c); #endif /* If the user has an event function, then call it periodically. */ if (rl_event_hook) { while (rl_event_hook && rl_get_char (&c) == 0) { (*rl_event_hook) (&c); if (rl_done) /* XXX - experimental */ return ('\n'); if (rl_gather_tyi () < 0) /* XXX - EIO */ { rl_done = 1; return ('\n'); } } } else { if (rl_get_char (&c) == 0) c = (*rl_getc_function) (rl_instream); } } return (c); } int rl_getc (stream) FILE *stream; { int result; unsigned char c; while (1) { result = read (fileno (stream), &c, sizeof (unsigned char)); if (result == sizeof (unsigned char)) return (c); /* If zero characters are returned, then the file that we are reading from is empty! Return EOF in that case. */ if (result == 0) return (EOF); #if defined (__BEOS__) if (errno == EINTR) continue; #endif #if defined (EWOULDBLOCK) # define X_EWOULDBLOCK EWOULDBLOCK #else # define X_EWOULDBLOCK -99 #endif #if defined (EAGAIN) # define X_EAGAIN EAGAIN #else # define X_EAGAIN -99 #endif if (errno == X_EWOULDBLOCK || errno == X_EAGAIN) { if (sys_blockingmode (fileno (stream), 0) < 0) return (EOF); continue; } #undef X_EWOULDBLOCK #undef X_EAGAIN /* If the error that we received was SIGINT, then try again, this is simply an interrupted system call to read (). Otherwise, some error ocurred, also signifying EOF. */ if (errno != EINTR) return (EOF); } } /* Stuff KEY into the *front* of the input buffer. Returns non-zero if successful, zero if there is no space left in the buffer. */ int _rl_unget_char (key) int key; { if (ibuffer_space ()) { pop_index--; if (pop_index < 0) pop_index = ibuffer_len - 1; ibuffer[pop_index] = key; return (1); } return (0); } int _rl_pushed_input_available () { return (push_index != pop_index); } int rl_set_keyboard_input_timeout (u) int u; { int o; o = _keyboard_input_timeout; if (u > 0) _keyboard_input_timeout = u; return (o); } --- NEW FILE: Makefile --- # # Title : Makefile # Author : Jeho-Park <de...@sk...> # Created date : 2006. 04. 30. (sun) 20:55:10 KST # Description : Makefile for gwcsh # #ident "@(#) $Header: /cvsroot/netadm/gwc/gwcsh/Makefile,v 1.1 2006/04/30 18:39:28 linuxpark Exp $" include ../Makefile.tmpl TARGET = gwcsh OBJECTS = input.o \ kbhit.o \ ipccmd.o \ gwcsh.o all: $(TARGET) $(TARGET): $(OBJECTS) $(CC) -o $@ $(OBJECTS) $(LIBSYS) .c.o: $(CC) $(CFLAGS) $(INCLUDE) -c $< tags: ctags *.c *.h clean: rm -f ${TARGET} *.o depend: $(MAKEDEPEND) -- $(CFLAGS) -- *.c rm -f Makefile.bak # DO NOT DELETE THIS LINE -- make depend depends on it. --- NEW FILE: ipccmd.c --- /* Title : ipccmd.c Author : Jeho-Park <de...@sk...> Created date : 2006. 05. 01. (mon) 00:24:33 KST Description : ipc command for gwcsh */ #ident "@(#) $Header: /cvsroot/netadm/gwc/gwcsh/ipccmd.c,v 1.1 2006/04/30 18:39:28 linuxpark Exp $" #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/time.h> #include <string.h> #include <strings.h> #include <errno.h> #include <stdio.h> #include <stdarg.h> #include <arpa/telnet.h> #include <unistd.h> #include <stdlib.h> #include "global.h" #include "sysipc.h" #include "slog.h" #include "sysutil.h" #include "sysshm.h" #include "confutil.h" #define SC_NOSPC 1 #define SC_DIGIT 2 extern sys_cmd_t cmdtab[]; extern sm_t *csm; extern int errno; static void pr(char *fmt, ...) { va_list ap; char buf[8192]; int n; if (fmt && *fmt) { va_start(ap, fmt); n = ssvsnprintf(buf, sizeof (buf) - 2, fmt, ap); va_end(ap); if (n < 0) sprintf(buf, "error: message truncated"); } else { buf[0] = '\0'; } strcat(buf, "\n"); printf(buf); } static void prnl(void) { printf("\n"); } static void help(int argc, char *argv[]) { sys_cmd_t *p; for (p = cmdtab; p->key; p++) { if (!strcmp(p->key, "dump")) continue; pr("\t %s:\t%s", p->key, p->hlp); } pr("\t %s:\t%s", "quit | exit", "exit this shell"); } int ipc_cmd (int argc, char *argv[]) { char buf[8192]; char *cp; char *ident; int remain; int i; sys_cmd_t *p; int msg; int len; int total; fr_t *pir; int col; int file = FALSE; #if 1 dprintf ("argc: %d argv[0]: [%s] argv[1]: [%s]\n", argc, argv[0], argv[1]); /* runtime argument checking and if needed, return help */ if (argc > (MAXARGC)) { printf("Max Argument Cannot Be More Than %d\n", MAXARGC); return FALSE; } if (argc < 1) { prnl(); pr("Usage:"); prnl(); help(argc, argv); return FALSE; } if ((ident = strrchr(argv[0], '/')) != NULL) ident++; else ident = argv[0]; if (strcmp(argv[0], "encconf") && strcmp(argv[0], "dumpconf")) { if (cshmattach(&csm) < 0) { printf("Cannot attach APCADMD SHM '%s'\n", strerror(errno)); return FALSE; } } else { csm = (sm_t *) malloc(sizeof (sm_t)); file = TRUE; } for (p = cmdtab; p->key; p++) { if (!strcasecmp(p->key, argv[0])) { msg = p->cmd; dprintf ("found ~!: [%s]\n", p->key); break; } } #endif if (!p->key) { prnl(); pr("Available Commands are:"); prnl(); help(argc, argv); return FALSE; } buf[0] = '\0'; remain = sizeof (buf) - 1; total = 0; cp = buf; for (i = 1; i < argc; i++) { len = strlen(argv[i]); if (len > (remain - 1)) { printf("Argument Too Long (MAX:%d)\n", sizeof (buf)); return FALSE; } else { strcpy(cp, argv[i]); cp += len + 1; remain -= len + 1; total += len + 1; } } pir = ipc_msg(msg, buf, total, argc - 1); if (pir->ret != RET_OK) { if (pir->p && strlen(pir->p)) { printf("%s", pir->p); if (pir->p[pir->len - 1] != '\n') printf("\n"); } else { /* this cannot happen */ printf("Unknown error(%d) occured\n", pir->ret); } frfree(pir); return FALSE; } if (pir->islist) { printf("Total %d found\n", pir->rows); for (col = 1, i = 0; i < pir->len; i++) { if (pir->p[i] == '\0') { if (col < pir->cols) { pir->p[i] = ','; col++; } else { pir->p[i] = '\n'; col = 1; } } } if (i != 0) { if (pir->p[i]) pir->p[i] = '\0'; } } if (pir->len && pir->p) { printf("%s", pir->p); if (!pir->islist && (pir->len > 1) && (pir->p[pir->len - 1] != '\n') && (pir->p[pir->len - 2] != '\n')) printf("\n"); } frfree(pir); if (file == FALSE) { if (cshmdetach(csm) < 0) printf("Cannot detach APCADMD SHM '%s'\n", strerror(errno)); } else { free(csm); } return TRUE; } --- NEW FILE: kbhit.c --- /* Title : kbhit.c Author : Jeho-Park <de...@sk...> Created date : 2006. 05. 01. (mon) 00:24:33 KST Description : */ #ident "@(#) $Header: /cvsroot/netadm/gwc/gwcsh/kbhit.c,v 1.1 2006/04/30 18:39:28 linuxpark Exp $" #include "kbhit.h" #include <termios.h> #include <unistd.h> static struct termios initial_settings, new_settings; static int peek_character = -1; void init_keyboard() { tcgetattr(0,&initial_settings); new_settings = initial_settings; new_settings.c_lflag &= ~ICANON; new_settings.c_lflag &= ~ECHO; new_settings.c_lflag &= ~ISIG; new_settings.c_cc[VMIN] = 1; new_settings.c_cc[VTIME] = 0; tcsetattr(0, TCSANOW, &new_settings); } void close_keyboard() { tcsetattr(0, TCSANOW, &initial_settings); } int kbhit() { unsigned char ch; int nread; if (peek_character != -1) return 1; new_settings.c_cc[VMIN]=0; tcsetattr(0, TCSANOW, &new_settings); nread = read(0,&ch,1); new_settings.c_cc[VMIN]=1; tcsetattr(0, TCSANOW, &new_settings); if(nread == 1) { peek_character = ch; write (1, &ch, 1); return 1; } return 0; } int readch() { char ch; if(peek_character != -1) { ch = peek_character; peek_character = -1; return ch; } read(0,&ch,1); return ch; } --- NEW FILE: ipccmd.h --- /* Title : ipccmd.h Author : Jeho-Park <de...@sk...> Created date : 2006. 05. 01. (mon) 00:18:18 KST Description : */ #ident "@(#) $Header: /cvsroot/netadm/gwc/gwcsh/ipccmd.h,v 1.1 2006/04/30 18:39:28 linuxpark Exp $" #ifndef __GWCSH_IPCCMD_H #define __GWCSH_IPCCMD_H int ipc_cmd (int argc, char *argv[]); #endif /* __GWCSH_IPCCMD_H */ --- NEW FILE: gwcsh.c --- /* Title : gwcsh.c Author : Jeho-Park <de...@sk...> Created date : 2006. 05. 01. (mon) 00:24:33 KST Description : main of gwcsh */ #ident "@(#) $Header: /cvsroot/netadm/gwc/gwcsh/gwcsh.c,v 1.1 2006/04/30 18:39:28 linuxpark Exp $" #include <sys/types.h> #include <sys/wait.h> #include <libgen.h> #include <signal.h> #include <unistd.h> #include <string.h> #include <curses.h> #include <fcntl.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include "input.h" #include "kbhit.h" #include "ipccmd.h" #include "global.h" #include "slog.h" #include "sysutil.h" int sh_quit = FALSE; static int cmd_depth = 1; bool bdebug = FALSE; int hook_kb (void *p) { return TRUE; } int getchs (char *s) { char c; int loop_quit = FALSE; #ifdef USE_READLINE while ((c = rl_read_key()) != NEWLINE ) { #else while (!loop_quit) { #endif if (kbhit()) { c = readch (); *s++ = c; switch (c) { case TAB: printf ("tab\n"); loop_quit = TRUE; /* TODO: show params */ break; case NEWLINE: loop_quit = TRUE; break; } } usleep (100000); } return TRUE; } static size_t bufsplit(char *buf, size_t n, char **a) { int i; int nsplit; static char *splitch = "\t\n"; if (buf != NULL && n == 0) { splitch = buf; return(1); } nsplit = 0; while (nsplit < n) { a[nsplit++] = buf; if ((buf = strpbrk(buf, splitch)) == NULL) break; *(buf++) = '\0'; if (*buf == '\0') break; } buf = strrchr(a[nsplit-1], '\0'); for (i=nsplit; i < n; i++) a[i] = buf; return(nsplit); } static void usage () { printf ("\n"); printf ("gwcsh: shell program for interfacing with the gwcadmd daemon\n"); printf ("-d: debug\n"); printf ("-h: this option\n"); printf ("\n"); printf ("may. 2. 2006, jeho park <de...@sk...>\n"); printf ("\n"); } static int execmd (int argc, char **argv, char *infile, char *outfile) { int status; pid_t pid = 0; int infd = -1; int outfd = -1; extern int errno; sigset_t mask; sigset_t savemask; struct sigaction ignore; struct sigaction saveint; struct sigaction savequit; if (bdebug != TRUE) { if (infile != NULL) { if ((infd = open(infile, O_RDONLY)) < 0) { perror(infile); return (-1); } } if (outfile != NULL) { if ((outfd = creat(outfile, 0666)) < 0) { perror(outfile); close(infd); return (-1); } } sigemptyset(&ignore.sa_mask); ignore.sa_handler = SIG_IGN; ignore.sa_flags = 0; sigaction(SIGINT, &ignore, &saveint); sigaction(SIGQUIT, &ignore, &savequit); sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, &savemask); if ((pid = fork()) < 0) status = -1; } /* * This code executes in the child process. */ if (!pid) { /* * Restore signals to their original dispositions, * and restore the signal mask. */ if (bdebug != TRUE) { sigaction(SIGINT, &saveint, (struct sigaction *) 0); sigaction(SIGQUIT, &savequit, (struct sigaction *) 0); sigprocmask(SIG_SETMASK, &savemask, (sigset_t *) 0); if (infd > 0) dup2(infd, 0); if (outfd > 0) dup2(outfd, 1); close (infd); } if ( ipc_cmd (argc, argv) != TRUE ) fprintf (stderr, "Failed to execute command\n"); _exit(0); } if (bdebug != TRUE) { while (waitpid(pid, &status, 0) < 0) { if (errno != EINTR) { status = -1; break; } } sigaction(SIGINT, &saveint, (struct sigaction *) 0); sigaction(SIGQUIT, &savequit, (struct sigaction *) 0); sigprocmask(SIG_SETMASK, &savemask, (sigset_t *) 0); close(outfd); close(infd); } return (status); } int main(int argc, char **argv) { char **cp; int sargc, status; char *sargv[MAXSHARG]; char command[BUFSIZ]; char *infile, *outfile; int c; while ((c = getopt(argc, argv, "dh")) != EOF) { switch (c) { case 'd': bdebug = TRUE; break; case 'h': usage(); exit(0); default: usage(); exit(0); } } rl_event_hook = hook_kb; rl_instream = stdin; rl_outstream = stdout; init_keyboard(); bufsplit(" \t\n", 0, NULL); while (!sh_quit) { again: printf("%s", SZPROMPT); fflush (rl_outstream); memset (command, 0, sizeof (command)); if ( getchs (command) < 0 ) { putchar('\n'); goto EXIT; } sargc = bufsplit(command, MAXSHARG, sargv); sargv[sargc] = NULL; if (!strcasecmp (command, "quit") || !strcasecmp (command, "exit")) { printf ("exit...\n"); putchar('\n'); goto EXIT; } dprintf ("sargc[%d]\n", sargc); if (**argv == '\0') continue; /* * Find any input and output redirections. */ infile = NULL; outfile = NULL; for (cp = argv; *cp != NULL; cp++) { if (strcmp(*cp, "<") == 0) { if (*(cp+1) == NULL) { fprintf(stderr, "You must specify "); fprintf(stderr, "an input file.\n"); goto again; } *cp++ = NULL; infile = *cp; } else if (strcmp(*cp, ">") == 0) { if (*(cp+1) == NULL) { fprintf(stderr, "You must specify "); fprintf(stderr, "an output file.\n"); goto again; } *cp++ = NULL; outfile = *cp; } } status = execmd (sargc, sargv, infile, outfile); } EXIT: close_keyboard(); exit(1); } --- NEW FILE: kbhit.h --- /* Title : kbhit.h Author : Jeho-Park <de...@sk...> Created date : 2006. 05. 01. (mon) 00:24:33 KST Description : */ #ident "@(#) $Header: /cvsroot/netadm/gwc/gwcsh/kbhit.h,v 1.1 2006/04/30 18:39:28 linuxpark Exp $" #ifndef __GWCSH_KBHIT_H #define __GWCSH_KBHIT_H void init_keyboard(void); void close_keyboard(void); int kbhit(void); int readch(void); #endif /* __GWCSH_KBHIT_H */ |