コード例 #1
0
ファイル: levels.cpp プロジェクト: sanjayui/tinymux
UTF8 *txlevel_description(dbref player, dbref target)
{
    // Allocate the return buffer.
    //
    int otype = Typeof(target);
    UTF8 *buff = alloc_mbuf("txlevel_description");
    UTF8 *bp = buff;

    int i;
    RLEVEL tl = TxLevel(target);
    for (i = 0; i < mudconf.no_levels; ++i)
    {
        confdata::rlevel_def *rldef = &mudconf.reality_level[i];
        if ((tl & rldef->value) == rldef->value)
        {
            safe_mb_chr(' ', buff, &bp);
            safe_mb_str(rldef->name, buff, &bp);
        }
    }

    // Terminate the string, and return the buffer to the caller.
    //
    *bp = '\0';
    return buff;
}
コード例 #2
0
ファイル: flags.c プロジェクト: sean-brandt/tinymush
char *flag_description( dbref player, dbref target ) {
    char *buff, *bp;

    FLAGENT *fp;

    int otype;

    FLAG fv;

    /*
     * Allocate the return buffer
     */

    otype = Typeof( target );
    bp = buff = alloc_mbuf( "flag_description" );

    /*
     * Store the header strings and object type
     */

    safe_mb_str( ( char * ) "Type: ", buff, &bp );
    safe_mb_str( ( char * ) object_types[otype].name, buff, &bp );
    safe_mb_str( ( char * ) " Flags:", buff, &bp );
    if( object_types[otype].perm != CA_PUBLIC ) {
        return buff;
    }
    /*
     * Store the type-invariant flags
     */

    for( fp = gen_flags; fp->flagname; fp++ ) {
        if( fp->flagflag & FLAG_WORD3 ) {
            fv = Flags3( target );
        } else if( fp->flagflag & FLAG_WORD2 ) {
            fv = Flags2( target );
        } else {
            fv = Flags( target );
        }
        if( fv & fp->flagvalue ) {
            if( ( fp->listperm & CA_WIZARD ) && !Wizard( player ) ) {
                continue;
            }
            if( ( fp->listperm & CA_GOD ) && !God( player ) ) {
                continue;
            }
            /*
             * don't show CONNECT on dark wizards to mortals
             */
            if( isPlayer( target ) && isConnFlag( fp ) &&
                    Can_Hide( target ) && Hidden( target ) &&
                    !See_Hidden( player ) ) {
                continue;
            }
            safe_mb_chr( ' ', buff, &bp );
            safe_mb_str( ( char * ) fp->flagname, buff, &bp );
        }
    }

    return buff;
}
コード例 #3
0
ファイル: fldigi.c プロジェクト: mlangelaar/jnos2
int fldigi_command (struct iface *ifp, char *cmdstr)
{
	struct mbuf *bp;

	struct socket lsock, rsock;

	int len = strlen (cmdstr);

	lsock.address = INADDR_ANY;
	lsock.port = 10000;

	rsock.address = Axip[ifp->dev].ipaddr;
	rsock.port = 10000;
	
	log (-1, "fldigi_command [%s]", cmdstr);

	if ((bp = alloc_mbuf (len)) == NULLBUF)
		return 0;

	strncpy ((char*)bp->data, cmdstr, len);

	bp->cnt = (int16)len;

	return send_udp (&lsock, &rsock, 0, 0, bp, 0, 0, 0);
}
コード例 #4
0
ファイル: version.c プロジェクト: Haunted-Memories/rhost
void do_version (dbref player, dbref cause, int extra)
{
char	*buff;

	notify(player, mudstate.version);
	buff=alloc_mbuf("do_version");
	sprintf(buff, "Build date: %.150s", MUSH_BUILD_DATE);
	notify(player, buff);
	free_mbuf(buff);
}
コード例 #5
0
ファイル: ftpserv.c プロジェクト: dieterdeyke/WAMPES
/* Do printf on a tcp connection */
static void Xprintf(struct tcb *tcb,char *message,char *arg1,char *arg2,char *arg3)
{
	struct mbuf *bp;

	if(tcb == NULL)
		return;

	bp = alloc_mbuf(256);
	sprintf((char *) bp->data,message,arg1,arg2,arg3);
	bp->cnt = strlen((char *) bp->data);
	send_tcp(tcb,&bp);
}
コード例 #6
0
ファイル: svdreport.cpp プロジェクト: Yargling/MuxDevelopment
void do_report(dbref executor, dbref caller, dbref enactor, int extra)
{
    UNUSED_PARAMETER(caller);
    UNUSED_PARAMETER(enactor);
    UNUSED_PARAMETER(extra);

    char *buff = alloc_mbuf("do_report");
    int nBin[NPERIODS];
    int i;

    for (i = 0; i < NPERIODS; i++)
    {
        nBin[i] = 0;
    }

    CLinearTimeAbsolute ltaNow, ltaPlayer;
    ltaNow.GetLocal();

    const int PeriodInSeconds = 28800;

    int iPlayer;
    DO_WHOLE_DB(iPlayer)
    {
        if (isPlayer(iPlayer))
        {
            int aowner, aflags;
            char *player_last = atr_get(iPlayer, A_LAST, &aowner, &aflags);

            if (ltaPlayer.SetString(player_last))
            {
                CLinearTimeDelta ltd(ltaPlayer, ltaNow);
                int ltdSeconds = ltd.ReturnSeconds();
                int iBin = ltdSeconds / PeriodInSeconds;
                if (0 <= iBin && iBin < NPERIODS)
                {
                    nBin[iBin]++;
                }
            }
            free_lbuf(player_last);
        }
    }

    int iHour, nSum = 0;
    notify(executor, "Day   Hours     Players  Total");
    for (i = 0, iHour = 0; i < NPERIODS; i++, iHour += 8)
    {
        nSum += nBin[i];
        mux_sprintf(buff, MBUF_SIZE, "%3d %03d - %03d: %6d %6d",
            iHour/24 + 1, iHour, iHour+8, nBin[i], nSum);
        notify(executor, buff);
    }
    free_mbuf(buff);
}
コード例 #7
0
ファイル: mbuf.c プロジェクト: hailynch/jnos2
void
refiq()
{
    register struct mbuf *bp;
    char i_state;
#ifdef  PI              /* Temp hack to satisfy PI DMA requirements */
    int32 dma_abs;  /* TEMP */
    int16 dma_page; /* TEMP */
#endif
  
    /* Empty the garbage */
    if(Garbq != NULLBUF){
        i_state = dirps();
        bp = Garbq;
        Garbq = NULLBUF;
        restore(i_state);
        free_p(bp);
    }
    /* Replenish interrupt buffer pool */ /* G1EMM and HB9RWM fix */
    while((Intqlen < Nibufs) && (Memthresh < availmem()) ){
#ifdef notdef
        while(Intqlen < Nibufs){
#endif
            if((bp = alloc_mbuf(Ibufsize)) == NULLBUF)
                break;
#ifdef  PI              /* Temp hack to satisfy PI DMA requirements */
            dma_abs = ((long)FP_SEG(bp->data) << 4) + (long)FP_OFF(bp->data);
            dma_page = dma_abs >> 16;
            if(((dma_abs+Ibufsize) >> 16) != dma_page){
                i_state = dirps();
                bp->next = Garbq;
                Garbq = bp;
                restore(i_state);
                continue;
            }
#endif
  
            i_state = dirps();
            bp->next = Intq;
            Intq = bp;
            Intqlen++;
            restore(i_state);
        }
        if(Iminfree == -1)
            Iminfree = Intqlen;
    }
  
    void
    iqstat()
    {
        tprintf("Intqlen %u Ibufsize %u Iminfree %u Ibuffail %lu Imaxrq %u\n",
        Intqlen,Ibufsize,Iminfree,Ibuffail,Ibuf_max_rq);    /* g8fsl */
    }
コード例 #8
0
ファイル: kiss.c プロジェクト: zidier215/tcpip
/* Perform device control on KISS TNC by sending control messages */
int32
kiss_ioctl(
struct iface *iface,
int cmd,
int set,
int32 val
){
	struct mbuf *hbp;
	uint8 *cp;
	int rval = 0;

	/* At present, only certain parameters are supported by
	 * stock KISS TNCs. As additional params are implemented,
	 * this will have to be edited
	 */
	switch(cmd){
	case PARAM_RETURN:
		set = 1;	/* Note fall-thru */
	case PARAM_TXDELAY:
	case PARAM_PERSIST:
	case PARAM_SLOTTIME:
	case PARAM_TXTAIL:
	case PARAM_FULLDUP:
	case PARAM_HW:
		if(!set){
			rval = -1;	/* Can't read back */
			break;
		}
		/* Allocate space for cmd and arg */
		if((hbp = alloc_mbuf(2)) == NULL){
			free_p(&hbp);
			rval = -1;
			break;
		}
		cp = hbp->data;
		*cp++ = cmd;
		*cp = val;
		hbp->cnt = 2;
		slip_raw(iface,&hbp);	/* Even more "raw" than kiss_raw */
		rval = val;		/* per Jay Maynard -- mce */
		break;
	case PARAM_SPEED:	/* These go to the local asy driver */
	case PARAM_DTR:
	case PARAM_RTS:
		rval = asy_ioctl(iface,cmd,set,val);
		break;
	default:		/* Not implemented */
		rval = -1;
		break;
	}
	return rval;
}
コード例 #9
0
ファイル: help.cpp プロジェクト: sanjayui/tinymux
static bool ValidateHelpFileIndex(int iHelpfile)
{
    if (  iHelpfile < 0
       || mudstate.mHelpDesc <= iHelpfile)
    {
        UTF8 *buf = alloc_mbuf("do_help.LOG");
        STARTLOG(LOG_BUGS, "BUG", "HELP");
        mux_sprintf(buf, MBUF_SIZE, T("Unknown help file number: %d"), iHelpfile);
        log_text(buf);
        ENDLOG;
        free_mbuf(buf);
        return false;
    }
    return true;
}
コード例 #10
0
ファイル: file_c.c プロジェクト: TinyMUSH/TinyMUSH
FBLOCK *fcache_fill(FBLOCK * fp, char ch)
{
    FBLOCK *tfp;

    if (fp->hdr.nchars >= (MBUF_SIZE - sizeof(FBLKHDR))) {
	/*
	 * We filled the current buffer.  Go get a new one.
	 */
	tfp = fp;
	fp = (FBLOCK *) alloc_mbuf("fcache_fill");
	fp->hdr.nxt = NULL;
	fp->hdr.nchars = 0;
	tfp->hdr.nxt = fp;
    }

    fp->data[fp->hdr.nchars++] = ch;
    return fp;
}
コード例 #11
0
ファイル: powers.c プロジェクト: TinyMUSH/TinyMUSH
char *power_description(dbref player, dbref target)
{
    char *buff, *bp;
    POWERENT *fp;
    int otype;
    POWER fv;
    /*
     * Allocate the return buffer
     */
    otype = Typeof(target);
    bp = buff = alloc_mbuf("power_description");
    /*
     * Store the header strings and object type
     */
    safe_mb_str((char *) "Powers:", buff, &bp);

    for (fp = gen_powers; fp->powername; fp++) {
	if (fp->powerpower & POWER_EXT) {
	    fv = Powers2(target);
	} else {
	    fv = Powers(target);
	}

	if (fv & fp->powervalue) {
	    if ((fp->listperm & CA_WIZARD) && !Wizard(player)) {
		continue;
	    }

	    if ((fp->listperm & CA_GOD) && !God(player)) {
		continue;
	    }

	    safe_mb_chr(' ', buff, &bp);
	    safe_mb_str((char *) fp->powername, buff, &bp);
	}
    }

    /*
     * Terminate the string, and return the buffer to the caller
     */
    *bp = '\0';
    return buff;
}
コード例 #12
0
ファイル: slip.c プロジェクト: dieterdeyke/WAMPES
/* Encode a packet in SLIP format */
static
struct mbuf *
slip_encode(struct mbuf **bpp)
{
	struct mbuf *lbp;       /* Mbuf containing line-ready packet */
	register uint8 *cp;
	int c;

	/* Allocate output mbuf that's twice as long as the packet.
	 * This is a worst-case guess (consider a packet full of FR_ENDs!)
	 */
	lbp = alloc_mbuf(2*len_p(*bpp) + 2);
	if(lbp == NULL){
		/* No space; drop */
		free_p(bpp);
		return NULL;
	}
	cp = lbp->data;

	/* Flush out any line garbage */
	*cp++ = FR_END;

	/* Copy input to output, escaping special characters */
	while((c = PULLCHAR(bpp)) != -1){
		switch(c){
		case FR_ESC:
			*cp++ = FR_ESC;
			*cp++ = T_FR_ESC;
			break;
		case FR_END:
			*cp++ = FR_ESC;
			*cp++ = T_FR_END;
			break;
		default:
			*cp++ = c;
		}
	}
	*cp++ = FR_END;
	lbp->cnt = cp - lbp->data;
	return lbp;
}
コード例 #13
0
ファイル: tcpgate.c プロジェクト: dieterdeyke/WAMPES
static void tcp_send(struct tcb *tcb)
{

  int cnt;
  struct mbuf *bp;

  if ((cnt = space_tcp(tcb)) <= 0) {
    off_read(tcb->user);
    return;
  }
  if (!(bp = alloc_mbuf(cnt))) return;
  cnt = read(tcb->user, bp->data, (unsigned) cnt);
  if (cnt <= 0) {
    free_p(&bp);
    off_read(tcb->user);
    close_tcp(tcb);
    return;
  }
  bp->cnt = cnt;
  send_tcp(tcb, &bp);
}
コード例 #14
0
ファイル: file_c.c プロジェクト: TinyMUSH/TinyMUSH
int fcache_read(FBLOCK ** cp, char *filename)
{
    int n, nmax, tchars, fd;
    char *buff;
    FBLOCK *fp, *tfp;
    /*
     * Free a prior buffer chain
     */
    fp = *cp;

    while (fp != NULL) {
	tfp = fp->hdr.nxt;
	free_mbuf(fp);
	fp = tfp;
    }

    *cp = NULL;

    /*
     * Read the text file into a new chain
     */

    if ((fd = tf_open(filename, O_RDONLY)) == -1) {
	/*
	 * Failure: log the event
	 */
	log_write(LOG_PROBLEMS, "FIL", "OPEN", "Couldn't open file '%s'.", filename);
	tf_close(fd);
	return -1;
    }

    buff = alloc_lbuf("fcache_read.temp");
    /*
     * Set up the initial cache buffer to make things easier
     */
    fp = (FBLOCK *) alloc_mbuf("fcache_read.first");
    fp->hdr.nxt = NULL;
    fp->hdr.nchars = 0;
    *cp = fp;
    tchars = 0;
    /*
     * Process the file, one lbuf at a time
     */
    nmax = read(fd, buff, LBUF_SIZE);

    while (nmax > 0) {
	for (n = 0; n < nmax; n++) {
	    switch (buff[n]) {
	    case '\n':
		fp = fcache_fill(fp, '\r');
		fp = fcache_fill(fp, '\n');
		tchars += 2;

	    case '\0':
	    case '\r':
		break;

	    default:
		fp = fcache_fill(fp, buff[n]);
		tchars++;
	    }
	}

	nmax = read(fd, buff, LBUF_SIZE);
    }

    free_lbuf(buff);
    tf_close(fd);

    /*
     * If we didn't read anything in, toss the initial buffer
     */

    if (fp->hdr.nchars == 0) {
	*cp = NULL;
	free_mbuf(fp);
    }

    return tchars;
}
コード例 #15
0
ファイル: create.c プロジェクト: pdbogen/RhostMUSH
void 
do_link(dbref player, dbref cause, int key, char *what, char *where)
{
    dbref thing, room;
    char *buff;
    int nomtest;

    if ( (key & SIDEEFFECT) && !SideFX(player) ) {
       notify(player, "#-1 FUNCTION DISABLED");
       return;
    }

    /* Find the thing to link */

    init_match(player, what, TYPE_EXIT);
    match_everything(0);
    thing = noisy_match_result();
    if (thing == NOTHING)
	return;

    nomtest = ((NoMod(thing) && !WizMod(player)) || (DePriv(player,Owner(thing),DP_MODIFY,POWER7,NOTHING) && (Owner(thing) != Owner(player))) || (Backstage(player) && NoBackstage(thing) && !Immortal(player)));
    /* Allow unlink if where is not specified */

    if (!where || !*where) {
      if (!nomtest)
	do_unlink(player, cause, key, what);
      else
	notify(player,"Permission denied.");
      return;
    }
    switch (Typeof(thing)) {
    case TYPE_EXIT:

	/* Set destination */

	room = parse_linkable_room(player, where);
	if (room != NOTHING) {
	  if (!nomtest)
	    link_exit(player, thing, room, key);
	  else
	    notify(player,"Permission denied.");
	}
	break;
    case TYPE_PLAYER:
    case TYPE_THING:

	/* Set home */

	if (!Controls(player, thing) || nomtest) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}
	init_match(player, where, NOTYPE);
	match_everything(MAT_NO_EXITS);
	room = noisy_match_result();
	if (!Good_obj(room))
	    break;
	if (!Has_contents(room)) {
	    notify_quiet(player, "Can't link to an exit.");
	    break;
	}
	if (!can_set_home(player, thing, room) ||
	    !could_doit(player, room, A_LLINK, 1, 0)) {
	    notify_quiet(player, "Permission denied.");
	} else if (room == HOME) {
	    notify_quiet(player, "Can't set home to home.");
	} else {
	    s_Home(thing, room);
	    if (!(Quiet(player) || (key & SIDEEFFECT)) )
		notify_quiet(player, "Home set.");
	}
	break;
    case TYPE_ROOM:

	/* Set dropto */

	if (!Controls(player, thing) || nomtest) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}
	room = parse_linkable_room(player, where);
	if (!Good_obj(room) && (room != HOME)) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}

	if ((room != HOME) && !isRoom(room)) {
	    notify_quiet(player, "That is not a room!");
	} else if ((room != HOME) &&
		   ((!controls(player, room) && !Link_ok(room)) ||
		    !could_doit(player, room, A_LLINK, 1, 0))) {
	    notify_quiet(player, "Permission denied.");
	} else {
	    s_Dropto(thing, room);
	    if (!Quiet(player))
		notify_quiet(player, "Dropto set.");
	}
	break;
    default:
	STARTLOG(LOG_BUGS, "BUG", "OTYPE")
	    buff = alloc_mbuf("do_link.LOG.badtype");
	sprintf(buff, "Strange object type: object #%d = %d",
		thing, Typeof(thing));
	log_text(buff);
	free_mbuf(buff);
	ENDLOG
    }
}
コード例 #16
0
ファイル: flags.cpp プロジェクト: sanjayui/tinymux
UTF8 *flag_description(dbref player, dbref target)
{
    // Allocate the return buffer.
    //
    int otype = Typeof(target);
    UTF8 *buff = alloc_mbuf("flag_description");
    UTF8 *bp = buff;

    // Store the header strings and object type.
    //
    safe_mb_str(T("Type: "), buff, &bp);
    safe_mb_str(object_types[otype].name, buff, &bp);
    safe_mb_str(T(" Flags:"), buff, &bp);
    if (object_types[otype].perm != CA_PUBLIC)
    {
        *bp = '\0';
        return buff;
    }

    // Store the type-invariant flags.
    //
    FLAGNAMEENT *fp;
    for (fp = gen_flag_names; fp->flagname; fp++)
    {
        if (!fp->bPositive)
        {
            continue;
        }
        FLAGBITENT *fbe = fp->fbe;
        if (db[target].fs.word[fbe->flagflag] & fbe->flagvalue)
        {
            if (  (  (fbe->listperm & CA_STAFF)
                  && !Staff(player))
               || (  (fbe->listperm & CA_ADMIN)
                  && !WizRoy(player))
               || (  (fbe->listperm & CA_WIZARD)
                  && !Wizard(player))
               || (  (fbe->listperm & CA_GOD)
                  && !God(player)))
            {
                continue;
            }

            // Don't show CONNECT on dark wizards to mortals.
            //
            if (  isPlayer(target)
               && (fbe->flagvalue == CONNECTED)
               && (fbe->flagflag == FLAG_WORD2)
               && Hidden(target)
               && !See_Hidden(player))
            {
                continue;
            }
            safe_mb_chr(' ', buff, &bp);
            safe_mb_str(fp->flagname, buff, &bp);
        }
    }

    // Terminate the string, and return the buffer to the caller.
    //
    *bp = '\0';
    return buff;
}
コード例 #17
0
ファイル: eval.c プロジェクト: gtaylor/btmux
void exec(char *buff, char **bufc, int tflags, dbref player, dbref cause,
		  int eval, char **dstr, char *cargs[], int ncargs)
{
#define	NFARGS	30
	char *fargs[NFARGS];
	char *preserve[MAX_GLOBAL_REGS];
	char *tstr, *tbuf, *tbufc, *savepos, *atr_gotten, *start, *oldp, *savestr;
	char savec, ch, *str;
	char *realbuff = NULL, *realbp = NULL;
	dbref aowner;
	int at_space, nfargs, gender, i, j, alldone, feval; long aflags;
	int is_trace, is_top, save_count;
	int ansi;
	FUN *fp;
	UFUN *ufp;

	static const char *subj[5] = { "", "it", "she", "he", "they" };
	static const char *poss[5] = { "", "its", "her", "his", "their" };
	static const char *obj[5] = { "", "it", "her", "him", "them" };
	static const char *absp[5] = { "", "its", "hers", "his", "theirs" };

	if(*dstr == NULL)
		return;

	// dprintk("%d/%s", player, *dstr);

	at_space = 1;
	gender = -1;
	alldone = 0;
	ansi = 0;

	is_trace = Trace(player) && !(eval & EV_NOTRACE);
	is_top = 0;

	/* Extend the buffer if we need to. */

	if(((*bufc) - buff) > (LBUF_SIZE - SBUF_SIZE)) {
		realbuff = buff;
		realbp = *bufc;
		buff = (char *) malloc(LBUF_SIZE);
		*bufc = buff;
	}

	oldp = start = *bufc;

	/*
	 * If we are tracing, save a copy of the starting buffer 
	 */

	savestr = NULL;
	if(is_trace) {
		is_top = tcache_empty();
		savestr = alloc_lbuf("exec.save");
		StringCopy(savestr, *dstr);
	}
	while (**dstr && !alldone) {
		switch (**dstr) {
		case ' ':
			/*
			 * A space.  Add a space if not compressing or if * * 
			 * 
			 * *  * * previous char was not a space 
			 */

			if(!(mudconf.space_compress && at_space) ||
			   (eval & EV_NO_COMPRESS)) {
				safe_chr(' ', buff, bufc);
				at_space = 1;
			}
			break;
		case '\\':
			/*
			 * General escape.  Add the following char without *
			 * * * * special processing 
			 */

			at_space = 0;
			(*dstr)++;
			if(**dstr)
				safe_chr(**dstr, buff, bufc);
			else
				(*dstr)--;
			break;
		case '[':
			/*
			 * Function start.  Evaluate the contents of the * *
			 * * * square brackets as a function.  If no closing
			 * * * * * bracket, insert the [ and continue. 
			 */

			at_space = 0;
			tstr = (*dstr)++;
			if(eval & EV_NOFCHECK) {
				safe_chr('[', buff, bufc);
				*dstr = tstr;
				break;
			}
			tbuf = parse_to(dstr, ']', 0);
			if(*dstr == NULL) {
				safe_chr('[', buff, bufc);
				*dstr = tstr;
			} else {
				str = tbuf;
				exec(buff, bufc, 0, player, cause,
					 (eval | EV_FCHECK | EV_FMAND), &str, cargs, ncargs);
				(*dstr)--;
			}
			break;
		case '{':
			/*
			 * Literal start.  Insert everything up to the * * *
			 * * terminating } without parsing.  If no closing *
			 * * * * brace, insert the { and continue. 
			 */

			at_space = 0;
			tstr = (*dstr)++;
			tbuf = parse_to(dstr, '}', 0);
			if(*dstr == NULL) {
				safe_chr('{', buff, bufc);
				*dstr = tstr;
			} else {
				if(!(eval & EV_STRIP)) {
					safe_chr('{', buff, bufc);
				}
				/*
				 * Preserve leading spaces (Felan) 
				 */

				if(*tbuf == ' ') {
					safe_chr(' ', buff, bufc);
					tbuf++;
				}
				str = tbuf;
				exec(buff, bufc, 0, player, cause,
					 (eval & ~(EV_STRIP | EV_FCHECK)), &str, cargs, ncargs);
				if(!(eval & EV_STRIP)) {
					safe_chr('}', buff, bufc);
				}
				(*dstr)--;
			}
			break;
		case '%':
			/*
			 * Percent-replace start.  Evaluate the chars * * *
			 * following * and perform the appropriate * * *
			 * substitution. 
			 */

			at_space = 0;
			(*dstr)++;
			savec = **dstr;
			savepos = *bufc;
			switch (savec) {
			case '\0':			/*
								 * Null - all done 
								 */
				(*dstr)--;
				break;
			case '|':			/* piped command output */
				safe_str(mudstate.pout, buff, bufc);
				break;
			case '%':			/*
								 * Percent - a literal % 
								 */
				safe_chr('%', buff, bufc);
				break;
			case 'c':
			case 'C':
				(*dstr)++;
				if(!**dstr)
					(*dstr)--;
				ansi = 1;
				switch (**dstr) {
				case 'h':		/*
								 * hilite 
								 */
					safe_str(ANSI_HILITE, buff, bufc);
					break;
				case 'i':		/*
								 * inverse 
								 */
					safe_str(ANSI_INVERSE, buff, bufc);
					break;
				case 'f':		/*
								 * flash 
								 */
					safe_str(ANSI_BLINK, buff, bufc);
					break;
				case 'u':		/* underline */
					safe_str(ANSI_UNDER, buff, bufc);
					break;
				case 'n':		/*
								 * normal 
								 */
					safe_str(ANSI_NORMAL, buff, bufc);
					ansi = 0;
					break;
				case 'x':		/*
								 * black fg 
								 */
					safe_str(ANSI_BLACK, buff, bufc);
					break;
				case 'r':		/*
								 * red fg 
								 */
					safe_str(ANSI_RED, buff, bufc);
					break;
				case 'g':		/*
								 * green fg 
								 */
					safe_str(ANSI_GREEN, buff, bufc);
					break;
				case 'y':		/*
								 * yellow fg 
								 */
					safe_str(ANSI_YELLOW, buff, bufc);
					break;
				case 'b':		/*
								 * blue fg 
								 */
					safe_str(ANSI_BLUE, buff, bufc);
					break;
				case 'm':		/*
								 * magenta fg 
								 */
					safe_str(ANSI_MAGENTA, buff, bufc);
					break;
				case 'c':		/*
								 * cyan fg 
								 */
					safe_str(ANSI_CYAN, buff, bufc);
					break;
				case 'w':		/*
								 * white fg 
								 */
					safe_str(ANSI_WHITE, buff, bufc);
					break;
				case 'X':		/*
								 * black bg 
								 */
					safe_str(ANSI_BBLACK, buff, bufc);
					break;
				case 'R':		/*
								 * red bg 
								 */
					safe_str(ANSI_BRED, buff, bufc);
					break;
				case 'G':		/*
								 * green bg 
								 */
					safe_str(ANSI_BGREEN, buff, bufc);
					break;
				case 'Y':		/*
								 * yellow bg 
								 */
					safe_str(ANSI_BYELLOW, buff, bufc);
					break;
				case 'B':		/*
								 * blue bg 
								 */
					safe_str(ANSI_BBLUE, buff, bufc);
					break;
				case 'M':		/*
								 * magenta bg 
								 */
					safe_str(ANSI_BMAGENTA, buff, bufc);
					break;
				case 'C':		/*
								 * cyan bg 
								 */
					safe_str(ANSI_BCYAN, buff, bufc);
					break;
				case 'W':		/*
								 * white bg 
								 */
					safe_str(ANSI_BWHITE, buff, bufc);
					break;
				default:
					safe_chr(**dstr, buff, bufc);
				}
				break;
			case 'r':			/*
								 * Carriage return 
								 */
			case 'R':
				safe_str((char *) "\r\n", buff, bufc);
				break;
			case 't':			/*
								 * Tab 
								 */
			case 'T':
				safe_chr('\t', buff, bufc);
				break;
			case 'B':			/*
								 * Blank 
								 */
			case 'b':
				safe_chr(' ', buff, bufc);
				break;
			case '0':			/*
								 * Command argument number N 
								 */
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				i = (**dstr - '0');
				if((i < ncargs) && (cargs[i] != NULL))
					safe_str(cargs[i], buff, bufc);
				break;
			case 'V':			/*
								 * Variable attribute 
								 */
			case 'v':
				(*dstr)++;
				ch = ToUpper(**dstr);
				if(!**dstr)
					(*dstr)--;
				if((ch < 'A') || (ch > 'Z'))
					break;
				i = 100 + ch - 'A';
				atr_gotten = atr_pget(player, i, &aowner, &aflags);
				safe_str(atr_gotten, buff, bufc);
				free_lbuf(atr_gotten);
				break;
			case 'Q':
			case 'q':
				(*dstr)++;
				i = (**dstr - '0');
				if((i >= 0) && (i <= 9) && mudstate.global_regs[i]) {
					safe_str(mudstate.global_regs[i], buff, bufc);
				}
				if(!**dstr)
					(*dstr)--;
				break;
			case 'O':			/*
								 * Objective pronoun 
								 */
			case 'o':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender)
					tbuf = Name(cause);
				else
					tbuf = (char *) obj[gender];
				safe_str(tbuf, buff, bufc);
				break;
			case 'P':			/*
								 * Personal pronoun 
								 */
			case 'p':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender) {
					safe_str(Name(cause), buff, bufc);
					safe_chr('s', buff, bufc);
				} else {
					safe_str((char *) poss[gender], buff, bufc);
				}
				break;
			case 'S':			/*
								 * Subjective pronoun 
								 */
			case 's':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender)
					tbuf = Name(cause);
				else
					tbuf = (char *) subj[gender];
				safe_str(tbuf, buff, bufc);
				break;
			case 'A':			/*
								 * Absolute posessive 
								 */
			case 'a':			/*
								 * idea from Empedocles 
								 */
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender) {
					safe_str(Name(cause), buff, bufc);
					safe_chr('s', buff, bufc);
				} else {
					safe_str((char *) absp[gender], buff, bufc);
				}
				break;
			case '#':			/*
								 * Invoker DB number 
								 */
				tbuf = alloc_sbuf("exec.invoker");
				sprintf(tbuf, "#%ld", cause);
				safe_str(tbuf, buff, bufc);
				free_sbuf(tbuf);
				break;
			case '!':			/*
								 * Executor DB number 
								 */
				tbuf = alloc_sbuf("exec.executor");
				sprintf(tbuf, "#%ld", player);
				safe_str(tbuf, buff, bufc);
				free_sbuf(tbuf);
				break;
			case 'N':			/*
								 * Invoker name 
								 */
			case 'n':
				safe_str(Name(cause), buff, bufc);
				break;
			case 'L':			/*
								 * Invoker location db# 
								 */
			case 'l':
				if(!(eval & EV_NO_LOCATION)) {
					tbuf = alloc_sbuf("exec.exloc");
					sprintf(tbuf, "#%ld", where_is(cause));
					safe_str(tbuf, buff, bufc);
					free_sbuf(tbuf);
				}

				break;
			default:			/*
								 * Just copy 
								 */
				safe_chr(**dstr, buff, bufc);
			}
			if(isupper(savec))
				*savepos = ToUpper(*savepos);
			break;
		case '(':
			/*
			 * Arglist start.  See if what precedes is a function. If so,
			 * execute it if we should.
			 */

			at_space = 0;
			if(!(eval & EV_FCHECK)) {
				safe_chr('(', buff, bufc);
				break;
			}
			/*
			 * Load an sbuf with an uppercase version of the func name, and
			 * see if the func exists.  Trim trailing spaces from the name
			 * if configured.
			 */

			**bufc = '\0';
			tbufc = tbuf = alloc_sbuf("exec.tbuf");
			safe_sb_str(oldp, tbuf, &tbufc);
			*tbufc = '\0';
			if(mudconf.space_compress) {
				while ((--tbufc >= tbuf) && isspace(*tbufc));
				tbufc++;
				*tbufc = '\0';
			}
			for(tbufc = tbuf; *tbufc; tbufc++)
				*tbufc = ToLower(*tbufc);
			fp = (FUN *) hashfind(tbuf, &mudstate.func_htab);

			/*
			 * If not a builtin func, check for global func 
			 */

			ufp = NULL;
			if(fp == NULL) {
				ufp = (UFUN *) hashfind(tbuf, &mudstate.ufunc_htab);
			}
			/*
			 * Do the right thing if it doesn't exist 
			 */

			if(!fp && !ufp) {
				if(eval & EV_FMAND) {
					*bufc = oldp;
					safe_str((char *) "#-1 FUNCTION (", buff, bufc);
					safe_str(tbuf, buff, bufc);
					safe_str((char *) ") NOT FOUND", buff, bufc);
					alldone = 1;
				} else {
					safe_chr('(', buff, bufc);
				}
				free_sbuf(tbuf);
				eval &= ~EV_FCHECK;
				break;
			}
			free_sbuf(tbuf);

			/*
			 * Get the arglist and count the number of args * Neg 
			 * 
			 * *  * *  * * # of args means catenate subsequent
			 * args 
			 */

			if(ufp)
				nfargs = NFARGS;
			else if(fp->nargs < 0)
				nfargs = -fp->nargs;
			else
				nfargs = NFARGS;
			tstr = *dstr;
			if(fp && (fp->flags & FN_NO_EVAL))
				feval = (eval & ~EV_EVAL) | EV_STRIP_ESC;
			else
				feval = eval;
			*dstr =
				parse_arglist(player, cause, *dstr + 1, ')', feval, fargs,
							  nfargs, cargs, ncargs);

			/*
			 * If no closing delim, just insert the '(' and * * * 
			 * 
			 * * continue normally 
			 */

			if(!*dstr) {
				*dstr = tstr;
				safe_chr(**dstr, buff, bufc);
				for(i = 0; i < nfargs; i++)
					if(fargs[i] != NULL)
						free_lbuf(fargs[i]);
				eval &= ~EV_FCHECK;
				break;
			}
			/*
			 * Count number of args returned 
			 */

			(*dstr)--;
			j = 0;
			for(i = 0; i < nfargs; i++)
				if(fargs[i] != NULL)
					j = i + 1;
			nfargs = j;

			/*
			 * If it's a user-defined function, perform it now. 
			 */

			if(ufp) {
				mudstate.func_nest_lev++;
				if(!check_access(player, ufp->perms)) {
					safe_str("#-1 PERMISSION DENIED", buff, &oldp);
					*bufc = oldp;
				} else {
					tstr = atr_get(ufp->obj, ufp->atr, &aowner, &aflags);
					if(ufp->flags & FN_PRIV)
						i = ufp->obj;
					else
						i = player;
					str = tstr;

					if(ufp->flags & FN_PRES) {
						for(j = 0; j < MAX_GLOBAL_REGS; j++) {
							if(!mudstate.global_regs[j])
								preserve[j] = NULL;
							else {
								preserve[j] = alloc_lbuf("eval_regs");
								StringCopy(preserve[j],
										   mudstate.global_regs[j]);
							}
						}
					}

					exec(buff, &oldp, 0, i, cause, feval, &str, fargs,
						 nfargs);
					*bufc = oldp;

					if(ufp->flags & FN_PRES) {
						for(j = 0; j < MAX_GLOBAL_REGS; j++) {
							if(preserve[j]) {
								if(!mudstate.global_regs[j])
									mudstate.global_regs[j] =
										alloc_lbuf("eval_regs");
								StringCopy(mudstate.global_regs[j],
										   preserve[j]);
								free_lbuf(preserve[j]);
							} else {
								if(mudstate.global_regs[j])
									*(mudstate.global_regs[i]) = '\0';
							}
						}
					}

					free_lbuf(tstr);
				}

				/*
				 * Return the space allocated for the args 
				 */

				mudstate.func_nest_lev--;
				for(i = 0; i < nfargs; i++)
					if(fargs[i] != NULL)
						free_lbuf(fargs[i]);
				eval &= ~EV_FCHECK;
				break;
			}
			/*
			 * If the number of args is right, perform the func.
			 * Otherwise return an error message.  Note
			 * that parse_arglist returns zero args as one
			 * null arg, so we have to handle that case
			 * specially. 
			 */

			if((fp->nargs == 0) && (nfargs == 1)) {
				if(!*fargs[0]) {
					free_lbuf(fargs[0]);
					fargs[0] = NULL;
					nfargs = 0;
				}
			}
			if((nfargs == fp->nargs) || (nfargs == -fp->nargs) ||
			   (fp->flags & FN_VARARGS)) {

				/*
				 * Check recursion limit 
				 */

				mudstate.func_nest_lev++;
				mudstate.func_invk_ctr++;
				if(mudstate.func_nest_lev >= mudconf.func_nest_lim) {
					safe_str("#-1 FUNCTION RECURSION LIMIT EXCEEDED", buff,
							 bufc);
				} else if(mudstate.func_invk_ctr == mudconf.func_invk_lim) {
					safe_str("#-1 FUNCTION INVOCATION LIMIT EXCEEDED",
							 buff, bufc);
				} else if(!check_access(player, fp->perms)) {
					safe_str("#-1 PERMISSION DENIED", buff, &oldp);
					*bufc = oldp;
				} else if(mudstate.func_invk_ctr < mudconf.func_invk_lim) {
					fp->fun(buff, &oldp, player, cause, fargs, nfargs,
							cargs, ncargs);
					*bufc = oldp;
				} else {
					**bufc = '\0';
				}
				mudstate.func_nest_lev--;
			} else {
				*bufc = oldp;
				tstr = alloc_sbuf("exec.funcargs");
				sprintf(tstr, "%d", fp->nargs);
				safe_str((char *) "#-1 FUNCTION (", buff, bufc);
				safe_str((char *) fp->name, buff, bufc);
				safe_str((char *) ") EXPECTS ", buff, bufc);
				safe_str(tstr, buff, bufc);
				safe_str((char *) " ARGUMENTS", buff, bufc);
				free_sbuf(tstr);
			}

			/*
			 * Return the space allocated for the arguments 
			 */

			for(i = 0; i < nfargs; i++)
				if(fargs[i] != NULL)
					free_lbuf(fargs[i]);
			eval &= ~EV_FCHECK;
			break;
		default:
			/*
			 * A mundane character.  Just copy it 
			 */

			at_space = 0;
			safe_chr(**dstr, buff, bufc);
		}
		(*dstr)++;
	}

	/*
	 * If we're eating spaces, and the last thing was a space, eat it
	 * up. Complicated by the fact that at_space is initially
	 * true. So check to see if we actually put something in the
	 * buffer, too. 
	 */

	if(mudconf.space_compress && at_space && !(eval & EV_NO_COMPRESS)
	   && (start != *bufc))
		(*bufc)--;

	/*
	 * The ansi() function knows how to take care of itself. However, 
	 * if the player used a %c sub in the string, and hasn't yet
	 * terminated the color with a %cn yet, we'll have to do it for 
	 * them. 
	 */

	if(ansi == 1)
		safe_str(ANSI_NORMAL, buff, bufc);

	**bufc = '\0';

	/*
	 * Report trace information 
	 */

	if(realbuff) {
		**bufc = '\0';
		*bufc = realbp;
		safe_str(buff, realbuff, bufc);
		free(buff);
		buff = realbuff;
	}

	if(is_trace) {
		tcache_add(savestr, start);
		save_count = tcache_count - mudconf.trace_limit;;
		if(is_top || !mudconf.trace_topdown)
			tcache_finish(player);
		if(is_top && (save_count > 0)) {
			tbuf = alloc_mbuf("exec.trace_diag");
			sprintf(tbuf, "%d lines of trace output discarded.", save_count);
			notify(player, tbuf);
			free_mbuf(tbuf);
		}
	}
}
コード例 #18
0
ファイル: cque.cpp プロジェクト: Yargling/MuxDevelopment
// ---------------------------------------------------------------------------
// do_ps: tell executor what commands they have pending in the queue
//
void do_ps(dbref executor, dbref caller, dbref enactor, int eval, int key, char *target)
{
    UNUSED_PARAMETER(caller);
    UNUSED_PARAMETER(enactor);
    UNUSED_PARAMETER(eval);

    char *bufp;
    dbref executor_targ, obj_targ;

    // Figure out what to list the queue for.
    //
    if ((key & PS_ALL) && !See_Queue(executor))
    {
        notify(executor, NOPERM_MESSAGE);
        return;
    }
    if (!target || !*target)
    {
        obj_targ = NOTHING;
        if (key & PS_ALL)
        {
            executor_targ = NOTHING;
        }
        else
        {
            executor_targ = Owner(executor);
            if (!isPlayer(executor))
            {
                obj_targ = executor;
            }
        }
    }
    else
    {
        executor_targ = Owner(executor);
        obj_targ = match_controlled(executor, target);
        if (obj_targ == NOTHING)
        {
            return;
        }
        if (key & PS_ALL)
        {
            notify(executor, "Can't specify a target and /all");
            return;
        }
        if (isPlayer(obj_targ))
        {
            executor_targ = obj_targ;
            obj_targ = NOTHING;
        }
    }
    key = key & ~PS_ALL;

    switch (key)
    {
    case PS_BRIEF:
    case PS_SUMM:
    case PS_LONG:
        break;

    default:
        notify(executor, "Illegal combination of switches.");
        return;
    }

    Show_lsaNow.GetUTC();
    Total_SystemTasks = 0;
    Total_RunQueueEntry = 0;
    Shown_RunQueueEntry = 0;
    Total_SemaphoreTimeout = 0;
    Shown_SemaphoreTimeout = 0;
    Show_Player_Target = executor_targ;
    Show_Object_Target = obj_targ;
    Show_Key = key;
    Show_Player = executor;
    Show_bFirstLine = true;
    scheduler.TraverseOrdered(CallBack_ShowWait);
    Show_bFirstLine = true;
    scheduler.TraverseOrdered(CallBack_ShowSemaphore);
#ifdef QUERY_SLAVE
    Show_bFirstLine = true;
    scheduler.TraverseOrdered(CallBack_ShowSQLQueries);
#endif // QUERY_SLAVE
    if (Wizard(executor))
    {
        notify(executor, "----- System Queue -----");
        scheduler.TraverseOrdered(CallBack_ShowDispatches);
    }

    // Display stats.
    //
    bufp = alloc_mbuf("do_ps");
#ifdef QUERY_SLAVE
    mux_sprintf(bufp, MBUF_SIZE, "Totals: Wait Queue...%d/%d  Semaphores...%d/%d  SQL %d/%d",
        Shown_RunQueueEntry, Total_RunQueueEntry,
        Shown_SemaphoreTimeout, Total_SemaphoreTimeout,
        Shown_SQLTimeout, Total_SQLTimeout);
#else
    mux_sprintf(bufp, MBUF_SIZE, "Totals: Wait Queue...%d/%d  Semaphores...%d/%d",
        Shown_RunQueueEntry, Total_RunQueueEntry,
        Shown_SemaphoreTimeout, Total_SemaphoreTimeout);
#endif // QUERY_SLAVE
    notify(executor, bufp);
    if (Wizard(executor))
    {
        mux_sprintf(bufp, MBUF_SIZE, "        System Tasks.....%d", Total_SystemTasks);
        notify(executor, bufp);
    }
    free_mbuf(bufp);
}
コード例 #19
0
ファイル: axui.c プロジェクト: hailynch/jnos2
int doaxui(int argc, char *argv[],void *p) {
char *cp;
char name[AXBUF];
char buf[256];
int i;
char tmpcall[AXALEN];
char tmpcall2[AXALEN];
struct session *sp;
struct mbuf *bp;
struct iface *axif,*ifc;
int first = 1;

	int goto_restart = 0, goto_done = 0;
  
	/* Check if this comes from console */
	if(Curproc->input != Command->input)
		return 1;

	/* Check to see if AXUI is already running. Only one copy at a time */
	if (Axui_sock != -1)	{
		tprintf("%s already running\n", Sestypes[AXUITNC]);
		return 1;
	}

	if(((axif = if_lookup(argv[1])) == NULLIF) || (axif->type != CL_AX25)) {
		tprintf("Iface %s not defined or not an AX25 type interface\n",argv[1]);
		return 1;
	}

	if (argc == 2 || setcall (tmpcall, argv[2]) == -1)
		memcpy (tmpcall, Ax25multi[IDCALL], AXALEN);
        if(argc > 3)  /* digis present? */
            if(connect_filt(argc,argv,tmpcall,axif) == 0)
                return 1;

	/* Now everything seems okay ! Get a session */
	if((sp = newsession("axui",AXUITNC,1)) == NULLSESSION) {
		j2tputs(TooManySessions);
		return 1;
	}

	while (1)
	{

/* restart: replace GOTO label with while loop */

	tprintf("%s%s session %u UI frames %s->%s on interface %s\n",
		(first) ? "" : "\n", Sestypes[sp->type],sp->num,
			pax25(buf, axif->hwaddr), pax25(name,tmpcall), axif->name);
	Axui_sock = Curproc->output;
	first = 0;
  
	/* Process whatever's typed on the terminal */
	while(recvline(Curproc->input,buf,sizeof(buf)-1) >= 0)
	{
		goto_restart = 0;	/* replaces GOTO label */
		goto_done = 0;		/* replaces GOTO label */

		if(buf[0] == '/')
		{
			rip (buf);
			cp = skipnonwhite(buf);  /* advance to first arg */
			cp = skipwhite(cp);

			/* process commands */
			switch(tolower(buf[1]))
			{
				case 'h':
				case '?':
						j2tputs("<Cmds>: /c call; /i iface; /q (to quit); /t (toggle timestamp)\n");
						goto_restart = 1;
						break;
				case 'c':
						if (argc > 3)
						{
							j2tputs(DigisUsed);
							break;
						}
						if (setcall (tmpcall2, cp) == -1)
							break;
						memcpy (tmpcall, tmpcall2, AXALEN);
						goto_restart = 1;
						break;
				case 'i':
						if (argc > 3)
						{
							j2tputs(DigisUsed);
							break;
						}
						if(((ifc = if_lookup(cp)) != NULLIF)
							&& (ifc->type == CL_AX25))
						{
							axif = ifc;
							goto_restart = 1;
						}
						else
							j2tputs ("<invalid interface>\n");
						break;
				case 'b':
				case 'e':
				case 'q':
						goto_done = 1;
						break;
				case 't':
						ui_timestamp = !ui_timestamp;
						break;
			}
			if (goto_done)	/* replaces GOTO 'done:' label */
				break;
			if (goto_restart)	/* replaces GOTO 'restart:' label */
				break;
		}
		else
		{
			i = strlen(buf);
			if((bp = alloc_mbuf(i)) == NULLBUF)
				break;

			/* unwritten protocol is that AX.25 lines end in \r, not \n.
			 * recvline will always return at least one character.  If the
			 * operater typed more than sizeof(buf) - 1 without eol,
			 * TOUGH! - K5JB
			 */
			buf[i - 1] = '\r';

			bp->cnt = i;	
			memcpy(bp->data,buf,(size_t)i);

			/* send it */
			(*axif->output)(axif, tmpcall, axif->hwaddr, PID_NO_L3, bp);
		}
		usflush(Curproc->output);
	}

	if (!goto_restart)	/* means the recv_line while naturally exited */
		break;			/* this covers the goto_done cases nicely */

	}	/* end of GOTO while loop */

/* done: */
	if (argc > 3)	/* remove digi route added by connect_filt */
		ax_drop(tmpcall, axif, 0);
	Axui_sock = -1;
	tprintf("\n%s session %u closed: EOF\n", Sestypes[sp->type],sp->num);
	keywait(NULLCHAR,1);
	freesession(sp);
	return 0;
}
コード例 #20
0
ファイル: slip.c プロジェクト: dieterdeyke/WAMPES
/* Process incoming bytes in SLIP format
 * When a buffer is complete, return it; otherwise NULL
 */
static
struct mbuf *
slip_decode(
register struct slip *sp,
uint8 c)                /* Incoming character */
{
	struct mbuf *bp;

	switch(c){
	case FR_END:
		bp = sp->rbp_head;
		sp->rbp_head = NULL;
		if(sp->escaped){
			/* Treat this as an abort - discard frame */
			free_p(&bp);
			bp = NULL;
		}
		sp->escaped &= ~SLIP_FLAG;
		return bp;      /* Will be NULL if empty frame */
	case FR_ESC:
		sp->escaped |= SLIP_FLAG;
		return NULL;
	}
	if(sp->escaped & SLIP_FLAG){
		/* Translate 2-char escape sequence back to original char */
		sp->escaped &= ~SLIP_FLAG;
		switch(c){
		case T_FR_ESC:
			c = FR_ESC;
			break;
		case T_FR_END:
			c = FR_END;
			break;
		default:
			sp->errors++;
			break;
		}
	}
	/* We reach here with a character for the buffer;
	 * make sure there's space for it
	 */
	if(sp->rbp_head == NULL){
		/* Allocate first mbuf for new packet */
		if((sp->rbp_tail = sp->rbp_head = alloc_mbuf(SLIP_ALLOC)) == NULL)
			return NULL; /* No memory, drop */
		sp->rcp = sp->rbp_head->data;
	} else if(sp->rbp_tail->cnt == SLIP_ALLOC){
		/* Current mbuf is full; link in another */
		if((sp->rbp_tail->next = alloc_mbuf(SLIP_ALLOC)) == NULL){
			/* No memory, drop whole thing */
			free_p(&sp->rbp_head);
			sp->rbp_head = NULL;
			return NULL;
		}
		sp->rbp_tail = sp->rbp_tail->next;
		sp->rcp = sp->rbp_tail->data;
	}
	/* Store the character, increment fragment and total
	 * byte counts
	 */
	*sp->rcp++ = c;
	sp->rbp_tail->cnt++;
	return NULL;
}