Пример #1
0
// place_node(pos, node)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_place_node(lua_State *L)
{
	GET_ENV_PTR;

	ScriptApiItem *scriptIfaceItem = getScriptApi<ScriptApiItem>(L);
	Server *server = getServer(L);
	INodeDefManager *ndef = server->ndef();
	IItemDefManager *idef = server->idef();

	v3s16 pos = read_v3s16(L, 1);
	MapNode n = readnode(L, 2, ndef);

	// Don't attempt to load non-loaded area as of now
	MapNode n_old = env->getMap().getNodeNoEx(pos);
	if(n_old.getContent() == CONTENT_IGNORE){
		lua_pushboolean(L, false);
		return 1;
	}
	// Create item to place
	ItemStack item(ndef->get(n).name, 1, 0, "", idef);
	// Make pointed position
	PointedThing pointed;
	pointed.type = POINTEDTHING_NODE;
	pointed.node_abovesurface = pos;
	pointed.node_undersurface = pos + v3s16(0,-1,0);
	// Place it with a NULL placer (appears in Lua as a non-functional
	// ObjectRef)
	bool success = scriptIfaceItem->item_OnPlace(item, NULL, pointed);
	lua_pushboolean(L, success);
	return 1;
}
Пример #2
0
void freenode(long t)
{
node nod;

  readnode(t, &nod);
  nod.ptr[0] = freelist;
  freelist = t;
  writenode(t, &nod);
}
Пример #3
0
void rdstart(void)
{
  if (fseek(fptree, 0L, SEEK_SET))
	 error("fseek in rdstart");
  if (fread(start, sizeof(long), 2, fptree) == 0)
	 error("fread in rdstart");
  readnode(start[0], &rootnode);
  root = start[0];
  freelist = start[1];
}
Пример #4
0
void found(long t,  int i)
{
node nod;

	printf("Found in position %i of node with contents:  ", i);
	readnode(t, &nod);
	for (i=0; i < nod.cnt; i++)
		printf("  %s", nod.tuple[i].index);
	puts("");

}
Пример #5
0
int LuaVoxelManip::l_set_node_at(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	GET_ENV_PTR;

	LuaVoxelManip *o = checkobject(L, 1);
	v3s16 pos        = read_v3s16(L, 2);
	MapNode n        = readnode(L, 3, env->getGameDef()->ndef());

	o->vm->setNodeNoEmerge(pos, n);

	return 0;
}
Пример #6
0
// set_node(pos, node)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_set_node(lua_State *L)
{
	GET_ENV_PTR;

	INodeDefManager *ndef = env->getGameDef()->ndef();
	// parameters
	v3s16 pos = read_v3s16(L, 1);
	MapNode n = readnode(L, 2, ndef);
	// Do it
	bool succeeded = env->setNode(pos, n);
	lua_pushboolean(L, succeeded);
	return 1;
}
Пример #7
0
int LuaVoxelManip::l_set_node_at(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();

	LuaVoxelManip *o = checkobject(L, 1);
	v3s16 pos        = check_v3s16(L, 2);
	MapNode n        = readnode(L, 3, ndef);

	o->vm->setNodeNoEmerge(pos, n);

	return 0;
}
Пример #8
0
/*  Driver function for node deletion, called only in the main function.

	 Most of the work is delegated to 'del'.
*/
status delnode(char *index)
{
    long newroot;
    btuple_t x;
    strcpy(x.index,index);

	status code = del(x, root);
	if (code == UNDERFLOW){
	  newroot = rootnode.ptr[0];
	  freenode(root);
	  if (newroot != NIL)
		 readnode(newroot, &rootnode);
	  root = newroot;
	  code = SUCCESS;
	}
	return(code);  /* Return index:  SUCCESS  or NOTFOUND   */
}
Пример #9
0
long getnode(void)
{
long t;
node nod;

  if (freelist == NIL) {
	 if (fseek(fptree, 0L, SEEK_END))
		 error("fseek in getnode");
  t = ftell(fptree);
  writenode(t, &nod);  }         /*  Allocate space on disk  */

  else{
	  t = freelist;
		readnode(t, &nod);             /*  To update freelist      */
		freelist = nod.ptr[0];
 }
 return(t);
}
Пример #10
0
void printtree(long t)
{
static int position=0;
int i, n;
btuple_t *k;
node nod;

  if (t != NIL){
	 //position += 0;
	 readnode(t, &nod);
	 k = nod.tuple;
	 n = nod.cnt;
	 //printf("%*s", position, "");
/*	 for (i=0; i<n; i++)
		printf(" [%9s] --> %li", k[i].index, k[i].value);
	 puts(""); */
	 for (i=0; i<=n; i++)
		printtree(nod.ptr[i]);
	 //position -= 6;
  }
}
Пример #11
0
long search(char *index)
{
int i, j, n;
btuple_t *k;

btuple_t x;
strcpy(x.index,index);

node nod;
long t = root;

	while (t != NIL){
		  readnode(t, &nod);
		  k = nod.tuple;
		  n = nod.cnt;
		  i = binsearch(x, k, n);
		  if (i < n && strcmp(x.index,k[i].index) == 0){
			  return k[i].value;
		  }
		  t = nod.ptr[i];
	}
	return -1;
}
Пример #12
0
bool xml::parse() {
	int otherchars = 0;
	readspace();
	while(m_current != NULL) {
		switch(m_current[0]) {
		case '<':
			m_slash = NULL;
			m_current++;
			readnode();
			break;
		case '>':
			if(m_slash == NULL)
				readdata();
			else
				m_current++;
			break;
		default:
			otherchars++;
			m_current++;
			break;
		}
	}
	return true;
}
Пример #13
0
Bool TERMWINDOWMEMBER net_master(void)
    {
    int tries = 1;

    if (!readnode(FALSE))
        {
        doccr();
        label Buffer;
        cPrintf(getmsg(206), CurrentUser->GetName(Buffer, sizeof(Buffer)));
        doccr();
        return (FALSE);
        }

    // cleanup
    changedir(LocalTempPath);
    ambigUnlink(getnetmsg(162));
    ambigUnlink(getnetmsg(163));
    unlink(roomreqIn);
    unlink(roomreqOut);
    unlink(roomdataIn);
    unlink(roomdataOut);
    unlink(getnetmsg(164));
    unlink(getnetmsg(165));

    int connected;

#ifdef WINCIT
    if (*node->GetIpAddress())
        {
            connected = TRUE;

        }
    else
#endif
    do
        {
        if (tries > 1)
            {
            doccr();
            cPrintf(getnetmsg(130), ltoac(tries));
            }

        if ((connected = n_dial()) == CERROR)
            {
            return (FALSE);
            }
        } while (tries++ < node->GetRedial() && !connected);

    if (!connected)
        {
        return (FALSE);
        }

    if (node->GetNetworkType() == NET_C86)
        {
        if (!net86_fetch(CONSOLE))
            {
            return (FALSE);
            }
        }

    if (!n_login())
        {
        return (FALSE);
        }

    // We have logged in: Call it a new call.
#ifdef WINCIT
    slideLTab(&ThisSlot, CurrentUser, LogOrder);
#else
    slideLTab(&ThisSlot, CurrentUser);
#endif
    cfg.callno++;

    netError = FALSE;

    switch (node->GetNetworkType())
        {
        default:
        case NET_DCIT10:
            {
            if (Net1Master() == FALSE)
                {
                return (FALSE);
                }

            if (Net1Slave() == FALSE)
                {
                return (FALSE);
                }

            Net1Cleanup();
            buildaddress(CONSOLE);
            break;
            }

        case NET_DCIT15:
        case NET_DCIT16:
            {
            if (!dc15network(TRUE))
                {
                return (FALSE);
                }

            Net1Cleanup();
            buildaddress(CONSOLE);
            break;
            }

        case NET_6_9:
            {
            if (!net69(TRUE))
                {
                return (FALSE);
                }

            break;
            }

        case NET_C86:
            {
            if (!Citadel86Network(TRUE))
                {
                return (FALSE);
                }

            break;
            }

#ifdef HENGE
        case NET_HENGE:
            {
            if (!hengeNet(TRUE))
                {
                return (FALSE);
                }

            break;
            }
#endif
        }

    CITWINDOW *w = ScreenSaver.IsOn() ? NULL :
            CitWindowsMsg(NULL, getmsg(19));

    Initport();

    if (w)
        {
        destroyCitWindow(w, FALSE);
        }

    return (TRUE);
    }
Пример #14
0
/* -------------------------------------------------------------------- */
void doLogin(char moreYet)
{
    int foundIt;
    char InitPw[NAMESIZE+NAMESIZE+2];
    char password[NAMESIZE+NAMESIZE+2];
    char initials[NAMESIZE+NAMESIZE+2];
    char *semicolon;

    Mflush();

    if (!CARRIER) return;

    if (login_user || login_pw) /* handle command line log-ins */
    {
        if (!modStat) 
            if (cfg.offhook)  offhook();

        /* login using initials and pw */
        if (login_pw)
        {
            normalizepw(cmd_login, initials, password);
            login_pw = FALSE;
        }
        else

        if (login_user)
        {
            normalizeString(cmd_login);
            if (findPerson(cmd_login, &logBuf) != ERROR)
            {
                strcpy(initials, logBuf.lbin);
                strcpy(password, logBuf.lbpw);
            }
            login_user = FALSE;
        }

    }
    else   /* ask user for initials and password */
    {


    if (moreYet == 2)
        moreYet = FALSE;
    else
    {
        /* dont print Login when hitting 'L' from console mode */
        if (!(!moreYet && !loggedIn && !modStat))
        {
            mPrintf("Login ");
        }
    }



    if (loggedIn)  
    {
        mPrintf("\n Already logged in!\n ");
        return;
    }

    if (!modStat) 
        if (cfg.offhook)  offhook();


  getNormStr((moreYet) ? "" : "your initials", InitPw, NAMESIZE+NAMESIZE+1, NO_ECHO);
    if (!CARRIER) return;

        dospCR();

        semicolon = strchr(InitPw, ';');

        if (!semicolon)
        {
            strcpy(initials, InitPw);
            getNormStr( "password",  password, NAMESIZE, NO_ECHO);
            dospCR();
        }     
        else  
        {
            normalizepw(InitPw, initials, password);
        }

        /* dont allow anything over 19 characters */
        initials[NAMESIZE] = '\0';
    }
    
    /* reset transmitted & received */
    transmitted = 0l;
    received    = 0l;

    /* reset read & entered */
    mread   = 0;
    entered = 0;

    foundIt = ((pwslot(initials, password)) != ERROR);

    if (foundIt && *password)
    {
        loggedIn    = TRUE;
        update25();

        /* trap it */
        if (!logBuf.lbflags.NODE) 
        {
            sprintf( msgBuf->mbtext, "Login %s", logBuf.lbname);
            if (onConsole)
                strcat(msgBuf->mbtext, " (Console)");

            trap(msgBuf->mbtext, T_LOGIN);
        }
        else
        {
            sprintf( msgBuf->mbtext, "NetLogin %s", logBuf.lbname);
            trap(msgBuf->mbtext, T_NETWORK);
        }
    }
    else
    {
        loginNew(initials, password);
    }

    if (!loggedIn)
        return;

    heldMessage = FALSE;

    setsysconfig();
    setgroupgen();
    setroomgen();
    setlbvisit();

    slideLTab(thisSlot);

    /* cant log in now. */
    if (cfg.accounting && !logBuf.lbflags.NOACCOUNT)
    {
        negotiate();
        logincrement();
        if (!logincheck()) 
        {
            Hangup();
            return;
        }
    }

    /* can't log in now. */
    if (logBuf.VERIFIED && !onConsole)
    {
        tutorial("verified.blb");
        Hangup();
        return;
    }

    if (logBuf.lbflags.NODE)
    {
#ifdef  TRASH       
        if (debug)
        {
            readnode();

            cPrintf("Node:  \"%s\" \"%s\"", node.ndname, node.ndregion);  doccr();
            cPrintf("Phone: \"%s\" %d", node.ndphone, node.nddialto);     doccr();
            cPrintf("Login: \"%s\" %d", node.ndlogin, node.ndwaitto);     doccr();
            cPrintf("Baud:  %d    Protocol: \"%s\"\n ", node.ndbaud, node.ndprotocol);
            cPrintf("Expire:%d    Waitout:  %d", node.ndexpire, node.ndwaitto); doccr();
            cPrintf("Network: %d  ZIP: %s UNZIP: %s", node.network, node.zip, node.unzip); doccr();
        }
#endif        
        
        time(&logtimestamp);
        return;
    }

    if (logBuf.PSYCHO)
    {
        backout = TRUE;
    }
    
    /* reverse engineering Minibin?!?! */
    if (logBuf.MINIBIN)
    {
        minibin();
    }
    
    changedir(cfg.helppath); 

    if ( filexists("bulletin.blb") )
    {
        tutorial("bulletin.blb");
    }
    
    gotodefaulthall();

    roomtalley();

    mf.mfLim = 0;   /* just to make sure. */
    mf.mfMai = 0;
    mf.mfPub = 0;
    mf.mfUser[0]=0;

    nochat(TRUE);       /* reset chats */
    
    /* verbose = FALSE; */
    verbose = logBuf.VERBOSE;

    /* hmmm... where to put this */
    if (roomBuf.rbflags.APLIC && roomBuf.rbflags.AUTOAPP )
        ExeAplic();

    showMessages(NEWoNLY, FALSE);

    verbose = FALSE;
    if (expert) listRooms(NEWRMS, FALSE);
    else        listRooms(OLDNEW, FALSE);

    outFlag = OUTOK;
    setio(whichIO, echo, outFlag);
    
    /* record login time, date */
    time(&logtimestamp);

    cfg.callno++;

    storeLog();
}
Пример #15
0
/* Delete item x in B-tree with root t.

	Return index:

	  SUCCESS, NOTFOUND, OR UNDERFLOW
*/
status del(btuple_t x, long t)
{
int i, j, *n, *nleft, *nright, borrowleft=0, nq;
 btuple_t *k, *ltuple, *rtuple, *item, *addr;
status code;
long *p, left, right, *lptr, *rptr, q, q1;
node nod, nod1, nod2, nodL, nodR;

 if (t == NIL)
	return(NOTFOUND);
 readnode(t, &nod);
 n = & nod.cnt;
 k = nod.tuple;
 p=nod.ptr;
 i=binsearch(x, k, *n);
 /* *t is a leaf */
 if (p[0] == NIL){
	if (i == *n || strcmp(x.index,k[i].index) < 0)
		 return NOTFOUND;
	 /* x is now equal to k[i], located in a leaf:  */
	 for (j=i+1; j < *n; j++){
		 k[j-1] = k[j];
		 p[j] = p[j+1];
	 }
	 --*n;
	writenode(t, &nod);
	 return(*n >= (t==root ? 1 : M) ? SUCCESS : UNDERFLOW);
  }
  /*  t is an interior node (not a leaf): */
  item = k+i;
  left = p[i];
  readnode(left, &nod1);
  nleft = & nod1.cnt;
    /* x found in interior node.  Go to left child *p[i] and then follow a

	  path all the way to a leaf, using rightmost branches:  */
  if (i < *n && strcmp(x.index,item->index) == 0){
	  q = p[i];
	  readnode(q, &nod1);
	  nq = nod1.cnt;
	  while (q1 = nod1.ptr[nq], q1!= NIL){
			 q = q1;
			 readnode(q, &nod1);
			 nq = nod1.cnt;
	  }
	  /*  Exchange k[i] with the rightmost item in that leaf:   */
	  addr = nod1.tuple + nq -1;
	  *item = *addr;
	  *addr = x;
	  writenode(t, &nod);
	  writenode(q, &nod1);
  }

  /*  Delete x in subtree with root p[i]:  */
	code = del(x, left);
	if (code != UNDERFLOW)
		return code;
	/*  Underflow, borrow, and , if necessary, merge:  */
	if (i < *n)
		readnode(p[i+1], &nodR);
	if (i == *n || nodR.cnt == M){
	  if (i > 0){
		 readnode(p[i-1], &nodL);
		 if (i == *n || nodL.cnt > M)
			borrowleft = 1;
	  }
	}
	/* borrow from left sibling */
	if (borrowleft){
	  item = k+i-1;
		left = p[i-1];
		right = p[i];
		nod1 = nodL;
		readnode(right, &nod2);
		nleft = & nod1.cnt;
	}else{
		right = p[i+1];        /*  borrow from right sibling   */
		readnode(left, &nod1);
		nod2 = nodR;
	}
	nright = & nod2.cnt;
	ltuple = nod1.tuple;
	rtuple = nod2.tuple;
	lptr = nod1.ptr;
	rptr = nod2.ptr;
	if (borrowleft){
		rptr[*nright + 1] = rptr[*nright];
		for (j=*nright; j>0; j--){
			rtuple[j] = rtuple[j-1];
			rptr[j] = rptr[j-1];
		}
		++*nright;
		rtuple[0] = *item;
		rptr[0] = lptr[*nleft];
		*item = ltuple[*nleft - 1];
		if (--*nleft >= M){
		  writenode(t, &nod);
		  writenode(left, &nod1);
		  writenode(right, &nod2);
		  return SUCCESS;
		}
	}else
	/* borrow from right sibling */
	 if (*nright > M){
		 ltuple[M-1] = *item;
		 lptr[M] = rptr[0];
		 *item = rtuple[0];
		 ++*nleft;
		 --*nright;
		 for (j=0; j < *nright; j++){
			 rptr[j] = rptr[j+1];
			 rtuple[j] = rtuple[j+1];
		 }
		 rptr[*nright] = rptr[*nright + 1];
		 writenode(t, &nod);
		 writenode(left, &nod1);
		 writenode(right, &nod2);
		 return(SUCCESS);
	 }
	 /*  Merge   */
	 ltuple[M-1] = *item;
	 lptr[M] = rptr[0];
	 for (j=0; j<M; j++){
		ltuple[M+j] = rtuple[j];
		lptr[M+j+1] = rptr[j+1];
	 }
	 *nleft = MM;
	 freenode(right);
	 for (j=i+1; j < *n; j++){
		 k[j-1] = k[j];
		 p[j] = p[j+1];
	 }
	 --*n;
	 writenode(t, &nod);
	 writenode(left, &nod1);
	 return( *n >= (t==root ? 1 : M) ? SUCCESS : UNDERFLOW);
}
Пример #16
0
Bool TERMWINDOWMEMBER net_slave(void)
    {
    callout = TRUE;

    if (!read_net_messages())
        {
        cPrintf(getmsg(59));
        callout = FALSE;
        return (FALSE);
        }

    if (!readnode(TRUE))
        {
        cOutOfMemory(112);
        callout = FALSE;
        dump_net_messages();
        return (FALSE);
        }

    label Buffer, Buffer1;
    if (!*CurrentUser->GetAlias(Buffer, sizeof(Buffer)) ||
            !*CurrentUser->GetLocID(Buffer1, sizeof(Buffer1)))
        {
        dump_net_messages();
        callout = FALSE;
        return (FALSE);
        }

    if (!onConsole)
        {
        netError = FALSE;

        // cleanup
        changedir(LocalTempPath);
        ambigUnlink(getnetmsg(162));
        ambigUnlink(getnetmsg(163));
        unlink(roomreqIn);
        unlink(roomreqOut);
        unlink(roomdataIn);
        unlink(roomdataOut);
        unlink(getnetmsg(164));
        unlink(getnetmsg(165));

        switch (node->GetNetworkType())
            {
            default:
            case NET_DCIT10:
                {
                Net1Slave();
                if (Net1Master())
                    {
                    Net1Cleanup();
                    buildaddress(CONSOLE);
                    did_net(node->GetName());
                    }
                else
                    {
                    dump_net_messages();
                    callout = FALSE;
                    return (FALSE);
                    }

                break;
                }

            case NET_DCIT15:
            case NET_DCIT16:
                {
                if (dc15network(FALSE))
                    {
                    Net1Cleanup();
                    buildaddress(CONSOLE);
                    did_net(node->GetName());
                    }
                else
                    {
                    dump_net_messages();
                    callout = FALSE;
                    return (FALSE);
                    }

                break;
                }

            case NET_6_9:
                {
                if (net69(FALSE))
                    {
                    did_net(node->GetName());
                    }
                else
                    {
                    dump_net_messages();
                    callout = FALSE;
                    return (FALSE);
                    }

                break;
                }

            case NET_C86:
                {
                if (!Citadel86Network(FALSE))
                    {
                    dump_net_messages();
                    callout = FALSE;
                    return (FALSE);
                    }

                did_net(node->GetName());
                break;
                }

#ifdef HENGE
            case NET_HENGE:
                {
                if (!hengeNet(FALSE))
                    {
                    dump_net_messages();
                    callout = FALSE;
                    return (FALSE);
                    }

                break;
                }
#endif
            }
        }
    else
        {
        dump_net_messages();
        callout = FALSE;
        return (FALSE);
        }

    dump_net_messages();
    callout = FALSE;
    return (TRUE);
    }
Пример #17
0
/*
	Insert x in B-tree with root t.  If not completely successful, the
	 integer *y and the pointer *u remain to be inserted.
*/
status ins(btuple_t x, long t, btuple_t *y, long *u)
{
 long tnew, p_final, *p;
 int i, j, *n;
 btuple_t *k;
 btuple_t xnew, k_final;
 status code;
 node nod, newnod;

	/*  Examine whether t is a pointer member in a leaf  */
	if (t == NIL){
		*u = NIL;
		 *y = x;
		 return(INSERTNOTCOMPLETE);
	}
	readnode(t, &nod);
	n = & nod.cnt;
	k = nod.tuple;
	p = nod.ptr;
	/*  Select pointer p[i] and try to insert x in  the subtree of whichp[i]
	  is  the root:  */
	i = binsearch(x, k, *n);
	if (i < *n && strcmp(x.index,k[i].index) == 0)
	  return(DUPLICATEKEY);
	code = ins(x, p[i], &xnew, &tnew);
	if (code != INSERTNOTCOMPLETE)
	  return code;
	/* Insertion in subtree did not completely succeed; try to insert xnew and
	tnew in the current node:  */
	if (*n < MM){
		i = binsearch(xnew, k, *n);
		for (j = *n; j > i; j--){
			k[j] = k[j-1];
			p[j+1] = p[j];
		}
	  k[i] = xnew;
	  p[i+1] = tnew;
	  ++*n;
	  writenode(t, &nod);
	  return(SUCCESS);
	}
	/*  The current node was already full, so split it.  Pass item k[M] in the
	 middle of the augmented sequence back through parameter y, so that it
	 can move upward in the tree.  Also, pass a pointer to the newly created
	 node back through u.  Return INSERTNOTCOMPLETE, to report that insertion
	 was not completed:    */
	if (i == MM){
	  k_final = xnew;
	  p_final = tnew;
	 }else{
		  k_final = k[MM-1];
		  p_final = p[MM];
		  for (j=MM-1; j>i; j--){
			  k[j] = k[j-1];
			  p[j+1] = p[j];
		  }
			k[i] = xnew;
			p[i+1] = tnew;
	}
	*y = k[M];
	*n = M;
	*u = getnode(); newnod.cnt = M;
	for (j=0; j< M-1; j++){
		newnod.tuple[j] = k[j+M+1];
		newnod.ptr[j] = p[j+M+1];
	}
	newnod.ptr[M-1] = p[MM];
	newnod.tuple[M-1] = k_final;
	newnod.ptr[M] = p_final;
	writenode(t, &nod);
	writenode(*u, &newnod);
	return(INSERTNOTCOMPLETE);
}
Пример #18
0
/**
   @param argc command line argument count
   @param argv command line arguments
   @return 0 on success
*/
int
main(int argc, char *argv[])
{
    int    sock;
    int    newsock;
    int    i;
    int    foreground = 0;
    int    portn = PORT;
    int    allowmulti = 0;
    size_t size;
    fd_set active_fd_set;
    fd_set read_fd_set;
    struct sockaddr_in clientname;
    char   msgs[255][MAXMSGLEN+1];
    char   opt;
    char   *fn_nodecfg = NULL;
    char   *fn_out = NULL;
    struct nodecfg_st **nodecfgs = NULL;
    struct nodemsg_st *nodemsg;

    fn_run = RUNFILE;

    while((opt=getopt(argc, argv, "c:fho:p:r:")) != -1)
    {
        switch(opt)
        {
            case 'c':
                fn_nodecfg = strdup(optarg);
                break;

            case 'f':
                foreground = 1;
                break;

            case 'o':
                fn_out = strdup(optarg);
                break;

            case 'p':
                portn = atoi(optarg);
                break;

            case 'r':
                fn_run = optarg;
                break;

            case 'h':
            default:
                usage();
                exit(1);
                break;
        } // switch
    } // while

    if(foreground == 0)
        daemon(1, 1);

    if(fn_nodecfg)
        nodecfgs = readnodecfg(fn_nodecfg);

   // we exit if there is another instance already running
   makerunfile();

   sock = make_socket(portn);
   if (listen(sock, LSTNBACKLOG) < 0)
   {
      perror("listen");
      exit(EXIT_FAILURE);
   }

   FD_ZERO(&active_fd_set);
   FD_SET(sock, &active_fd_set);

   while(1)
   {
      // TODO: failed select should attempt to create new socket
      read_fd_set = active_fd_set;
      if(select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
      {
      // TODO: handle this error without exiting
         perror ("select");
         exit (EXIT_FAILURE);
      }

      /* Service all the sockets with input pending. */
      for (i = 0; i < FD_SETSIZE; ++i)
      {
         if(FD_ISSET(i, &read_fd_set))
         {
            if(i == sock)
            {
                #ifdef DEBUG
                printf("DEBUG: select read fd %d\n", i);
                #endif

                size = sizeof(clientname);
                newsock = accept(sock, (struct sockaddr *) &clientname
                 , (socklen_t *) &size);
                if(newsock < 0)
                {
                    // TODO: handle this error without exiting
                    perror ("accept");
                    exit (EXIT_FAILURE);
                }
                msgs[newsock][0] = '\0'; 
                FD_SET (newsock, &active_fd_set);
            } // if i == sock
            else
            {
               /* Data arriving on an already-connected socket. */
               /* is appended to the message in the array */
               if(readnode(i, msgs[i]) < 0)
               {
                    /* once we get 0 bytes from the fd we know that we are
                       done reading and can process the message */
                    close(i);
                    FD_CLR(i, &active_fd_set);
                    printmsg(nodecfgs, msgs[i], fn_out);
                    memset(msgs[i], '\0', MAXMSGLEN);
                } // if readnode
            } // if i == sock else
         } // if read fd is set
      } // for
   } // while 1

   return 0;
} // main