示例#1
0
int main(int argc, char **argv)
{
    pthread_t thread_lan;
    void *retval; // pthread线程的返回值,本程序中没有实际用处

#ifdef ENABLE_NLS
	textdomain(GETTEXT_PACKAGE);
	setlocale(LC_ALL, "");
#endif
	atexit(exit_handle);
	initConfig(argc, argv);
	signal(SIGALRM, sig_handle);	/* 定时器 */
	signal(SIGHUP, sig_handle);	 /* 注销时 */
	signal(SIGINT, sig_handle);	 /* Ctrl+C */
	signal(SIGQUIT, sig_handle);	/* Ctrl+\ */
	signal(SIGTSTP, sig_handle);	/* Ctrl+Z */
	signal(SIGTERM, sig_handle);	/* 被结束时 */
	if (dhcpMode == 3)	  /* 认证前DHCP */
		switchState(ID_DHCP);
	else
		if (proxyMode == 0)
			switchState(ID_START);	/* 不使用代理时直接开始认证 */
		else
			switchState(ID_WAITCLIENT); /* 开启代理时等待客户端认证 */
	if (proxyMode == 0) {
		wan_thread(); // 非代理模式,直接执行,不使用多线程
	} else { // 代理模式,为LAN多开一个线程
		pthread_create(&thread_lan, NULL, lan_thread, 0);
		wan_thread();
		pthread_join(thread_lan, &retval);
	}
	exit(EXIT_FAILURE);
}
示例#2
0
int main(int argc, char **argv)
{

	atexit(exit_handle);

	if(initConfig(argc, argv))
		exit(EXIT_FAILURE);
	signal(SIGALRM, sig_handle);	/* 定时器 */
	signal(SIGHUP, sig_handle);	 /* 注销时 */
	signal(SIGINT, sig_handle);	 /* Ctrl+C */
	signal(SIGQUIT, sig_handle);	/* Ctrl+\ */
	signal(SIGTSTP, sig_handle);	/* Ctrl+Z */
	signal(SIGTERM, sig_handle);	/* 被结束时 */
	signal(SIGKILL, sig_handle);


	if (dhcpMode == 3)	  /* 认证前DHCP */
		switchState(ID_DHCP);
	else
		switchState(ID_START);	/* 开始认证 */
	if (-1 == pcap_loop(hPcap, -1, pcap_handle, NULL)) { /* 开始捕获数据包 */
		printf("!! 捕获数据包失败,请检查网络连接!\n");
#ifndef NO_NOTIFY
		if (showNotify)
			show_notify("MentoHUST - 错误提示", "捕获数据包失败,请检查网络连接!");
#endif
	}
	exit(EXIT_FAILURE);
}
示例#3
0
int switchState(int type)
{
	if (state == type) /* 跟上次是同一状态? */
		sendCount++;
	else
	{
		state = type;
		sendCount = 0;
	}
	if (sendCount>=MAX_SEND_COUNT && type!=ID_ECHO)  /* 超时太多次? */
	{
		switch (type)
		{
		case ID_START:
			printf(_(">> 找不到服务器,重启认证!\n"));
			break;
		case ID_IDENTITY:
			printf(_(">> 发送用户名超时,重启认证!\n"));
			break;
		case ID_CHALLENGE:
			printf(_(">> 发送密码超时,重启认证!\n"));
			break;
		case ID_WAITECHO:
			printf(_(">> 等候响应包超时,自行响应!\n"));
			return switchState(ID_ECHO);
		}
		return restart();
	}
	switch (type)
	{
	case ID_DHCP:
		return renewIP();
	case ID_START:
		return sendStartPacket();
	case ID_IDENTITY:
		return sendIdentityPacket();
	case ID_CHALLENGE:
		return sendChallengePacket();
	case ID_WAITECHO:	/* 塞尔的就不ping了,不好计时 */
		return waitEchoPacket();
	case ID_ECHO:
		if (pingHost && sendCount*echoInterval > 60) {	/* 1分钟左右 */
			if (isOnline() == -1) {
				printf(_(">> 认证掉线,开始重连!\n"));
				return switchState(ID_START);
			}
			sendCount = 1;
		}
#ifndef NO_ARP
		if (gateMAC[0] != 0xFE)
			sendArpPacket();
#endif
		return sendEchoPacket();
	case ID_DISCONNECT:
		return sendLogoffPacket();
	}
	return 0;
}
示例#4
0
void OptionState::step_impl()
{
	const int MAX_BOT_DELAY = 25;		// 25 frames = 0.33s (gamespeed: normal)

	IMGUI& imgui = IMGUI::getSingleton();
	imgui.doCursor();
	imgui.doImage(GEN_ID, Vector2(400.0, 300.0), "background");
	imgui.doOverlay(GEN_ID, Vector2(0.0, 0.0), Vector2(800.0, 600.0));

	imgui.doEditbox(GEN_ID, Vector2(5.0, 10.0), 15, mPlayerName[LEFT_PLAYER], mPlayerNamePosition[LEFT_PLAYER]);
	imgui.doEditbox(GEN_ID, Vector2(425.0, 10.0), 15, mPlayerName[RIGHT_PLAYER], mPlayerNamePosition[RIGHT_PLAYER]);

	imgui.doSelectbox(GEN_ID, Vector2(5.0, 50.0), Vector2(375.0, 300.0), mScriptNames, mPlayerOptions[LEFT_PLAYER]);
	imgui.doSelectbox(GEN_ID, Vector2(425.0, 50.0), Vector2(795.0, 300.0), mScriptNames, mPlayerOptions[RIGHT_PLAYER]);

	imgui.doText(GEN_ID, Vector2(270.0, 310.0), TextManager::OP_DIFFICULTY );

	float f = 1.f - (float)mBotStrength[0] / MAX_BOT_DELAY;
	imgui.doScrollbar(GEN_ID, Vector2(15.0, 350.0), f);
	mBotStrength[0] = static_cast<unsigned int> ((1.f-f) * MAX_BOT_DELAY + 0.5f);
	imgui.doText(GEN_ID, Vector2(235.0, 350.0), f > 0.66 ? TextManager::OP_STRONG :
											 	(f > 0.33 ? TextManager::OP_MEDIUM:
												TextManager::OP_WEAK));

	f = 1.f - (float)mBotStrength[1] / MAX_BOT_DELAY;
	imgui.doScrollbar(GEN_ID, Vector2(440.0, 350.0), f);
	mBotStrength[1] = static_cast<unsigned int> ((1.f - f) * MAX_BOT_DELAY + 0.5f);
	imgui.doText(GEN_ID, Vector2(660.0, 350.0), f > 0.66 ? TextManager::OP_STRONG :
											 	(f > 0.33 ? TextManager::OP_MEDIUM:
												TextManager::OP_WEAK));

	if (imgui.doButton(GEN_ID, Vector2(40.0, 390.0), TextManager::OP_INPUT_OP))
	{
		save();
		switchState(new InputOptionsState());
	}

	if (imgui.doButton(GEN_ID, Vector2(40.0, 430.0), TextManager::OP_GFX_OP))
	{
		save();
		switchState(new GraphicOptionsState());
	}
	if (imgui.doButton(GEN_ID, Vector2(40.0, 470.0), TextManager::OP_MISC))
	{
		save();
		switchState(new MiscOptionsState());
	}

	if (imgui.doButton(GEN_ID, Vector2(224.0, 530.0), TextManager::LBL_OK))
	{
		save();
		switchState(new MainMenuState());
	}
	if (imgui.doButton(GEN_ID, Vector2(424.0, 530.0), TextManager::LBL_CANCEL))
	{
		switchState(new MainMenuState());
	}
}
示例#5
0
void InputOptionsState::step_impl()
{
	IMGUI& imgui = IMGUI::getSingleton();
	imgui.doCursor();
	imgui.doImage(GEN_ID, Vector2(400.0, 300.0), "background");
	imgui.doOverlay(GEN_ID, Vector2(0.0, 0.0), Vector2(800.0, 600.0));

	imgui.doText(GEN_ID, Vector2(43.0, 10.0), TextManager::OP_TOUCH_TYPE);
	if (imgui.doButton(GEN_ID, Vector2(70.0, 50.0), TextManager::OP_TOUCH_DIRECT))
		mBlobbyTouchType = 0;
	if (imgui.doButton(GEN_ID, Vector2(70.0, 100.0), TextManager::OP_TOUCH_ARROWS))
		mBlobbyTouchType = 1;
	if (mBlobbyTouchType == 0)
		imgui.doImage(GEN_ID, Vector2(52.0, 62.0), "gfx/pfeil_rechts.bmp");
	else
		imgui.doImage(GEN_ID, Vector2(52.0, 112.0), "gfx/pfeil_rechts.bmp");

	imgui.doOverlay(GEN_ID, Vector2(180.0, 150.0), Vector2(620.0, 490.0));
	imgui.doImage(GEN_ID, Vector2(400.0, 320.0), "background", Vector2(400.0, 300.0));

	// We draw the range of the touchsurfaces here
	if (mBlobbyTouchType == 0)
	{
		// Left arrowkey
		imgui.doOverlay(GEN_ID, Vector2(200.0 + 5.0, 170.0 + 100.0 + 5.0), Vector2(200.0 + 95.0 + 100.0, 170.0 + 295));
		imgui.doImage(GEN_ID, Vector2(289.0, 440.0), "gfx/pfeil_links.bmp");
		imgui.doImage(GEN_ID, Vector2(311.0, 440.0), "gfx/pfeil_rechts.bmp");
	}
	else
	{
		// Background is x: 200, y: 170, w: 400, h: 300

		// Left arrowkey
		imgui.doOverlay(GEN_ID, Vector2(200.0 + 5.0, 170.0 + 100.0 + 5.0), Vector2(200.0 + 95.0, 170.0 + 295));
		imgui.doImage(GEN_ID, Vector2(250.0, 440.0), "gfx/pfeil_links.bmp");

		// Right arrowkey
		imgui.doOverlay(GEN_ID, Vector2(200.0 + 5.0 + 100.0, 170.0 + 100.0 + 5.0), Vector2(200.0 + 95.0 + 100.0, 170.0 + 295));
		imgui.doImage(GEN_ID, Vector2(350.0, 440.0), "gfx/pfeil_rechts.bmp");
	}

	imgui.doOverlay(GEN_ID, Vector2(200.0 + 5.0 + 250.0, 170.0 + 100.0 + 5.0), Vector2(200.0 + 95.0 + 300.0, 170.0 + 295));
	imgui.doImage(GEN_ID, Vector2(525.0, 440.0), "gfx/pfeil_oben.bmp");


	if (imgui.doButton(GEN_ID, Vector2(224.0, 530.0), TextManager::LBL_OK))
	{
		save();
		switchState(new OptionState());
	}
	if (imgui.doButton(GEN_ID, Vector2(424.0, 530.0), TextManager::LBL_CANCEL))
	{
		switchState(new OptionState());
	}
}
示例#6
0
static int renewIP()
{
	setTimer(0);	/* 取消定时器 */
	printf(_(">> 正在获取IP...\n"));
	system(dhcpScript);
	printf(_(">> 操作结束。\n"));
	dhcpMode += 3; /* 标记为已获取,123变为456,5不需再认证*/
	if (fillHeader() == -1)
		exit(EXIT_FAILURE);
	if (dhcpMode == 5)
		return switchState(ID_ECHO);
	return switchState(ID_START);
}
示例#7
0
int main(int argc, char *argv[])
{
    QCoreApplication::setOrganizationName("SRFGames");
    QCoreApplication::setOrganizationDomain("sol-online.org"),
    QCoreApplication::setApplicationName("ShareYourClipboard");

#ifdef Q_OS_MAC
    QDir dir(argv[0]);
    dir.cdUp();
    QString currentDir = dir.absolutePath();
    dir.cdUp();
    dir.cd("PlugIns");
    QCoreApplication::setLibraryPaths(QStringList(dir.absolutePath()));
#endif

    QApplication a(argc, argv);
    QApplication::setQuitOnLastWindowClosed(false);

#ifdef Q_OS_MAC
    QDir::setCurrent(currentDir);
#endif

    qDebug() << "init manager\n";
    cClipboardManager manager(a.clipboard());

    qDebug() << "init tray icon\n";
    cTrayIcon trIcon(&manager);
    QObject::connect(&trIcon, SIGNAL(switchState()), &manager, SLOT(switchState()));
    QObject::connect(&trIcon, SIGNAL(pasteFiles()), &manager, SLOT(pasteFiles()));
    QObject::connect(&manager, SIGNAL(onStateChanged(cClipboardManager::eClipboardState)), &trIcon, SLOT(setState(cClipboardManager::eClipboardState)));

    qDebug() << "init settings window\n";
    SettingsWindow settingsWindow(&manager);
    QObject::connect(&trIcon, SIGNAL(showSettings()), &settingsWindow, SLOT(showNormal()));
    QObject::connect(&settingsWindow, SIGNAL(preferencesChange()), &manager, SLOT(onPreferencesChanged()));

    qDebug() << "init copy dialog\n";
    CopyProgressDialog copydialog;
    QObject::connect(&manager, SIGNAL(onStartCopyProcess(QString)), &copydialog, SLOT(start(QString)));
    QObject::connect(&manager, SIGNAL(onStopCopyProcess()), &copydialog, SLOT(stop()));
    QObject::connect(&manager, SIGNAL(showMessage(QString)), &copydialog, SLOT(showMessage(QString)));
    QObject::connect(&manager, SIGNAL(onSetProgressMain(QString,int,int)), &copydialog, SLOT(setProgressMain(QString,int,int)));
    QObject::connect(&manager, SIGNAL(onSetProgressSecond(QString,int,int)), &copydialog, SLOT(setProgressSecond(QString,int,int)));
    QObject::connect(&copydialog, SIGNAL(cancel()), &manager, SLOT(cancelDownloading()));

    qDebug() << "start app loop\n";
    int result = a.exec();
    qDebug() << "application close\n";
    return result;
}
示例#8
0
文件: jeti.cpp 项目: 4408/opentx
void telemetryInterrupt10ms()
{
  if (jetiReady) {
    jetiKeys = JETI_KEY_NOCHANGE;
    if (switchState((EnumKeys)(KEY_UP))) jetiKeys &= JETI_KEY_UP;
    if (switchState((EnumKeys)(KEY_DOWN))) jetiKeys &= JETI_KEY_DOWN;
    if (switchState((EnumKeys)(KEY_LEFT))) jetiKeys &= JETI_KEY_LEFT;
    if (switchState((EnumKeys)(KEY_RIGHT))) jetiKeys &= JETI_KEY_RIGHT;

    jetiReady = 0;    // invalidate buffer

    JETI_EnableTXD();
  }
}
示例#9
0
static ekU32 fileLines(struct ekContext *E, ekU32 argCount)
{
    ekValue *thisValue;
    ekValue *ret = ekValueNullPtr;
    ekValue *lineValue;
    ekValue *chompValue = NULL;
    ekBool chomp = ekFalse;
    ekFile *file;

    if(!ekContextGetArgs(E, argCount, "*F|?", &thisValue, &chompValue))
    {
        return ekContextArgsFailure(E, argCount, "file.lines([optional bool] chompNewline)");
    }

    file = (ekFile *)thisValue->ptrVal;
    if(chompValue)
    {
        chompValue = ekValueToBool(E, chompValue);
        chomp = chompValue->boolVal;
        ekValueRemoveRefNote(E, chompValue, "chompValue temporary no longer needed");
    }

    switchState(E, file, EFS_READ);

    ret = ekValueCreateArray(E);
    while((lineValue = readLineInternal(E, file, chomp)) != ekValueNullPtr)
    {
        ekValueArrayPush(E, ret, lineValue);
    }

    ekValueRemoveRefNote(E, thisValue, "lines no longer needs thisValue");
    ekContextReturn(E, ret); // will be the data if we succesfully read
}
示例#10
0
void cTrayIcon::onTray(QSystemTrayIcon::ActivationReason reason)
{
#ifndef Q_OS_MAC
    if (reason==QSystemTrayIcon::Trigger)
        emit switchState();
#endif
}
示例#11
0
 void getHit() {
     currState->hit();
     auto x = dynamic_cast<InvincMarioState*>(currState);
     if (x) { return; }
     //if not invincible, convert to short mario
     switchState(new ShortMarioState());
 }
示例#12
0
 void getStarMan() {
     //better way would be to use a transition table
     auto x = dynamic_cast<InvincMarioState*>(currState);
     if (!x) {
         switchState(new InvincMarioState());
     }
 }
示例#13
0
static int sendEchoPacket()
{
	if (startMode%3 == 2)	/* 赛尔 */
	{
		*(u_int16_t *)(sendPacket+0x0E) = htons(0x0106);
		*(u_int16_t *)(sendPacket+0x10) = 0;
		memset(sendPacket+0x12, 0xa5, 42);
		switchState(ID_WAITECHO);	/* 继续等待 */
		return pcap_sendpacket(hPcap, sendPacket, 60);
	}
	if (sendCount == 0)
	{
		u_char echo[] =
		{
			0x00,0x1E,0xFF,0xFF,0x37,0x77,0x7F,0x9F,0xFF,0xFF,0xD9,0x13,0xFF,0xFF,0x37,0x77,
			0x7F,0x9F,0xFF,0xFF,0xF7,0x2B,0xFF,0xFF,0x37,0x77,0x7F,0x3F,0xFF
		};
		printf(_(">> 发送心跳包以保持在线...\n"));
		fillEtherAddr(0x888E01BF);
		memcpy(sendPacket+0x10, echo, sizeof(echo));
		setTimer(echoInterval);
	}
	fillEchoPacket(sendPacket);
	return pcap_sendpacket(hPcap, sendPacket, 0x2D);
}
示例#14
0
static ekU32 fileWrite(struct ekContext *E, ekU32 argCount)
{
    ekValue *thisValue;
    ekValue *ret = ekValueNullPtr;
    ekValue *dataValue = NULL;
    ekFile *file;

    if(!ekContextGetArgs(E, argCount, "*Fs", &thisValue, &dataValue))
    {
        return ekContextArgsFailure(E, argCount, "file.write([string] data)");
    }

    file = (ekFile *)thisValue->ptrVal;

    if((file->state != EFS_WRITE) && (file->state != EFS_APPEND))
    {
        switchState(E, file, EFS_WRITE);
    }
    if(file->handle)
    {
        const char *data = ekValueSafeStr(dataValue);
        int len = strlen(data);
        int bytesWritten = fwrite(data, 1, len, file->handle);
        if(bytesWritten == len)
        {
            ret = ekValueCreateInt(E, 1);
        }
    }
    ekValueRemoveRefNote(E, thisValue, "fileWrite no longer needs thisValue");
    ekContextReturn(E, ret); // will be true if we successfully wrote
}
示例#15
0
ImapSession::~ImapSession() {
    switchState(ImapSessionState::EXIT);
    if (service_)
        delete service_;
    if (socket_)
        delete socket_;
}
示例#16
0
文件: dodge.cpp 项目: TurpIF/EUSDAB
 void Dodge::onAnimationEnd()
 {
     State::onAnimationEnd();
     Movement newMvt(_mvt);
     newMvt.setAction(Movement::Shield);
     switchState(newMvt & ~Movement::Up & ~Movement::Down);
 }
 void message(const NetMessage* msg)
 {
     T new_state = current->message(msg);
     if ( new_state != state )
     {
         switchState(new_state);
     }
 }
示例#18
0
文件: sstvrx.cpp 项目: cureton/qsstv
void sstvRx::eraseImage()
{
  switchState(RESTART);
  while(SSTVState!=HUNTING)
    {
      QApplication::processEvents();
    }
}
void QgsAddRemoveMultiFrameCommand::undo()
{
  if ( checkFirstRun() )
  {
    return;
  }
  switchState();
}
 void process()
 {
     T new_state = current->process();
     if ( new_state != state )
     {
         switchState(new_state);
     }
 }
示例#21
0
文件: crouch.cpp 项目: TurpIF/EUSDAB
 void Crouch::onRight(const Event & e)
 {
     State::onRight(e);
     if (e.edge == Event::RisingEdge)
     {
         switchState(Movement::Crouch | Movement::Right);
         setNextStateAnimationFrameToCurrentFrame();
     }
 }
示例#22
0
ImapSession::ImapSession(service::Service *service, net::SocketSingle *socket)
        : state_(ImapSessionState::START), service_(service), socket_(socket),
          onExitCallback_(nullptr) {
    if (service_ == nullptr)
        throw invalid_argument("ImapSession::ImapSession: service is nullptr");
    if (socket_ == nullptr)
        throw invalid_argument("ImapSession::ImapSession: socket is nullptr");
    switchState(ImapSessionState::CONNECTED);
}
示例#23
0
文件: main.cpp 项目: fjanssen/Car2X
int main()
{
	MemController<CarState> ctrl = MemController<CarState>();

	CarState state;

	//initial state:
	state = ctrl.getLastElement();
	memset(&state,0,sizeof(state));

	ctrl.pushElement(state);


	while(1)
	{
		for(int i=0;i<5000;i++){;}
		int nios;

		// get the lastest car state from the shared memory
		state = ctrl.getLastElement(true);

		// print some diagnostics information
		int speed = state.motorEcus[0].iCurrentSpeed + state.motorEcus[1].iCurrentSpeed + state.motorEcus[2].iCurrentSpeed + state.motorEcus[3].iCurrentSpeed;

		LOG_DEBUG("\rSpeed: %+5d mm/s, OpMode: %#x ", speed, state.currMode);
		//LOG_DEBUG("yippee!");

		// perform state switch if requested.
		if(state.reqMode != state.currMode)
		{
			switchState(&state);
		}
		state.counterCarControl=state.counterComm;

		setMotorSpeeds(&state);

		if(state.currMode==OPMODE_MANUDRIVE){
			state.ip1=state.reqip1;
			state.ip2=state.reqip2;
			state.ip3=state.reqip3;
			state.ip4=state.reqip4;
		}
		else{
			state.ip1=VCIPPart1;
			state.ip2=VCIPPart2;
			state.ip3=VCIPPart3;
			state.ip4=VCIPPart4;
		}
		ctrl.pushElement(state);

		// TODO: write a delay function w/ timer. Otherwise we might run into problems blocking the mutex from all the shared memory reads...
		//delay(10);
		for (int i = 0; i < 10000; i++) {;}
	}

	return -1;
}
示例#24
0
文件: run.cpp 项目: tcantenot/EUSDAB
 void Run::onLeft(const Event & e)
 {
     State::onLeft(e);
     if (e.edge == Event::RisingEdge)
     {
         if (_mvt.flag() & Movement::Right)
         {
             switchState(Movement::Walk | Movement::Left);
         }
         else if (_mvt.flag() & Movement::Left)
         {
             switchState(Movement::Run | Movement::Left);
         }
     }
     else if (e.edge == Event::FallingEdge)
     {
         switchState(Movement::Idle | Movement::Left);
     }
 }
示例#25
0
文件: crouch.cpp 项目: TurpIF/EUSDAB
        void Crouch::onDown(const Event & e)
        {
            State::onDown(e);

            if (e.edge == Event::FallingEdge)
            {
                switchState(Movement::Stand | _mvt.direction());
            }

        }
示例#26
0
void KscreenEffect::prePaintScreen(ScreenPrePaintData &data, int time)
{
    if (m_state == StateFadingIn || m_state == StateFadingOut) {
        m_timeLine.setCurrentTime(m_timeLine.currentTime() + time);
        if (m_timeLine.currentValue() >= 1.0) {
            switchState();
        }
    }
    effects->prePaintScreen(data, time);
}
示例#27
0
void QgsAddRemoveItemCommand::redo()
{
  QUndoCommand::redo(); // call redo() on all children
  if ( mFirstRun )
  {
    mFirstRun = false;
    return;
  }
  switchState();
}
示例#28
0
void QgsAddRemoveItemCommand::undo()
{
  QUndoCommand::undo(); // call undo() on all children, in reverse order
  if ( mFirstRun )
  {
    mFirstRun = false;
    return;
  }
  switchState();
}
示例#29
0
static void fileFuncClear(struct ekContext *E, struct ekValue *p)
{
    ekFile *file = (ekFile *)p->ptrVal;
    if(!file->permanent)
    {
        switchState(E, file, EFS_CLOSED);
    }
    ekValueRemoveRefNote(E, file->filename, "file doesnt need filename anymore");
    ekFree(file);
}
示例#30
0
static ekU32 fileRead(struct ekContext *E, ekU32 argCount)
{
    ekValue *thisValue;
    ekValue *ret = ekValueNullPtr;
    ekValue *bytesValue = NULL;
    int bytes = 0;
    ekFile *file;

    if(!ekContextGetArgs(E, argCount, "*F|i", &thisValue, &bytesValue))
    {
        return ekContextArgsFailure(E, argCount, "file.read([optional int] bytes)");
    }

    file = (ekFile *)thisValue->ptrVal;

    switchState(E, file, EFS_READ);

    if(file->handle)
    {
        if(bytesValue)
        {
            bytesValue = ekValueToInt(E, bytesValue);
            bytes = bytesValue->intVal;
            ekValueRemoveRefNote(E, bytesValue, "bytesValue temporary no longer needed");
        }
        else
        {
            // we want "the rest" of the file (could be the whole thing if you just opened it)
            int end;
            int currentPos = ftell(file->handle);
            fseek(file->handle, 0, SEEK_END);
            end = ftell(file->handle);
            fseek(file->handle, currentPos, SEEK_SET);
            bytes = end - currentPos;
        }

        if(bytes > 0)
        {
            char *data = ekAlloc(bytes+1);
            int bytesRead = fread(data, 1, bytes, file->handle);
            if(bytesRead >= 0)
            {
                data[bytesRead] = 0;
                ret = ekValueDonateString(E, data);
            }
            else
            {
                ekFree(data);
            }
        }
    }

    ekValueRemoveRefNote(E, thisValue, "fileRead no longer needs thisValue");
    ekContextReturn(E, ret); // will be the data if we succesfully read
}