Ejemplo n.º 1
0
/*!
 * \brief Print the list of files in the specified SimplePost instance.
 *
 * \param[in] args Arguments passed to this program
 *
 * \return true if all files being served by the specified instance were
 * enumerated successfully, false if not
 */
static bool __list_files(const simplearg_t args)
{
	simplepost_file_t files; // List of files being served by the server
	ssize_t count;           // Number of files being served
	char count_buf[1024];    // COUNT string of the file being served
	size_t failures = 0;     // Number of files we failed to print

	count = simplecmd_get_files(args->pid, &files);
	if(count < 0)
	{
		impact(0, "%s: Failed to get the list of files being served by the %s instance with PID %d\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
			args->pid);
		return false;
	}

	for(simplepost_file_t p = files; p; p = p->next)
	{
		if(simplestr_count_to_str(count_buf, sizeof(count_buf)/sizeof(count_buf[0]), p->count) == 0)
		{
			impact(0, "%s: Failed to convert the %s COUNT to a string\n",
				SP_MAIN_HEADER_NAMESPACE,
				p->file);
			++failures;
			continue;
		}

		printf("[PID %d] Serving %s on %s %s\n",
			args->pid, p->file, p->url, count_buf);
	}

	simplepost_file_free(files);

	return (failures == 0);
}
Ejemplo n.º 2
0
/*!
 * \brief Cleanly shut down the specified SimplePost instance.
 *
 * \param[in] args Arguments passed to this program
 *
 * \return true if the instance was shut down successfully, false if not
 */
static bool __shutdown_inst(const simplearg_t args)
{
	const unsigned short max_sleep = 5; // Maximum number of seconds to wait for the other instance to terminate
	const unsigned short sleep_res = 1; // Number of seconds to wait between checks for the other instance
	unsigned short sleep_count = 0;     // Number of seconds that we have waited for the other instance

	impact(1, "%s: Shutting down the %s instance with PID %d ...\n",
		SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
		args->pid);

	if(kill(args->pid, SIGTERM) == -1)
	{
		impact(0, "%s: Failed to kill the %s instance with PID %d: %s\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
			args->pid, strerror(errno));
		return false;
	}

	while(sleep_count < max_sleep)
	{
		sleep(sleep_res);
		if(kill(args->pid, 0) == -1 && errno == ESRCH) break;
		sleep_count += sleep_res;
	}

	if(sleep_count >= max_sleep)
	{
		impact(0, "%s: %s %d did not shut down after %hu seconds!\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
			args->pid, sleep_count);
		return false;
	}

	return true;
}
Ejemplo n.º 3
0
/*!
 * \brief Safely handle SIGPIPE by completely resetting the command server.
 *
 * \note This function effectively takes the nuclear option to handling
 * command communication errors. Maybe the Chernobyl kind of nuclear (initiate
 * damage control and start over), not Hiroshima (permanently wipe out
 * everything in sight), but it is definitely *not* subtle.
 *
 * \param[in] sig Signal to handle
 */
static void __server_reset_pipe(int sig)
{
	// Unused parameters
	(void) sig;

	if(cmdd)
	{
		impact(0, "%s: LOCAL SOCKET COMMUNICATION ERROR!\n",
			SP_MAIN_HEADER_NAMESPACE);

		impact(2, "%s: Attempting to restart command server ...\n",
			SP_MAIN_HEADER_NAMESPACE);
		simplecmd_free(cmdd);
		cmdd = simplecmd_init();

		if(cmdd)
		{
			impact(2, "%s: Command server restarted\n",
				SP_MAIN_HEADER_NAMESPACE);
		}
		else
		{
			impact(2, "%s: Failed to restart command server\n",
				SP_MAIN_HEADER_NAMESPACE);
		}
	}
	else
	{
		impact(0, "%s: Highly improbable! Received SIGPIPE with no active local sockets!\n",
			SP_MAIN_HEADER_NAMESPACE);
	}
}
Ejemplo n.º 4
0
/*!
 * \brief Process a request accepted by the server.
 *
 * \param[in] p SimplePost command + client socket wrapper
 *
 * \return NULL
 */
static void* __process_request(void* p)
{
	struct simplecmd_request* scrp = (struct simplecmd_request*) p; // Properly cast SimplePost command request handle

	simplecmd_t scp = scrp->scp;  // SimplePost command instance to act on
	int sock = scrp->client_sock; // Socket the client connected on

	free(scrp);
	scrp = p = NULL;

	char* command; // Command to process
	size_t length; // Length of the command string
	bool response; // Command handler return value

	++(scp->client_count);

	length = __sock_recv(sock, NULL, &command);
	if(command == NULL || length == 0) goto error;
	response = -1;

	for(unsigned int i = SP_COMMAND_MIN; i <= SP_COMMAND_MAX; ++i)
	{
		if(strcmp(command, __command_handlers[i].request) == 0)
		{
			impact(2, "%s: Request 0x%lx: Responding to %s command\n",
				SP_COMMAND_HEADER_NAMESPACE, pthread_self(),
				__command_handlers[i].request);
			response = (*__command_handlers[i].handler)(scp, sock);
			break;
		}
	}

	#ifdef DEBUG
	if(response)
	{
		impact(2, "%s: Request 0x%lx: Successfully processed %s command\n",
			SP_COMMAND_HEADER_NAMESPACE, pthread_self(),
			command);
	}
	else
	{
		impact(2, "%s: Request 0x%lx: Failed to process %s command\n",
			SP_COMMAND_HEADER_NAMESPACE, pthread_self(),
			command);
	}
	#endif // DEBUG

error:
	impact(4, "%s: Request 0x%lx: Closing client %d\n",
		SP_COMMAND_HEADER_NAMESPACE, pthread_self(),
		sock);
	close(sock);

	if(command) free(command);
	--(scp->client_count);

	return NULL;
}
Ejemplo n.º 5
0
/*!
 * \brief Print the list of accessible SimplePost instances.
 *
 * \return true if all instances were enumerated successfully, false if not
 */
static bool __list_inst()
{
	simplecmd_list_t sclp; // List of SimplePost Command instances
	char* address;         // Address of the server
	unsigned short port;   // Port the server is listening on
	char* version;         // Server's version
	size_t failures = 0;   // Number of instances that we failed to query

	simplecmd_list_inst(&sclp);
	for(simplecmd_list_t p = sclp; p; p = p->next)
	{
		if(simplecmd_get_version(p->inst_pid, &version) == 0)
		{
			impact(0, "%s: Failed to get the version of the %s instance with PID %d\n",
				SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
				p->inst_pid);
			++failures;
			continue;
		}

		if(simplecmd_get_address(p->inst_pid, &address) == 0)
		{
			impact(0, "%s: Failed to get the address of the %s instance with PID %d\n",
				SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
				p->inst_pid);
			++failures;
			free(version);
			continue;
		}

		port = simplecmd_get_port(p->inst_pid);
		if(port == 0)
		{
			impact(0, "%s: Failed to get the port of the %s instance with PID %d\n",
				SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
				p->inst_pid);
			++failures;
			free(address);
			free(version);
			continue;
		}

		printf("[PID %d] %s %s serving files on %s:%hu\n",
			p->inst_pid,
			SP_MAIN_DESCRIPTION, version,
			address, port);
		free(address);
		free(version);
	}
	simplecmd_list_free(sclp);

	return (failures == 0);
}
Ejemplo n.º 6
0
/*!
 * \brief Get the port the specified server is listening on.
 *
 * \param[in] server_pid Process identifier of the server to query
 *
 * \return the server's port number
 */
unsigned short simplecmd_get_port(pid_t server_pid)
{
	int sock;            // Socket descriptor
	unsigned short port; // Port the specified server is listening on
	char* buffer;        // Port as a string (directly from the server)

	sock = __open_sock_by_pid(server_pid);
	if(sock < 0) return 0;

	__sock_recv(sock, __command_handlers[SP_COMMAND_GET_PORT].request, &buffer);
	if(buffer)
	{
		if(sscanf(buffer, "%hu", &port) != 1)
		{
			impact(0, "%s: %s: %s is not a port number\n",
				SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR,
				buffer);
			port = 0;
		}
		free(buffer);
	}
	else
	{
		port = 0;
	}

	close(sock);

	return port;
}
Ejemplo n.º 7
0
/*
* CG_Fire_SpiralPattern
*/
static void CG_Fire_SpiralPattern( vec3_t start, vec3_t dir, int *seed, int ignore, int count, int spread, int range, void ( *impact )(trace_t *tr) )
{
	int i;
	float r;
	float u;
	trace_t trace, *water_trace;

	assert( seed );

	for( i = 0; i < count; i++ )
	{
		r = cos( *seed + i ) * spread * i;
		u = sin( *seed + i ) * spread * i;

		water_trace = GS_TraceBullet( &trace, start, dir, r, u, range, ignore, 0 );
		if( water_trace )
		{
			trace_t *tr = water_trace;
			if( !VectorCompare( tr->endpos, start ) )
				CG_LeadWaterSplash( tr );
		}

		if( trace.ent != -1 && !( trace.surfFlags & SURF_NOIMPACT ) )
			impact( &trace );

		if( water_trace )
			CG_LeadBubbleTrail( &trace, water_trace->endpos );
	}
}
Ejemplo n.º 8
0
/*!
 * \brief Open a socket to the server with the specified process identifier.
 *
 * \note This functions prints error messages so its consumers don't have to.
 *
 * \param[in] server_pid Process identifier of the server
 *
 * \return an open socket descriptor if the specified PID belongs to a
 * compatible SimplePost server with an open local socket, -1 if POSIX open()
 * encounters an error, or -2 if this function encounters an error
 */
static int __open_sock_by_pid(pid_t server_pid)
{
	int sock;                     // Socket descriptor
	struct sockaddr_un sock_addr; // Address to assign to the socket
	char sock_name[512];          // Name of the socket
	struct stat sock_status;      // Status of the socket

	sprintf(sock_name, "%s/%s_sock_%d", SP_COMMAND_SOCK_DIR, SP_MAIN_SHORT_NAME, server_pid);
	if(stat(sock_name, &sock_status) == -1)
	{
		impact(0, "%s: Socket %s does not exist\n",
			SP_COMMAND_HEADER_NAMESPACE,
			sock_name);
		return -2;
	}
	if(S_ISSOCK(sock_status.st_mode) == 0)
	{
		impact(0, "%s: %s is not a socket\n",
			SP_COMMAND_HEADER_NAMESPACE,
			sock_name);
		return -2;
	}

	sock = socket(AF_UNIX, SOCK_STREAM, 0);
	if(sock == -1)
	{
		impact(0, "%s: Failed to open socket %s\n",
			SP_COMMAND_HEADER_NAMESPACE,
			sock_name);
		return -1;
	}

	memset(&sock_addr, 0, sizeof(struct sockaddr_un));
	sock_addr.sun_family = AF_UNIX;
	strncpy(sock_addr.sun_path, sock_name, sizeof(sock_addr.sun_path) - 1);

	if(connect(sock, (struct sockaddr*) &sock_addr, sizeof(sock_addr)) == -1)
	{
		impact(0, "%s: Failed to connect to socket %s\n",
			SP_COMMAND_HEADER_NAMESPACE,
			sock_name);
		close(sock);
		return -1;
	}

	return sock;
}
Ejemplo n.º 9
0
/*!
 * \brief Add a file to the specified server.
 *
 * \param[in] server_pid Process identifier of the server to act on
 * \param[in] file       Name and path of the file to serve
 * \param[in] uri        URI of the file to serve
 * \param[in] count      Number of times the file should be served
 *
 * \return true if the file was successfully added to the server, false if
 * something went wrong (and the file was not added to the server)
 */
bool simplecmd_set_file(
	pid_t server_pid,
	const char* file,
	const char* uri,
	unsigned int count)
{
	int sock;         // Socket descriptor
	char buffer[512]; // Count as a string

	sock = __open_sock_by_pid(server_pid);
	if(sock < 0) return false;

	__sock_send(sock, __command_handlers[SP_COMMAND_SET_FILE].request, NULL);

	if(file)
	{
		impact(3, "%s: %s: Sending %s %s\n",
			SP_COMMAND_HEADER_NAMESPACE, __func__,
			SP_COMMAND_FILE_FILE, file);
		__sock_send(sock, SP_COMMAND_FILE_FILE, file);
	}

	if(count)
	{
		sprintf(buffer, "%u", count);

		impact(3, "%s: %s: Sending %s %s\n",
			SP_COMMAND_HEADER_NAMESPACE, __func__,
			SP_COMMAND_FILE_COUNT, buffer);
		__sock_send(sock, SP_COMMAND_FILE_COUNT, buffer);
	}

	if(uri)
	{
		impact(3, "%s: %s: Sending %s %s\n",
			SP_COMMAND_HEADER_NAMESPACE, __func__,
			SP_COMMAND_FILE_URI, uri);
		__sock_send(sock, SP_COMMAND_FILE_URI, uri);
	}

	close(sock);

	return true;
}
Ejemplo n.º 10
0
/*!
 * \brief Stop accepting client commands.
 *
 * \param[in] scp Instance to act on
 *
 * \retval true the command server has been successfully killed
 * \retval false the command server is not running or could not be shut down
 */
bool simplecmd_deactivate(simplecmd_t scp)
{
	if(scp->sock == -1)
	{
		impact(0, "%s: Server is not active\n", SP_COMMAND_HEADER_NAMESPACE);
		return false;
	}

	impact(1, "%s: Shutting down ...\n", SP_COMMAND_HEADER_NAMESPACE);

	scp->accpeting_clients = false;
	pthread_join(scp->accept_thread, NULL);

	#ifdef DEBUG
	impact(2, "%s: 0x%tu cleanup complete\n",
		SP_COMMAND_HEADER_NAMESPACE, scp->accept_thread);
	#endif // DEBUG

	return true;
}
Ejemplo n.º 11
0
/*!
 * \brief Do we have a valid PID to a SimplePost instance?
 *
 * \param[in] args Arguments passed to this program
 *
 * \return true if the PID is valid, false if not
 *
 * \note This function should always be called after __resolve_pid()!
 */
static bool __is_pid_valid(const simplearg_t args)
{
	if(args->pid == 0)
	{
		if(args->address && args->port)
		{
			impact(0, "%s: There is no %s instance bound to ADDRESS %s listening on PORT %hu\n",
				SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
				args->address, args->port);
		}
		else if(args->address)
		{
			impact(0, "%s: There is no %s instance bound to ADDRESS %s\n",
				SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
				args->address);
		}
		else if(args->port)
		{
			impact(0, "%s: There is no %s instance listening on PORT %hu\n",
				SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
				args->port);
		}
		else
		{
			impact(0, "%s: There are no other accessible %s instances\n",
				SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION);
		}
		return false;
	}
	else if(args->options & SA_OPT_NEW)
	{
		impact(0, "%s: No %s PID may be given with the '--new' option\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION);
		return false;
	}

	return true;
}
Ejemplo n.º 12
0
void CtcUnion::contract(IntervalVector& box) {
	IntervalVector savebox(box);
	IntervalVector result(IntervalVector::empty(box.size()));
	BitSet flags(BitSet::empty(Ctc::NB_OUTPUT_FLAGS));
	BitSet impact(BitSet::all(nb_var)); // always set to "all" for the moment (to be improved later)

	for (int i=0; i<list.size(); i++) {
		if (i>0) box=savebox;

		flags.clear();
		list[i].contract(box,impact,flags);
		result |= box;

		if (flags[INACTIVE]) { set_flag(INACTIVE); break; }
	}

	box = result;
} // end namespace ibex
Ejemplo n.º 13
0
std::pair<int, float>
calculate_impact (aabb<vector> body, vector motion,
                  const collision_aabb& block)
{
    vector impact (0, 0, 0);

    auto sa_int (sa_intersection(body, block));
    if (!sa_intersects(sa_int))
        return { -1, 0.0f };

    int shortest_axis (-1);
    float shortest (std::numeric_limits<float>::max());
    float shortest_impact (0);

    for (int axis (0); axis < 3; ++axis)
    {
        auto d (motion[axis]);
        if (d == 0)
            continue;

        // Pick the direction along this axis opposite to the motion
        int dir (axis * 2 + (motion[axis] > 0 ? 1 : 0));
        int mask (1 << dir);

        // If there's no face exposed on this side, there's no collision
        // either.
        if ((block.open_sides & mask) == 0)
            continue;

        auto axis_impact ((d < 0 ? sa_int.first : sa_int.second)[axis]);
        auto dist (axis_impact / d);

        assert(dist > 0);
        if (dist > 0 && dist < shortest)
        {
            shortest_axis = axis;
            shortest = dist;
            shortest_impact = axis_impact;
        }
    }

    return std::make_pair(shortest_axis, -shortest_impact);
}
Ejemplo n.º 14
0
/*!
 * \brief Free the given SimplePost command instance.
 *
 * \param[in] scp Instance to act on
 */
void simplecmd_free(simplecmd_t scp)
{
	if(scp == NULL) return;

	if(scp->accpeting_clients) simplecmd_deactivate(scp);

	if(scp->sock != -1)
	{
		impact(2, "%s:%d: BUG! %s should have (directly or indirectly) closed the socket already!\n",
			__FILE__, __LINE__, __func__);
		close(scp->sock);
	}

	if(scp->sock_name)
	{
		remove(scp->sock_name);
		free(scp->sock_name);
	}
}
Ejemplo n.º 15
0
/*
* CG_FireBullet
*/
static void CG_FireBullet( int self, vec3_t start, vec3_t forward, int count, int spread, int seed, void ( *impact )(trace_t *tr /*, int impactnum*/) )
{
	int i;
	trace_t tr;
	vec3_t dir, axis[3];
	qboolean takedamage;

	// calculate normal vectors
	VecToAngles( forward, dir );
	AngleVectors( dir, axis[0], axis[1], axis[2] );

	for( i = 0; i < count; i++ )
	{
		CG_FireLead( self, start, axis, spread, spread, &seed, &tr );
		takedamage = tr.ent && ( cg_entities[tr.ent].current.effects & EF_TAKEDAMAGE );

		if( tr.fraction < 1.0f && !takedamage && !( tr.surfFlags & SURF_NOIMPACT ) )
			impact( &tr );
	}
}
Ejemplo n.º 16
0
void Particle :: collisionEvent(std::shared_ptr<Object>& object)
{
    if(object->solid())
    {
        IOwnable* owned;
        if((owned = dynamic_cast<IOwnable*>(object.get())))
            if(owner() && owned->owner() && owned->owner() != owner()) // diff owner?
            {

                std::string impact_fn;
                if(properties().getStringValue("events", "impact", impact_fn)
                        && Filesystem::hasExtension(impact_fn, "ini")) // make sure event is not a script
                {
                    std::shared_ptr<Object> impact(new Particle(impact_fn));
                    impact->pos(pos() + size()/2.0f - impact->size()/2.0f);
                    world()->add(impact);
                }
                invalidate();
            }
    }
}
Ejemplo n.º 17
0
void CtcCompo::contract(IntervalVector& box) {

	// TODO: wrong algorithm here
//	if (incremental) {
//		for (int i=0; i<list.size(); i++) {
//			IntervalVector old_box(box);
//			impacts[i] |= impact;
//
//			list[i].contract(box);
//
//			for (int j=0; j<nb_var; j++) {
//				if (old_box[j].rel_distance(box[j])>ratio)
//					for (int i2=0; i2<list.size(); i2++)
//						if (i2!=i) impacts[i2].set(j);
//			}
//		}
//		return;
//	}
	bool inactive= true;
	BitSet flags(BitSet::empty(Ctc::NB_OUTPUT_FLAGS));

	BitSet impact(BitSet::all(nb_var)); // always set to "all" for the moment (to be improved later)

	for (int i=0; i<list.size(); i++) {
		if (inactive) {
			flags.clear();
			list[i].contract(box,impact,flags);
			if (!flags[INACTIVE]) inactive=false;
		} else {
			list[i].contract(box);
		}

		if (box.is_empty()) {
			set_flag(FIXPOINT);
			return;
		}
	}

	if (inactive) set_flag(INACTIVE);
}
Ejemplo n.º 18
0
/*!
 * \brief Add the files to our SimplePost instance and start the HTTP server.
 *
 * \param[in] args Arguments passed to this program
 *
 * \return true if the HTTP server was started successfully, false if not
 */
static bool __start_httpd(const simplearg_t args)
{
	httpd = simplepost_init();
	if(httpd == NULL)
	{
		impact(2, "%s: %s: Failed to allocate memory for %s HTTP server instance\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC,
			SP_MAIN_DESCRIPTION);
		return false;
	}

	if(simplepost_bind(httpd, args->address, args->port) == 0) return false;
	for(simplefile_t p = args->files; p; p = p->next)
	{
		char* url; // URL of the file being served

		if(simplepost_serve_file(httpd, &url, p->file, p->uri, p->count) == 0) return false;
		free(url);
	}

	return true;
}
Ejemplo n.º 19
0
/*!
 * \brief Resolve the PID of the SimplePost instance to connect to.
 *
 * \param[inout] args Arguments passed to this program
 *
 * \return true if the PID was resolved successfully, false if not
 *
 * \note This function will return false only if no SimplePost instance exists
 * with the given PID or if the stated arguments are invalid (or contradictory)
 * and no PID can be resolved. Use the return value as a sanity check before
 * attempting to use the PID. Although the various simplecmd methods WILL
 * catch the error and return properly if an invalid PID is given, it should
 * never get that far. This method's error messages are far more user-friendly.
 *
 * \note Just because this function returns true does not necessarily mean
 * that there is a PID, even if one was set from the command line. If the
 * "--new" argument was given, this function will clear the PID if one was set
 * and return true.
 */
static bool __resolve_pid(simplearg_t args)
{
	if(args->options & SA_OPT_NEW)
	{
		args->pid = 0;
	}
	else if(args->pid)
	{
		pid_t pid = simplecmd_find_inst(args->address, args->port, args->pid);
		if(pid == 0)
		{
			impact(0, "%s: Found no %s command instance with PID %d\n",
				SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid);
			return false;
		}
	}
	else
	{
		args->pid = simplecmd_find_inst(args->address, args->port, args->pid);
	}

	return true;
}
Ejemplo n.º 20
0
bool			collision(t_circle circle, t_rectangle brick[NB_BRICK])
{
  int			i;
  t_bunny_position	pos;

  i = 0;
  while (i < NB_BRICK)
    {
      pos.y = brick[i].pos.y;
      while (pos.y < (brick[i].pos.y + brick[i].height))
	{
	  pos.x = brick[i].pos.x;
	  while (pos.x < (brick[i].pos.x + brick[i].width))
	    {
	      if (impact(pos, circle) == true)
		return (true);
	      pos.x++;
	    }
	  pos.y++;
	}
      i++;
    }
  return (false);
}
Ejemplo n.º 21
0
/*!
 * \brief Add new files to be served to another SimplePost instance.
 *
 * \param[in] args Arguments passed to this program
 *
 * \return true if all files were added to the specified instance successfully,
 * false if not
 */
static bool __add_to_other_inst(const simplearg_t args)
{
	char* address;       // Destination server's address
	unsigned short port; // Destination server's port
	char buf[2048];      // String describing the file to add to the server
	size_t failures = 0; // The number of files we failed to add to the server

	impact(2, "%s: Trying to connect to the %s instance with PID %d ...\n",
		SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
		args->pid);

	if(simplecmd_get_address(args->pid, &address) == 0)
	{
		impact(0, "%s: Failed to get the ADDRESS of the %s instance with PID %d\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
			args->pid);
		return false;
	}

	port = simplecmd_get_port(args->pid);
	if(port == 0)
	{
		impact(0, "%s: Failed to get the PORT of the %s instance with PID %d\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
			args->pid);
		free(address);
		return false;
	}

	#ifdef DEBUG
	char* version; // Destination server's version

	if(simplecmd_get_version(args->pid, &version) == 0)
	{
		impact(0, "%s: Failed to get the version of the %s instance with PID %d\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
			args->pid);
		free(address);
		return false;
	}

	impact(2, "%s: Serving FILESs on the %s %s instance with PID %d\n",
		SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION,
		version, args->pid);

	free(version);
	#endif // DEBUG

	for(simplefile_t p = args->files; p; p = p->next)
	{
		if(simplecmd_set_file(args->pid, p->file, p->uri, p->count) == false)
		{
			impact(0, "%s: Failed to add FILE %s to the %s instance with PID %d\n",
				SP_MAIN_HEADER_NAMESPACE,
				p->file, SP_MAIN_DESCRIPTION, args->pid);
			++failures;
		}
		else
		{
			if(simplestr_get_serving_str(buf, sizeof(buf)/sizeof(buf[0]),
				p->file, address, port, p->uri, p->count) == 0)
			{
				impact(0, "%s: Failed to construct the description string for %s\n",
					SP_MAIN_HEADER_NAMESPACE,
					p->file);
				++failures;
				continue;
			}

			impact(1, "[PID %d] %s\n", args->pid, buf);
		}
	}

	free(address);

	return (failures == 0);
}
Ejemplo n.º 22
0
/*!
 * \brief Send the list of files that we are serving to the client.
 *
 * \param[in] scp  Instance to act on
 * \param[in] sock Client socket
 *
 * \retval true the requested information was sent successfully
 * \retval false failed to respond to the request
 */
static bool __command_send_files(simplecmd_t scp, int sock)
{
	char buffer[30];         // File count or index as a string
	simplepost_file_t files; // List of files being served
	size_t count;            // Number of files being served
	size_t i = 0;            // Index of the current file being sent

	count = simplepost_get_files(scp->spp, &files);

	impact(3, "%s: %s: Sending list of %zu files\n",
		SP_COMMAND_HEADER_NAMESPACE,
		__func__, count);
	if(sprintf(buffer, "%zu", count) <= 0)
	{
		simplepost_file_free(files);
		return false;
	}
	__sock_send(sock, NULL, buffer);

	for(simplepost_file_t p = files; p; p = p->next)
	{
		impact(3, "%s: %s: Sending %s %zu\n",
			SP_COMMAND_HEADER_NAMESPACE, __func__,
			SP_COMMAND_FILE_INDEX, i);
		if(sprintf(buffer, "%zu", i++) <= 0)
		{
			simplepost_file_free(files);
			return false;
		}
		__sock_send(sock, SP_COMMAND_FILE_INDEX, buffer);

		if(p->file)
		{
			impact(3, "%s: %s: Sending %s %s\n",
				SP_COMMAND_HEADER_NAMESPACE, __func__,
				SP_COMMAND_FILE_FILE, p->file);
			__sock_send(sock, SP_COMMAND_FILE_FILE, p->file);
		}

		if(p->count)
		{
			if(sprintf(buffer, "%u", p->count) <= 0)
			{
				impact(0, "%s: %s: Failed to buffer %s %u\n",
					SP_COMMAND_HEADER_NAMESPACE, __func__,
					SP_COMMAND_FILE_COUNT, p->count);
				simplepost_file_free(files);
				return false;
			}

			impact(3, "%s: %s: Sending %s %s\n",
				SP_COMMAND_HEADER_NAMESPACE, __func__,
				SP_COMMAND_FILE_COUNT, buffer);
			__sock_send(sock, SP_COMMAND_FILE_COUNT, buffer);
		}

		/* Always send the URL last. The reason for this is that only the FILE
		 * and URL fields and required per-file. All others are optional.
		 * Therefore to make sure that the optional fields are not skipped on
		 * the client side, always send a required field last.
		 */
		if(p->url)
		{
			impact(3, "%s: %s: Sending %s %s\n",
				SP_COMMAND_HEADER_NAMESPACE, __func__,
				SP_COMMAND_FILE_URL, p->url);
			__sock_send(sock, SP_COMMAND_FILE_URL, p->url);
		}
	}

	simplepost_file_free(files);

	return true;
}
Ejemplo n.º 23
0
void KeyboardCharacterMover::move(sf::RenderWindow &window, Character &character, Collisions &collisions, TilesMap &tilesMap, Camera &camera, Background &background, sf::Time elapsedTime)
{
// Check if we`re flying
    m_testRect = character.m_characterRect;
    m_testRect.top++;
    m_result = collisions.collidedY(m_testRect, character.m_digPower, tilesMap, m_blockPos);
    if(m_result == Collisions::NoCollision)
        m_flying = true;
    else
        m_flying = false;

// If a direction is true, add or delete 13 to the velocity (x or y) to be able to move in that direction
    if(m_north)
        character.m_velocityY -= 13.0f;

    if(m_south)
        character.m_velocityY += 3.0f; // Only add 3 if m_south is true (because we'll add the gravity

    if(m_east)
        character.m_velocityX += 13.0f;

    if(m_west)
        character.m_velocityX -= 13.0f;

// Add gravity (only if we're flying)
    if(m_flying)
        m_physic.addGravity(character.m_velocityY);

// If east or west are false et their velocity is not equal to 0
    if(!m_east && character.m_velocityX > 0)
    {
        character.m_velocityX = character.m_velocityX*97/100; // Reduce the velocity
            if(character.m_velocityX <= 15) // If the velocity is less than 15 set the velocity to 0
                character.m_velocityX = 0;
    }

    if(!m_west && character.m_velocityX < 0)
    {
        character.m_velocityX = character.m_velocityX*97/100; // Reduce the velocity
            if(character.m_velocityX >= -15) // If the velocity is more than -15, set the velocity to 0
                character.m_velocityX = 0;
    }

// Check if the velocity are higher than the max
    if(character.m_velocityX > character.m_maxVelocity)
        character.m_velocityX = character.m_maxVelocity;

    if(character.m_velocityX < -character.m_maxVelocity)
        character.m_velocityX = -character.m_maxVelocity;

    if(character.m_velocityY < -character.m_maxVelocity)
        character.m_velocityY = -character.m_maxVelocity;

    if(character.m_velocityY > 2000)
        character.m_velocityY = 2000;

// Check for collisions, if everything is ok: move the character. Else, check if we can dig
    m_testRect = character.m_characterRect;

    // Collisions in x axis
        m_testRect.left += elapsedTime.asSeconds()* character.m_velocityX; // Add x movement
        m_result = collisions.collidedX(m_testRect, character.m_digPower, tilesMap, m_blockPos); // Test

        // If there're no collision
            if(m_result == Collisions::NoCollision)
            {
                character.m_characterRect.left = m_testRect.left; // Move the character position
                camera.moveX(character.m_characterRect, tilesMap.getWorldSize()); // Move the camera position
            }
        // If we can dig
            else if(m_result == Collisions::Diggable)
            {
                // Only dig if we are not flying and if the the key is pressed
                    if(m_blockPos.x < character.m_characterRect.left && m_west && !m_flying)
                    {
                        dig(window, character, tilesMap, camera, background, m_blockPos, KeyboardCharacterMover::WEST);
                        return;
                    }
                    if(m_blockPos.x > character.m_characterRect.left && m_east && !m_flying)
                    {
                        dig(window, character, tilesMap, camera, background, m_blockPos, KeyboardCharacterMover::EAST);
                        return;
                    }
            }
            else
            {
                character.m_velocityX = 0;
            }

    // Collisions in y axis
        m_testRect.left = character.m_characterRect.left; // Because we don't care about the movement in x axis
        m_testRect.top += elapsedTime.asSeconds()* character.m_velocityY; // Add y movement
        m_result = collisions.collidedY(m_testRect, character.m_digPower, tilesMap, m_blockPos); // Test

        // If there's no collision
            if(m_result == Collisions::NoCollision)
            {
                character.m_characterRect.top = m_testRect.top; // Move the character position
                camera.moveY(character.m_characterRect, tilesMap.getWorldSize()); // Move the camera position
            }

        // If we can dig
            else if(m_result == Collisions::Diggable)
            {
                // Only dig if the the key is pressed, the block is under the character and the velocity in Y isn't too high
                    if(m_blockPos.y > character.m_characterRect.top && m_south && character.m_velocityY <= 500)
                    {
                        m_flying = false;
                        dig(window, character, tilesMap, camera, background, m_blockPos, KeyboardCharacterMover::SOUTH);
                    }

                    else if(m_blockPos.y > character.m_characterRect.top)
                    {
                        impact(character);
                    }
                    else
                    {
                        character.m_velocityY = 0;
                    }
            }

        // If we collided but we can't dig
            else if(m_result == Collisions::BlockCollision && m_blockPos.y > character.m_characterRect.top)
            {
                impact(character);
            }

        // If we collided with the top or the end of the world (in which case we need to lose life)
            else if(m_result == Collisions::Collision)
            {
                if(!impact(character))
                    character.m_velocityY = 0;
            }

            else
            {
                // Set the velocity to 0 if we hit
                    character.m_velocityY = 0;
            }

// Set the image of the character
    if(character.m_velocityX > 0)
    {
        if(m_flying)
            character.setCharacterTexture("flyRight.png");
        else
            character.setCharacterTexture("vehiculeRight.png");

        if(!ServiceLocator::GetAudio()->isSoundPlaying("normal.ogg") && !m_flying)
        {
            ServiceLocator::GetAudio()->stopSounds();
            ServiceLocator::GetAudio()->playSound("normal.ogg", 60, true);
        }
        else if(!ServiceLocator::GetAudio()->isSoundPlaying("fly.ogg") && m_flying)
        {
            ServiceLocator::GetAudio()->stopSounds();
            ServiceLocator::GetAudio()->playSound("fly.ogg", 60, true);
        }
    }

    else if(character.m_velocityX < 0)
    {
        if(m_flying)
            character.setCharacterTexture("flyLeft.png");
        else
            character.setCharacterTexture("vehiculeLeft.png");

        if(!ServiceLocator::GetAudio()->isSoundPlaying("normal.ogg") && !m_flying)
        {
            ServiceLocator::GetAudio()->stopSounds();
            ServiceLocator::GetAudio()->playSound("normal.ogg", 60, true);
        }
        else if(!ServiceLocator::GetAudio()->isSoundPlaying("fly.ogg") && m_flying)
        {
            ServiceLocator::GetAudio()->stopSounds();
            ServiceLocator::GetAudio()->playSound("fly.ogg", 60, true);
        }
    }

    else if(character.m_velocityX == 0 && m_flying)
    {
        if(character.m_characterTextureName == "vehiculeLeft.png")
            character.setCharacterTexture("flyLeft.png");
        else if(character.m_characterTextureName == "vehiculeRight.png")
            character.setCharacterTexture("flyRight.png");

        if(!ServiceLocator::GetAudio()->isSoundPlaying("fly.ogg"))
        {
            ServiceLocator::GetAudio()->stopSounds();
            ServiceLocator::GetAudio()->playSound("fly.ogg", 60, true);
        }
    }

    else if(character.m_velocityX == 0 && !m_flying)
    {
        if(character.m_characterTextureName == "flyLeft.png")
            character.setCharacterTexture("vehiculeLeft.png");
        else if(character.m_characterTextureName == "flyRight.png")
            character.setCharacterTexture("vehiculeRight.png");

        if(!ServiceLocator::GetAudio()->isSoundPlaying("normal.ogg"))
        {
            ServiceLocator::GetAudio()->stopSounds();
            ServiceLocator::GetAudio()->playSound("normal.ogg", 60, true);
        }
    }
}
Ejemplo n.º 24
0
void GS_TraceLaserBeam( trace_t *trace, vec3_t origin, vec3_t angles, float range, int ignore, int timeDelta, void ( *impact )( trace_t *tr, vec3_t dir ) )
{
	vec3_t from, dir, end;
	int mask = MASK_SHOT;
	int passthrough = ignore;
	entity_state_t *hit;
	vec3_t mins = { -0.5, -0.5, -0.5 };
	vec3_t maxs = { 0.5, 0.5, 0.5 };
	int hits[MAX_BEAM_HIT_ENTITIES];
	int j, numhits;

	assert( trace );

	AngleVectors( angles, dir, NULL, NULL );
	VectorCopy( origin, from );
	VectorMA( origin, range, dir, end );

	trace->ent = 0;

	numhits = 0;
	while( trace->ent != -1 )
	{
		module_Trace( trace, from, mins, maxs, end, passthrough, mask, timeDelta );
		if( trace->ent != -1 )
		{
			// prevent endless loops by checking whether we have already impacted this entity
			for( j = 0; j < numhits; j++ )
			{
				if( trace->ent == hits[j] )
					break;
			}
			if( j < numhits )
				break;

			// callback impact
			if( impact )
				impact( trace, dir );

			// check for pass-through
			hit = module_GetEntityState( trace->ent, timeDelta );
			if( trace->ent == 0 || !hit || hit->solid == SOLID_BMODEL ) // can't pass through brush models
				break;

			// if trapped inside solid, just forget about it
			if( trace->fraction == 0 || trace->allsolid || trace->startsolid )
				break;

			// put a limit on number of hit entities
			if( numhits < MAX_BEAM_HIT_ENTITIES )
				hits[numhits++] = trace->ent;
			else
				break;

			passthrough = trace->ent;
			VectorCopy( trace->endpos, from );
		}
	}

	if( trace->ent != -1 ) // was interrupted by a brush model impact
	{
	}
}
Ejemplo n.º 25
0
/*!
 * \brief Start accepting requests from clients.
 *
 * \param[in] p Instance to act on
 *
 * \return NULL
 */
static void* __accept_requests(void* p)
{
	simplecmd_t scp = (simplecmd_t) p; // Properly cast SimplePost command handle

	int client_sock;                // Socket the client connected on
	struct sockaddr_in client_name; // Name of the client
	socklen_t client_name_len;      // Length of the client name structure
	pthread_t client_thread;        // Handle of the client thread

	struct timespec timeout; // Maximum time to wait for a connection before checking the shutdown sentinel
	fd_set fds;              // File descriptor set (for pselect() socket monitoring)

	scp->client_count = 0;
	scp->accpeting_clients = true;

	while(scp->accpeting_clients)
	{
		FD_ZERO(&fds);
		FD_SET(scp->sock, &fds);

		timeout.tv_sec = 2;
		timeout.tv_nsec = 0;

		switch(pselect(scp->sock + 1, &fds, NULL, NULL, &timeout, NULL))
		{
			case -1:
				impact(0, "%s: Cannot accept connections on socket %d\n",
					SP_COMMAND_HEADER_NAMESPACE,
					scp->sock);
				scp->accpeting_clients = false;
				continue;

			case 0:
				continue;
		}

		client_name_len = sizeof(client_name);
		client_sock = accept(scp->sock, (struct sockaddr*) &client_name, &client_name_len);
		if(client_sock == -1) continue;

		struct simplecmd_request* scrp = (struct simplecmd_request*) malloc(sizeof(struct simplecmd_request));
		if(scrp == NULL)
		{
			impact(0, "%s: %s: Failed to allocate memory for a new command request thread\n",
				SP_COMMAND_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC);
			scp->accpeting_clients = false;
			continue;
		}
		scrp->scp = scp;
		scrp->client_sock = client_sock;

		if(pthread_create(&client_thread, NULL, &__process_request, (void*) scrp) == 0)
		{
			impact(2, "%s: Launched request processing thread 0x%lx for client %d\n",
				SP_COMMAND_HEADER_NAMESPACE,
				client_thread, client_sock);
			pthread_detach(client_thread);
		}
		else
		{
			impact(2, "%s: Failed to launch request processing thread for client %d\n",
				SP_COMMAND_HEADER_NAMESPACE,
				client_sock);
			close(scrp->client_sock);
			free(scrp);
		}
	}

	impact(2, "%s: Waiting for %zu clients to finish processing ...\n",
		SP_COMMAND_HEADER_NAMESPACE,
		scp->client_count);
	while(scp->client_count) usleep(1000);

	impact(4, "%s: Closing socket %d\n",
		SP_COMMAND_HEADER_NAMESPACE,
		scp->sock);
	close(scp->sock);
	scp->sock = -1;
	remove(scp->sock_name);

	return NULL;
}
Ejemplo n.º 26
0
/*!
 * \brief Safely handle SIGINT by cleanly shutting down the server.
 *
 * \warning This function exits the program!
 *
 * \param[in] sig Signal to handle
 */
static void __server_terminal_interrupt(int sig)
{
	impact(1, "\n"); // Terminate the ^C line
	__server_shutdown(sig);
}
Ejemplo n.º 27
0
/*!
 * \brief Initialize the server.
 */
int main(int argc, char* argv[])
{
	simplearg_t args; // SimplePost arguments

	args = simplearg_init();
	if(args == NULL)
	{
		impact(2, "%s: %s: Failed to allocate memory for %s arguments instance\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC,
			SP_MAIN_DESCRIPTION);
		return 0;
	}
	simplearg_parse(args, argc, argv);
	impact_level = args->verbosity;

	if(args->options & SA_OPT_ERROR) return 1;
	if(args->actions)
	{
		if(args->actions & SA_ACT_HELP)
		{
			__print_help();
			goto no_error;
		}
		else if(args->actions & SA_ACT_VERSION)
		{
			__print_version();
			goto no_error;
		}
		else if(args->actions & SA_ACT_LIST_INST)
		{
			if(__list_inst()) goto no_error;
			else goto error;
		}
		else if(args->actions & SA_ACT_LIST_FILES)
		{
			if(__resolve_pid(args) == false) goto error;
			if(__is_pid_valid(args) == false) goto error;
			if(__list_files(args)) goto no_error;
			else goto error;
		}
		else if(args->actions & SA_ACT_SHUTDOWN)
		{
			if(__resolve_pid(args) == false) goto error;
			if(__is_pid_valid(args) == false) goto error;
			if(__shutdown_inst(args) == false) goto error;
			goto no_error;
		}
		else
		{
			impact(0, "%s: BUG! Failed to handle action 0x%02X\n",
				__PRETTY_FUNCTION__, args->actions);
			goto error;
		}
	}

	if(__resolve_pid(args) == false) goto error;

	if(args->pid)
	{
		if(__add_to_other_inst(args)) goto no_error;
		else goto error;
	}

	if(args->options & SA_OPT_DAEMON)
	{
		impact(1, "%s: Daemonizing and forking to the background\n",
			SP_MAIN_HEADER_NAMESPACE);
		if(daemon(1, 0) == -1)
		{
			impact(0, "%s: Failed to daemonize %s: %s\n",
				SP_MAIN_HEADER_NAMESPACE,
				SP_MAIN_DESCRIPTION, strerror(errno));
			goto error;
		}
	}

	if(__start_httpd(args) == false) goto error;

	signal(SIGPIPE, &__server_reset_pipe);
	signal(SIGINT, &__server_terminal_interrupt);
	signal(SIGTSTP, &__server_shutdown);
	signal(SIGQUIT, &__server_shutdown);
	signal(SIGTERM, &__server_shutdown);

	cmdd = simplecmd_init();
	if(cmdd == NULL)
	{
		impact(2, "%s: %s: Failed to allocate memory for %s command server instance\n",
			SP_MAIN_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC,
			SP_MAIN_DESCRIPTION);
		goto error;
	}

	simplecmd_activate(cmdd, httpd);
	simplepost_block_files(httpd);

no_error:
	simplecmd_free(cmdd);
	simplepost_free(httpd);
	simplearg_free(args);
	return 0;

error:
	simplecmd_free(cmdd);
	simplepost_free(httpd);
	simplearg_free(args);
	return 1;
}
Ejemplo n.º 28
0
void GameScene::update()
{
    Q_ASSERT(sender() == findChild<QTimer*>());

    if(m_paused) return;

    GraphicsPlayerObject* player = nullptr;
    QList<AbstractGraphicsPlaneObject*> planes;
    for(auto item : items()) // find planes
    {
        switch(item->type())
        {
        case PlayerType:
            player = qgraphicsitem_cast<GraphicsPlayerObject*>(item);
        case EnemyType:
            planes.append(dynamic_cast<AbstractGraphicsPlaneObject*>(item));
        }
    }
    if(player && !player->isInvencible())
    {
        Q_ASSERT(player == m_player);

        const auto playerRect = player->sceneBoundingRect();
        for(auto plane : planes)
        {
            if(plane != player)
            {
                const auto enemyRect = plane->sceneBoundingRect();
                if (playerRect.intersects(enemyRect))
                    player->impact(std::numeric_limits<qint32>::max());
            }
        }
    }

    for(auto item : items())
    {
        if(item->type() == BulletType || item->type() == EnemyBulletType)
        {
            const auto rect = item->boundingRect().translated(item->pos());
            if(!sceneRect().contains(rect))
                delete item;
            else
            {
                bool impacted = false;
                for(auto it = planes.begin(); it != planes.end() && !impacted;
                    ++it)
                {
                    const auto planeRect = (*it)->sceneBoundingRect();
                    auto plane = qgraphicsitem_cast<
                        AbstractGraphicsPlaneObject*>(*it);
                    const auto status = plane->status();
                    if(status == AbstractGraphicsPlaneObject::Status::Alive
                       && planeRect.contains(rect))
                    {
                        plane->impact(100);
                        impacted = true;
                    }
                }
                if(impacted) delete item;
            }
        }
    }

    if(--m_spawnEnemiesTicks == 0) // Spawn enemies
    {
        if(!(qrand() % 24)) // 1/25
            spawnEnemies(GraphicsEnemyObject::EnemyType::Boss, true);
        else
            spawnEnemies(GraphicsEnemyObject::EnemyType::White, true);
        m_spawnEnemiesTicks = m_spawnEnemiesMaxTicks;
    }
    else if(m_spawnEnemiesTicks == m_spawnEnemiesMaxTicks / 2)
    {
        if(!(qrand() % 24)) // 1/25
            spawnEnemies(GraphicsEnemyObject::EnemyType::Boss, false);
        else
            spawnEnemies(GraphicsEnemyObject::EnemyType::Green, false);
    }

    if(m_respawnTicks && --m_respawnTicks == 0)
        spawnPlayer();

    QGraphicsScene::advance();
}
Ejemplo n.º 29
0
/*!
 * \brief Get a list of all SimplePost instances on the system with open sockets.
 *
 * \note This function has two very important exclusions. (1) First, it will
 * not include the socket created by this SimplePost instance in the resulting
 * list. (2) Second, it will only include sockets that we have read/write
 * access to.
 *
 * \param[out] sclp
 * \parblock
 * List of all open SimplePost sockets (excluding ours)
 *
 * If *sclp != NULL, you are responsible for freeing it.
 * \endparblock
 *
 * \return the number of instances in the list. If zero is returned, either a
 * memory allocation error occurred, or, more likely, there are no other
 * instances of SimplePost currently active
 */
size_t simplecmd_list_inst(simplecmd_list_t* sclp)
{
	DIR* dp;                    // Directory handle
	struct dirent* ep;          // Entity in the directory
	char suspect[512];          // Absolute path of the current entity
	int suspect_len;            // Length of the current entity's absolute path
	struct stat suspect_status; // Status of the current entity

	char sock_name[512]; // Name of our socket
	regex_t regex;       // Compiled SimplePost socket matching regular expression

	simplecmd_list_t tail; // Last element in the list
	size_t count = 0;      // Number of items in the list
	tail = *sclp = NULL;   // Failsafe

	dp = opendir(SP_COMMAND_SOCK_DIR);
	if(dp == NULL)
	{
		impact(0, "%s: Failed to open the command socket directory %s: %s\n",
			SP_COMMAND_HEADER_NAMESPACE,
			SP_COMMAND_SOCK_DIR, strerror(errno));
		return 0;
	}

	sprintf(sock_name, "^%s_sock_[0-9]+$", SP_MAIN_SHORT_NAME);
	if(regcomp(&regex, sock_name, REG_EXTENDED | REG_NOSUB | REG_NEWLINE))
	{
		impact(0, "%s: BUG! Failed to compile the socket matching regular expression\n",
			__PRETTY_FUNCTION__);
		closedir(dp);
		return 0;
	}

	sprintf(sock_name, "%s_sock_%d", SP_MAIN_SHORT_NAME, getpid());

	while((ep = readdir(dp)))
	{
		suspect_len = snprintf(suspect, sizeof(suspect), "%s/%s", SP_COMMAND_SOCK_DIR, ep->d_name);
		if(suspect_len < 1 || (size_t) suspect_len >= sizeof(suspect))
		{
			impact(0, "%s: Skipping %s/%s because only %zu of %d bytes are available in the buffer\n",
				SP_COMMAND_HEADER_NAMESPACE,
				SP_COMMAND_SOCK_DIR, ep->d_name,
				sizeof(suspect), suspect_len);
			continue;
		}

		if(stat(suspect, &suspect_status) == 0 && S_ISSOCK(suspect_status.st_mode) && access(suspect, R_OK | W_OK) == 0)
		{
			int regex_ret = regexec(&regex, ep->d_name, 0, NULL, 0);
			if(regex_ret == 0 && strcmp(sock_name, ep->d_name) != 0)
			{
				if(tail)
				{
					tail->next = simplecmd_list_init();
					if(tail->next == NULL)
					{
						impact(0, "%s: %s: Failed to add a new element to the element list\n",
							SP_COMMAND_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC);

						simplecmd_list_free(*sclp);
						*sclp = NULL;
						count = 0;

						break;
					}
					tail->next->prev = tail;
					tail = tail->next;
				}
				else
				{
					tail = *sclp = simplecmd_list_init();
					if(tail == NULL)
					{
						impact(0, "%s:%d: Failed to initialize the list\n",
							__FILE__, __LINE__);
						break;
					}
				}
				count++;

				tail->sock_name = (char*) malloc(sizeof(char) * (strlen(suspect) + 1));
				if(tail->sock_name == NULL)
				{
					impact(2, "%s: %s: Failed to allocate memory for socket name\n",
						SP_COMMAND_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC);

					simplecmd_list_free(*sclp);
					*sclp = NULL;
					count = 0;

					break;
				}
				strcpy(tail->sock_name, suspect);

				const char* pid_ptr = suspect;
				while(isdigit(*pid_ptr) == 0) ++pid_ptr;
				sscanf(pid_ptr, "%d", &tail->inst_pid);

				impact(4, "%s: Found %s:%d socket %s\n",
					SP_COMMAND_HEADER_NAMESPACE,
						SP_MAIN_DESCRIPTION, tail->inst_pid,
						tail->sock_name);
			}
			else if(regex_ret != REG_NOMATCH)
			{
				char buffer[1024]; // regerror() error message

				regerror(regex_ret, &regex, buffer, sizeof(buffer)/sizeof(buffer[0]));
				impact(0, "%s: %s\n", SP_COMMAND_HEADER_NAMESPACE, buffer);

				if(*sclp)
				{
					simplecmd_list_free(*sclp);
					*sclp = NULL;
					count = 0;
				}

				break;
			}
		}
	}

	regfree(&regex);
	closedir(dp);

	return count;
}
Ejemplo n.º 30
0
/*!
 * \brief Receive a file and count from the client and add it our web server.
 *
 * \param[in] scp  Instance to act on
 * \param[in] sock Client socket
 *
 * \retval true the requested information was sent successfully
 * \retval false failed to respond to the request
 */
static bool __command_recv_file(simplecmd_t scp, int sock)
{
	char* url = NULL;    // URL of the file being served
	char* file = NULL;   // Name and path of the file to serve
	char* uri = NULL;    // URI of the file to serve
	char* buffer = NULL; // Count or identifier string from the client
	unsigned int count;  // Number of times the file should be served

	while(__sock_recv(sock, NULL, &buffer))
	{
		if(buffer == NULL) goto error;

		impact(3, "%s: %s: Receiving %s\n",
			SP_COMMAND_HEADER_NAMESPACE, __func__,
			buffer);

		if(strcmp(buffer, SP_COMMAND_FILE_FILE) == 0)
		{
			free(buffer);
			buffer = NULL;

			if(file)
			{
				impact(0, "%s: %s: Received a second FILE\n",
					SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR);
				goto error;
			}
			else if(__sock_recv(sock, NULL, &file) == 0)
			{
				impact(0, "%s: %s: Did not receive a FILE as expected\n",
					SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR);
				goto error;
			}
		}
		else if(strcmp(buffer, SP_COMMAND_FILE_URI) == 0)
		{
			free(buffer);
			buffer = NULL;

			if(uri)
			{
				impact(0, "%s: %s: Received a second URI\n",
					SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR);
				goto error;
			}
			else if(__sock_recv(sock, NULL, &uri) == 0)
			{
				impact(0, "%s: %s: Did not receive a URI as expected\n",
					SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR);
				goto error;
			}
		}
		else if(strcmp(buffer, SP_COMMAND_FILE_COUNT) == 0)
		{
			free(buffer);
			buffer = NULL;

			if(__sock_recv(sock, NULL, &buffer) == 0)
			{
				impact(0, "%s: %s: Did not receive the COUNT as expected\n",
					SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR);
				goto error;
			}

			if(sscanf(buffer, "%u", &count) == EOF)
			{
				impact(0, "%s: %s: %s is not a valid COUNT\n",
					SP_COMMAND_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC,
					buffer);
				goto error;
			}

			free(buffer);
			buffer = NULL;
		}
		else
		{
			impact(3, "%s: %s: Invalid file identifier \"%s\"\n",
				SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR,
				buffer);
			goto error;
		}
	}

	if(file == NULL)
	{
		impact(0, "%s: %s: Did not receive a FILE to serve\n",
			SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR);
		goto error;
	}

	if(simplepost_serve_file(scp->spp, &url, file, uri, count) == 0) return false;

	free(buffer);
	free(uri);
	free(file);
	free(url);
	return true;

error:
	free(buffer);
	free(uri);
	free(file);
	free(url);
	return false;
}