Ejemplo n.º 1
0
/*ARGSUSED*/
void
docomplete(Char **v, struct command *t)
{
    struct varent *vp;
    Char *p;
    Char **pp;

    USE(t);
    v++;
    p = *v++;
    if (p == 0)
	tw_prlist(&completions);
    else if (*v == 0) {
	vp = adrof1(strip(p), &completions);
	if (vp && vp->vec)
	    tw_pr(vp->vec), xputchar('\n');
	else
	{
#ifdef TDEBUG
	    xprintf("tw_find(%s) \n", short2str(strip(p)));
#endif /* TDEBUG */
	    pp = tw_find(strip(p), &completions, FALSE);
	    if (pp)
		tw_pr(pp), xputchar('\n');
	}
    }
    else
	set1(strip(p), saveblk(v), &completions, VAR_READWRITE);
} /* end docomplete */
Ejemplo n.º 2
0
void MmeCIFGrabber::saveblks(const u_char* in)
{
	int is = 2 * inw_;
	u_char* crv = crvec_;
	u_char* lum = frame_;
	u_char* chm = frame_ + framesize_;
	u_int off = framesize_ >> 2;

	crv += vstart_ * blkw_ + hstart_;
	lum += vstart_ * outw_ * 16 + hstart_ * 16;
	chm += vstart_ * (outw_ >> 1) * 8 + hstart_ * 8;

	int skip = hstart_ + (blkw_ - hstop_);

	for (int y = vstart_; y < vstop_; ++y) {
		const u_char* nin = in;
		for (int x = hstart_; x < hstop_; ++x) {
			int s = *crv++;
			if ((s & CR_SEND) != 0)
				saveblk(in, lum, chm, chm + off, outw_, is);

			in += 32;
			lum += 16;
			chm += 8;
		}
		crv += skip;
		lum += 15 * outw_ + skip * 16;
		chm += 7 * (outw_ >> 1) + skip * 8;
		in = nin + 16 * is;
	}
}
Ejemplo n.º 3
0
Archivo: ps.c Proyecto: cftyngit/nctuns
void dops(Char ** vc, struct command *c) {
	
	DWORD nump;
	unsigned int i,k;
	char **v;

	if (!ProcessListFunc)
		return;
	gflag = 0;
	tglob(vc);
	if (gflag) {
		vc = globall(vc);
		if (vc == 0)
			stderror(ERR_NAME | ERR_NOMATCH);
	}
	else
		vc = gargv = saveblk(vc);
	trim(vc);
	v = short2blk(vc);
	for (k = 0; v[k] != NULL ; k++){
		if ( v[k][0] == '-' ) {
			if( (v[k][1] == 'W') || (v[k][1] == 'w'))
				g_dowindows = 1;
		}
	}
	nump = ProcessListFunc();

	for(i=0; i< nump; i++) {
		if (gdwPlatform == VER_PLATFORM_WIN32_NT) 
			xprintf("%6u  %-20s %-30s\n",processlist[i].pid,
							processlist[i].exename, 
							g_dowindows?processlist[i].title:"");
		else
			xprintf("0x%08x  %-20s %-30s\n",processlist[i].pid,
							processlist[i].exename,
							g_dowindows?processlist[i].title:"");
	}
	g_dowindows =0;

	if (processlist)
		heap_free(processlist);

}
Ejemplo n.º 4
0
void Mme422Grabber::saveblks(const u_char* in)
{
	u_char* crv = crvec_;
	u_char* lum = frame_;
	int off = framesize_;
	u_char* chm = lum + off;
	off >>= 1;
	int stride = 15 * inw_;
	for (int y = 0; y < blkh_; ++y) {
		for (int x = 0; x < blkw_; ++x) {
			int s = *crv++;
			if ((s & CR_SEND) != 0)
				saveblk(in, lum, chm, chm + off, outw_);

			in += 32;
			lum += 16;
			chm += 8;
		}
		lum += stride;
		chm += stride >> 1;
		in += stride << 1;
	}
}
Ejemplo n.º 5
0
void
/*ARGSUSED*/
doexec(Char **v, struct command *t)
{
    struct varent *pathv;
    Char *blk[2], **av, *dp, **pv, *sav;
    int i, hashval, hashval1;
    sigset_t nsigset;
    int slash;

    hashval = 0;
    /*
     * Glob the command name. We will search $path even if this does something,
     * as in sh but not in csh.  One special case: if there is no PATH, then we
     * execute only commands which start with '/'.
     */
    blk[0] = t->t_dcom[0];
    blk[1] = 0;
    gflag = 0, tglob(blk);
    if (gflag) {
	pv = globall(blk);
	if (pv == 0) {
	    setname(vis_str(blk[0]));
	    stderror(ERR_NAME | ERR_NOMATCH);
	}
	gargv = 0;
    }
    else
	pv = saveblk(blk);

    trim(pv);

    exerr = 0;
    expath = Strsave(pv[0]);
    Vexpath = expath;

    pathv = adrof(STRpath);
    if (pathv == 0 && expath[0] != '/') {
	blkfree(pv);
	pexerr();
    }
    slash = any(short2str(expath), '/');

    /*
     * Glob the argument list, if necessary. Otherwise trim off the quote bits.
     */
    gflag = 0;
    av = &t->t_dcom[1];
    tglob(av);
    if (gflag) {
	av = globall(av);
	if (av == 0) {
	    blkfree(pv);
	    setname(vis_str(expath));
	    stderror(ERR_NAME | ERR_NOMATCH);
	}
	gargv = 0;
    }
    else
	av = saveblk(av);

    blkfree(t->t_dcom);
    t->t_dcom = blkspl(pv, av);
    free(pv);
    free(av);
    av = t->t_dcom;
    trim(av);

    if (*av == NULL || **av == '\0')
	pexerr();

    xechoit(av);		/* Echo command if -x */
    /*
     * Since all internal file descriptors are set to close on exec, we don't
     * need to close them explicitly here.  Just reorient ourselves for error
     * messages.
     */
    SHIN = 0;
    SHOUT = 1;
    SHERR = 2;
    OLDSTD = 0;
    /*
     * We must do this AFTER any possible forking (like `foo` in glob) so that
     * this shell can still do subprocesses.
     */
    sigemptyset(&nsigset);
    (void)sigprocmask(SIG_SETMASK, &nsigset, NULL);
    /*
     * If no path, no words in path, or a / in the filename then restrict the
     * command search.
     */
    if (pathv == 0 || pathv->vec[0] == 0 || slash)
	pv = justabs;
    else
	pv = pathv->vec;
    sav = Strspl(STRslash, *av); 	/* / command name for postpending */
    Vsav = sav;
    if (havhash)
	hashval = hashname(*av);
    i = 0;
    hits++;
    do {
	/*
	 * Try to save time by looking at the hash table for where this command
	 * could be.  If we are doing delayed hashing, then we put the names in
	 * one at a time, as the user enters them.  This is kinda like Korn
	 * Shell's "tracked aliases".
	 */
	if (!slash && pv[0][0] == '/' && havhash) {
	    hashval1 = hash(hashval, i);
	    if (!bit(xhash, hashval1))
		goto cont;
	}
	if (pv[0][0] == 0 || eq(pv[0], STRdot))	/* don't make ./xxx */
	    texec(*av, av);
	else {
	    dp = Strspl(*pv, sav);
	    Vdp = dp;
	    texec(dp, av);
	    Vdp = 0;
	    free(dp);
	}
	misses++;
cont:
	pv++;
	i++;
    } while (*pv);
    hits--;
    Vsav = 0;
    free(sav);
    pexerr();
    /* NOTREACHED */
}
Ejemplo n.º 6
0
/*ARGSUSED*/
void
doset(Char **v, struct command *c)
{
    Char *p;
    Char   *vp;
    Char  **vecp;
    int    hadsub;
    int     subscr;
    int	    flags = VAR_READWRITE;
    int    first_match = 0;
    int    last_match = 0;
    int    changed = 0;

    USE(c);
    v++;
    do {
	changed = 0;
	/*
	 * Readonly addition From: Tim P. Starrin <*****@*****.**>
	 */
	if (*v && eq(*v, STRmr)) {
	    flags = VAR_READONLY;
	    v++;
	    changed = 1;
	}
	if (*v && eq(*v, STRmf) && !last_match) {
	    first_match = 1;
	    v++;
	    changed = 1;
	}
	if (*v && eq(*v, STRml) && !first_match) {
	    last_match = 1;
	    v++;
	    changed = 1;
	}
    } while(changed);
    p = *v++;
    if (p == 0) {
	plist(&shvhed, flags);
	return;
    }
    do {
	hadsub = 0;
	vp = p;
	if (!letter(*p))
	    stderror(ERR_NAME | ERR_VARBEGIN);
	do {
	    p++;
	} while (alnum(*p));
	if (*p == '[') {
	    hadsub++;
	    p = getinx(p, &subscr);
	}
	if (*p != '\0' && *p != '=')
	    stderror(ERR_NAME | ERR_VARALNUM);
	if (*p == '=') {
	    *p++ = '\0';
	    if (*p == '\0' && *v != NULL && **v == '(')
		p = *v++;
	}
	else if (*v && eq(*v, STRequal)) {
	    if (*++v != NULL)
		p = *v++;
	}
	if (eq(p, STRLparen)) {
	    Char **e = v;

	    if (hadsub)
		stderror(ERR_NAME | ERR_SYNTAX);
	    for (;;) {
		if (!*e)
		    stderror(ERR_NAME | ERR_MISSING, ')');
		if (**e == ')')
		    break;
		e++;
	    }
	    p = *e;
	    *e = 0;
	    vecp = saveblk(v);
	    if (first_match)
	       flags |= VAR_FIRST;
	    else if (last_match)
	       flags |= VAR_LAST;

	    set1(vp, vecp, &shvhed, flags);
	    *e = p;
	    v = e + 1;
	}
	else if (hadsub) {
	    Char *copy;

	    copy = Strsave(p);
	    cleanup_push(copy, xfree);
	    asx(vp, subscr, copy);
	    cleanup_ignore(copy);
	    cleanup_until(copy);
	}
	else
	    setv(vp, Strsave(p), flags);
	update_vars(vp);
    } while ((p = *v++) != NULL);
}
Ejemplo n.º 7
0
Archivo: set.c Proyecto: Open343/bitrig
void
/*ARGSUSED*/
doset(Char **v, struct command *t)
{
    Char *p;
    Char   *vp, op;
    Char  **vecp;
    bool    hadsub;
    int     subscr;

    v++;
    p = *v++;
    if (p == 0) {
	prvars();
	return;
    }
    do {
	hadsub = 0;
	vp = p;
	if (letter(*p))
	    for (; alnum(*p); p++)
		continue;
	if (vp == p || !letter(*vp))
	    stderror(ERR_NAME | ERR_VARBEGIN);
	if ((p - vp) > MAXVARLEN) {
	    stderror(ERR_NAME | ERR_VARTOOLONG);
	    return;
	}
	if (*p == '[') {
	    hadsub++;
	    p = getinx(p, &subscr);
	}
	if ((op = *p) != '\0') {
	    *p++ = 0;
	    if (*p == 0 && *v && **v == '(')
		p = *v++;
	}
	else if (*v && eq(*v, STRequal)) {
	    op = '=', v++;
	    if (*v)
		p = *v++;
	}
	if (op && op != '=')
	    stderror(ERR_NAME | ERR_SYNTAX);
	if (eq(p, STRLparen)) {
	    Char **e = v;

	    if (hadsub)
		stderror(ERR_NAME | ERR_SYNTAX);
	    for (;;) {
		if (!*e)
		    stderror(ERR_NAME | ERR_MISSING, ')');
		if (**e == ')')
		    break;
		e++;
	    }
	    p = *e;
	    *e = 0;
	    vecp = saveblk(v);
	    set1(vp, vecp, &shvhed);
	    *e = p;
	    v = e + 1;
	}
	else if (hadsub)
	    asx(vp, subscr, Strsave(p));
	else
	    set(vp, Strsave(p));
	if (eq(vp, STRpath)) {
	    exportpath(adrof(STRpath)->vec);
	    dohash(NULL, NULL);
	}
	else if (eq(vp, STRhistchars)) {
	    Char *pn = value(STRhistchars);

	    HIST = *pn++;
	    HISTSUB = *pn;
	}
	else if (eq(vp, STRuser)) {
	    Setenv(STRUSER, value(vp));
	    Setenv(STRLOGNAME, value(vp));
	}
	else if (eq(vp, STRwordchars)) {
	    word_chars = value(vp);
	}
	else if (eq(vp, STRterm))
	    Setenv(STRTERM, value(vp));
	else if (eq(vp, STRhome)) {
	    Char *cp;

	    cp = Strsave(value(vp));	/* get the old value back */

	    /*
	     * convert to canonical pathname (possibly resolving symlinks)
	     */
	    cp = dcanon(cp, cp);

	    set(vp, Strsave(cp));	/* have to save the new val */

	    /* and now mirror home with HOME */
	    Setenv(STRHOME, cp);
	    /* fix directory stack for new tilde home */
	    dtilde();
	    free(cp);
	}
	else if (eq(vp, STRfilec))
	    filec = 1;
    } while ((p = *v++) != NULL);
}
Ejemplo n.º 8
0
Archivo: ps.c Proyecto: cftyngit/nctuns
The default action is to shutdown without a reboot.\n\"now\" must be \
specified to actually shutdown or reboot\n"};

void doshutdown(Char **vc, struct command *c) {

	unsigned int flags = 0;
	unsigned char reboot,shutdown,logoff,shutdown_ok;
	char **v;
	char *ptr;
	char errbuf[128];
	int k;
	HANDLE hToken;
	TOKEN_PRIVILEGES tp,tpPrevious;
	LUID luid;
	DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);

	if (gdwPlatform != VER_PLATFORM_WIN32_NT) {
		stderror(ERR_SYSTEM,"shutdown","Sorry,not supported on win95");
	}

	shutdown_ok = reboot = shutdown = logoff = 0;
	gflag = 0;
	tglob(vc);
	if (gflag) {
		vc = globall(vc);
		if (vc == 0)
			stderror(ERR_NAME | ERR_NOMATCH);
	}
	else
		vc = gargv = saveblk(vc);
	trim(vc);
	v = short2blk(vc);
	for (k = 0; v[k] != NULL ; k++){
		if ( v[k][0] == '-' ) {
			ptr = v[k];
			ptr++;
			while( ptr && *ptr) {
				if (*ptr == 'f')
					flags |= EWX_FORCE;
				if (*ptr == 'r')
					reboot =1;
				else if (*ptr == 'l')
					logoff =1;
				else {
					blkfree((Char **)v);
					stderror(ERR_SYSTEM,"Usage",shutdown_usage);
				}
				ptr++;
			}
		}
		else if (!lstrcmpi(v[k],"now")) {
			shutdown_ok = 1;
		}
	}
	if (k == 0) {
		blkfree((Char**)v);
		stderror(ERR_SYSTEM,"Usage",shutdown_usage);
	}
	if (!reboot && !logoff){
		flags |= EWX_SHUTDOWN;
		shutdown = 1;
	}
	if (reboot && logoff ) {
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"Usage",shutdown_usage);
	}
	if (reboot)
		flags |= EWX_REBOOT;
	if (logoff)
		flags |= EWX_LOGOFF;

	if ((reboot || shutdown) && (!shutdown_ok) ) {
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown","Specify \"now\" to really shutdown");
	}


	if (!OpenProcessToken(GetCurrentProcess(),
							TOKEN_ADJUST_PRIVILEGES| TOKEN_QUERY,
							&hToken) ){
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
							

	if (!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid)) {
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = 0;

	if (!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),&tpPrevious,
				&cbPrevious)){
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
	tpPrevious.PrivilegeCount = 1;
	tpPrevious.Privileges[0].Luid = luid;
	tpPrevious.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;

	if (!AdjustTokenPrivileges(hToken,FALSE,&tpPrevious,cbPrevious,NULL,
				NULL)){
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
	if  (  !ExitWindowsEx(flags,0) ) {
		make_err_str(GetLastError(),errbuf,128);
		blkfree((Char **)v);
		stderror(ERR_SYSTEM,"shutdown failed",errbuf);
	}
}
Ejemplo n.º 9
0
Archivo: ntfunc.c Proyecto: phase/tcsh
int nt_try_fast_exec(struct command *t) {
	register Char  **pv, **av;
	register Char *dp,*sav;
	register char **tt;
	register char *f;
	register struct varent *v;
	register int hashval,i;
	register int slash;
	int rc = 0, gflag;
	Char *vp;
	Char   *blk[2];

	vp = varval(STRNTslowexec);
	if (vp != STRNULL)
		return 1;

	blk[0] = t->t_dcom[0];
	blk[1] = 0;

	// don't do backtick
	if(Strchr(t->t_dcom[0],'`') )
		return 1;


	gflag = tglob(blk);
	if (gflag) {
		pv = globall(blk, gflag);
		if (pv == 0) {
			return 1;
		}
	}
	else
		pv = saveblk(blk);

	trim(pv);

	epath = Strsave(pv[0]);
	v = adrof(STRpath);
	if (v == 0 && epath[0] != '/' && epath[0] != '.') {
		blkfree(pv);
		return 1;
	}
	slash = any(short2str(epath),'/');
	/*
	 * Glob the argument list, if necessary. Otherwise trim off the quote bits.
	 */
	av = &t->t_dcom[1];
	gflag = tglob(av);
	if (gflag) {
		av = globall(av, gflag);/*FIXRESET*/
		if (av == 0) {
			blkfree(pv);
			return 1;
		}
	}
	else
		av = saveblk(av);

	blkfree(t->t_dcom);
	t->t_dcom = blkspl(pv, av);
	xfree((ptr_t) pv);
	xfree((ptr_t) av);
	av = t->t_dcom;
	//trim(av);

	if (*av == NULL || **av == '\0')
		return 1;

	xechoit(av);/*FIXRESET*/		/* Echo command if -x */
	if (v == 0 || v->vec[0] == 0 || slash)
		pv = abspath;
	else
		pv = v->vec;

	sav = Strspl(STRslash,*av);
	hashval = hashval_extern(*av);

	i = 0;
	do {
#pragma warning(disable:4310)
		if (!slash && ABSOLUTEP(pv[0]) && havhash) {
#pragma warning(default:4310)
			if (!bit_extern(hashval,i)){
				pv++;i++;
				continue;
			}
		}
		if (pv[0][0] == 0 || eq(pv[0],STRdot)) {

			tt = short2blk(av);
			f = short2str(*av);

			rc = nt_texec(f, tt);

			blkfree((Char**)tt);
			if (!rc)
				break;
		}
		else {
			dp = Strspl(*pv,sav);
			tt = short2blk(av);
			f = short2str(dp);

			rc = nt_texec(f, tt);

			blkfree((Char**)tt);
			xfree((ptr_t)dp);
			if (!rc)
				break;
		}
		pv++;
		i++;
	}while(*pv);
	return rc;
}
Ejemplo n.º 10
0
void
doset(tchar **v)
{
	tchar *p;
	tchar *vp, op;
	tchar **vecp;
	bool hadsub;
	int subscr;
	tchar *retp;

#ifdef TRACE
	tprintf("TRACE- doset()\n");
#endif
	v++;
	p = *v++;
	if (p == 0) {
		prvars();
		return;
	}
	do {
		hadsub = 0;
		/*
		 * check for proper variable syntax
		 * must be alphanumeric, start with a letter and
		 * be at most 20 characters
		 */
		for (vp = p; alnum(*p); p++)
			continue;
		if (vp == p || !letter(*vp))
			goto setsyn;
		if ((p - vp) > MAX_VAR_LEN)
			bferr("Variable name too long");
		if (*p == '[') {
			hadsub++;
			p = getinx(p, &subscr);
		}
		if (op = *p) {
			*p++ = 0;
			if (*p == 0 && *v && **v == '(')
				p = *v++;
		} else if (*v && eq(*v, S_EQ /* "=" */)) {
			op = '=', v++;
			if (*v)
				p = *v++;
		}
		if (op && op != '=')
setsyn:
			bferr("Syntax error");
		if (eq(p, S_LPAR /* "(" */)) {
			tchar **e = v;

			if (hadsub)
				goto setsyn;
			for (;;) {
				if (!*e)
					bferr("Missing )");
				if (**e == ')')
					break;
				e++;
			}
			p = *e;
			*e = 0;
			vecp = saveblk(v);
			set1(vp, vecp, &shvhed);
			*e = p;
			v = e + 1;
		} else if (hadsub) {
			retp = savestr(p);
			asx(vp, subscr, retp);
			xfree(retp);
			retp = 0;
		} else
			set(vp, savestr(p));
		if (eq(vp, S_path /* "path" */)) {
			exportpath(adrof(S_path /* "path" */)->vec);
			dohash(xhash);
		} else if (eq(vp, S_histchars /* "histchars" */)) {
			tchar *p = value(S_histchars /* "histchars" */);
			HIST = *p++;
			HISTSUB = *p;
		} else if (eq(vp, S_user /* "user" */))
			local_setenv(S_USER /* "USER" */, value(vp));
		else if (eq(vp, S_term /* "term" */))
			local_setenv(S_TERM /* "TERM" */, value(vp));
		else if (eq(vp, S_home /* "home" */))
			local_setenv(S_HOME /* "HOME" */, value(vp));
#ifdef FILEC
		else if (eq(vp, S_filec /* "filec" */))
			filec = 1;
		else if (eq(vp, S_cdpath /* "cdpath" */))
			dohash(xhash2);
#endif
	} while (p = *v++);
}
Ejemplo n.º 11
0
/*ARGSUSED*/
void
dosched(Char **v, struct command *c)
{
    struct sched_event *tp, **pp;
    time_t  cur_time;
    int     count, hours, minutes, dif_hour, dif_min;
    Char   *cp;
    int    relative;		/* time specified as +hh:mm */
    struct tm *ltp;

    USE(c);
/* This is a major kludge because of a gcc linker  */
/* Problem.  It may or may not be needed for you   */
#if defined(_MINIX) && !defined(_MINIX_VMD)
    char kludge[10];
    extern char *sprintf();
    sprintf(kludge, CGETS(24, 1, "kludge"));
#endif /* _MINIX && !_MINIX_VMD */

    v++;
    cp = *v++;
    if (cp == NULL) {
	const Char *fmt;
	if ((fmt = varval(STRsched)) == STRNULL)
	    fmt = str2short("%h\t%T\t%R\n");
	/* print list of scheduled events */
	for (count = 1, tp = sched_ptr; tp; count++, tp = tp->t_next) {
	    Char *buf, *str;

	    buf = blkexpand(tp->t_lex);
	    cleanup_push(buf, xfree);
	    str = tprintf(FMT_SCHED, fmt, short2str(buf), tp->t_when, &count);
	    cleanup_until(buf);
	    cleanup_push(str, xfree);
	    for (cp = str; *cp;)
		xputwchar(*cp++);
	    cleanup_until(str);
	}
	return;
    }

    if (*cp == '-') {
	/* remove item from list */
	if (!sched_ptr)
	    stderror(ERR_NOSCHED);
	if (*v)
	    stderror(ERR_SCHEDUSAGE);
	count = atoi(short2str(++cp));
	if (count <= 0)
	    stderror(ERR_SCHEDUSAGE);
	pp = &sched_ptr;
	tp = sched_ptr;
	while (--count) {
	    if (tp->t_next == 0)
		break;
	    else {
		pp = &tp->t_next;
		tp = tp->t_next;
	    }
	}
	if (count)
	    stderror(ERR_SCHEDEV);
	*pp = tp->t_next;
	blkfree(tp->t_lex);
	xfree(tp);
	return;
    }

    /* else, add an item to the list */
    if (!*v)
	stderror(ERR_SCHEDCOM);
    relative = 0;
    if (!Isdigit(*cp)) {	/* not abs. time */
	if (*cp != '+')
	    stderror(ERR_SCHEDUSAGE);
	cp++, relative++;
    }
    minutes = 0;
    hours = atoi(short2str(cp));
    while (*cp && *cp != ':' && *cp != 'a' && *cp != 'p')
	cp++;
    if (*cp && *cp == ':')
	minutes = atoi(short2str(++cp));
    if ((hours < 0) || (minutes < 0) ||
	(hours > 23) || (minutes > 59))
	stderror(ERR_SCHEDTIME);
    while (*cp && *cp != 'p' && *cp != 'a')
	cp++;
    if (*cp && relative)
	stderror(ERR_SCHEDREL);
    if (*cp == 'p')
	hours += 12;
    (void) time(&cur_time);
    ltp = localtime(&cur_time);
    if (relative) {
	dif_hour = hours;
	dif_min = minutes;
    }
    else {
	if ((dif_hour = hours - ltp->tm_hour) < 0)
	    dif_hour += 24;
	if ((dif_min = minutes - ltp->tm_min) < 0) {
	    dif_min += 60;
	    if ((--dif_hour) < 0)
		dif_hour = 23;
	}
    }
    tp = xcalloc(1, sizeof *tp);
#ifdef _SX
    tp->t_when = cur_time - ltp->tm_sec + dif_hour * 3600 + dif_min * 60;
#else	/* _SX */
    tp->t_when = cur_time - ltp->tm_sec + dif_hour * 3600L + dif_min * 60L;
#endif /* _SX */
    /* use of tm_sec: get to beginning of minute. */
    for (pp = &sched_ptr; *pp != NULL && tp->t_when >= (*pp)->t_when;
	 pp = &(*pp)->t_next)
	;
    tp->t_next = *pp;
    *pp = tp;
    tp->t_lex = saveblk(v);
}