Exemple #1
0
static void
test_small_writes (void)
{
  GIOChannel *io;
  GIOStatus status = G_IO_STATUS_NORMAL;
  guint cnt;
  gchar tmp;
  GError *error = NULL;

  io = g_io_channel_new_file ("iochannel-test-outfile", "w", &error);
  
  gcut_assert_error (error);

  g_io_channel_set_encoding (io, NULL, NULL);
  g_io_channel_set_buffer_size (io, 1022);

  cnt = 2 * g_io_channel_get_buffer_size (io);
  tmp = 0;
 
  while (cnt)
    {
      status = g_io_channel_write_chars (io, &tmp, 1, NULL, NULL);
      if (status == G_IO_STATUS_ERROR)
	break;
      if (status == G_IO_STATUS_NORMAL)
	cnt--;
    }

  cut_assert_equal_int (G_IO_STATUS_NORMAL, status);

  g_io_channel_unref (io);
}
Exemple #2
0
void net_login(char *email, char *password)
{
	uemail = g_strdup(email);
	upass = g_strdup(password);
	mwin_create();
	
	GInetAddr* addr;
	addr = gnet_inetaddr_new("messenger.hotmail.com", 1863);
	if(addr)
	{
		msn_socket = gnet_tcp_socket_new(addr);
		gnet_inetaddr_delete(addr);
	}
	else
	{
		error_dialog("Failed to resolve messenger.msn.com");
		return;
	}
	
	msn_channel = gnet_tcp_socket_get_io_channel(msn_socket);
	g_io_channel_set_buffer_size(msn_channel,128);
	g_io_channel_set_buffered(msn_channel,1);
	g_io_channel_set_encoding(msn_channel, NULL, NULL);
	g_io_add_watch(msn_channel,G_IO_IN|G_IO_HUP|G_IO_ERR,(GIOFunc)network_receive,NULL);
	
	/* Start off the authentication process */
	net_send("VER 0 MSNP8 MYPROTOCOL CVR0 \r\n");
}
static void
fr_channel_data_set_fd (FrChannelData *channel,
			int            fd,
			const char    *charset)
{
	fr_channel_data_reset (channel);

	channel->source = g_io_channel_unix_new (fd);
	g_io_channel_set_flags (channel->source, G_IO_FLAG_NONBLOCK, NULL);
	g_io_channel_set_buffer_size (channel->source, BUFFER_SIZE);
	if (charset != NULL)
		g_io_channel_set_encoding (channel->source, charset, NULL);
}
static void
test_small_writes (void)
{
  GIOChannel *io;
  GIOStatus status;
  guint cnt; 
  gchar tmp;
  GError *error = NULL;

  io = g_io_channel_new_file ("iochannel-test-outfile", "w", &error);
  if (error)
    {
      g_warning ("Unable to open file %s: %s", 
		 "iochannel-test-outfile", 
		 error->message);
      g_clear_error (&error);
      
      exit (1);
    }

  g_io_channel_set_encoding (io, NULL, NULL);
  g_io_channel_set_buffer_size (io, 1022);

  cnt = 2 * g_io_channel_get_buffer_size (io);
  tmp = 0;
 
  while (cnt)
    {
      status = g_io_channel_write_chars (io, &tmp, 1, NULL, NULL);
      if (status == G_IO_STATUS_ERROR)
	break;
      if (status == G_IO_STATUS_NORMAL)
	cnt--;
    }

  g_assert (status == G_IO_STATUS_NORMAL);

  g_io_channel_unref (io);
}
gint main (gint argc, gchar * argv[])
{
    GIOChannel *gio_r, *gio_w ;
    GError *gerr = NULL;
    GString *buffer;
    char *filename;
    char *srcdir = getenv ("srcdir");
    gint rlength = 0;
    glong wlength = 0;
    gsize length_out;
    const gchar encoding[] = "ISO-8859-5";
    GIOStatus status;
    GIOFlags flags;

  #ifdef SYMBIAN
  g_log_set_handler (NULL,  G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL);
  g_set_print_handler(mrtPrintHandler);
  #endif /*SYMBIAN*/
	  

    if (!srcdir)
      srcdir = "c:";
    filename = g_strconcat (srcdir, G_DIR_SEPARATOR_S, "iochannel-test-infile", NULL);
  
    setbuf (stdout, NULL); /* For debugging */

    gio_r = g_io_channel_new_file (filename, "r", &gerr);
    if (gerr)
      {
        g_warning ("Unable to open file %s: %s", filename, gerr->message);
        g_error_free (gerr);
        
        g_assert(FALSE && "iochannel-test failed");
        
        #if SYMBIAN
  		testResultXml("iochannel-test");
  		#endif /* EMULATOR */
        
        return 1;
      }
    gio_w = g_io_channel_new_file ("c:\\iochannel-test-outfile", "w", &gerr);
    if (gerr)
      {
        g_warning ("Unable to open file %s: %s", "iochannel-test-outfile", gerr->message);
        g_error_free (gerr);
        
        g_assert(FALSE && "iochannel-test failed");
        
        #if SYMBIAN
  		testResultXml("iochannel-test");
  		#endif /* EMULATOR */
        
        return 1;
      }

    g_io_channel_set_encoding (gio_r, encoding, &gerr);
    if (gerr)
      {
        g_warning (gerr->message);
        g_error_free (gerr);
        
        g_assert(FALSE && "iochannel-test failed");
        
        #if SYMBIAN
  		testResultXml("iochannel-test");
  		#endif /* EMULATOR */
        
        return 1;
      }
    
    g_io_channel_set_buffer_size (gio_r, BUFFER_SIZE);

    status = g_io_channel_set_flags (gio_r, G_IO_FLAG_NONBLOCK, &gerr);
    if (status == G_IO_STATUS_ERROR)
      {
        g_warning (gerr->message);
        g_assert(FALSE && "iochannel-test failed");
        g_error_free (gerr);
        gerr = NULL;
      }
    flags = g_io_channel_get_flags (gio_r);
    buffer = g_string_sized_new (BUFFER_SIZE);

    while (TRUE)
    {
        do
          status = g_io_channel_read_line_string (gio_r, buffer, NULL, &gerr);
        while (status == G_IO_STATUS_AGAIN);
        if (status != G_IO_STATUS_NORMAL)
          break;

        rlength += buffer->len;

        do
          status = g_io_channel_write_chars (gio_w, buffer->str, buffer->len,
            &length_out, &gerr);
        while (status == G_IO_STATUS_AGAIN);
        if (status != G_IO_STATUS_NORMAL)
          break;

        wlength += length_out;

        if (length_out < buffer->len)
        {
        	g_warning ("Only wrote part of the line.");
        	g_assert(FALSE && "iochannel-test failed");
        }
          

#ifdef VERBOSE
        g_print ("%s", buffer->str);
#endif
        g_string_truncate (buffer, 0);
    }

    switch (status)
      {
        case G_IO_STATUS_EOF:
          break;
        case G_IO_STATUS_ERROR:
          g_warning (gerr->message);
          g_error_free (gerr);
          gerr = NULL;
          break;
        default:
          g_warning ("Abnormal exit from write loop.");
          g_assert(FALSE && "iochannel-test failed");
          break;
      }

    do
      status = g_io_channel_flush (gio_w, &gerr);
    while (status == G_IO_STATUS_AGAIN);

    if (status == G_IO_STATUS_ERROR)
      {
        g_warning (gerr->message);
        g_assert(FALSE && "iochannel-test failed");
        g_error_free (gerr);
        gerr = NULL;
      }

#ifdef VERBOSE
    g_print ("read %d bytes, wrote %ld bytes\n", rlength, wlength);
#endif

    g_io_channel_unref(gio_r);
    g_io_channel_unref(gio_w);
    
   	#if SYMBIAN
  	testResultXml("iochannel-test");
  	#endif /* EMULATOR */
  	    
    return 0;
}
gint main (gint argc, gchar * argv[])
{
    GIOChannel *gio_r, *gio_w ;
    GError *gerr = NULL;
    GString *buffer;
    char *filename;
    char *srcdir = getenv ("srcdir");
    gint rlength = 0;
    glong wlength = 0;
    gsize length_out;
    const gchar encoding[] = "EUC-JP";
    GIOStatus status;

    if (!srcdir)
      srcdir = ".";
    filename = g_strconcat (srcdir, G_DIR_SEPARATOR_S, "iochannel-test-infile", NULL);
  
    setbuf (stdout, NULL); /* For debugging */

    gio_r = g_io_channel_new_file (filename, "r", &gerr);
    if (gerr)
      {
        g_warning ("Unable to open file %s: %s", filename, gerr->message);
        g_clear_error (&gerr);
        return 1;
      }
    gio_w = g_io_channel_new_file ("iochannel-test-outfile", "w", &gerr);
    if (gerr)
      {
        g_warning ("Unable to open file %s: %s", "iochannel-test-outfile", gerr->message);
        g_clear_error (&gerr);
        return 1;
      }

    g_io_channel_set_encoding (gio_r, encoding, &gerr);
    if (gerr)
      {
        g_warning ("%s", gerr->message);
        /* Keep going if this is just a case of iconv not supporting EUC-JP, see bug 428048 */
        if (gerr->code != G_CONVERT_ERROR_NO_CONVERSION)
          return 1;
        g_clear_error (&gerr);
      }
    
    g_io_channel_set_buffer_size (gio_r, BUFFER_SIZE);

    status = g_io_channel_set_flags (gio_r, G_IO_FLAG_NONBLOCK, &gerr);
    if (status == G_IO_STATUS_ERROR)
      {
        g_warning ("%s", gerr->message);
        g_clear_error (&gerr);
      }
    buffer = g_string_sized_new (BUFFER_SIZE);

    while (TRUE)
    {
        do
          status = g_io_channel_read_line_string (gio_r, buffer, NULL, &gerr);
        while (status == G_IO_STATUS_AGAIN);
        if (status != G_IO_STATUS_NORMAL)
          break;

        rlength += buffer->len;

        do
          status = g_io_channel_write_chars (gio_w, buffer->str, buffer->len,
            &length_out, &gerr);
        while (status == G_IO_STATUS_AGAIN);
        if (status != G_IO_STATUS_NORMAL)
          break;

        wlength += length_out;

        if (length_out < buffer->len)
          g_warning ("Only wrote part of the line.");

#ifdef VERBOSE
        g_print ("%s", buffer->str);
#endif
        g_string_truncate (buffer, 0);
    }

    switch (status)
      {
        case G_IO_STATUS_EOF:
          break;
        case G_IO_STATUS_ERROR:
          g_warning ("%s", gerr->message);
          g_clear_error (&gerr);
          break;
        default:
          g_warning ("Abnormal exit from write loop.");
          break;
      }

    do
      status = g_io_channel_flush (gio_w, &gerr);
    while (status == G_IO_STATUS_AGAIN);

    if (status == G_IO_STATUS_ERROR)
      {
        g_warning ("%s", gerr->message);
        g_clear_error (&gerr);
      }

#ifdef VERBOSE
    g_print ("read %d bytes, wrote %ld bytes\n", rlength, wlength);
#endif

    g_io_channel_unref(gio_r);
    g_io_channel_unref(gio_w);

    test_small_writes ();
    
    return 0;
}
Exemple #7
0
void
test_iochannel (void)
{
  GIOChannel *gio_r, *gio_w ;
  GString *buffer;
  char *filename;
  char *srcdir = getenv ("srcdir");
  gint rlength = 0;
  glong wlength = 0;
  gsize length_out;
  const gchar encoding[] = "EUC-JP";
  GIOStatus status;
  GError *error = NULL;

  if (!srcdir)
    srcdir = ".";
  filename = g_build_filename (srcdir, "iochannel-test-infile", NULL);

  gio_r = g_io_channel_new_file (filename, "r", &error);
  gcut_assert_error (error);

  gio_w = g_io_channel_new_file ("iochannel-test-outfile", "w", &error);
  gcut_assert_error (error);

  g_io_channel_set_encoding (gio_r, encoding, &error);
  gcut_assert_error (error);

  g_io_channel_set_buffer_size (gio_r, BUFFER_SIZE);

  status = g_io_channel_set_flags (gio_r, G_IO_FLAG_NONBLOCK, &error);
  gcut_assert_error (error);
  buffer = g_string_sized_new (BUFFER_SIZE);

  while (TRUE)
  {
      do
        {
          status = g_io_channel_read_line_string (gio_r, buffer, NULL, &error);
          gcut_assert_error (error);
        } while (status == G_IO_STATUS_AGAIN);
      if (status != G_IO_STATUS_NORMAL)
        break;

      rlength += buffer->len;

      do
        {
          status = g_io_channel_write_chars (gio_w, buffer->str, buffer->len,
                                             &length_out, &error);
          gcut_assert_error (error);
        } while (status == G_IO_STATUS_AGAIN);
      if (status != G_IO_STATUS_NORMAL)
        break;

      wlength += length_out;

      if (length_out < buffer->len)
        g_warning ("Only wrote part of the line.");

      g_string_truncate (buffer, 0);
  }

  switch (status)
    {
      case G_IO_STATUS_EOF:
        break;
      case G_IO_STATUS_ERROR:
        gcut_assert_error(error);
        break;
      default:
        g_warning ("Abnormal exit from write loop.");
        break;
    }

  do
    {
      status = g_io_channel_flush (gio_w, &error);
      gcut_assert_error (error);
    } while (status == G_IO_STATUS_AGAIN);

  cut_assert_equal_int (G_IO_STATUS_NORMAL, status);

  g_io_channel_unref(gio_r);
  g_io_channel_unref(gio_w);

  test_small_writes ();
}
Exemple #8
0
gboolean network_receive(GIOChannel *source, GIOCondition condition, gpointer data)
{
	/* Primarily, we'll only be reading in a small amount of info */
	if(log_level == 0)
	{
		if((condition&G_IO_HUP)==G_IO_HUP)
		{
			return FALSE;
		}
		if((condition&G_IO_IN) == G_IO_IN)
		{
			GIOError error = G_IO_ERROR_NONE;
			char data = 0;
			unsigned int offset = 0;
			char message[1024] = { '\0' };
			gsize n = 1;
			while(data!='\n')
			{
				error = gnet_io_channel_readn(msn_channel, &data, n, &n); 
				if(n == 0)
				{
					return FALSE;
				}
				if (error != G_IO_ERROR_NONE) 
				{
					error_dialog("Error receiving network data!");
					return FALSE;
				}
				message[offset++] = data;
			}
			printf("Received: %s\n",message);
			/*
				TODO: action to take
			*/
			if(strncmp(message, "VER",3)==0)
			{
				/* Got a response from VER, time to send CVR */
				char *tmp_message = g_strdup_printf("CVR 2 0x0c0a winnt 5.1 i386 MSNMSGR 8.0.0792 msmsgs %s\r\n",uemail);
				net_send(tmp_message);
				g_free(tmp_message);
			}
			else if(strncmp(message, "CVR", 3) == 0)
			{
				/* Got a response from CVR, time to send USR */
				char *tmp_message = g_strdup_printf("USR 3 TWN I %s\r\n",uemail);
				net_send(tmp_message);
				g_free(tmp_message);
			}
			else if(strncmp(message, "XFR", 3) == 0)
			{
				/* The tricky part... */
				log_level = 1;

				/*
					Now we close our socket, and point it at the ip given to us in the XFR message

					Sample specimen

					XFR 3 NS 207.46.108.91:1863 0 65.54.239.210:1863

				*/

				char *ip_start = strstr(message, "NS ");
				/* Skip past the "NS " */
				ip_start+=3;

				/* Find the splitter, " 0 " */
				char *ip_end = strstr(ip_start, " 0 ");
				ip_end[0] = '\0';

				char *ip_port_split = strstr(ip_start, ":");
				ip_port_split[0] = '\0';

				/* Voila */
				printf("IP: %s\n",ip_start);
				gnet_tcp_socket_delete(msn_socket);
				
				GInetAddr* addr;
				addr = gnet_inetaddr_new(ip_start, 1863);
				if(addr)
				{
					msn_socket = gnet_tcp_socket_new(addr);
					gnet_inetaddr_delete(addr);
				}
				else
				{
					error_dialog("Failed to resolve messenger.msn.com");
					return;
				}
	
				msn_channel = gnet_tcp_socket_get_io_channel(msn_socket);
				g_io_channel_set_buffer_size(msn_channel,128);
				g_io_channel_set_buffered(msn_channel,1);
				g_io_channel_set_encoding(msn_channel, NULL, NULL);
				g_io_add_watch(msn_channel,G_IO_IN|G_IO_HUP|G_IO_ERR,(GIOFunc)network_receive,NULL);
				printf("Transfered\n");
				net_send("VER 0 MSNP8 MYPROTOCOL CVR0 \r\n");
				return FALSE;
			}
		}
	}
	/* When the primary login stage (jumping connection) is done log_level = 1 */
	else if(log_level == 1)
	{
		if((condition&G_IO_HUP)==G_IO_HUP)
		{
			return FALSE;
		}
		if((condition&G_IO_IN) == G_IO_IN)
		{
			GIOError error = G_IO_ERROR_NONE;
			char data = 0;
			unsigned int offset = 0;
			char message[1024] = { '\0' };
			gsize n = 1;
			while(data!='\n')
			{
				error = gnet_io_channel_readn(msn_channel, &data, n, &n); 
				if(n == 0)
				{
					return FALSE;
				}
				if (error != G_IO_ERROR_NONE) 
				{
					error_dialog("Error receiving network data!");
					return FALSE;
				}
				message[offset++] = data;
			}
			printf("Received: %s\n",message);
			/*
				TODO: action to take
			*/
			if(strncmp(message, "VER",3)==0)
			{
				/* Got a response from VER, time to send CVR */
				char *tmp_message = g_strdup_printf("CVR 2 0x0c0a winnt 5.1 i386 MSNMSGR 8.0.0792 msmsgs %s\r\n",uemail);
				net_send(tmp_message);
				g_free(tmp_message);
			}
			else if(strncmp(message, "CVR", 3) == 0)
			{
				/* Got a response from CVR, time to send USR */
				char *tmp_message = g_strdup_printf("USR 3 TWN I %s\r\n",uemail);
				net_send(tmp_message);
				g_free(tmp_message);
			}
			else if(strncmp(message, "USR 3", 5) == 0)
			{
				/* 
					REALLY Tricky part now. OpenSSL - woohoo :( 

					Basically, the MSN protocol uses SSL to autheticate clients; so what happens now is, the MSN server sends us a 'challenge'
					for the SSL login page that we must send to it. So we need to extract that data, and send it to MSN to grab our golden 'ticket'
					which is used in the final login period.
				*/
				
				/* Example: USR 3 TWN S ct=1202475836,rver=5.0.3270.0,wp=FS_40SEC_0_COMPACT,lc=1033,id=507,ru=http:%2F%2Fmessenger.msn.com,tw=0,kpp=1,kv=4,ver=2.1.6000.1,rn=1lgjBfIL,tpf=b0735e3a873dfb5e75054465196398e0 */
				char *ticket = strstr(message, " ct=")+1;
				printf("Ticket: %s\n",ticket);
				
				char *return_ticket = net_ssl_auth(ticket);
				printf("Got ticket: %s\n",return_ticket);
				char *tmp_message = g_strdup_printf("USR 4 TWN S %s\r\n", return_ticket);
				net_send(tmp_message);
				g_free(tmp_message);
			}
			else if(strncmp(message, "USR 4", 5) == 0)
			{
				/* Woot I'm in! - We just got our email (useless) AND OUR NICKNAME! DAMN RIGHT BITCHES! */

				char *nick = split(message, ' ', 4);
				char *email = split(message, ' ', 3);
				globals_email = email;
				mwin_change_nick(nick);

				g_free(nick);
				char *tmp_message = g_strdup_printf("SYN 5 0\r\n");
				net_send(tmp_message);
				g_free(tmp_message);
				tmp_message = g_strdup_printf("CHG %d NLN 0\r\n",msg_num++);
				net_send(tmp_message);
				g_free(tmp_message);
				
			}
			else if(strncmp(message, "CHL", 3) == 0)
			{
				/* Got a challenge from MSN, and who am I to refuse? */
				char *challenge = message + 6;
				char *end = strstr(message, "\r\n");
				end[0] = '\0';
				char *chal_string = g_strdup_printf("%s%s",challenge,"Q1P7W2E4J9R8U3S5");
				GMD5* chal_md5 = gnet_md5_new(chal_string,strlen(chal_string));
				g_free(chal_string);
				
				gchar *hash = gnet_md5_get_string(chal_md5);
				gnet_md5_delete(chal_md5);
				
				printf("Challenge reply: %s\n",hash);
				
				char *tmp_message = g_strdup_printf("QRY %d [email protected] 32\r\n%s",msg_num++, hash);
				net_send(tmp_message);
				g_free(tmp_message);	
			}
			else if(strncmp(message,"RNG",3) == 0)
			{
				/* Got an incoming message! */
				printf("Got an incoming message, someone hast double clicked upon us!\n");
				printf("MESSAGE: %s\n",message);
				char *phost = split(message,' ', 2);
				char *host = split(phost,':',0);
				free(phost);
				printf("Host: %s\n",host);
				
				char *session = split(message,' ', 1);
				printf("Session: %s\n",session);
				
				char *auth_str = split(message,' ',4);
				char *email = split(message, ' ', 5);
				char *nick = split(message, ' ', 6);
				nick[strlen(nick)-2]='\0';
			
				printf("Auth: %s\n",auth_str);
				printf("Email: %s\n",email);
				printf("Nick: %s\n", nick);

				conversation_new(host, session, auth_str, email, nick, uemail);
			}
			else if(strncmp(message,"MSG",3) == 0)
			{
				// Got a message, most likely it's gonna be from Hotmail
				// Important thing is, MSG's have a payload size!
				char *nick = split(message,' ',2);
				char *len = split(message,' ',3);
				len[strlen(len)-2] = '\0';
				int length = atoi(len);
				printf("Inbound message length: %d\n",length);

				error = G_IO_ERROR_NONE;
				char incoming_msg[length+1];
				memset(incoming_msg, '\0',length+1);
				gsize n = length;
				error = gnet_io_channel_readn(msn_channel, incoming_msg, n, &n);
				if(error != G_IO_ERROR_NONE)
				{
				   fprintf(stderr, "Error occurred reading message\n");
				   return FALSE;
				}
				printf("Message: %s\n",incoming_msg);
			}
		}
	}
	return TRUE;
}
Exemple #9
0
static VALUE
rg_set_buffer_size(VALUE self, VALUE buffer_size)
{
    g_io_channel_set_buffer_size(_SELF(self), NUM2UINT(buffer_size));
    return self;
}
Exemple #10
0
int main(
    int              argc,
    char            *argv[])
{

    glob_t                   gbuf;
    int                      grc, i;
    GString                 *cmd;
    GError                  *err = NULL;

    GMainLoop *loop;

    GPtrArray    *child_args     = NULL;

    /* parse options */
    parse_options(&argc, &argv);

    /* set up logging */
    if (!logc_setup(&err)) {
        air_opterr("%s", err->message);
    }

    if (fd_nextdir == NULL) {
        air_opterr("The --nextdir switch is required");
    }

    child_args = g_ptr_array_sized_new(64);
    for (i=1; i < argc; i++) {
        /* Double dash indicates end of filedaemon's arguments */
        if (!strncmp(argv[i], "--", strlen(argv[i])) )
            continue;
        g_ptr_array_add(child_args, g_strdup(argv[i]));
    }
    g_ptr_array_add(child_args, NULL);

    if (child_args->len > 1) {
        if (fd_faildir == NULL) {
            air_opterr("The --faildir switch is required");
        }
    }

    cmd  = g_string_new("");

    loop = g_main_loop_new(NULL, FALSE);

    /* We need an input glob */
    if (!fd_inspec) {
        air_opterr("Input glob must be specified");
    }

    /* If an output destination is provided, make sure it's a directory */
    if (fd_outspec && !g_file_test(fd_outspec, G_FILE_TEST_IS_DIR )) {
        air_opterr("Output is not a directory");
    }

    /* Options check out; daemonize */
    if (!fd_nodaemon) {
        if (!daemonize()) {
            goto end;
        }
    }

    while (1) {
        /* Evaluate glob expression */
        grc = glob(fd_inspec, 0, NULL, &gbuf);

        if (grc == GLOB_NOSPACE) {
            g_error("Out of memory: glob allocation failure");
        }
#ifdef GLOB_NOMATCH
        /* HaX0riffic! Simulate behavior without NOMATCH where we have it. */
        else if (grc == GLOB_NOMATCH) {
            gbuf.gl_pathc = 0;
            gbuf.gl_pathv = NULL;
        }
#endif

        /* Iterate over glob paths, enqueueing. */
        for (i = 0; i < gbuf.gl_pathc; i++) {
            char      **child_envp            = {NULL};
            GError     *child_err             = NULL;

            GString    *filename_in           = NULL;
            GString    *filename_out          = NULL;
            GString    *filename_lock         = NULL;

            GIOChannel *file_in               = NULL;
            GIOChannel *file_out              = NULL;

            GIOChannel *child_stdin           = NULL;
            gint        child_stdin_fd        = -1;

            GIOChannel *child_stdout          = NULL;
            gint        child_stdout_fd       = -1;

            GPid          child_pid;
            int         len;

            fd_read_data_t  read_data;
            fd_write_data_t write_data;

            filename_in = g_string_new(gbuf.gl_pathv[i]);

            /* Skip non-regular files */
            if (!g_file_test(filename_in->str, G_FILE_TEST_IS_REGULAR) ) {
                g_string_free(filename_in, TRUE);
                continue;
            }

            /* Skip lockfiles */
            if (!strcmp(".lock", filename_in->str
                        + strlen(filename_in->str) - 5))
            {
                g_string_free(filename_in, TRUE);
                continue;
            }

            /* Generate lock path */
            if (!filename_lock) filename_lock = g_string_new("");
            g_string_printf(filename_lock, "%s.lock", filename_in->str);

            /* Skip files locked at queue time */
            if (g_file_test(filename_lock->str, G_FILE_TEST_IS_REGULAR)) {
                g_debug("file %s is locked", filename_in->str);
                g_string_free(filename_in, TRUE);
                g_string_free(filename_lock, TRUE);
                continue;
            }

            if (child_args->len == 1) {
                /* Do move or delete */
                GString *destpath = g_string_new("");
                char    *dbase    = NULL;
                /* Calculate move destination path */
                dbase = g_path_get_basename(filename_in->str);

                g_string_printf(destpath, "%s/%s", fd_nextdir, dbase);
                if (dbase) free(dbase);
                /* Do link */
                g_message("moving %s -> %s", filename_in->str, fd_nextdir);
                if (link(filename_in->str, destpath->str) < 0)
                    g_critical(
                        "error moving input file to destination directory: %s",
                        strerror(errno));
                /* Do delete */
                if (unlink(filename_in->str) < 0) {
                    g_critical("error deleting input file");
                }
                g_string_free(destpath, TRUE);
                g_string_free(filename_in, TRUE);
                g_string_free(filename_lock, TRUE);
                continue;
            }

            if (fd_lock) {
                fd_lock_file(filename_in->str);
            }

            file_in = g_io_channel_new_file(filename_in->str, "r", &err);

            if (file_in == NULL) {
                g_critical("Cannot open input file!");
            }

            g_io_channel_set_encoding(file_in, NULL, &err);

            if (err) {
                g_critical("error setting input encoding!");
            }

            g_io_channel_set_buffer_size(file_in, fd_bufsize);

            filename_out = g_string_new("");

            if (fd_outspec == NULL) {
                g_string_printf(filename_out, "%s", gbuf.gl_pathv[i]);
            } else {
                g_string_printf(filename_out, "%s/%s", fd_outspec,
                                gbuf.gl_pathv[i]);
            }

            len  = filename_out->len;

            if (g_strrstr(filename_out->str, ".")) {
                while (len-- > 0
                       && !g_str_has_suffix(filename_out->str, ".") )
                {
                    g_string_set_size(filename_out, filename_out->len - 1);
                }
                g_string_set_size(filename_out, filename_out->len - 1);
            }
            if (fd_outext) {
                g_string_append_printf(filename_out, ".%s", fd_outext);
            } else {
                g_string_append(filename_out, ".out");
            }

            g_message("%d: %s -> %s", i, filename_in->str, filename_out->str);

            file_out = g_io_channel_new_file(filename_out->str, "w", &err);

            if (file_out == NULL) {
                g_error("Cannot open output file!");
            }

            g_io_channel_set_encoding(file_out, NULL, &err);

            if (err) {
                g_error("error setting output encoding!");
            }

            g_io_channel_set_buffer_size(file_out, fd_bufsize);

            if (!g_spawn_async_with_pipes(".",
                                          (gchar **) child_args->pdata,
                                          child_envp,
                                          G_SPAWN_SEARCH_PATH |
                                          G_SPAWN_DO_NOT_REAP_CHILD,
                                          NULL,
                                          NULL,
                                          &child_pid,
                                          &child_stdin_fd,
                                          &child_stdout_fd,
                                          NULL,
                                          &child_err))
            {
                g_error("error spawning process: %s",
                        (child_err && child_err->message ? child_err->
                         message : "unknown error"));
            }
            g_debug("spawned process %d", i);

            /* Watch for process exit status */
            g_child_watch_add(child_pid, on_child_exit, filename_in->str);

            child_stdin = g_io_channel_unix_new(child_stdin_fd);

            if (child_stdin == NULL) {
                g_error("Cannot open child stdin!");
            }

            g_io_channel_set_encoding(child_stdin, NULL, &err);

            if (err) {
                g_error("error setting child stdin encoding!");
            }

            g_io_channel_set_buffer_size(child_stdin, fd_bufsize);

            child_stdout = g_io_channel_unix_new(child_stdout_fd);

            if (child_stdout == NULL) {
                g_error("Cannot open child stdout!");
            }

            g_io_channel_set_encoding(child_stdout, NULL, &err);

            if (err) {
                g_error("error setting child stdout encoding!");
            }


            g_io_channel_set_buffer_size(child_stdout, fd_bufsize);


            write_data.infile = file_in;
            write_data.buf    = g_malloc(g_io_channel_get_buffer_size(file_in));

            if (write_data.buf == NULL) {
                g_error("error allocating file_in buffer");
            }

            if (!g_io_add_watch(child_stdin,  G_IO_OUT | G_IO_PRI | G_IO_HUP |
                                G_IO_ERR, write_to_child, &write_data))
                g_error("Cannot add watch on GIOChannel!");

            read_data.outfile = file_out;
            read_data.loop    = loop;
            read_data.buf     = g_malloc(g_io_channel_get_buffer_size(file_out));

            if (write_data.buf == NULL) {
                g_error("error allocating file_in buffer");
            }

            if (!g_io_add_watch(child_stdout, G_IO_IN | G_IO_PRI | G_IO_HUP |
                                G_IO_ERR, read_from_child, &read_data))
                g_error("Cannot add watch on GIOChannel!");

            g_main_loop_run(loop);

            if (fd_lock) {
                fd_unlock_file(filename_in->str);
            }

            if (read_data.buf) {
                g_free(read_data.buf);
            }
            if (write_data.buf) {
                g_free(write_data.buf);
            }

            g_string_free(filename_in, TRUE);
            g_string_free(filename_out, TRUE);
            g_string_free(filename_lock, TRUE);
        }
        sleep(fd_poll_delay);
    }

  end:

    return 0;
}