ReactOS  0.4.13-dev-235-g7373cb3
shell.c
Go to the documentation of this file.
1 /* shell.c
2  *
3  * Copyright (c) 1992-2001 by Mike Gleason.
4  * All rights reserved.
5  *
6  */
7 
8 #include "syshdrs.h"
9 
10 #include "shell.h"
11 #include "util.h"
12 #include "bookmark.h"
13 #include "cmds.h"
14 #include "readln.h"
15 #include "trace.h"
16 #include "main.h"
17 
18 /* We keep running the command line interpreter until gDoneApplication
19  * is non-zero.
20  */
22 
23 /* Track how many times they use ^C. */
25 
26 /* Keep a count of the number of commands the user has entered. */
27 int gEventNumber = 0;
28 
29 
30 #if defined(WIN32) || defined(_WINDOWS)
31 #elif defined(HAVE_SIGSETJMP)
32 /* A command function can set this to have a user generated signal
33  * cause execution to jump here.
34  */
36 
37 /* This is used by the shell so that an unexpected signal can have
38  * execution come back to the main shell prompt.
39  */
41 #else /* HAVE_SIGSETJMP */
42 /* A command function can set this to have a user generated signal
43  * cause execution to jump here.
44  */
46 
47 /* This is used by the shell so that an unexpected signal can have
48  * execution come back to the main shell prompt.
49  */
51 #endif /* HAVE_SIGSETJMP */
52 
53 /* Flag specifying whether the jmp has been set. */
54 int gMayCancelJmp = 0;
55 
56 /* Flag specifying whether the jmp has been set. */
58 
59 /* Save the last signal number. */
60 int gGotSig = 0;
61 
62 /* If the shell is running one of our commands, this is set to non-zero. */
64 
65 /* If set, we need to abort the current session. */
66 int gCancelCtrl = 0;
67 
68 extern Command gCommands[];
69 extern size_t gNumCommands;
70 extern int gStartupUrlParameterGiven;
71 extern FTPLibraryInfo gLib;
74 extern int gNumProgramRuns;
75 extern char gCopyright[];
76 
77 
78 /* This is used as the comparison function when we sort the name list. */
79 static int
81 {
82  return (strcmp((*a).name, (*b).name));
83 } /* CommandSortCmp */
84 
85 
86 
87 
88 /* Sort the command list, in case it wasn't hard-coded that way. */
89 void
91 {
93 } /* InitCommandList */
94 
95 
96 
97 
98 /* This is used as the comparison function when we lookup something
99  * in the command list, and when we want an exact match.
100  */
101 static int
102 CommandExactSearchCmp(const char *const key, const CommandPtr b)
103 {
104  return (strcmp(key, (*b).name));
105 } /* CommandExactSearchCmp */
106 
107 
108 
109 
110 /* This is used as the comparison function when we lookup something
111  * in the command list, and when the key can be just the first few
112  * letters of one or more commands. So a key of "qu" might would match
113  * "quit" and "quote" for example.
114  */
115 static int
116 CommandSubSearchCmp(const char *const key, const CommandPtr a)
117 {
118  register const char *kcp, *cp;
119  int d;
120 
121  for (cp = (*a).name, kcp = key; ; ) {
122  if (*kcp == 0)
123  break;
124  d = *kcp++ - *cp++;
125  if (d)
126  return d;
127  }
128  return (0);
129 } /* CommandSubSearchCmp */
130 
131 
132 
133 
134 /* This returns a pointer to a Command, if the name supplied was long
135  * enough to be a unique name. We return a 0 CommandPtr if we did not
136  * find any matches, a -1 CommandPtr if we found more than one match,
137  * or the unique CommandPtr.
138  */
141 {
142  if ((i < 0) || (i >= (int) gNumCommands))
143  return (kNoCommand);
144  return (&gCommands[i]);
145 } /* GetCommandByIndex */
146 
147 
148 
149 
150 /* This returns a pointer to a Command, if the name supplied was long
151  * enough to be a unique name. We return a 0 CommandPtr if we did not
152  * find any matches, a -1 CommandPtr if we found more than one match,
153  * or the unique CommandPtr.
154  */
156 GetCommandByName(const char *const name, int wantExactMatch)
157 {
158  CommandPtr canp, canp2;
159 
160  /* First check for an exact match. Otherwise if you if asked for
161  * 'cd', it would match both 'cd' and 'cdup' and return an
162  * ambiguous name error, despite having the exact name for 'cd.'
163  */
165 
166  if (canp == kNoCommand && !wantExactMatch) {
167  /* Now see if the user typed an abbreviation unique enough
168  * to match only one name in the list.
169  */
171 
172  if (canp != kNoCommand) {
173  /* Check the entry above us and see if the name we're looking
174  * for would match that, too.
175  */
176  if (canp != &gCommands[0]) {
177  canp2 = canp - 1;
178  if (CommandSubSearchCmp(name, canp2) == 0)
179  return kAmbiguousCommand;
180  }
181  /* Check the entry below us and see if the name we're looking
182  * for would match that one.
183  */
184  if (canp != &gCommands[gNumCommands - 1]) {
185  canp2 = canp + 1;
186  if (CommandSubSearchCmp(name, canp2) == 0)
187  return kAmbiguousCommand;
188  }
189  }
190  }
191  return canp;
192 } /* GetCommandByName */
193 
194 
195 
196 
197 /* Print the help string for the command specified. */
198 
199 void
201 {
202  (void) printf("%s: %s.\n", c->name, c->help);
203 } /* PrintCmdHelp */
204 
205 
206 
207 
208 /* Print the usage string for the command specified. */
209 void
211 {
212  if (c->usage != NULL)
213  (void) printf("Usage: %s %s\n", c->name, c->usage);
214 } /* PrintCmdUsage */
215 
216 
217 
218 
219 /* Parse a command line into an array of arguments. */
220 int
221 MakeArgv(char *line, int *cargc, const char **cargv, int cargcmax, char *dbuf, size_t dbufsize, int *noglobargv, int readlineHacks)
222 {
223  int c;
224  int retval;
225  char *dlim;
226  char *dcp;
227  char *scp;
228  char *arg;
229 
230  *cargc = 0;
231  scp = line;
232  dlim = dbuf + dbufsize - 1;
233  dcp = dbuf;
234 
235  for (*cargc = 0; *cargc < cargcmax; ) {
236  /* Eat preceding junk. */
237  for ( ; ; scp++) {
238  c = *scp;
239  if (c == '\0')
240  goto done;
241  if (isspace(c))
242  continue;
243  if ((c == ';') || (c == '\n')) {
244  scp++;
245  goto done;
246  }
247  break;
248  }
249 
250  arg = dcp;
251  cargv[*cargc] = arg;
252  noglobargv[*cargc] = 0;
253  (*cargc)++;
254 
255  /* Special hack so that "!cmd" is always split into "!" "cmd" */
256  if ((*cargc == 1) && (*scp == '!')) {
257  if (scp[1] == '!') {
258  scp[1] = '\0';
259  } else if ((scp[1] != '\0') && (!isspace((int) scp[1]))) {
260  cargv[0] = "!";
261  scp++;
262  arg = dcp;
263  cargv[*cargc] = arg;
264  noglobargv[*cargc] = 0;
265  (*cargc)++;
266  }
267  }
268 
269  /* Add characters to the new argument. */
270  for ( ; ; ) {
271  c = *scp;
272  if (c == '\0')
273  break;
274  if (isspace(c))
275  break;
276  if ((c == ';') || (c == '\n')) {
277  break;
278  }
279 
280  scp++;
281 
282  if (c == '\'') {
283  for ( ; ; ) {
284  c = *scp++;
285  if (c == '\0') {
286  if (readlineHacks != 0)
287  break;
288  /* Syntax error */
289  (void) fprintf(stderr, "Error: Unbalanced quotes.\n");
290  return (-1);
291  }
292  if (c == '\'')
293  break;
294 
295  /* Add char. */
296  if (dcp >= dlim)
297  goto toolong;
298  *dcp++ = c;
299 
300  if (strchr(kGlobChars, c) != NULL) {
301  /* User quoted glob characters,
302  * so mark this argument for
303  * noglob.
304  */
305  noglobargv[*cargc - 1] = 1;
306  }
307  }
308  } else if (c == '"') {
309  for ( ; ; ) {
310  c = *scp++;
311  if (c == '\0') {
312  if (readlineHacks != 0)
313  break;
314  /* Syntax error */
315  (void) fprintf(stderr, "Error: Unbalanced quotes.\n");
316  return (-1);
317  }
318  if (c == '"')
319  break;
320 
321  /* Add char. */
322  if (dcp >= dlim)
323  goto toolong;
324  *dcp++ = c;
325 
326  if (strchr(kGlobChars, c) != NULL) {
327  /* User quoted glob characters,
328  * so mark this argument for
329  * noglob.
330  */
331  noglobargv[*cargc - 1] = 1;
332  }
333  }
334  } else
335 #if defined(WIN32) || defined(_WINDOWS)
336  if (c == '|') {
337 #else
338  if (c == '\\') {
339 #endif
340  /* Add next character, verbatim. */
341  c = *scp++;
342  if (c == '\0')
343  break;
344 
345  /* Add char. */
346  if (dcp >= dlim)
347  goto toolong;
348  *dcp++ = c;
349  } else {
350  /* Add char. */
351  if (dcp >= dlim)
352  goto toolong;
353  *dcp++ = c;
354  }
355  }
356 
357  *dcp++ = '\0';
358  }
359 
360  (void) fprintf(stderr, "Error: Argument list too long.\n");
361  *cargc = 0;
362  cargv[*cargc] = NULL;
363  return (-1);
364 
365 done:
366  retval = (int) (scp - line);
367  cargv[*cargc] = NULL;
368  return (retval);
369 
370 toolong:
371  (void) fprintf(stderr, "Error: Line too long.\n");
372  *cargc = 0;
373  cargv[*cargc] = NULL;
374  return (-1);
375 } /* MakeArgv */
376 
377 
378 
379 
380 static int
382 {
383  CommandPtr cmdp;
384  int flags;
385  int cargc, cargcm1;
386 
387  cmdp = GetCommandByName(aip->cargv[0], 0);
388  if (cmdp == kAmbiguousCommand) {
389  (void) printf("%s: ambiguous command name.\n", aip->cargv[0]);
390  return (-1);
391  } else if (cmdp == kNoCommand) {
392  (void) printf("%s: no such command.\n", aip->cargv[0]);
393  return (-1);
394  }
395 
396  cargc = aip->cargc;
397  cargcm1 = cargc - 1;
398  flags = cmdp->flags;
399 
400  if (((flags & kCmdMustBeConnected) != 0) && (gConn.connected == 0)) {
401  (void) printf("%s: must be connected to do that.\n", aip->cargv[0]);
402  } else if (((flags & kCmdMustBeDisconnected) != 0) && (gConn.connected != 0)) {
403  (void) printf("%s: must be disconnected to do that.\n", aip->cargv[0]);
404  } else if ((cmdp->minargs != kNoMin) && (cmdp->minargs > cargcm1)) {
405  PrintCmdUsage(cmdp);
406  } else if ((cmdp->maxargs != kNoMax) && (cmdp->maxargs < cargcm1)) {
407  PrintCmdUsage(cmdp);
408  } else {
409  (*cmdp->proc)(cargc, aip->cargv, cmdp, aip);
410  }
411  return (0);
412 } /* DoCommand */
413 
414 
415 
416 
417 /* Allows the user to cancel a data transfer. */
418 void
419 XferCanceller(int sigNum)
420 {
421  gGotSig = sigNum;
422  if (gConn.cancelXfer > 0) {
423 #if defined(WIN32) || defined(_WINDOWS)
425 #else
426  /* User already tried it once, they
427  * must think it's locked up.
428  *
429  * Jump back to the top, and
430  * close down the current session.
431  */
432  gCancelCtrl = 1;
433  if (gMayBackToTopJmp > 0) {
434 #ifdef HAVE_SIGSETJMP
436 #else /* HAVE_SIGSETJMP */
438 #endif /* HAVE_SIGSETJMP */
439  }
440 #endif
441  }
442  gConn.cancelXfer++;
443 } /* XferCanceller */
444 
445 
446 
447 #if defined(WIN32) || defined(_WINDOWS)
448 #else
449 
450 /* Allows the user to cancel a long operation and get back to the shell. */
451 void
452 BackToTop(int sigNum)
453 {
454  gGotSig = sigNum;
455  if (sigNum == SIGPIPE) {
456  if (gRunningCommand == 1) {
457  (void) fprintf(stderr, "Unexpected broken pipe.\n");
458  gRunningCommand = 0;
459  } else {
460  SetXtermTitle("RESTORE");
461  exit(1);
462  }
463  } else if (sigNum == SIGINT) {
464  if (gRunningCommand == 0)
465  gDoneApplication = 1;
466  }
467  if (gMayBackToTopJmp > 0) {
468 #ifdef HAVE_SIGSETJMP
470 #else /* HAVE_SIGSETJMP */
472 #endif /* HAVE_SIGSETJMP */
473  }
474 } /* BackToTop */
475 
476 
477 
478 
479 /* Some commands may want to jump back to the start too. */
480 void
481 Cancel(int sigNum)
482 {
483  if (gMayCancelJmp != 0) {
484  gGotSig = sigNum;
485  gMayCancelJmp = 0;
486 #ifdef HAVE_SIGSETJMP
488 #else /* HAVE_SIGSETJMP */
489  longjmp(gCancelJmp, 1);
490 #endif /* HAVE_SIGSETJMP */
491  }
492 } /* Cancel */
493 
494 #endif
495 
496 
497 
498 void
500 {
501  int tUsed, bUsed;
502  ArgvInfo ai;
503  char prompt[64];
504  char *lineRead;
505 #if defined(WIN32) || defined(_WINDOWS)
506 #else
507  int sj;
508 #endif
510 
511  /* Execution may jump back to this point to restart the shell. */
512 #if defined(WIN32) || defined(_WINDOWS)
513 
514 #elif defined(HAVE_SIGSETJMP)
515  sj = sigsetjmp(gBackToTopJmp, 1);
516 #else /* HAVE_SIGSETJMP */
517  sj = setjmp(gBackToTopJmp);
518 #endif /* HAVE_SIGSETJMP */
519 
520 #if defined(WIN32) || defined(_WINDOWS)
521 #else
522  if (sj != 0) {
523  Trace(0, "Caught signal %d, back at top.\n", gGotSig);
524  if (gGotSig == SIGALRM) {
525  (void) printf("\nRemote host was not responding, closing down the session.");
527  } else{
528  (void) printf("\nInterrupted.\n");
529  if (gCancelCtrl != 0) {
530  gCancelCtrl = 0;
531  (void) printf("Closing down the current FTP session: ");
533  (void) sleep(1);
534  (void) printf("done.\n");
535  }
536  }
537  }
538 
539  gMayBackToTopJmp = 1;
540 #endif
541 
542 
543  ++gEventNumber;
544 
545  while (gDoneApplication == 0) {
546 #if defined(WIN32) || defined(_WINDOWS)
547 #else
550  (void) NcSignal(SIGALRM, BackToTop);
551 #endif
552 
553  MakePrompt(prompt, sizeof(prompt));
554 
555  if (gConn.connected == 0) {
556  SetXtermTitle("DEFAULT");
557  } else {
558  SetXtermTitle("%s - NcFTP", gConn.host);
559  }
560 
561  lineRead = Readline(prompt);
562  if (lineRead == NULL) {
563  /* EOF, Control-D */
564  (void) printf("\n");
565  break;
566  }
567  Trace(0, "> %s\n", lineRead);
568  AddHistory(lineRead);
569  for (tUsed = 0;;) {
570  (void) memset(&ai, 0, sizeof(ai));
571  bUsed = MakeArgv(lineRead + tUsed, &ai.cargc, ai.cargv,
572  (int) (sizeof(ai.cargv) / sizeof(char *)),
573  ai.argbuf, sizeof(ai.argbuf),
574  ai.noglobargv, 0);
575  if (bUsed <= 0)
576  break;
577  tUsed += bUsed;
578  if (ai.cargc == 0)
579  continue;
580  gRunningCommand = 1;
581  (void) time(&cmdStart);
582  if (DoCommand(&ai) < 0) {
583  (void) time(&cmdStop);
584  gRunningCommand = 0;
585  break;
586  }
587  (void) time(&cmdStop);
588  gRunningCommand = 0;
589  if ((cmdStop - cmdStart) > kBeepAfterCmdTime) {
590  /* Let the user know that a time-consuming
591  * operation has completed.
592  */
593 #if defined(WIN32) || defined(_WINDOWS)
595 #else
596  (void) fprintf(stderr, "\007");
597 #endif
598  }
599  ++gEventNumber;
600  }
601 
602  free(lineRead);
603  }
604 
605  CloseHost();
606  gMayBackToTopJmp = 0;
607 } /* Shell */
#define isspace(c)
Definition: acclib.h:69
jmp_buf sigjmp_buf
Definition: port.h:324
CommandPtr GetCommandByName(const char *const name, int wantExactMatch)
Definition: shell.c:156
#define sleep
Definition: syshdrs.h:37
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
int gDoneApplication
Definition: shell.c:21
char argbuf[256]
Definition: shell.h:12
int gEventNumber
Definition: shell.c:27
const char * cargv[64]
Definition: shell.h:9
int gCancelCtrl
Definition: shell.c:66
WCHAR * name
Definition: path.c:44
#define kAmbiguousCommand
Definition: shell.h:54
void PrintCmdUsage(CommandPtr c)
Definition: shell.c:210
#define free
Definition: debug_ros.c:5
#define kNoCommand
Definition: shell.h:55
int gGotSig
Definition: shell.c:60
int gRunningCommand
Definition: shell.c:63
INT cmdStart(INT argc, WCHAR **argv)
Definition: cmdStart.c:163
void * arg
Definition: msvc.h:12
#define SIGINT
Definition: signal.h:23
Definition: shell.h:41
__u16 time
Definition: mkdosfs.c:366
#define SIG_DFL
Definition: signal.h:47
void BackToTop(int sigNum)
Definition: shell.c:452
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
char host[64]
Definition: ncftp.h:136
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int gNumProgramRuns
Definition: preffw.c:14
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
#define kCmdMustBeConnected
Definition: shell.h:59
void SetXtermTitle(const char *const fmt,...)
Definition: readln.c:718
smooth NULL
Definition: ftsmooth.c:416
int minargs
Definition: shell.h:46
Definition: parser.c:48
Command gCommands[]
Definition: cmdlist.c:16
static int DoCommand(const ArgvInfoPtr aip)
Definition: shell.c:381
#define kCmdMustBeDisconnected
Definition: shell.h:60
int(* qsort_proc_t)(const void *, const void *)
Definition: util.h:8
int longjmp(jmp_buf buf, int retval)
FTPLibraryInfo gLib
Definition: main.c:36
void siglongjmp(sigjmp_buf buf, int val)
int noglobargv[64]
Definition: shell.h:10
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
void Cancel(int sigNum)
Definition: shell.c:481
#define d
Definition: ke_i.h:81
#define kBeepAfterCmdTime
Definition: shell.h:26
static int CommandSortCmp(const CommandPtr a, const CommandPtr b)
Definition: shell.c:80
int MakeArgv(char *line, int *cargc, const char **cargv, int cargcmax, char *dbuf, size_t dbufsize, int *noglobargv, int readlineHacks)
Definition: shell.c:221
int sigsetjmp(sigjmp_buf buf, int savesigs)
const GLubyte * c
Definition: glext.h:8905
FTPConnectionInfo gConn
Definition: main.c:37
void InitCommandList(void)
Definition: shell.c:90
int cargc
Definition: shell.h:11
GLbitfield flags
Definition: glext.h:7161
#define SIGPIPE
Definition: signal.h:35
char line[200]
Definition: main.c:97
int signal
Definition: xcptfil.c:12
Definition: ncftp.h:84
#define kGlobChars
Definition: ncftp.h:357
jmp_buf gBackToTopJmp
Definition: shell.c:50
static int CommandExactSearchCmp(const char *const key, const CommandPtr b)
Definition: shell.c:102
void MakePrompt(char *dst, size_t dsize)
Definition: readln.c:802
int maxargs
Definition: shell.h:46
void CommandShell(void)
Definition: shell.c:499
CmdProc proc
Definition: shell.h:43
#define Trace(x)
Definition: zutil.h:197
Definition: shell.h:8
INT cmdStop(INT argc, WCHAR **argv)
Definition: cmdStop.c:12
static int CommandSubSearchCmp(const char *const key, const CommandPtr a)
Definition: shell.c:116
int gMayCancelJmp
Definition: shell.c:54
jmp_buf gCancelJmp
Definition: shell.c:45
#define NcSignal
Definition: ncftp.h:604
BOOL WINAPI MessageBeep(_In_ UINT)
int flags
Definition: shell.h:45
void CloseHost(void)
Definition: main.c:153
int(* bsearch_proc_t)(const void *, const void *)
Definition: util.h:9
__kernel_time_t time_t
Definition: linux.h:252
char gCopyright[]
Definition: version.c:17
LineList gStartupURLCdList
Definition: main.c:38
#define kNoMin
Definition: shell.h:35
#define MB_OK
Definition: winuser.h:784
void XferCanceller(int sigNum)
Definition: shell.c:419
#define setjmp
Definition: setjmp.h:183
char * strchr(const char *String, int ch)
Definition: utclib.c:501
POINT cp
Definition: magnifier.c:61
Definition: name.c:36
#define kNoMax
Definition: shell.h:34
#define c
Definition: ke_i.h:80
void AddHistory(char *line)
Definition: readln.c:699
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
struct Command * CommandPtr
Definition: shell.h:28
long jmp_buf[100]
Definition: of.h:11
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
void exit(int exitcode)
Definition: _exit.c:33
int gNumInterruptions
Definition: shell.c:24
#define memset(x, y, z)
Definition: compat.h:39
size_t gNumCommands
Definition: cmdlist.c:525
int gStartupUrlParameterGiven
Definition: main.c:32
void PrintCmdHelp(CommandPtr c)
Definition: shell.c:200
int gMayBackToTopJmp
Definition: shell.c:57
void FTPShutdownHost(const FTPCIPtr cip)
Definition: open.c:564
CommandPtr GetCommandByIndex(const int i)
Definition: shell.c:140
char * Readline(char *prompt)
Definition: readln.c:671
Definition: path.c:42
#define printf
Definition: config.h:203
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define bsearch