void	       *server_management(void *tmp)
{
  int		rtrn;
  char		buffer[1024];
  int		flag_start;

  (void)tmp;
  flag_start = 0;
  while (42)
    {
      if ((rtrn = read(0, buffer, 1024)) < 0)
	return (NULL);
      buffer[rtrn - 1] = '\0';
      if ((my_strcmp(buffer, "/start") == 0) && (flag_start == 0))
	{
	  if (server_client_count() >= 1)
	    {
	      printf("[*] Raytracer: Clustering: Start of the distribution computing.\n");
	      if ((server_distribution_start()) == EXIT_FAILURE)
		return (NULL);
	      flag_start = 1;
	    }
	  else
	    printf("Raytracer: Clustering: Error: Start not avaible, 0 client.\n");
	}
      else if ((my_strcmp(buffer, "/start") == 0) && (flag_start == 1))
	printf("Raytracer: Clustering: Error: Start not available, already in progress.\n");
      else if (my_strcmp(buffer, "/list") == 0)
	server_client_display(list);
      else if (my_strcmp(buffer, "/quit") == 0)
	server_close(0);
      else
	printf("Raytracer: Clustering: Error: Command unknow.\n");
    }
  return (NULL);
}
Exemple #2
0
int main(int argc, char const * argv[]) {
	const char * config_file;
	int connection_numer = 0, ret, pid;
	short vals[SEM_SIZE] = {1, 1};
	key_t key = ftok("database.sql", KEY_ID);
	key_t key_db = ftok("database.sql", KEY_DB_ID);

	switch(argc) {
		case 1: {
			config_file = CONFIG_FILE_DEFAULT;
		} break;

		case 2: {
			config_file = argv[1];
		} break;

		default: {
			fprintf(stderr, "Usage: 'server.app [config_file]'.\n");
			exit(EXIT_FAILURE);
		}
	}

	pcg32_srandom(time(NULL), (intptr_t)&connection_numer);

	server_sems = sem_make(key, SEM_SIZE, vals);
	if(server_sems == -1) {
		fprintf(stderr, "1 Can't create neccessary data to operate.\n");
		exit(EXIT_FAILURE);
	}

	bettors = mmap(NULL, sizeof(*bettors), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
	if(bettors == MAP_FAILED) {
		fprintf(stderr, "2 Can't create neccessary data to operate.\n");
		exit(EXIT_FAILURE);
	}

	clients = mmap(NULL, sizeof(*clients), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
	if(clients == MAP_FAILED) {
		fprintf(stderr, "3 Can't create neccessary data to operate.\n");
		exit(EXIT_FAILURE);
	}

	winner = mmap(NULL, sizeof(*winner) * MAX_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
	if(winner == MAP_FAILED) {
		fprintf(stderr, "4 Can't create neccessary data to operate.\n");
		exit(EXIT_FAILURE);
	}

	*bettors = 0;
	*clients = 0;
	memset(winner, 0, sizeof(*winner) * MAX_SIZE);

	if(!log_open()) {
		fprintf(stderr, "Can't connect logging server.\n");
		//exit(EXIT_FAILURE);
	}

	database = smemory_open(key_db); // TODO: define 8080
	if(database == NULL) {
		fprintf(stderr, "Can't reach the database.\n");
		exit(EXIT_FAILURE);
	}

	connection = server_open(config_file);
	if(connection == NULL) {
		fprintf(stderr, "Can't create the main connection.\n");
		exit(EXIT_FAILURE);
	}

	signal(SIGINT, handle_int);
	signal(SIGCHLD, handle_int);

	while(TRUE) {
		connection_t connection_accepted;

		connection_accepted = server_accept(connection);
		if(connection_accepted == NULL) {
			log_send(LEVEL_ERROR, "[MAIN SV] Can't connect to client.");
			exit(EXIT_FAILURE); // TODO: Exit?
		}

		connection_numer++;
		(*clients)++;

		pid = fork();
		if(pid == -1) {
			log_send(LEVEL_ERROR, "[MAIN SV] Can't assign resources to client.");
			exit(EXIT_FAILURE); // TODO: Exit?
		}

		if(!pid) { // Child process
			// sem_lock(server_sems, 1);
			// (*clients)++;
			// sem_unlock(server_sems, 1);
			server_ajar(connection);
			log_send(LEVEL_INFO, "[CHILD SV] Disconnecting main connection.");

			ret = handle(connection_accepted);
			if(ret == EXIT_FAILURE) {
				log_send(LEVEL_ERROR, "[CHILD SV] There was an error handling client.");
			}

			server_close(connection_accepted);
			log_send(LEVEL_INFO, "[CHILD SV] Closed client connection.");
			// sem_lock(server_sems, 1);
			// (*clients)--;
			// sem_unlock(server_sems, 1);
			exit(ret);
		}

		log_send(LEVEL_INFO, "[MAIN SV] Disconnecting new connection.");
		server_ajar(connection_accepted);
	}

	server_close(connection);
	if(!db_close(database)) {
		log_send(LEVEL_ERROR, "[MAIN SV] Couldn't correctly logout from database.");
	}
	log_close();
	sem_remove(server_sems);

	return 0;
}
Exemple #3
0
void my_logic_on_close_pt(struct server_s* self, int index)
{
	printf("client %d is closed in logic \n", index);
    free_index(index);
    server_close(server, index);
}
Exemple #4
0
/* Startet den Server */
void server_start() {
	unsigned int clientlen;
	int readBytes, childPid;
	struct sockaddr_in servaddr, clientaddr;

	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(port);

	if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("socket");
		exit(2);
	}
	if (bind(server_socket, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0) {
		perror("bind");
		exit(3);
	}
	if (listen(server_socket, 5) < 0) {
		perror("listen");
		exit(4);
	}
	clientlen = sizeof(clientaddr);
	for (;;) {

		/* Get new client socket conection */
		if ((client_socket = accept(server_socket,
				(struct sockaddr *) &clientaddr, &clientlen)) < 0) {
			perror("accept");
			exit(5);
		}

		/* Fork a child to handle the request */
		if ((childPid = fork()) < 0) {
			perror("fork");
			exit(6);
		} else if (childPid == 0) {
			if (debuglevel > 0)
				printf("Child: Client connected from host %s:%d\n", inet_ntoa(
						clientaddr.sin_addr), ntohs(clientaddr.sin_port));
			while (client_socket > 0) {
				/* read request */
				netcp_message *requestMessage = malloc(sizeof(netcp_message));
				readBytes = read(client_socket, requestMessage,
						sizeof(netcp_message));
				if (readBytes < 0) {
					perror("read");
					server_close();
					exit(7);
				}
				server_handle_message(requestMessage);
				free(requestMessage);
			}
			if (debuglevel > 0)
				printf("Client disconnected from host %s:%d\n", inet_ntoa(
						clientaddr.sin_addr), ntohs(clientaddr.sin_port));
			exit(0);
		} else {
			if (debuglevel > 0)
				printf("Forking child %d for client %s:%d\n", childPid,
						inet_ntoa(clientaddr.sin_addr), ntohs(
								clientaddr.sin_port));
			server_close();
		}
	}
}
Exemple #5
0
char *getHeaders(int serversocket)
{
  int count = 0;
  int j, i = 0;
  int retval, errorCode = 0;
  char *ptr;
  char headers[4096]; /* Must check for overflow */
  char buffer[512];
  char c;

  memset(headers, 0, 4096);
  memset(buffer, 0, 512);

  /* For select() it's a global struct. */
  timeout.tv_sec = SOCKET_TIMEOUT;
  timeout.tv_usec = 0;

  retval = select(server_socket+1, &rfds, NULL, NULL, &timeout);
  if (retval <= 0)
  {
    _ERROR("Erreur de connexion in getHeaders().\n");
    goto error;
  }
  
  i = 0;
  
  while ( (recv(serversocket, &c, 1, 0) > 0) && (i < 512) )
  {
    if (c == '\r')
      continue;
    
    if (c == '\n')
      break;

    buffer[i++] = c;
  }

  errorCode = getHTTPCode(buffer);
  switch(errorCode)
  {
    case 200:
    case 301:
    case 302:
      break;
    default:
      _ERROR("Unknown error code received: %d\n", errorCode);
      goto error;
      break;
  }
  
  headers[0] = 0;

  for(j = 0, i = 0; ((j < 4096) && (count != 4)); j++)
  {
    /* For select() it's a global struct. */
    timeout.tv_sec = SOCKET_TIMEOUT;
    timeout.tv_usec = 0;
    retval = select(server_socket+1, &rfds, NULL, NULL, &timeout);
    if (retval <= 0)
    {
      _ERROR("Connection error in select (getHeaders).\n");
      goto error;

    } else if (recv(server_socket, &c, 1, 0) != 1) {
      _ERROR("Error reading data in getHeaders()\n");
      goto error;
    }
    
    if ((c == '\n') || (c == '\r'))
    {
       headers[i++] = c;
       count++;
    } else  {
       headers[i++] = c;
       count = 0;
    }
  }
  headers[i] = 0;
  
  if (!strlen(headers)) 
    return NULL;
  
  ptr = strdup(headers);
  printf("\n\n%s\n\n", ptr);

  return ptr;
  
error:
  server_close(server_socket);
  
  return NULL;
}
Exemple #6
0
void server_stop_signal_handler(int sig) {
    log_message("terminate signal catched");
    server_close();
    exit(EXIT_SUCCESS);
}
Exemple #7
0
int main(int argc, char *const argv[]) {
	int error = 0;
	
	log_debug("Parsing options");
	Options *opts = parse_opt(argc, argv);
	if (!opts) {
		show_banner();
		show_help();
		return -1;
	}
	log_set_level(opts->loglevel);
	if (opts->logfile) {
		log_set_logfile(opts->logfile);
		log_set_logfile_level(LOG_LEVEL_MAX);
	}
#ifdef HAVE_VSYSLOG
	if (opts->syslog) {
		log_set_syslog("daliserver");
	}
#endif
	if (opts->background) {
		daemonize(opts->pidfile);
	} else {
		show_banner();
	}

	log_info("Starting daliserver");

	log_debug("Initializing dispatch queue");
	DispatchPtr dispatch = dispatch_new();
	if (!dispatch) {
		error = -1;
	} else {
		//dispatch_set_timeout(dispatch, 100);

		UsbDaliPtr usb = NULL;
		if (!opts->dryrun) {
			log_debug("Initializing USB connection");
			usb = usbdali_open(NULL, dispatch, opts->usbbus, opts->usbdev);
			if (!usb) {
				error = -1;
			}
		}

		if (opts->dryrun || usb) {
			log_debug("Initializing server");
			ServerPtr server = server_open(dispatch, opts->address, opts->port, DEFAULT_NET_FRAMESIZE, net_frame_handler, usb);

			if (!server) {
				error = -1;
			} else {
				server_set_connection_destroy_callback(server, net_dequeue_connection, usb);
				
				if (usb) {
					usbdali_set_outband_callback(usb, dali_outband_handler, server);
					usbdali_set_inband_callback(usb, dali_inband_handler);
				}

				log_debug("Creating shutdown notifier");
				killsocket = ipc_new();
				
				if (!killsocket) {
					error = -1;
				} else {
					ipc_register(killsocket, dispatch);

					log_info("Server ready, waiting for events");
					running = 1;
					signal(SIGTERM, signal_handler);
					signal(SIGINT, signal_handler);
					while (running && dispatch_run(dispatch, usbdali_get_timeout(usb)));

					log_info("Shutting daliserver down");
					ipc_free(killsocket);
				}
				
				server_close(server);
			}
			
			if (usb) {
				usbdali_close(usb);
			}
		}

		dispatch_free(dispatch);
	}

	free_opt(opts);
	
	log_info("Exiting");
	return error;
}
Exemple #8
0
int main(int argc, char* argv[]) {

	//----------------------

#ifndef DEBUG
	srand(time(NULL));
	srand_sse(time(NULL));
#else
	srand(1);
	srand_sse(1111);
#endif

	if (argc < 3) {
		printf("Usage: %s <scd file name> <port> \n", argv[0]);
		return -1;
	}

	int port = atoi(argv[2]);
	int connfd = server_init(port);
	if (connfd == -1) {
		printf("Something's wrong with the socket!\n");
		return -1;
	}

#define GARBLING

#ifndef GARBLING
	server_close(connfd);
	return 0;

#else
	//----------------------------------------- Garbling
	GarbledCircuit garbledCircuit;
	long i, j, cid;

	readCircuitFromFile(&garbledCircuit, argv[1]);

	printf("garbledCircuit.I[0] = %d\n", garbledCircuit.I[0]);

	int n = garbledCircuit.n;
	int g = garbledCircuit.g;
	int p = garbledCircuit.p;
	int m = garbledCircuit.m;
	int c = garbledCircuit.c;
	int e = n - g;

	int *garbler_inputs = (int *) malloc(sizeof(int) * (g) * c);
	block *inputLabels = (block *) malloc(sizeof(block) * 2 * n * c);
	block *initialDFFLable = (block *) malloc(sizeof(block) * 2 * p);
	block *outputLabels = (block *) malloc(sizeof(block) * 2 * m * c);

	printf("\n\ninputs:\n");
	for (cid = 0; cid < c; cid++) {
		for (j = 0; j < g; j++) {
			garbler_inputs[cid * g + j] = rand() % 2;
			printf("%d ", garbler_inputs[cid * g + j]);
		}
	}
	printf("\n\n");

#ifndef DEBUG
	block R = randomBlock();
	*((short *) (&R)) |= 1;
#else
	block R = makeBlock((long )(-1), (long )(-1));
#endif
	uint8_t * rptr = (uint8_t*) &R;
	for (int i = 0; i < 16; i++)
		rptr[i] = 0xff;

//	*((short *) (&R)) |= 1;
	rptr[0] |= 1;

	createInputLabels(inputLabels, R, n * c);
	createInputLabels(initialDFFLable, R, p);

	///--------------------------------------------------------------- OT Extension
	//Parameters
	int numOTs = c * e;
	int bitlength = 128;
	m_nSecParam = 128;
	m_nNumOTThreads = 1;
	BYTE version;
	crypto *crypt = new crypto(m_nSecParam, (uint8_t*) m_vSeed);
	InitOTSender(connfd, crypt);
	CBitVector delta, X1, X2;

	delta.Create(numOTs, bitlength, crypt);
	m_fMaskFct = new XORMasking(bitlength, delta);
	for (int i=0;i<numOTs;i++)
		delta.SetBytes(rptr, i*16, 16);

	printf("Delta: ");
	for (int i = 0; i < 16; i++) {
		printf("%02x", delta.GetByte(i));
	}
	printf("\n");

	printf("R: ");
	print__m128i(R);
	printf("\n");



	X1.Create(numOTs, bitlength);
	X1.Reset();
	X2.Create(numOTs, bitlength);
	X2.Reset();
	uint8_t* b = new BYTE[16];
	BYTE* b2 = new BYTE[16];

	cout << "Sender performing " << numOTs << " C_OT extensions on "
			<< bitlength << " bit elements" << endl;

	version = C_OT;
	ObliviouslySend(X1, X2, numOTs, bitlength, version, crypt);



	//putting X1 & X2 into inputLabels
	printf("printing inputLabels after copy from X1 and X2:\n\n");
	uint8_t* inputLabelsptr;
	for (cid = 0; cid < c; cid++) {
		for (j = 0; j < e; j++) {
			inputLabelsptr = (uint8_t*) &inputLabels[2 * (cid * n + g + j)];
			X1.GetBytes(inputLabelsptr, 16*(cid * e + j), 16);
			print__m128i(inputLabels[2 * (cid * n + g + j)]);

			inputLabelsptr = (uint8_t*) &inputLabels[2 * (cid * n + g + j) + 1];
			X2.GetBytes(inputLabelsptr, 16*(cid * e + j), 16);
			print__m128i(inputLabels[2 * (cid * n + g + j) + 1]);

		}
	}

	//print
	printf("Printing X1:\n");
	for (int j = 0; j < numOTs; j++) {
		for (int i = 0; i < 16; i++) {
			b[i] = X1.GetByte(i + j * 16);
			printf("%02x", b[i]);
		}
		printf("\n");
	}
	printf("\n\n");
	printf("Printing X2:\n");
	for (int j = 0; j < numOTs; j++) {
		for (int i = 0; i < 16; i++) {
			b[i] = X2.GetByte(i + j * 16);
			printf("%02x", b[i]);
		}
		printf("\n");
	}
	printf("\n\n");
	printf("Printing delta:\t");
	for (int i = 0; i < 16; i++) {
		b[i] = delta.GetByte(i);
		printf("%02x", b[i]);
	}
	printf("\n");

//----------------------------------------------------end of OT Extension

	for (cid = 0; cid < c; cid++) {
		for (j = 0; j < g; j++) {
			if (garbler_inputs[cid * g + j] == 0)
				send_block(connfd, inputLabels[2 * (cid * n + j)]);
			else
				send_block(connfd, inputLabels[2 * (cid * n + j) + 1]);

			printf("i(%ld, %ld, %d)\n", cid, j, garbler_inputs[cid * g + j]);
			print__m128i(inputLabels[2 * (cid * n + j)]);
			print__m128i(inputLabels[2 * (cid * n + j) + 1]);
		}

		//------------------------------------------------------------------------------------------ CHANGE 1
		for (j = 0; j < e; j++) {
//			int ev_input;
//			read(connfd, &ev_input, sizeof(int));
//			if (!ev_input)
//				send_block(connfd, inputLabels[2 * (cid * n + g + j)]);
//			else
//				send_block(connfd, inputLabels[2 * (cid * n + g + j) + 1]);

			printf("evaluator : i(%ld, %ld, ?)\n", cid, j);
			print__m128i(inputLabels[2 * (cid * n + g + j)]);
			print__m128i(inputLabels[2 * (cid * n + g + j) + 1]);

		}

		printf("Compare to:   ");

		printf("\n");
		//----------------------------------------------------------------------end

	}
	printf("\n\n");

	for (j = 0; j < p; j++) //p:#DFF
			{
		printf("garbledCircuit.I[j] = %d\n", garbledCircuit.I[j]);
		if (garbledCircuit.I[j] == CONST_ZERO) // constant zero
		{
			send_block(connfd, initialDFFLable[2 * j]);
			printf("dffi(%ld, %ld, %d)\n", cid, j, 0);
			print__m128i(initialDFFLable[2 * j]);
			print__m128i(initialDFFLable[2 * j + 1]);

		} else if (garbledCircuit.I[j] == CONST_ONE) // constant zero
		{
			send_block(connfd, initialDFFLable[2 * j + 1]);
			printf("dffi(%ld, %ld, %d)\n", cid, j, 0);
			print__m128i(inputLabels[2 * j]);
			print__m128i(inputLabels[2 * j + 1]);

		} else if (garbledCircuit.I[j] < g) //belongs to Alice (garbler)
				{
			int index = garbledCircuit.I[j];

			if (garbler_inputs[index] == 0)
				send_block(connfd, initialDFFLable[2 * j]);
			else
				send_block(connfd, initialDFFLable[2 * j + 1]);

			printf("dffi(%ld, %ld, %d)\n", cid, j, garbler_inputs[index]);
			print__m128i(initialDFFLable[2 * j]);
			print__m128i(initialDFFLable[2 * j + 1]);

		}
		//------------------------------------------------------------------------------------------ CHANGE 2
		else //**** belongs to Bob
		{
//			int ev_input;
//			read(connfd, &ev_input, sizeof(int));
//			if (!ev_input)
//				send_block(connfd, initialDFFLable[2 * j]);
//			else
//				send_block(connfd, initialDFFLable[2 * j + 1]);

//			printf("dffi(%ld, %ld, %d)\n", cid, j, ev_input);
			print__m128i(initialDFFLable[2 * j]);
			print__m128i(initialDFFLable[2 * j + 1]);
			printf("\n");
		}
		//----------------------------------------------------------------------end
	}
	printf("\n\n");

	///--------------------------------------------------------------- OT Extension
		//Parameters
		numOTs = p;
		delta.Create(numOTs, bitlength, crypt);
		m_fMaskFct = new XORMasking(bitlength, delta);
		for (int i=0;i<numOTs;i++)
			delta.SetBytes(rptr, i*16, 16);

		printf("Delta: ");
		for (int i = 0; i < 16; i++) {
			printf("%02x", delta.GetByte(i));
		}
		printf("\n");

		printf("R: ");
		print__m128i(R);
		printf("\n");



		X1.Create(numOTs, bitlength);
		X1.Reset();
		X2.Create(numOTs, bitlength);
		X2.Reset();


		cout << "Sender performing " << numOTs << " C_OT extensions on "
				<< bitlength << " bit elements" << endl;

		version = C_OT;
		ObliviouslySend(X1, X2, numOTs, bitlength, version, crypt);



		//putting X1 & X2 into inputLabels
		printf("printing inputLabels after copy from X1 and X2:\n\n");


			for (j = 0; j < p; j++) {
				inputLabelsptr = (uint8_t*) &initialDFFLable[2 * j];
				X1.GetBytes(inputLabelsptr, 16*(j), 16);


				inputLabelsptr = (uint8_t*) &initialDFFLable[2 * j +1];
				X2.GetBytes(inputLabelsptr, 16*( j), 16);
			}

		delete crypt;
	//----------------------------------------------------end of OT Extension



	garbledCircuit.globalKey = randomBlock();
	send_block(connfd, garbledCircuit.globalKey); // send DKC key

	printf("R: ");
	print__m128i(R);
	printf("\n");

	garble(&garbledCircuit, inputLabels, initialDFFLable, outputLabels, &R,
			connfd);

	printf("***************** InputLabels\n");
	for (int i=0;i<n*c*2;i++)
		print__m128i(inputLabels[i]);

	for (cid = 0; cid < c; cid++) {
		for (i = 0; i < m; i++) {
			short outputType = getLSB(outputLabels[2 * (m * cid + i) + 0]);
			send_type(connfd, outputType);
		}
	}

	server_close(connfd);
	removeGarbledCircuit(&garbledCircuit);

	return 0;
#endif
}
Exemple #9
0
int
main (int argc, char *argv[]) {
    int portable = 0;
#if STATICLINK
    int staticlink = 1;
#else
    int staticlink = 0;
#endif
#if PORTABLE
    portable = 1;
    if (!realpath (argv[0], dbinstalldir)) {
        strcpy (dbinstalldir, argv[0]);
    }
    char *e = strrchr (dbinstalldir, '/');
    if (e) {
        *e = 0;
    }
    else {
        fprintf (stderr, "couldn't determine install folder from path %s\n", argv[0]);
        exit (-1);
    }
#else
    if (!realpath (argv[0], dbinstalldir)) {
        strcpy (dbinstalldir, argv[0]);
    }
    char *e = strrchr (dbinstalldir, '/');
    if (e) {
        *e = 0;
        struct stat st;
        char checkpath[PATH_MAX];
        snprintf (checkpath, sizeof (checkpath), "%s/.ddb_portable", dbinstalldir);
        if (!stat (checkpath, &st)) {
            if (S_ISREG (st.st_mode)) {
                portable = 1;
            }
        }
    }
    if (!portable) {
        strcpy (dbinstalldir, PREFIX);
    }
#endif

#ifdef __GLIBC__
    signal (SIGSEGV, sigsegv_handler);
#endif
    setlocale (LC_ALL, "");
    setlocale (LC_NUMERIC, "C");
#ifdef ENABLE_NLS
//    fprintf (stderr, "enabling gettext support: package=" PACKAGE ", dir=" LOCALEDIR "...\n");
    if (portable) {
        char localedir[PATH_MAX];
        snprintf (localedir, sizeof (localedir), "%s/locale", dbinstalldir);
        bindtextdomain (PACKAGE, localedir);
    }
    else {
        bindtextdomain (PACKAGE, LOCALEDIR);
    }
	bind_textdomain_codeset (PACKAGE, "UTF-8");
	textdomain (PACKAGE);
#endif

    fprintf (stderr, "starting deadbeef " VERSION "%s%s\n", staticlink ? " [static]" : "", portable ? " [portable]" : "");
    srand (time (NULL));
#ifdef __linux__
    prctl (PR_SET_NAME, "deadbeef-main", 0, 0, 0, 0);
#endif

#if PORTABLE_FULL
    if (snprintf (confdir, sizeof (confdir), "%s/config", dbinstalldir) > sizeof (confdir)) {
        fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
        return -1;
    }

    strcpy (dbconfdir, confdir);
#else
    char *homedir = getenv ("HOME");
    if (!homedir) {
        fprintf (stderr, "unable to find home directory. stopping.\n");
        return -1;
    }

    char *xdg_conf_dir = getenv ("XDG_CONFIG_HOME");
    if (xdg_conf_dir) {
        if (snprintf (confdir, sizeof (confdir), "%s", xdg_conf_dir) > sizeof (confdir)) {
            fprintf (stderr, "fatal: XDG_CONFIG_HOME value is too long: %s\n", xdg_conf_dir);
            return -1;
        }
    }
    else {
        if (snprintf (confdir, sizeof (confdir), "%s/.config", homedir) > sizeof (confdir)) {
            fprintf (stderr, "fatal: HOME value is too long: %s\n", homedir);
            return -1;
        }
    }
    if (snprintf (dbconfdir, sizeof (dbconfdir), "%s/deadbeef", confdir) > sizeof (dbconfdir)) {
        fprintf (stderr, "fatal: out of memory while configuring\n");
        return -1;
    }
    mkdir (confdir, 0755);
#endif


    if (portable) {
        if (snprintf (dbdocdir, sizeof (dbdocdir), "%s/doc", dbinstalldir) > sizeof (dbdocdir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
#ifdef HAVE_COCOAUI
        char respath[PATH_MAX];
        cocoautil_get_resources_path (respath, sizeof (respath));
        if (snprintf (dbplugindir, sizeof (dbplugindir), "%s", respath) > sizeof (dbplugindir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
#else
        if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/plugins", dbinstalldir) > sizeof (dbplugindir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
#endif
        if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/pixmaps", dbinstalldir) > sizeof (dbpixmapdir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
        mkdir (dbplugindir, 0755);
    }
    else {
        if (snprintf (dbdocdir, sizeof (dbdocdir), "%s", DOCDIR) > sizeof (dbdocdir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
        if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/deadbeef", LIBDIR) > sizeof (dbplugindir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
        if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/share/deadbeef/pixmaps", PREFIX) > sizeof (dbpixmapdir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
    }

    for (int i = 1; i < argc; i++) {
        // help, version and nowplaying are executed with any filter
        if (!strcmp (argv[i], "--help") || !strcmp (argv[i], "-h")) {
            print_help ();
            return 0;
        }
        else if (!strcmp (argv[i], "--version")) {
            fprintf (stderr, "DeaDBeeF " VERSION " Copyright © 2009-2013 Alexey Yakovenko\n");
            return 0;
        }
        else if (!strcmp (argv[i], "--gui")) {
            if (i == argc-1) {
                break;
            }
            i++;
            strncpy (use_gui_plugin, argv[i], sizeof(use_gui_plugin) - 1);
            use_gui_plugin[sizeof(use_gui_plugin) - 1] = 0;
        }
    }

    trace ("installdir: %s\n", dbinstalldir);
    trace ("confdir: %s\n", confdir);
    trace ("docdir: %s\n", dbdocdir);
    trace ("plugindir: %s\n", dbplugindir);
    trace ("pixmapdir: %s\n", dbpixmapdir);

    mkdir (dbconfdir, 0755);

    int size = 0;
    char *cmdline = prepare_command_line (argc, argv, &size);

    // try to connect to remote player
    int s, len;
    struct sockaddr_un remote;

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    memset (&remote, 0, sizeof (remote));
    remote.sun_family = AF_UNIX;
#if USE_ABSTRACT_SOCKET_NAME
    memcpy (remote.sun_path, server_id, sizeof (server_id));
    len = offsetof(struct sockaddr_un, sun_path) + sizeof (server_id)-1;
#else
    char *socketdirenv = getenv ("DDB_SOCKET_DIR");
    snprintf (remote.sun_path, sizeof (remote.sun_path), "%s/socket", socketdirenv ? socketdirenv : dbconfdir);
    len = offsetof(struct sockaddr_un, sun_path) + strlen (remote.sun_path);
#endif
    if (connect(s, (struct sockaddr *)&remote, len) == 0) {
        // pass args to remote and exit
        if (send(s, cmdline, size, 0) == -1) {
            perror ("send");
            exit (-1);
        }
        // end of message
        shutdown(s, SHUT_WR);

        int sz = -1;
        char *out = read_entire_message(s, &sz);
        if (sz == -1) {
            fprintf (stderr, "failed to pass args to remote!\n");
            exit (-1);
        }
        else {
            // check if that's nowplaying response
            const char np[] = "nowplaying ";
            const char err[] = "error ";
            if (!strncmp (out, np, sizeof (np)-1)) {
                const char *prn = &out[sizeof (np)-1];
                fwrite (prn, 1, strlen (prn), stdout);
            }
            else if (!strncmp (out, err, sizeof (err)-1)) {
                const char *prn = &out[sizeof (err)-1];
                fwrite (prn, 1, strlen (prn), stderr);
            }
            else if (sz > 0 && out[0]) {
                fprintf (stderr, "%s\n", out);
            }
        }
        if (out) {
            free (out);
        }
        close (s);
        exit (0);
    }
//    else {
//        perror ("INFO: failed to connect to existing session:");
//    }
    close(s);

    // become a server
    if (server_start () < 0) {
        exit (-1);
    }

    // hack: report nowplaying
    if (!strcmp (cmdline, "--nowplaying")) {
        char nothing[] = "nothing";
        fwrite (nothing, 1, sizeof (nothing)-1, stdout);
        return 0;
    }

    pl_init ();
    conf_init ();
    conf_load (); // required by some plugins at startup

    if (use_gui_plugin[0]) {
        conf_set_str ("gui_plugin", use_gui_plugin);
    }

    conf_set_str ("deadbeef_version", VERSION);

    volume_set_db (conf_get_float ("playback.volume", 0)); // volume need to be initialized before plugins start

    messagepump_init (); // required to push messages while handling commandline
    if (plug_load_all ()) { // required to add files to playlist from commandline
        exit (-1);
    }
    pl_load_all ();
    plt_set_curr_idx (conf_get_int ("playlist.current", 0));

    // execute server commands in local context
    int noloadpl = 0;
    if (argc > 1) {
        int res = server_exec_command_line (cmdline, size, NULL, 0);
        // some of the server commands ran on 1st instance should terminate it
        if (res == 2) {
            noloadpl = 1;
        }
        else if (res > 0) {
            exit (0);
        }
        else if (res < 0) {
            exit (-1);
        }
    }

    free (cmdline);

#if 0
    signal (SIGTERM, sigterm_handler);
    atexit (atexit_handler); // helps to save in simple cases
#endif

    streamer_init ();

    plug_connect_all ();
    messagepump_push (DB_EV_PLUGINSLOADED, 0, 0, 0);

    if (!noloadpl) {
        restore_resume_state ();
    }

    server_tid = thread_start (server_loop, NULL);

    mainloop_tid = thread_start (mainloop_thread, NULL);

    DB_plugin_t *gui = plug_get_gui ();
    if (gui) {
        gui->start ();
    }

    fprintf (stderr, "gui plugin has quit; waiting for mainloop thread to finish\n");
    thread_join (mainloop_tid);

    // terminate server and wait for completion
    if (server_tid) {
        server_terminate = 1;
        thread_join (server_tid);
        server_tid = 0;
    }

    // save config
    pl_save_all ();
    conf_save ();

    // delete legacy session file
    {
        char sessfile[1024]; // $HOME/.config/deadbeef/session
        if (snprintf (sessfile, sizeof (sessfile), "%s/deadbeef/session", confdir) < sizeof (sessfile)) {
            unlink (sessfile);
        }
    }

    // stop receiving messages from outside
    server_close ();

    // plugins might still hold references to playitems,
    // and query configuration in background
    // so unload everything 1st before final cleanup
    plug_disconnect_all ();
    plug_unload_all ();

    // at this point we can simply do exit(0), but let's clean up for debugging
    pl_free (); // may access conf_*
    conf_free ();

    fprintf (stderr, "messagepump_free\n");
    messagepump_free ();
    fprintf (stderr, "plug_cleanup\n");
    plug_cleanup ();

    fprintf (stderr, "hej-hej!\n");

    return 0;
}