/* * process the command line and execute the appropriate functions * full input/output redirection and piping are supported */ void parsecommandline(char *s, int redirect) { char *in = 0; char *out = 0; char *fname0 = 0; char *fname1 = 0; char *nextcmd; int of_attrib = O_CREAT | O_TRUNC | O_WRONLY; int num; assert(s); dprintf(("[parsecommandline (%s)]\n", s)); #ifdef FEATURE_ALIASES aliasexpand(s, MAX_INTERNAL_COMMAND_SIZE); dprintf(("[alias expanded to (%s)]\n", s)); #endif if (tracemode) { /* Question after the variables expansion and make sure _all_ executed commands will honor the trace mode */ /* * Commands may be nested ("if errorlevel 1 echo done>test"). To * prevent redirecting FreeCOM prompts to user file, temporarily * revert redirection. */ int redir_fdin, redir_fdout, answer; if (oldinfd != -1) { redir_fdin = dup (0); dup2 (oldinfd, 0); } if (oldoutfd != -1) { redir_fdout = dup (1); dup2 (oldoutfd, 1); } printprompt(); outs(s); /* If the user hits ^Break, it has the same effect as usually: If he is in a batch file, he is asked if to abort all the batchfiles or just the current one */ answer = userprompt(PROMPT_YES_NO); if (oldinfd != -1) { dup2 (redir_fdin, 0); dos_close (redir_fdin); } if (oldoutfd != -1) { dup2 (redir_fdout, 1); dos_close (redir_fdout); } if (answer != 1) return; /* "No" or ^Break */ } if(!redirect) { docommand(s); return; } assert(oldinfd == -1); /* if fails something is wrong; should NEVER */ assert(oldoutfd == -1); /* happen! -- 2000/01/13 ska*/ num = get_redirection(s, &in, &out, &of_attrib); if (num < 0) /* error */ goto abort; /* Set up the initial conditions ... */ if (in || (num > 1)) /* Need to preserve stdin */ oldinfd = dup(0); if (in) /* redirect input from this file name */ { dos_close(0); if (0 != devopen(in, O_RDONLY)) { error_redirect_from_file(in); goto abort; } } if (out || (num > 1)) /* Need to preserve stdout */ oldoutfd = dup(1); /* Now do all but the last pipe command */ while (num-- > 1) { dos_close(1); /* Close current output file */ if ((fname0 = tmpfn()) == 0) goto abort; dos_creat(fname0, 0); nextcmd = s + strlen(s) + 1; docommand(s); dos_close(1); dup2(oldoutfd, 1); dos_close(0); killtmpfn(fname1); /* fname1 can by NULL */ fname1 = fname0; fname0 = 0; dos_open(fname1, O_RDONLY); s = nextcmd; } /* Now set up the end conditions... */ if (out) /* Final output to here */ { dos_close(1); if (1 != devopen(out, of_attrib)) { error_redirect_to_file(out); goto abort; } } else if (oldoutfd != -1) /* Restore original stdout */ { dos_close(1); dup2(oldoutfd, 1); dos_close(oldoutfd); oldoutfd = -1; } docommand(s); /* process final command */ abort: if (oldinfd != -1) /* Restore original STDIN */ { dos_close(0); dup2(oldinfd, 0); dos_close(oldinfd); oldinfd = -1; } if (oldoutfd != -1) /* Restore original STDOUT */ { dos_close(1); dup2(oldoutfd, 1); dos_close(oldoutfd); oldoutfd = -1; } killtmpfn(fname1); killtmpfn(fname0); if (out) free(out); if (in) free(in); }
COUNT DosCreat(BYTE FAR * fname, COUNT attrib) { psp FAR *p = MK_FP(cu_psp, 0); WORD hndl, sft_idx; sft FAR *sftp; struct dhdr FAR *dhp; BYTE FAR *froot; WORD i; /* get a free handle */ if ((hndl = get_free_hndl()) == 0xff) return DE_TOOMANY; /* now get a free system file table entry */ if ((sftp = get_free_sft((WORD FAR *) & sft_idx)) == (sft FAR *) - 1) return DE_TOOMANY; /* check for a device */ froot = get_root(fname); for (i = 0; i < FNAME_SIZE; i++) { if (*froot != '\0' && *froot != '.') PriPathName[i] = *froot++; else break; } for (; i < FNAME_SIZE; i++) PriPathName[i] = ' '; /* if we have an extension, can't be a device */ if (*froot != '.') { for (dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1; dhp = dhp->dh_next) { if (fnmatch((BYTE FAR *) PriPathName, (BYTE FAR *) dhp->dh_name, FNAME_SIZE, FALSE)) { sftp->sft_count += 1; sftp->sft_mode = SFT_MRDWR; sftp->sft_attrib = attrib; sftp->sft_flags = ((dhp->dh_attr & ~SFT_MASK) & ~SFT_FSHARED) | SFT_FDEVICE | SFT_FEOF; sftp->sft_psp = cu_psp; fbcopy((BYTE FAR *) PriPathName, sftp->sft_name, FNAME_SIZE + FEXT_SIZE); sftp->sft_dev = dhp; p->ps_filetab[hndl] = sft_idx; return hndl; } } } if (Remote_OCT(REM_CREATE, fname, attrib, sftp) == 0) { if (sftp->sft_flags & SFT_FSHARED) { sftp->sft_count += 1; p->ps_filetab[hndl] = sft_idx; return hndl; } } sftp->sft_status = dos_creat(fname, attrib); if (sftp->sft_status >= 0) { p->ps_filetab[hndl] = sft_idx; sftp->sft_count += 1; sftp->sft_mode = SFT_MRDWR; sftp->sft_attrib = attrib; sftp->sft_flags = 0; sftp->sft_psp = cu_psp; DosGetFile(fname, sftp->sft_name); return hndl; } else return sftp->sft_status; }
BOOL FcbCreate(xfcb FAR * lpXfcb) { WORD sft_idx; sft FAR *sftp; struct dhdr FAR *dhp; COUNT FcbDrive; /* get a free system file table entry */ if ((sftp = FcbGetFreeSft((WORD FAR *) & sft_idx)) == (sft FAR *) - 1) return DE_TOOMANY; /* Build a traditional DOS file name */ lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive); /* check for a device */ /* if we have an extension, can't be a device */ if (IsDevice(PriPathName)) { for (dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1; dhp = dhp->dh_next) { if (FcbFnameMatch((BYTE FAR *) PriPathName, (BYTE FAR *) dhp->dh_name, FNAME_SIZE, FALSE)) { sftp->sft_count += 1; sftp->sft_mode = O_RDWR; sftp->sft_attrib = 0; sftp->sft_flags = (dhp->dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF; sftp->sft_psp = cu_psp; fbcopy(lpFcb->fcb_fname, sftp->sft_name, FNAME_SIZE + FEXT_SIZE); sftp->sft_dev = dhp; lpFcb->fcb_sftno = sft_idx; lpFcb->fcb_curec = 0; lpFcb->fcb_recsiz = 0; lpFcb->fcb_fsize = 0; lpFcb->fcb_date = dos_getdate(); lpFcb->fcb_time = dos_gettime(); lpFcb->fcb_rndm = 0; return TRUE; } } } sftp->sft_status = dos_creat(PriPathName, 0); if (sftp->sft_status >= 0) { lpFcb->fcb_drive = FcbDrive; lpFcb->fcb_sftno = sft_idx; lpFcb->fcb_curec = 0; lpFcb->fcb_recsiz = 128; lpFcb->fcb_fsize = 0; lpFcb->fcb_date = dos_getdate(); lpFcb->fcb_time = dos_gettime(); lpFcb->fcb_rndm = 0; sftp->sft_count += 1; sftp->sft_mode = O_RDWR; sftp->sft_attrib = 0; sftp->sft_flags = 0; sftp->sft_psp = cu_psp; fbcopy((BYTE FAR *) & lpFcb->fcb_fname, (BYTE FAR *) & sftp->sft_name, FNAME_SIZE + FEXT_SIZE); return TRUE; } else return FALSE; }