Example #1
0
/* fd, is a user file descriptor. */
PRIVILEGED_FUNCTION int _close_r(struct _reent *ptr, int fd) 
{
	int res;
	struct fdent *pfd;

	pfd = findslot(fd);
	if (pfd == NULL)
	{
		ptr->_errno = EBADF;
		return -1;
	}

	/* Handle stderr == stdout. */
	if ((fd == 1 || fd == 2)
			&& (openfiles[1].handle == openfiles[2].handle))
	{
		pfd->handle = -1;
		return 0;
	}

	/* Attempt to close the handle. */
	res = checkerror(do_AngelSWI (AngelSWI_Reason_Close, &f(pfd->handle)));

	/* Reclaim handle? */
	if (res == 0)
		pfd->handle = -1;

	return res;
}
Example #2
0
int rc_open( unsigned long ip_net ,unsigned short port_net )
{

	int fd;

	if( (fd = findslot())< 0 ) return -2;

	slot[fd].ip_net = ip_net;
	slot[fd].port_net = port_net;

	if(addsendp( fd , SEQ_NOUSE , COMMAND_OPEN ,
				LEN_NOUSE , fd , RFD_NOUSE , BUF_NOUSE )<0){
		return -100;
	}

	slot[fd].open_send = 1;

	while(1){
		rc_proc();
		if( slot[fd].open_ack){
			break;
		}
	}
	return fd;
}
Example #3
0
static int
findfreeslot(void)
{
	int slot;

	if ((slot = findslot(NOPID)) < 0)
		errx(1, "internal error: no free pid slot");
	return (slot);
}
Example #4
0
static int
Xslot (char *ttys_file, char *servers_file, char *tty_line, char *host_name,
       int addp)
{
	FILE	*ttys, *servers;
	int	c;
	int	slot = 1;
	int	column0 = 1;
	char	servers_line[1024];
	char	disp_name[512];
	int	len;
	char	*pos;

	/* remove screen number from the display name */
	memset(disp_name, 0, sizeof(disp_name));
	strncpy(disp_name, host_name ? host_name : tty_line, sizeof(disp_name)-1);
	pos = strrchr(disp_name, ':');
	if (pos) {
		pos = strchr(pos, '.');
		if (pos)
			*pos = '\0';
	}
	sysnerr ((int)(long)(ttys = fopen (ttys_file, "r")), ttys_file);
	while ((c = getc (ttys)) != EOF)
		if (c == '\n') {
			++slot;
			column0 = 1;
		} else
			column0 = 0;
	if (!column0)
		++slot;
	(void) fclose (ttys);
	sysnerr ((int)(long)(servers = fopen (servers_file, "r")), servers_file);

	len = strlen (disp_name);
	column0 = 1;
	while (fgets (servers_line, sizeof (servers_line), servers)) {
		if (column0 && *servers_line != '#') {
			if (!strncmp (disp_name, servers_line, len) &&
			    (servers_line[len] == ' ' ||
			     servers_line[len] == '\t'))
				return slot;
			++slot;
		}
		if (servers_line[strlen(servers_line)-1] != '\n')
			column0 = 0;
		else
			column0 = 1;
	}
	/*
	 * display not found in Xservers file - allocate utmp entry dinamically
	 */
	return findslot (tty_line, host_name, addp, slot);
}
Example #5
0
static int
pids_remove(pid_t pid)
{
	int slot;

	if ((slot = findslot(pid)) < 0)
		return (0);

	clearslot(slot);
	curprocs--;
	return (1);
}
Example #6
0
bool StateManager::save(const char *filename, uint8 slot, serializer &s, const char *description) {
  //if no state archive exists ...
  if(file::exists(filename) == false) {
    //try and create one
    if(create(filename) == false) return false;
  }
  //if we cannot load the existing state archive ...
  if(load(filename) == false) {
    //it's probably an older version, try and create a new one
    if(create(filename) == false) return false;
    //it still needs to be loaded before we can write to it
    if(load(filename) == false) return false;
  }

  uint8 index = findslot(slot);
  if(index == SlotInvalid) {
    //create new slot instead of over-writing existing slot
    if(info.slotcount >= 255) return false;
    index = info.slotcount;
    slot  = info.slotcount;
  }

  file fp;
  if(fp.open(filename, file::mode_readwrite) == false) return false;

  fp.seek(SlotIndex + index);
  fp.write(slot);

  time_t current = time(0);
  tm *ts = localtime(&current);
  char timestamp[32];
  sprintf(timestamp, "%.4u-%.2u-%.2u %.2u:%.2u:%.2u",
    1900 + ts->tm_year, ts->tm_mon + 1, ts->tm_mday,
    ts->tm_hour, ts->tm_min, ts->tm_sec,
    (ts->tm_hour < 12 ? "AM" : "PM")
  );
  fp.seek(DateTimeIndex + index * DateTimeSize);
  fp.write((uint8*)&timestamp[0], DateTimeSize);

  char desc[DescriptionSize];
  memset(&desc, 0, DescriptionSize);
  strlcpy(desc, description, DescriptionSize);
  fp.seek(DescIndex + index * DescriptionSize);
  fp.write((uint8*)&desc[0], DescriptionSize);

  fp.seek(HeaderSize + index * system.serialize_size);
  fp.write(s.data(), s.size());
  for(unsigned n = 0; n < system.serialize_size - s.size(); n++) fp.write(0x00);

  fp.close();
  return true;
}
Example #7
0
serializer StateManager::load(const char *filename, uint8 slot) {
  if(load(filename) == false) throw;
  if(info.slotcount <= slot) throw;
  uint8 index = findslot(slot);
  if(index == SlotInvalid) throw;
  file fp;
  if(fp.open(filename, file::mode_read) == false) throw;

  fp.seek(HeaderSize + system.serialize_size * index);
  uint8 *data = new uint8[system.serialize_size];
  fp.read(data, system.serialize_size);
  serializer s(data, system.serialize_size);
  delete[] data;
  fp.close();
  return s;
}
Example #8
0
bool StateManager::set_description(const char *filename, uint8 slot, const char *description) {
  if(load(filename) == false) return false;
  if(info.slotcount <= slot) return false;
  file fp;
  if(fp.open(filename, file::mode_readwrite) == false) return false;

  uint8 index = findslot(slot);
  if(index == SlotInvalid) { fp.close(); return false; }

  char desc[DescriptionSize];
  memset(&desc, 0, DescriptionSize);
  strlcpy(desc, description, DescriptionSize);

  fp.seek(DescIndex + index * DescriptionSize);
  fp.write((uint8*)&desc[0], DescriptionSize);
  fp.close();
  return true;
}
Example #9
0
bool StateManager::erase(const char *filename, uint8 slot) {
  if(load(filename) == false) return false;
  uint8 index = findslot(slot);
  if(index == SlotInvalid) return false;

  file fp;
  if(fp.open(filename, file::mode_readwrite) == false) return false;
  if(info.slotcount <= slot) return false;

  //copy the very last state to the slot that is to be erased
  uint8 lastslot = info.slotcount - 1;
  info.slot[index] = info.slot[lastslot];
  info.slot[lastslot] = SlotInvalid;

  fp.seek(DateTimeIndex + index * DateTimeSize);
  fp.write((uint8*)&info.datetime[lastslot * DateTimeSize], DateTimeSize);

  fp.seek(DescIndex + index * DescriptionSize);
  fp.write((uint8*)&info.description[lastslot * DescriptionSize], DescriptionSize);

  fp.seek(HeaderSize + system.serialize_size * lastslot);
  uint8 *data = new uint8[system.serialize_size];
  fp.read(data, system.serialize_size);

  fp.seek(HeaderSize + system.serialize_size * index);
  fp.write(data, system.serialize_size);
  delete[] data;

  //decrement all IDs after the deleted one (removes empty slot ID from deletion)
  for(unsigned n = 0; n < lastslot; n++) {
    if(info.slot[n] > slot) info.slot[n]--;
  }

  fp.seek(SlotIndex);
  fp.write(info.slot, 256);

  unsigned size = fp.size();
  fp.truncate(size - system.serialize_size);
  return true;
}
Example #10
0
int rc_proc(void)
{
	int i;
	int ll;
	double now_time = getUTimeDouble();

	if( ( now_time - lasttime ) < (INTERVAL_MS*1000)) return 0;
	lasttime = now_time;


	fprintf(stderr , "!");

	for(ll=0;ll<rc.maxslot;ll++){
		int j;
		struct sendp *sq;
		
		/* 誰を処理するのか */
		do_first++;
		if( do_first == rc.maxslot ) do_first = 0;
		
		if( slot[do_first].use == 0 ) continue;
		sq = slot[do_first].sendq;

		
		/* 書きこみ不可になるか、全部のスロットを処理しきるまで書きつづける */
		if(  ! select_writable()) break;
		
		
		for(j=0;j<SENDQSIZE;j++){
			if( sq[j].state == SENDP_SENDWAIT ){
				/* 送信まちになっているぞ */
				if(sender( slot[do_first].ip_net , slot[do_first].port_net ,
						  sq[j].seq , sq[j].cmd , sq[j].len,
						  sq[j].sfd , sq[j].rfd ,sq[j].buf )<=0){
					/* 送信できなかったらとりあえずやめる */
					break;
				} else {
				}
					
				sq[j].sendtime = now_time;
				sq[j].nexttime = now_time + timetable[0];
					
				switch( sq[j].cmd ){
					case COMMAND_DATA:
					case COMMAND_OPEN:
					case COMMAND_CLOSE:
					sq[j].state = SENDP_ACKWAIT;
					break;
					case COMMAND_DATAACK:
					case COMMAND_OPENACK:
					case COMMAND_CLOSEACK:
					deletesendp( &sq[j] );
					break;
					default:	/* ERROR!!!!!!*/
					break;
				}
				if( select_writable() ) continue; else break;
			} else if( sq[j].state == SENDP_ACKWAIT){
				/* 1回送信して、ACKをまっているのだ。時間次第で再送 */
					
				if( sq[j].nexttime < now_time ){
					sq[j].retrytimes++;
					if( sq[j].retrytimes == sizeof( timetable)/sizeof(timetable[0])){
						closeslot( do_first );
						fprintf( stderr, "TIMEOUT on slot %d\n" , do_first);
					} else {

						fprintf( stderr, "RETRY Qi:%d fd:%d\n" ,j , do_first );
						if( sender( slot[do_first].ip_net , slot[do_first].port_net ,
								   sq[j].seq , sq[j].cmd , sq[j].len,
								   sq[j].sfd , sq[j].rfd ,sq[j].buf )<=0){
							break;
						}
						sq[j].nexttime = sq[j].sendtime +
						timetable[sq[j].retrytimes];
					}
				}
					
			} else {
				/* 何もせん */
			}
		}
	}		/* while */



	while(1){
		struct sockaddr_in sin;
		int clilen = sizeof( sin );
		int n;
		int ret;
		char buf[MTU];
		int seq , cmd , len , sfd , rfd;
		char *data;
		unsigned long ip_net;
		unsigned short port_net;

		/* 読みこみ可能なら永久に読みつづける */
		if( select_readable()){
			n = recvfrom( rc.sockfd , buf , sizeof( buf ), 0 ,
						 ( struct sockaddr*)&sin , &clilen );
			if( n <= 0 )break;
		} else {
			break;
		}

		getheader( buf , n , &seq , &cmd, &len , &sfd , &rfd , &data );
		ip_net = sin.sin_addr.s_addr;
		port_net = sin.sin_port;

		fprintf( stderr ,"PACKET!  SEQ:%x CMD:%x LEN:%x SFD:%x RFD:%x\n",
				seq,cmd,len,sfd,rfd);


		/* COMMANDによってわける */
		if( cmd == COMMAND_DATA ){

			if( FDINVALID( rfd ) ) continue;
				
			/* 2重チェックをここでする */
			for(i=0;i<RECVQSIZE;i++){
				if( slot[rfd].recvq[i].seq == seq &&
				   slot[rfd].recvq[i].state == RECVP_SENDACK )break;
			}
			if( i != RECVQSIZE ){
				fprintf( stderr, "Ignored datapacket. seq:%d\n" , seq );
				continue;
			}

			addrecvp( rfd , seq , cmd , len , sfd , rfd , data );

			/* ACKを送信 */
			addsendp( rfd , seq , COMMAND_DATAACK , LEN_NOUSE , sfd , rfd , BUF_NOUSE );
				
		} else if( cmd == COMMAND_OPEN ){
				
			int si;

				
			/* 2重openをチェック */
			for(i=0;i<rc.maxslot;i++){
				if( 
				   slot[i].ip_net == ip_net &&
				   slot[i].port_net == port_net &&
				   slot[i].dslot == sfd &&
				   slot[i].use  ){
					break;
				}
			}
			if( i != rc.maxslot) continue;
				
			if( (si = findslot())<0) continue;
			if( addsendp( si , SEQ_NOUSE , COMMAND_OPENACK , LEN_NOUSE ,
						 sfd , si , BUF_NOUSE )<0){
				/* ACKおくれん */
				fprintf( stderr , "CLOSE BECAUSE OF OPENACK F**K\n");
				closeslot(si);
			} else {
				slot[si].ip_net = ip_net;
				slot[si].port_net = port_net;
				slot[si].dslot = sfd;
				slot[si].send_i = slot[si].recv_i = 0;
				slot[si].open_ack = 0;
				slot[si].accept_wait = 1;

				fprintf(stderr,"NASUNASU Si:%d\n", si );
					
			}
				
		} else if( cmd == COMMAND_CLOSE ){
			if( FDINVALID( rfd ) ) continue;
		} else if( cmd == COMMAND_DATAACK ){
			if( FDINVALID( sfd ) ) continue;

			fprintf( stderr , "RECEIVED DATA ACK. SEQ:%d\n" , seq );

			/* 到着したパケットと同じseqをもつsendqをさがす */
			for(i=0;i<SENDQSIZE;i++){
				if( slot[sfd].sendq[i].seq == seq &&
				   slot[sfd].sendq[i].state == SENDP_ACKWAIT ){
					/* 到着を確認! 確認の条件はseqが同じでかつ */
					/* ACKWAITしていること。おなじseqをもつものはすべて消してしまう。*/
					deletesendp( & slot[sfd].sendq[i] );
					fprintf( stderr,  "Confirmed seq %d\n", seq );
				}

			}
			/* ACKまちを消せたら、閉じれる状態かもしれない。 */
			if( closable( sfd ) )closeslot(sfd);

				
		} else if( cmd == COMMAND_OPENACK ){
			if( FDINVALID( sfd ) )continue;

			slot[sfd].open_ack = 1;
			slot[sfd].dslot = rfd;
			fprintf( stderr, "BBBBBBBBBBBBBBBBB RFD:%d\n" , rfd );
			deleteopensendp( sfd );
				
		} else if( cmd == COMMAND_CLOSEACK ){
			if( FDINVALID(  sfd ) )continue;
			deleteclosesendp( sfd );
			slot[sfd].close_wait = 1;
		}
	}
}
Example #11
0
/* fd, is a user file descriptor. */
PRIVILEGED_FUNCTION _off_t _lseek_r(struct _reent *ptr, int fd, _off_t offs, int dir) 
{
	int res;
	struct fdent *pfd;

	/* Valid file descriptor? */
	pfd = findslot(fd);
	if (pfd == NULL)
	{
		ptr->_errno = EBADF;
		return -1;
	}

	/* Valid whence? */
	if ((dir != SEEK_CUR)
			&& (dir != SEEK_SET)
			&& (dir != SEEK_END))
	{
		ptr->_errno = EINVAL;
		return -1;
	}

	/* Convert SEEK_CUR to SEEK_SET */
	if (dir == SEEK_CUR)
	{
		offs = pfd->pos + offs;
		/* The resulting file offset would be negative. */
		if (offs < 0)
		{
			ptr->_errno = EINVAL;
			if ((pfd->pos > 0) && (offs > 0))
				ptr->_errno = EOVERFLOW;
			return -1;
		}
		dir = SEEK_SET;
	}

	int block[2];
	if (dir == SEEK_END)
	{
		block[0] = pfd->handle;
		res = checkerror(do_AngelSWI(AngelSWI_Reason_FLen, block));
		if (res == -1)
			return -1;
		offs += res;
	}

	/* This code only does absolute seeks.  */
	block[0] = pfd->handle;
	block[1] = offs;
	res = checkerror(do_AngelSWI(AngelSWI_Reason_Seek, block));

	/* At this point offs is the current file position. */
	if (res >= 0)
	{
		pfd->pos = offs;
		return offs;
	}
	else
		return -1;
}
int
main(int argc, char **argv)
{
    int     team, s_type;
    char   *dpyname = NULL;
    int     usage = 0;
    int     err = 0;
    char   *name, *ptr, *cp;
    struct passwd *pwent;
    int     passive = 0;
    int     xpmopt = 1;
    int     useORopt = 0;
    int     useCookieOpt = 0;
    int     dontUseCookieOpt = 0;
/*    char *defaultsFile=NULL;*/

    pseudo[0] = defpasswd[0] = '\0';

    name = *argv++;
    argc--;
    if ((ptr = strrchr(name, '/')) != NULL)
	name = ptr + 1;
    while (*argv) {
	if (**argv != '-') {
	    serverName = *argv;	/* don't abort argument processing */
	    argv++;
	    argc--;
	} else {
	    ++*argv;

	    argc--;
	    ptr = *argv++;
	    while (*ptr) {
		switch (*ptr) {
		case 'C':	/* character name */
		    (void) strncpy(pseudo, *argv, sizeof(pseudo));
		    argv++;
		    argc--;
		    break;

		case 'P':	/* authorization password */
		    (void) strncpy(defpasswd, *argv, sizeof(defpasswd));
		    {
			int     i;
			for (i = 0; (*argv)[i]; i++)
			    (*argv)[i] = 0;
		    }
		    argv++;
		    argc--;
		    break;

		case 'u':
		    usage++;
		    break;
		case 's':
		    if (*argv) {
			xtrekPort = atoi(*argv);
			passive = 1;
			argv++;
			argc--;
		    }
		    break;
		case 'p':
		    if (*argv) {
			xtrekPort = atoi(*argv);
			argv++;
			argc--;
		    }
		    break;
		case 'd':
		    dpyname = *argv;
		    argc--;
		    argv++;
		    break;
		case 'm':
		    usemeta = 1;
		    break;
		case 'h':
		    serverName = *argv;
		    argc--;
		    argv++;
		    break;

		case 't':
		    title = *argv;
		    argc--;
		    argv++;
		    break;
		case 'r':
		    defaultsFile = *argv;
		    argv++;
		    argc--;
		    break;
#ifdef AUTHORIZE
		case 'o':
		    RSA_Client = -1;
		    break;
		case 'R':
		    RSA_Client = -2;
		    break;
#else
		case 'o':
		case 'R':
		    printf("This client does not have binary authorization.\n");
		    break;
#endif
		case 'e':
#ifdef AUTHORIZE
		    checkExpire(1);
#else
		    printf("This client does not RSA verify and will not expire.\n");
#endif
		    exit(0);
		    break;
		case 'f':	/* list ftp sites */
		    fprintf(stderr, "\n\
The newest version of the Paradise client can be found at:\n\
      ftp.netrek.org  in /pub/netrek/paradise/bin/\n");
		    exit(0);
		case 'G':
		    if (*argv) {
			ghoststart++;
			ghost_pno = atoi(*argv);
			printf("Emergency restart being attempted...\n");
			argv++;
			argc--;
		    }
		    break;
		case '2':	/* force paradise */
		    paradise = 1;
		    break;
		case 'F':	/* File playback */
		    if (*argv) {
			playFile = strdup(*argv);
			playback = 1;
			argv++;
			argc--;
		    }
		    break;
		case 'x':
		    xpmopt = 0;
		    break;
		case 'k':		/* cookie mode [BDyess] */
		    useCookieOpt = 1;
		    break;
		case 'K':		/* no-cookies :( [BDyess] */
		    dontUseCookieOpt = 1;
		    break;
		case 'v':
		    verbose_image_loading = 1;
		    break;
		case 'O':		/* turn on GXor image drawing [BDyess]*/
		    useORopt = 1;	
		    break;
                case 'c': 	/* dump .paradiserc defaults [BDyess] */
		    dump_defaults = 1;
		    break;
		default:
		    fprintf(stderr, "%s: unknown option '%c'\n", name, *ptr);
		    err++;
		    break;
		}
		ptr++;
	    }
	}
    }

    inittrigtables();

    initStars();		/* moved from redraw.c at KAO\'s suggestion */

    if (usage || err) {
	printUsage(name);
#ifdef AUTHORIZE
	checkExpire(1);
#endif
	exit(0);
	/* exit(err); Exits from checkExpire */
    }
    defaultsFile = initDefaults(defaultsFile);

    if(xpmopt) xpm = 1;
    else xpm = booleanDefault("xpm",xpm);
    if(xpm) printf("XPM mode enabled.\n");
    /* command line option overrides .paradiserc value [BDyess] */
    if(useORopt) useOR = 1;
    else useOR = booleanDefault("useOR",useOR);
    if(useOR) printf("OR mode enabled.\n");
    if(useOR || !xpm) cookie = 0;	/* default no-cookies unless in XPM
    					   mode w/out OR [BDyess] */
					/* note: need a milk mode :) */
    if(useCookieOpt) cookie = 1;
    else if(dontUseCookieOpt) cookie = 0;
    else cookie = booleanDefault("cookie",cookie);
    if(cookie) printf("Cookie mode enabled.\n");

#ifdef AUTHORIZE
    if (RSA_Client != -1)
	checkExpire(0);
#endif

    /* compatability */
    if (argc > 0)
	serverName = argv[0];

    srandom(getpid() + time((long *) 0));

    if(playback || booleanDefault("playback",0)) {
        defNickName = "playback";
	usemeta=0;
        serverName = "playback";
    } else
    {
        if (serverName) {
	    char    temp[80], *s;
	    sprintf(temp, "server.%s", serverName);
	    if ((s = stringDefault(temp,NULL))) {
		printf("Using nickname \"%s\" for server %s\n", serverName, s);
		defNickName = serverName;
		serverName = s;
		defFlavor = stringDefault("flavor",NULL);
	    }
	}
	if (!serverName) {
	    serverName = stringDefault("server",NULL);
        }
	if (!serverName && !passive) {
	    serverName = DEFAULT_SERVER;
	    usemeta = 1;		/* no server specified, show the menu */
	}
	if (passive)
	    serverName = "passive";	/* newwin gets a wrong title otherwise */

	if (xtrekPort < 0)
	    xtrekPort = intDefault("port", -1);
	if (xtrekPort < 0)
	    xtrekPort = DEFAULT_PORT;
    } /* playback */
    build_default_configuration();

    metaserverAddress = stringDefault("metaserver",
				      "metaserver.netrek.org");
    if (usemeta)
	openmeta();

    W_Initialize(dpyname);

    metaFork = booleanDefault("metaFork", metaFork);
    /* do the metawindow thang */
    if (usemeta) {
	metawindow();
	metainput();
	if (metaFork)
	    W_Initialize(dpyname);
	newwin(dpyname, name);
    } else

	/* this creates the necessary x windows for the game */
	newwin(dpyname, name);

    /* open memory...? */
    openmem();
    if (!startPlayback())
    {
	if (!passive) {
	    serverName = callServer(xtrekPort, serverName);
	} else {
	    connectToServer(xtrekPort);
	}
    }
    sendFeature("FEATURE_PACKETS", 'S', 1, 0, 0);

    timeStart = time(NULL);
    findslot();

    /* sets all the settings from defaults file (.xtrekrc probably) */
    resetDefaults();

#ifdef UNIX_SOUND
    init_sound();
    play_sound(SND_PARADISE);
#endif

    mapAll();
/*    signal(SIGINT, SIG_IGN);*/
    signal(SIGCHLD, reaper);

    /* Get login name */
    if ((pwent = getpwuid(getuid())) != NULL)
	(void) strncpy(login, pwent->pw_name, sizeof(login));
    else
	(void) strncpy(login, "Bozo", sizeof(login));
    login[sizeof(login) - 1] = '\0';

    if (pseudo[0] == '\0') {
	char *freeme;
	strncpy(pseudo, freeme = stringDefault("name",login), sizeof(pseudo));
	free(freeme);
    }
    pseudo[sizeof(pseudo) - 1] = '\0';

    if (defpasswd[0] == '\0') {
	char buf[100];  /* added password by character name -JR */
	sprintf(buf,"password.%s",pseudo);
	if((cp = stringDefault(buf,NULL)) || (cp = stringDefault("password",NULL)))
	    (void) strncpy(defpasswd, cp, sizeof(defpasswd));
    }
    defpasswd[sizeof(defpasswd) - 1] = '\0';

    /*
       sendLoginReq("Gray Lensman", "hh", "sfd", 0); loginAccept = -1; while
       (loginAccept == -1) { socketPause(1,0); readFromServer(); }
    */
    getname(pseudo, defpasswd);
    loggedIn = 1;

    /*
       Set p_hostile to hostile, so if keeppeace is on, the guy starts off
       hating everyone (like a good fighter should)
    */
    me->p_hostile = (1 << number_of_teams) - 1;

    redrawTstats();

    me->p_planets = 0;
    me->p_genoplanets = 0;
    me->p_armsbomb = 0;
    me->p_genoarmsbomb = 0;
    /* Set up a reasonable default */
    me->p_whydead = KNOREASON;
    me->p_teami = -1;
    s_type = defaultShip(CRUISER);	/* from rlb7h 11/15/91 TC */

    if (booleanDefault("netStats", 1))
	startPing();		/* tell the server that we support pings */

    /*
       hack to make galaxy class ships work.  This could be more elegant, but
       the configuration code would have to be modified quite a bit, since
       the client doesn't know if it's on a paradise server until after it
       connects, and it needs the configuration info before it connects.
    */
    init_galaxy_class();

    initkeymap(-1);		/* needs to have ship types initialized -JR */

    setjmp(env);		/* Reentry point of game */

    if (ghoststart) {
	int     i;

	ghoststart = 0;

	for (i = -1; i < 5; i++)
	    if (teaminfo[i].letter == me->p_mapchars[0])
		break;

	me->p_teami = i;

	if (me->p_damage > me->p_ship->s_maxdamage) {
	    me->p_status = POUTFIT;
	} else
	    me->p_status = PALIVE;
    } else
	me->p_status = POUTFIT;

    while (1) {
	switch (me->p_status) {
	case POUTFIT:
	case PTQUEUE:
	    /* give the player the motd and find out which team he wants */
	    new_entrywindow(&team, &s_type);
	    allowPlayerlist = 1;
	    if (W_IsMapped(playerw))
		playerlist();

	    if (!playback)
		if (team == -1) {
		    W_DestroyWindow(w);
		    sendByeReq();
		    sleep(1);
		    printf("OK, bye!\n");
		    EXIT(0);
		}
	    sendVersion();
	    myship = getship(myship->s_type);

	    currentship = myship->s_type;

	    /*
	       sendOptionsPacket(); this would totally blast any flags you
	       had on the server
	    */

	    redrawall = 1;
	    enter();
	    calibrate_stats();
	    W_ClearWindow(w);
	    /*
	       for (i = 0; i < NSIG; i++) { signal(i, SIG_IGN); }
	    */

	    me->p_status = PALIVE;	/* Put player in game */

#ifdef UNIX_SOUND
            kill_sound ();
#endif
            
	    hockeyInit();

	    if (showStats)	/* Default showstats are on. */
		W_MapWindow(statwin);
	    if (showNewStats)	/* default showNewStats are off. [BDyess] */
	        W_MapWindow(newstatwin);

	    if (tryUdp && commMode != COMM_UDP) {
		sendUdpReq(COMM_UDP);
	    }

	    if (tryShort) {
		sendShortReq(SPK_VON);
		tryShort = 0;	/* only try it once */
	    }
	    /* Send request for a full update */
	    if (askforUpdate) {
		if(recv_short)
		    sendShortReq(SPK_SALL);
		else
		    sendUdpReq(COMM_UPDATE);
	    }
	    sendUpdatePacket(1000000 / updateSpeed);

	    W_Deiconify(baseWin);

	    break;
	case PALIVE:
	case PEXPLODE:
	case PDEAD:
	case POBSERVE:

	    /* Get input until the player quits or dies */
	    input();
	    W_ClearWindow(mapw);
	    break;
	default:
	    printf("client has p_status=%d.  how strange\n", me->p_status);
	    me->p_status = POUTFIT;
	}
    }

    /* NOTREACHED */
}
Example #13
0
PUBLIC int run_vm(VMSTATE vms) {
  OBJ vm_hold;	/* Holding register. NOT SEEN BY GC */
  int ticks_left = VM_TIMESLICE_TICKS;

  while (vms->c.vm_state != VM_STATE_DYING && ticks_left-- && vms->r->vm_acc != yield_thread) {
    if (vms->c.vm_state > 0) {
      vms->c.vm_state--;
      if (vms->c.vm_state == 0) {
	/* Quota expired. Warn. */
	vms->c.vm_state = VM_DEFAULT_CPU_QUOTA;
	vm_raise(vms, (OBJ) newsym("quota-expired"), NULL);
	/* Make sure we don't recurse :-) */
	vms->r->vm_trap_closure = NULL;
      }
    }

    gc_reach_safepoint();

#ifdef DEBUG
    debug_dump_instr( vms->r->vm_code->vec , vms->c.vm_ip );
#endif

    switch (CODEAT(vms->c.vm_ip)) {
      case OP_AT: {
	int index = CODEAT(vms->c.vm_ip + 1);

	if (index < 0 || index >= vms->r->vm_acc->length) {
	  vm_raise(vms, (OBJ) newsym("range-check-error"), vms->r->vm_acc);
	  break;
	}

	if (!VECTORP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	vms->r->vm_acc = AT((VECTOR) vms->r->vm_acc, index);
	vms->c.vm_ip += 2;
	break;
      }

      case OP_ATPUT: {
	int index = CODEAT(vms->c.vm_ip + 1);

	vm_hold = PEEK();

	if (index < 0 || index >= vm_hold->length) {
	  vm_raise(vms, (OBJ) newsym("range-check-error"), vm_hold);
	  break;
	}

	if (!VECTORP(vm_hold)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vm_hold);
	  break;
	}

	ATPUT((VECTOR) vm_hold, index, vms->r->vm_acc);
	vms->c.vm_ip += 2;
	break;
      }

      case OP_MOV_A_LOCL: {
	int i = CODEAT(vms->c.vm_ip + 1);
	vm_hold = (OBJ) vms->r->vm_env;
	while (i-- > 0) vm_hold = AT((VECTOR) vm_hold, 0);
	vms->r->vm_acc = AT((VECTOR) vm_hold, CODEAT(vms->c.vm_ip + 2) + 1);
	vms->c.vm_ip += 3;
	break;
      }

      case OP_MOV_A_GLOB:
	vm_hold = AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	vms->r->vm_acc = AT((OVECTOR) vm_hold, SY_VALUE);
	vms->c.vm_ip += 2;
	break;

      case OP_MOV_A_SLOT: {
	OVECTOR slot, slotname;

	if (!OBJECTP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	slotname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));

	if (!O_CAN_X((OBJECT) vms->r->vm_acc, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) slotname);
	}

	slot = findslot((OBJECT) vms->r->vm_acc, slotname, NULL);

	if (slot == NULL) {
	  vm_raise(vms, (OBJ) newsym("slot-not-found"), (OBJ) slotname);
	  break;
	}

	if (!MS_CAN_R(slot, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) slotname);
	}

	vms->r->vm_acc = AT(slot, SL_VALUE);
	vms->c.vm_ip += 2;
	break;
      }

      case OP_MOV_A_LITL:
	vms->r->vm_acc = AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	vms->c.vm_ip += 2;
	break;

      case OP_MOV_A_SELF: vms->r->vm_acc = (OBJ) vms->r->vm_self; vms->c.vm_ip++; break;
      case OP_MOV_A_FRAM: vms->r->vm_acc = (OBJ) vms->r->vm_frame; vms->c.vm_ip++; break;

      case OP_MOV_LOCL_A: {
	int i = CODEAT(vms->c.vm_ip + 1);
	vm_hold = (OBJ) vms->r->vm_env;
	while (i-- > 0) vm_hold = AT((VECTOR) vm_hold, 0);
	ATPUT((VECTOR) vm_hold, CODEAT(vms->c.vm_ip + 2) + 1, vms->r->vm_acc);
	vms->c.vm_ip += 3;
	break;
      }

      case OP_MOV_GLOB_A:
	if (!PRIVILEGEDP(vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) newsym("setting-global-value"));
	}
	vm_hold = AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	ATPUT((OVECTOR) vm_hold, SY_VALUE, vms->r->vm_acc);
	vms->c.vm_ip += 2;
	break;

      case OP_MOV_SLOT_A: {
	OVECTOR slot, slotname;
	OBJECT target = (OBJECT) POP();
	OBJECT foundin;

	if (!OBJECTP(target)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), (OBJ) target);
	  break;
	}

	slotname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));

	if (!O_CAN_X(target, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) slotname);
	}

	slot = findslot(target, slotname, &foundin);

	if (slot == NULL) {
	  vm_raise(vms, (OBJ) newsym("slot-not-found"), (OBJ) slotname);
	  break;
	}

	if (!MS_CAN_W(slot, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) slotname);
	}

	if (foundin == target) {
	  ATPUT(slot, SL_VALUE, vms->r->vm_acc);
	} else {
	  OVECTOR newslot = addslot(target, slotname, (OBJECT) AT(slot, SL_OWNER));
	  ATPUT(newslot, SL_FLAGS, AT(slot, SL_FLAGS));
	  ATPUT(newslot, SL_VALUE, vms->r->vm_acc);
	}

	vms->c.vm_ip += 2;
	break;
      }

      case OP_MOV_FRAM_A:
	if (!PRIVILEGEDP(vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) newsym("restoring-vm-frame-pointer"));
	}

	if (!OVECTORP(vms->r->vm_acc) || ((OVECTOR) vms->r->vm_acc)->type != T_FRAME) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	vms->r->vm_frame = (OVECTOR) vms->r->vm_acc;
	vms->c.vm_ip++;
	break;

      case OP_PUSH: PUSH(vms->r->vm_acc); vms->c.vm_ip++; break;
      case OP_POP: vms->r->vm_acc = POP(); vms->c.vm_ip++; break;
      case OP_SWAP:
	vm_hold = POP();
	PUSH(vms->r->vm_acc);
	vms->r->vm_acc = vm_hold;
	vms->c.vm_ip++;
	break;

      case OP_VECTOR:
	vms->r->vm_acc = (OBJ) newvector(CODEAT(vms->c.vm_ip+1));
	vms->c.vm_ip += 2;
	break;
	
      case OP_ENTER_SCOPE:
	vm_hold = (OBJ) newvector(CODEAT(vms->c.vm_ip+1) + 1);
	ATPUT((VECTOR) vm_hold, 0, (OBJ) vms->r->vm_env);
	vms->r->vm_env = (VECTOR) vm_hold;
	vms->c.vm_ip += 2;
	break;

      case OP_LEAVE_SCOPE:
	vms->r->vm_env = (VECTOR) AT(vms->r->vm_env, 0);
	vms->c.vm_ip++;
	break;

      case OP_MAKE_VECTOR: {
	int i = 0;
	int len = CODEAT(vms->c.vm_ip+1);
	VECTOR vec = newvector_noinit(len);

	for (i = len - 1; i >= 0; i--)
	  ATPUT(vec, i, POP());

	vms->r->vm_acc = (OBJ) vec;
	vms->c.vm_ip += 2;
	break;
      }

      case OP_CLOSURE:
	vms->r->vm_acc = make_closure_from((OVECTOR) vms->r->vm_acc,
					   vms->r->vm_self,
					   vms->r->vm_env,
					   vms->r->vm_effuid);
	vms->c.vm_ip++;
	break;

      case OP_METHOD_CLOSURE: {
	OVECTOR methname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	OVECTOR method;

	if (!OBJECTP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	method = findmethod((OBJECT) vms->r->vm_acc, methname);

	if (method == NULL) {
	  vm_raise(vms, (OBJ) newsym("method-not-found"), (OBJ) methname);
	  break;
	}

	if (!MS_CAN_R(method, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) methname);
	}

	vm_hold = (OBJ) newovector(CL_MAXSLOTINDEX, T_CLOSURE);
	ATPUT((OVECTOR) vm_hold, CL_METHOD, (OBJ) method);
	ATPUT((OVECTOR) vm_hold, CL_SELF, vms->r->vm_acc);
	vms->r->vm_acc = vm_hold;

	vms->c.vm_ip += 2;
	break;
      }

      case OP_RET:
	if (vms->r->vm_frame != NULL) {
	  restoreframe(vms, vms->r->vm_frame);
	  if (vms->r->vm_code != NULL)
	    break;
	}

	vms->c.vm_state = VM_STATE_DYING;
	return 1;	/* finished, nothing more to run! */
	
      case OP_CALL: {
	OVECTOR methname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	OVECTOR method;

	if (vms->r->vm_acc == NULL || TAGGEDP(vms->r->vm_acc)) {
	  vm_raise(vms,
		   (OBJ) newsym("null-call-error"),
		   AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip+1)));
	  break;
	}

	if (!OBJECTP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	method = findmethod((OBJECT) vms->r->vm_acc, methname);

	if (method == NULL) {
	  vm_raise(vms, (OBJ) newsym("method-not-found"), (OBJ) methname);
	  break;
	}

	if (!MS_CAN_X(method, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) methname);
	}

	vm_hold = POP();
	if (vm_hold->length-1 != NUM(AT(method, ME_ARGC))) {
	  vm_raise(vms, (OBJ) newsym("wrong-argc"), (OBJ) methname);
	  break;
	}

	vms->c.vm_ip += 2;
	push_frame(vms);

	vms->r->vm_env = (VECTOR) vm_hold;
	ATPUT(vms->r->vm_env, 0, AT(method, ME_ENV));
	vms->r->vm_code = (BVECTOR) AT(method, ME_CODE);
	vms->r->vm_lits = (VECTOR) AT(method, ME_LITS);
	vms->r->vm_self = (OBJECT) vms->r->vm_acc;
	if (NUM(AT(method, ME_FLAGS)) & O_SETUID)
	  vms->r->vm_effuid = (OBJECT) AT(method, ME_OWNER);
	vms->r->vm_method = method;
	vms->c.vm_ip = 0;
	break;
      }

      case OP_CALL_AS: {
	OVECTOR methname = (OVECTOR) AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip + 1));
	OVECTOR method;

	if (vms->r->vm_self == NULL ||
	    vms->r->vm_acc == NULL || TAGGEDP(vms->r->vm_acc)) {
	  vm_raise(vms,
		   (OBJ) newsym("null-call-error"),
		   AT(vms->r->vm_lits, CODEAT(vms->c.vm_ip+1)));
	  break;
	}

	if (!OBJECTP(vms->r->vm_acc)) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}

	method = findmethod((OBJECT) vms->r->vm_acc, methname);

	if (method == NULL) {
	  vm_raise(vms, (OBJ) newsym("method-not-found"), (OBJ) methname);
	  break;
	}

	if (!MS_CAN_X(method, vms->r->vm_effuid)) {
	  NOPERMISSION((OBJ) methname);
	}

	vm_hold = POP();
	if (vm_hold->length-1 != NUM(AT(method, ME_ARGC))) {
	  vm_raise(vms, (OBJ) newsym("wrong-argc"), (OBJ) methname);
	  break;
	}

	vms->c.vm_ip += 2;
	push_frame(vms);

	vms->r->vm_env = (VECTOR) vm_hold;
	ATPUT(vms->r->vm_env, 0, AT(method, ME_ENV));
	vms->r->vm_code = (BVECTOR) AT(method, ME_CODE);
	vms->r->vm_lits = (VECTOR) AT(method, ME_LITS);

	/* don't set vm_self, this is OP_CALL_AS. */
	/* vms->r->vm_self = vms->r->vm_acc; */

	if (NUM(AT(method, ME_FLAGS)) & O_SETUID)
	  vms->r->vm_effuid = (OBJECT) AT(method, ME_OWNER);
	vms->r->vm_method = method;
	vms->c.vm_ip = 0;
	break;
      }

      case OP_APPLY:
	vms->c.vm_ip++;
	apply_closure(vms, (OVECTOR) vms->r->vm_acc, (VECTOR) POP());
	break;

      case OP_JUMP: vms->c.vm_ip += 3 + ((int16_t) CODE16AT(vms->c.vm_ip+1)); break;

      case OP_JUMP_TRUE:
	vms->c.vm_ip += (vms->r->vm_acc == false) ? 3 :
						    3 + ((int16_t) CODE16AT(vms->c.vm_ip+1));
	break;

      case OP_JUMP_FALSE:
	vms->c.vm_ip += (vms->r->vm_acc != false) ? 3 :
						    3 + ((int16_t) CODE16AT(vms->c.vm_ip+1));
	break;

      case OP_NOT:
	vms->r->vm_acc = (vms->r->vm_acc == false) ? true : false;
	vms->c.vm_ip++;
	break;

      case OP_EQ:
	vms->r->vm_acc = (vms->r->vm_acc == POP()) ? true : false;
	vms->c.vm_ip++;
	break;

      case OP_NE:
	vms->r->vm_acc = (vms->r->vm_acc != POP()) ? true : false;
	vms->c.vm_ip++;
	break;

      NUMOP(OP_GT, vms->r->vm_acc = (NUM(vms->r->vm_acc) < NUM(POP())) ? true : false);
      NUMOP(OP_LT, vms->r->vm_acc = (NUM(vms->r->vm_acc) > NUM(POP())) ? true : false);
      NUMOP(OP_GE, vms->r->vm_acc = (NUM(vms->r->vm_acc) <= NUM(POP())) ? true : false);
      NUMOP(OP_LE, vms->r->vm_acc = (NUM(vms->r->vm_acc) >= NUM(POP())) ? true : false);

      NUMOP(OP_NEG, vms->r->vm_acc = MKNUM(-NUM(vms->r->vm_acc)));
      NUMOP(OP_BNOT, vms->r->vm_acc = MKNUM(~NUM(vms->r->vm_acc)));
      NUMOP(OP_BOR, vms->r->vm_acc = MKNUM(NUM(vms->r->vm_acc)|NUM(POP())));
      NUMOP(OP_BAND, vms->r->vm_acc = MKNUM(NUM(vms->r->vm_acc)&NUM(POP())));

      case OP_PLUS:
	if (vms->r->vm_acc == NULL || PEEK() == NULL) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}
	if (NUMP(vms->r->vm_acc) && NUMP(PEEK()))
	  vms->r->vm_acc = MKNUM(NUM(vms->r->vm_acc)+NUM(POP()));
	else if (TAGGEDP(vms->r->vm_acc) || TAGGEDP(PEEK())) {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	} else if (BVECTORP(vms->r->vm_acc) && BVECTORP(PEEK()))
	  vms->r->vm_acc = (OBJ) bvector_concat((BVECTOR) POP(), (BVECTOR) vms->r->vm_acc);
	else if (VECTORP(vms->r->vm_acc) && VECTORP(PEEK()))
	  vms->r->vm_acc = (OBJ) vector_concat((VECTOR) POP(), (VECTOR) vms->r->vm_acc);
	else {
	  vm_raise(vms, (OBJ) newsym("vm-runtime-type-error"), vms->r->vm_acc);
	  break;
	}
	vms->c.vm_ip++;
	break;

      NUMOP(OP_MINUS, vms->r->vm_acc = MKNUM(NUM(POP())-NUM(vms->r->vm_acc)));
      NUMOP(OP_STAR, vms->r->vm_acc = MKNUM(NUM(POP())*NUM(vms->r->vm_acc)));
      NUMOP(OP_SLASH,
	    if (vms->r->vm_acc == MKNUM(0))
	      vm_raise(vms, (OBJ) newsym("divide-by-zero"), NULL);
	    else
	      vms->r->vm_acc = MKNUM(NUM(POP())/NUM(vms->r->vm_acc)));
      NUMOP(OP_PERCENT,
	    if (vms->r->vm_acc == MKNUM(0))
	      vm_raise(vms, (OBJ) newsym("divide-by-zero"), NULL);
	    else
	      vms->r->vm_acc = MKNUM(NUM(POP())%NUM(vms->r->vm_acc)));

      default:
	fprintf(stderr, "Unknown bytecode reached (%d == 0x%x).\n",
		CODEAT(vms->c.vm_ip),
		CODEAT(vms->c.vm_ip));
	exit(MOVE_EXIT_PROGRAMMER_FUCKUP);
    }
  }

  return vms->c.vm_state == VM_STATE_DYING;
}