Пример #1
0
int main(int argc, char **argv) {
    char *cmd;
    char **args;

    printf("------Welcome to Shelldon------\n");
    printf("use \"help\" to see list of available features\n");

    while(1) {
        printf("%s=> ",getlogin());
        cmd = readCmd();
        args = splitCmd(cmd);

        if(args[0]!=NULL&&!runCmd(args)) //need to skip if blank command
            break;

        //printf("%s\n%s\n%s\n",args[0],args[1],args[2]);
        free(cmd);
        free(args);
    }

    free(cmd);
    free(args);

    return 0;
}
Пример #2
0
int ExtComm::commandReceived(Command *cmd)
{
  if (_sd >= 0) {
    struct timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 100;
    fd_set tmp_fds;
    memcpy(&tmp_fds, &_fds, sizeof(_fds));
    int result = select(_max_sd + 1, &tmp_fds, NULL, NULL, &timeout);
    //someone is ready
    if (result >= 0) {
      int waiting = result;
      for (int i=0; i <= _max_sd && waiting > 0; ++i) {
        //check each one
        if (FD_ISSET(i, &tmp_fds)) {
          waiting--;
          //if it is not the listening socket, read from it
          if (i != _sd) {
            //an existing connection became readable
            if (readHeader(i)) {
              unsigned char buffer[6] = {0};
              if (readCmd(i, buffer, sizeof(buffer))) {
                //don't read more than one command, and let them pile up in the network buffer if there is too much
                cmd->parse(buffer);
                Log::log("valid command\n");
                return 1;
              } else Log::log("invalid command\n");
            }
          }
        }
      }
    }
  }
  return 0;
}
Пример #3
0
int pmdOptions::init(int argc, char **argv)
{
	int rc = EDB_OK;
	
	po::options_description all("Command options");
	po::variables_map vm;
	po::variables_map vm2;
	
	PMD_ADD_PARAM_OPTIONS_BEGIN(all)
		PMD_COMMANDS_OPTIONS
	PMD_ADD_PARAM_OPTIONS_END
	
	rc = readCmd(ragc, argv, all, vm);
	if(rc)
	{
		PD_LOG(PDERROR, "Failed to read cmd, rc=%d", rc);
		goto error;
	}
	
	//check if we have help options
	if(vm.count(PMD_OPTION_HELP))
	{
		std::cout<<all<<std::endl;
		
		rc = EDB__PMD_HELP_ONLY;
		goto done;
	}
	
	//check if there's conf path
	if(vm.count(PMD_OPTION_CONFPATH))
	{
		rc = readConfigureFile(vm[PMD_OPTION_CONFPATH].as<string>().c_str(), all, vm2);
	}
	if(rc)
	{
		PD_LOG(PDERROR, "Unexpected error when reading conf file, rc = %d", rc);
		goto error;
	}
	
	//load vm from file
	rc = importVM(vm2);
	if(rc)
	{
		PD_LOG(PDERROR, "Failed to import from vm2, rc = %d", rc);
		goto error;
	}
	
	//load vm from command line
	rc = importVM(vm);
	if(rc)
	{
		PD_LOG(PDERROR, "Failed to import from vm, rc = %d", rc);
		goto error;
	}

done:
	return rc;
error:
	goto done;
}
void ACC_GYRO_GY80::readGyroData(float buff[]) {
  byte buffer[6];
  readCmd(L3G4_ADDRESS, READALLSIX, 6, buffer);
  buff[0] = (float)( (((buffer[1] << 8) | buffer[0]) - L3G4_Offset[0]) * SCALE_2000);
  buff[1] = (float)( (((buffer[3] << 8) | buffer[2]) - L3G4_Offset[1]) * SCALE_2000);
  buff[2] = (float)( (((buffer[5] << 8) | buffer[4]) - L3G4_Offset[2]) * SCALE_2000);
}
void ACC_GYRO_GY80::readAccData(float buff[]) {
  byte buffer[6];
  readCmd(ADXL_ADDRESS, DATAX0, 6, buffer);
  buff[0] = (((buffer[1] << 8) | buffer[0]) * ADXL_Gain[0]  + ADXL_Offset[0]);
  buff[1] = (((buffer[3] << 8) | buffer[2]) * ADXL_Gain[1]  + ADXL_Offset[1]);
  buff[2] = (((buffer[5] << 8) | buffer[4]) * ADXL_Gain[2]  + ADXL_Offset[2]);
}
Пример #6
0
void MPULib::getMagData(int buff[]){
byte buffer[6];
readCmd(HMC_addr,HMC_X_MSB,6,buffer);
buff[0]=(buffer[0]<<8) | buffer[1];
buff[2]=(buffer[2]<<8) | buffer[3];
buff[1]=(buffer[4]<<8) | buffer[5];
}
Пример #7
0
void MPULib::getGyroData(float *gyro_x, float *gyro_y, float *gyro_z){
byte buffer[6];
readCmd(L3G4_addr,READALLSIX,6,buffer);
*gyro_x = (float)((int)(buffer[1]<<8) | buffer[0])*SCALE_2000;
*gyro_y = (float)-1*((int)(buffer[3]<<8) | buffer[2])*SCALE_2000;
*gyro_z = (float)((int)(buffer[5]<<8) | buffer[4])*SCALE_2000;
}
Пример #8
0
int main(void) {
char s[1000];
countVar=0;
countAlias=0;
getcwd(currentPath,100);

system("clear");
while(1)
{
	printf("> ");
	init();
	readCmd();
	checkVariable();
	if(strcmp("unalias",tokens[cmds[0].args[0]])!=0)
		checkAlias();
	
	checkWildcard();

	replaceHomePath();
 
	if(buildInCmd())
        continue;
    exeNormalCmd();

}
return 0;
}
Пример #9
0
void MPULib::getAxlData(int16_t *axl_x, int16_t *axl_y, int16_t *axl_z){
byte buffer[6];
readCmd(ADXL_addr,DATAX0,6,buffer);
*axl_y=(buffer[1]<<8) | buffer[0];
*axl_x=(buffer[3]<<8) | buffer[2];
*axl_z=(buffer[5]<<8) | buffer[4];

}
void ACC_GYRO_GY80::sumGyroSamples() {
  byte buffer[6];
  readCmd(L3G4_ADDRESS, READALLSIX, 6, buffer);
  gyroSamplesArray[0] += (float)((buffer[1] << 8) | buffer[0]);
  gyroSamplesArray[1] += (float)((buffer[3] << 8) | buffer[2]);
  gyroSamplesArray[2] += (float)((buffer[5] << 8) | buffer[4]);
  gyroSamplesCounter++;
}
Пример #11
0
	bool readCmdGroup() {
		readWhitespace();
		while (!reader.empty()) {
			if (!readCmd()) {
				return false;
			}
		}
		return true;
	}
Пример #12
0
int runCommands(heap *hp, bool print)
{
	CmdFunc *commands = createCmdMap();
	if(print)
		printmenu();
	for(int i = 0;; i++) {
		if(print)
			printf(">> ");
		char cmd = readCmd();
		if(commands[(int)cmd])
			commands[(int)cmd](hp, print);
	}
	free(commands);
}
Пример #13
0
int DebugConsole::exec()
{
    MyDevice mydev;

    if (!devUsbOpen(mydev))
		return 1;


    MyDeviceProto mydevproto(mydev);

	printHelp();
	bool go = true;
	while (go)
	{
		QStringList params;
		CmdType ct = readCmd(params);
		if (ct == ctUnknown)
		{
			qout << "ERROR: Unknown command" << endl;
		}
		else if (ct == ctHelp)
		{
			printHelp();
		}
		else if (ct == ctExit)
		{
			go = false;
		}
		else
		{
            CmdError ce = runCmd(mydevproto, ct, params);
			if (ce == ceParams)
			{
				qout << "ERROR: Incorrect parameters" << endl;
			}
			else if (ce == ceRun)
			{
				qout << "ERROR: Can't run the command! The device may be unplugged..." << endl;
			}
		}
	}


    devUsbClose(mydev);

	return 0;
}
Пример #14
0
/**
 * Load _cmdList from Hugo.dat
 */
void Parser::loadCmdList(Common::ReadStream &in) {
	cmd tmpCmd;
	memset(&tmpCmd, 0, sizeof(tmpCmd));
	for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
		uint16 numElem = in.readUint16BE();
		if (varnt == _vm->_gameVariant) {
			_cmdListSize = numElem;
			_cmdList = (cmd **)malloc(sizeof(cmd *) * _cmdListSize);
		}

		for (int16 i = 0; i < numElem; i++) {
			uint16 numSubElem = in.readUint16BE();
			if (varnt == _vm->_gameVariant)
				_cmdList[i] = (cmd *)malloc(sizeof(cmd) * numSubElem);
			for (int16 j = 0; j < numSubElem; j++)
				readCmd(in, (varnt == _vm->_gameVariant) ? _cmdList[i][j] : tmpCmd);
		}
	}
}
Пример #15
0
// interprets the user command;
// try to find the username in the database,
// forces the next command to be PASS
void user(char **params, short *abor, int fd,
	struct state *cstate, struct config *configuration) {
	if (params[0] == NULL) {
		respond(fd, 5, 0, 4, "Require username.");
		return;
	}
	switch (lookupUser(configuration->user_db, params[0], NULL, 0)) {
		// some error occured while reading the database
		case -1:
			respond(fd, 4, 5, 1, "Internal server error.");
			return;
		break;
		// user exists
		case 0:
			respond(fd, 3, 3, 1, "OK, awaiting password.");
		break;
		// user does not exist
		case 1:
			respond(fd, 4, 3, 0, "Unknown user.");
			return;
		break;
	}
	// waits for the next command and check if it is PASS
	struct cmd psswd;
	readCmd(fd, &psswd);
	if (strcasecmp(psswd.name, "PASS") != 0) {
		respond(fd, 5, 0, 3, "Bad command sequence.");
		return;
	}
	// sets the username and initial path
	strcpy(cstate->user, params[0]);
	(*cstate->path) = '/';
	(*(cstate->path + 1)) = 0;
	cstate->logged = 0;
	executeCmd(&psswd, NULL, fd, cstate, configuration);
}
Пример #16
0
bool triSurface::readAC(const fileName& ACfileName)
{
    IFstream ACfile(ACfileName);

    if (!ACfile.good())
    {
        FatalErrorIn("triSurface::readAC(const fileName&)")
            << "Cannot read file " << ACfileName
            << exit(FatalError);
    }

    string line;
    ACfile.getLine(line);

    string version = line.substr(4);

    if (version != "b")
    {
        WarningIn("bool triSurface::readAC(const fileName& ACfileName)")
            << "When reading AC3D file " << ACfileName
            << " read header " << line << " with version " << version
            << endl << "Only tested reading with version 'b'."
            << " This might give problems" << endl;
    }

    string cmd;

    string args;

    if (!readUpto("OBJECT", ACfile, args) || (args != "world"))
    {
        FatalErrorIn("bool triSurface::readAC(const fileName& ACfileName)")
            << "Cannot find \"OBJECT world\" in file " << ACfileName
            << exit(FatalError);
    }

    // Number of kids = patches

    readUpto("kids", ACfile, args, "");

    label nPatches = parseInt(args);

    // Storage for patches and unmerged points and faces

    DynamicList<point> points;
    DynamicList<labelledTri> faces;
    geometricSurfacePatchList patches(nPatches);


    // Start of vertices for object/patch
    label patchStartVert = 0;

    for (label patchI = 0; patchI < nPatches; patchI++)
    {
        readUpto("OBJECT", ACfile, args, " while reading patch " + patchI);

        // Object global values
        string patchName = string("patch") + name(patchI);
        label nVerts = 0;
        tensor rot(I);
        vector loc(0, 0, 0);

        // Read all info for current patch
        while (ACfile.good())
        {
            // Read line and get first word. If end of file break since
            // patch should always end with 'kids' command ?not sure.
            if (!readCmd(ACfile, cmd, args))
            {
                FatalErrorIn("triSurface::readAC(const fileName&)")
                    << "Did not read up to \"kids 0\" while reading patch "
                    << patchI << " from file " << ACfileName
                    << exit(FatalError);
            }

            if (cmd == "name")
            {
                IStringStream nameStream(args);

                nameStream >> patchName;
            }
            else if (cmd == "rot")
            {
                // rot %f %f %f  %f %f %f  %f %f %f
                IStringStream lineStream(args);

                lineStream
                    >> rot.xx() >> rot.xy() >> rot.xz()
                    >> rot.yx() >> rot.yy() >> rot.yz()
                    >> rot.zx() >> rot.zy() >> rot.zz();

                WarningIn("triSurface::readAC(const fileName&)")
                    << "rot (rotation tensor) command not implemented"
                    << "Line:" << cmd << ' ' << args << endl
                    << "while reading patch " << patchI << endl;
            }
Пример #17
0
static void app(void)
{
    SOCKET sock = init_connection();
    int actual = 0;
    int max = sock;
    Client clients[MAX_CLIENTS];
    srand(time(NULL));
    /* Initialiser la plateau de jeu de la vie
     * et son plateau d'etats
     */

    plateau* p_vie = jv_newPlat(GAME_SIZE, GAME_SIZE);
    jv_randPlat(p_vie);
    plateau* p_vie_next = jv_newPlat(GAME_SIZE, GAME_SIZE);
    PlateauStatut* p_statuts = jvs_newPlat(GAME_SIZE, GAME_SIZE);
    int fintache = 0;

    aff_init();

    fd_set rdfs;
    while(1)
    {
	int i = 0;
	FD_ZERO(&rdfs);
	FD_SET(STDIN_FILENO, &rdfs);
	FD_SET(sock, &rdfs);
	for(i=0; i<actual; i++)
	{
	    FD_SET(clients[i].sock, &rdfs);
	}

	if(select(max+1, &rdfs, NULL, NULL, NULL) == -1)
	{
	    perror("select()");
	    exit(errno);
	}

	if(FD_ISSET(STDIN_FILENO, &rdfs))
	{
	    /* stop when type on keyboard */
	    break;
	}
	else if(FD_ISSET(sock, &rdfs))
	{
	    /* new client */
	    SOCKADDR_IN csin = { 0 };
	    size_t sinsize = sizeof csin;
	    int csock = accept(sock, (SOCKADDR *)&csin, &sinsize);
	    if(csock == SOCKET_ERROR)
	    {
		perror("accept()");
		continue;
	    }

	    /* Lire la commande startCom */
	    Command cmd;
	    if(readCmd(csock, &cmd) == -1)
	    {
		continue;
	    }
	    if(cmd.type != CMD_START_COMMUNICATION)
	    {
		continue;
	    }
	    
	    if(writeCmd(csock, &cmd) > 0)
	    {
		max = csock > max ? csock : max;

		FD_SET(csock, &rdfs);
		Client c;
		c.sock = csock;
		c.type = 0;
		c.generation = -1;
		c.x = -1;
		c.y = -1;
		c.width = -1;
		c.height = -1;
		clients[actual] = c;
		actual ++;
	    }
	}
	else
	{
	    int i = 0;
	    for(i=0; i<actual; i++)
	    {
		/* Commande d'un client */
		if(FD_ISSET(clients[i].sock, &rdfs))
		{
		    Client client = clients[i];
		    Command cmd;
		    int c = readCmd(clients[i].sock, &cmd);
		    if(c==0)
		    {
			close(clients[i].sock);
			remove_client(clients, i, &actual);
		    }
		    else
		    {
			switch(cmd.type)
			{
			    Command com;
			    /* CLient demande une tache */
			    case CMD_REQUEST_TASK:
			    {	
			    	/* TODO verifier si le process n'est pas déja sur un block non traité ou en traitement */
			    	
				/* sélection aleatoire d'une commande */
				int ctp;
				if (!fintache)
				    ctp = rand() % 100;
				else
				    ctp = 1;

				/* Retirer une tache du sac */
				if (ctp < 80)
				{
				    Block b = jvs_getBlock(p_statuts, BLOCK_SIZE, BLOCK_SIZE);
				    if (b.x == -1)
				    {
					/* erreur, aucun block libre */
					Command att;
					att.type = CMD_NO_TASK;
					att.noTask.waitingTime = 0.5;
					writeCmd(clients[i].sock, &att);
					break;
				    }

				    /* verifier le type de bloc */
				    if (b.t == NORMAL)
				    {
					/* Construction et envoi de la commande */
					char* pack = jv_pack_s(p_vie, b.x, b.y, b.width+2, b.height+2);
					com.type = CMD_TASK;
					com.task.width = b.width+2;
					com.task.height = b.height+2;
					com.task.cells = pack;
					if (writeCmd(clients[i].sock, &com)>0)
					{
					    /* Assigne le block au client */
					    if (jvs_assigne(p_statuts, b.x, b.y, b.width, b.height, clients[i].sock) == -1)
						printf("erreur");
					    clients[i].generation = p_statuts->generation;
					    clients[i].x = b.x; clients[i].y = b.y; clients[i].width = b.width; clients[i].height = b.height;		    	 
					    clients[i].type = CMD_TASK;
					}
					else
					{
					    /* enlever le client */
					    close(clients[i].sock);
					    remove_client(clients, i, &actual);
					}
					free(pack);
				    }
				    else
				    {
					fintache = 1;
					/* construire la commande */
					com.type = CMD_LIST_CELL;
					if (b.t == HEAL) com.listCell.type = CMD_HEAL;
					else com.listCell.type = CMD_VIRUS;
					com.listCell.nb =1;
					com.listCell.list = (coord*)malloc(sizeof(coord));
					com.listCell.list[0].cell = p_vie->grille[b.x][b.y];
					com.listCell.list[0].x = b.x; com.listCell.list[0].y = b.y;
					/* envoyer la cellule */
					if (writeCmd(clients[i].sock, &com)>0)
					{
					    /* Assigner le traitement heal */
					    jvs_assigne_vh(p_statuts, b.x, b.y, clients[i].sock);
					    clients[i].generation = p_statuts->generation;
					    clients[i].x = b.x; clients[i].y = b.y; clients[i].width = b.width; clients[i].height = b.height;
					    if (b.t == HEAL) clients[i].type = CMD_HEAL;
					    else clients[i].type = CMD_VIRUS;
					}
					else
					{
					    /* Enelever le client */
					    close(clients[i].sock);
					    remove_client(clients, i, &actual);
					}
					free(com.listCell.list);
				    }
				}
				/* Générer vie */
				else if (ctp<98)
				{
				    /* Construction commande */
				    com.type = CMD_HEAL;
				    com.heal.width = p_vie->width;
				    com.heal.height = p_vie->height;
				    /* Envoi de la commande */
				    if (writeCmd(clients[i].sock, &com)<=0)
				    {
					/* Enlever le client */
					close(clients[i].sock);
					remove_client(clients, i, &actual);
				    }
				}
				/* Infection virale */
				else
				{
				    /* Construction commande */
				    com.type = CMD_VIRUS;
				    com.virus.width = p_vie->width;
				    com.virus.height = p_vie->height;
				    /* Envoi de la commande */
				    if (writeCmd(clients[i].sock, &com) <=0)
				    {
					/* Enlever client */
					close(clients[i].sock);
					remove_client(clients, i, &actual);
				    }
				}
				break;
			    }

			    /* Client envoi resultat generation */
			    case CMD_TASK:
			    if (p_statuts->generation == clients[i].generation)
			    {
				jv_unpack_s(p_vie_next, cmd.task.cells, clients[i].x, clients[i].y, cmd.task.width, cmd.task.height);
				jvs_termine(p_statuts, clients[i].x, clients[i].y, clients[i].width, clients[i].height);
				//jvs_termine2(p_statuts, clients[i].sock);
			    }	
				break;

			    /* autres types commandes */
			    case CMD_LIST_CELL:
			    {
				type t = VIRUS;
				switch (cmd.listCell.type)
				{
				case CMD_HEAL:
				    t=HEAL;
				case CMD_VIRUS:
				{
				    int k; 
				    for (k = 0; k <cmd.listCell.nb; k++)
				    {
					jvs_set_vh(p_statuts, t, cmd.listCell.list[k].x, cmd.listCell.list[k].y);
				    }
				    break;
				}
				case CMD_TASK:
				{
				    /* Récupérer l'etat de la cellule */
				    int k;
				    for (k=0; k<cmd.listCell.nb; k++)
				    {
					p_vie_next->grille[cmd.listCell.list[k].x][cmd.listCell.list[k].y] = cmd.listCell.list[k].cell;
					p_statuts->grille[cmd.listCell.list[k].x][cmd.listCell.list[k].y].statut = TRAITEE; 
				    }
				    break;
				}
				default:
				    break;
				}
				free(cmd.listCell.list);
			    }
			    default:
				break;
			    
			}
		    }
		    break;
		}
	    }
	}
	
	aff_plateau_s(p_vie, p_statuts);

	/* verifier changement generations */
	if (jvs_nextGen(p_statuts) != -1)
	{
	    p_vie = p_vie_next;
	    fintache = 0;
	}

    }
    clear_clients(clients, actual);
    end_connection(sock);
    aff_end();
}
bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
(
    const fileName& filename
)
{
    const bool mustTriangulate = this->isTri();
    this->clear();

    IFstream is(filename);
    if (!is.good())
    {
        FatalErrorIn
        (
            "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
        )
                << "Cannot read file " << filename
                << exit(FatalError);
    }

    string line, cmd, args;

    is.getLine(line);

    string version = line.substr(4);

    if (version != "b")
    {
        WarningIn
        (
            "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
        )
                << "When reading AC3D file " << filename
                << " read header " << line << " with version "
                << version << endl
                << "Only tested reading with version 'b'."
                << " This might give problems" << endl;
    }


    if (!cueTo(is, "OBJECT", args) || (args != "world"))
    {
        FatalErrorIn
        (
            "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
        )
                << "Cannot find \"OBJECT world\" in file " << filename
                << exit(FatalError);
    }

    // # of kids is the # of zones
    args = cueToOrDie(is, "kids");
    label nZones = parse<int>(args);

    // Start of vertices for object/zones
    label vertexOffset = 0;

    DynamicList<point> dynPoints;
    DynamicList<Face>  dynFaces;
    List<word>         names(nZones);
    List<label>        sizes(nZones, 0);

    for (label zoneI = 0; zoneI < nZones; ++zoneI)
    {
        names[zoneI] = word("zone") + Foam::name(zoneI);

        args = cueToOrDie(is, "OBJECT", "while reading " + names[zoneI]);

        // number of vertices for this zone
        label  nZonePoints = 0;
        vector location(pTraits<vector>::zero);
        // tensor rotation(I);

        // Read all info for current zone
        while (is.good())
        {
            // Read line and get first word. If end of file break since
            // zone should always end with 'kids' command ?not sure.
            if (!readCmd(is, cmd, args))
            {
                FatalErrorIn
                (
                    "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
                )
                        << "Did not read up to \"kids 0\" while reading zone "
                        << zoneI << " from file " << filename
                        << exit(FatalError);
            }

            if (cmd == "name")
            {
                // name %s
                string str = parse<string>(args);
                string::stripInvalid<word>(str);

                names[zoneI] = str;
            }
            else if (cmd == "rot")
            {
                // rot  %f %f %f  %f %f %f  %f %f %f

                // IStringStream lineStream(args);
                //
                // lineStream
                //     >> rotation.xx() >> rotation.xy() >> rotation.xz()
                //     >> rotation.yx() >> rotation.yy() >> rotation.yz()
                //     >> rotation.zx() >> rotation.zy() >> rotation.zz();

                WarningIn
                (
                    "fileFormats::AC3DsurfaceFormat::read"
                    "(const fileName&)"
                )
                        << "rot (rotation tensor) command not implemented"
                        << "Line:" << cmd << ' ' << args << endl
                        << "while reading zone " << zoneI << endl;
            }
            else if (cmd == "loc")
            {
                // loc  %f %f %f
                IStringStream lineStream(args);

                lineStream
                        >> location.x()
                        >> location.y()
                        >> location.z();
            }
            else if (cmd == "numvert")
            {
                // numvert  %d
                nZonePoints = parse<int>(args);

                for (label vertI = 0; vertI < nZonePoints; ++vertI)
                {
                    is.getLine(line);
                    IStringStream lineStream(line);

                    point pt;
                    lineStream
                            >> pt.x() >> pt.y() >> pt.z();

                    // Offset with current translation vector
                    dynPoints.append(location + pt);
                }
            }
Пример #19
0
Файл: core.c Проект: vojtsek/FTP
// function running in separate thread, handling data connection
int controlRoutine(struct control_info *info) {
	int fd = info->fd;
	struct cmd command;
	time_t now = time(NULL);
	struct state cstate = (struct state) { .logged = 0,
		.path = "/",
		.data_port = info->configuration->data_port,
		.transfer_count = 0,
		.data_sock = 0,
		.control_sock = 0,
		.port = 1,
		.last_accepted = 0,
		.addr_family = 1,
		.data_thread = 0,
		.transfer_type = Image,
		.client_addr = *(info->client_addr) };
	snprintf(cstate.dir, 32, "%d", (int)now);
	short abor = 0;
	if (isDir("/control_sockets") == -1)
		if (mkdir("/control_sockets", 0755) == -1) {
			perror("Failed to create control_sockets directory.");
			return (-1);
		}
	// reads commands from the accepted connection and executes it
	while (readCmd(fd, &command) != -1) {
		executeCmd(&command, &abor, fd, &cstate, info->configuration);
		freeCmd(&command);
		if (abor) break;
	}
	if (errno == EINTR)
		return (1);
	return (0);
}

// function running in separate thread, handles data connection
void *dataRoutine(void *arg) {
	struct data_info *info = (struct data_info *) arg;
	int sck;
	struct sockaddr_un sa;
	struct sockaddr_in in;
	bzero(&in, sizeof (in));
	bzero(&sa, sizeof (sa));
	struct state cstate = *(info->cstate);
	strncpy(sa.sun_path, info->control_sock, sizeof (sa.sun_path));
	sa.sun_family = AF_UNIX;

	// tries to create a connection
	// for communicating with the control thread
	if ((sck = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		perror("Error creating control socket.");
		return (arg);
	}
	if (connect(sck, (struct sockaddr *) &sa, sizeof (sa)) == -1) {
		perror("Error connecting to control socket.");
		return (arg);
	}
	struct cmd command;
	cstate.data_sock = 0;
	// reads commands from control thread and executes them
	while (1) {
		// printf("Data socket: %d\n", cstate.data_sock);
		readUntil(command.name, sck, 0, 256);
		if (command.name[0] == 'Q') {
			break;
		}
		executeCmd(&command, NULL, sck, &cstate, info->configuration);
		// projects the changes to the control thread,
		info->cstate->data_sock = cstate.data_sock;
		info->cstate->last_accepted = cstate.last_accepted;
	}
	if (cstate.data_sock) {
		close(cstate.data_sock);
	}
	free(info);
	return (arg);
}