Ejemplo n.º 1
0
/* abort routine originally from Cftp by Dieter Baron
 */
int ftp_abort(Socket* fp)
{
	char buf[4096];

#ifdef HAVE_LIBSSH
	if(ftp->session)
		/* FIXME: what? */
		return 0;
#endif

	if(!ftp_connected())
		return -1;

	ftp_set_close_handler();

	if (sock_check_pending(fp, false) == 1) {
		ftp_trace("There is data on the control channel, won't send ABOR\n");
		/* read remaining bytes from connection */
		while(fp && sock_read(fp, buf, sizeof(buf)) > 0)
			/* LOOP */ ;
		return 0;
	}

	ftp->ti.interrupted = true;
	ftp_err(_("Waiting for remote to finish abort...\n"));

	ftp_trace("--> telnet interrupt\n");
	if(sock_telnet_interrupt(ftp->ctrl) != 0)
		ftp_err("telnet interrupt: %s\n", strerror(errno));

	/* ftp_cmd("ABOR") won't work here,
	 * we must flush data between the ABOR command and ftp_read_reply()
	 */
	sock_krb_printf(ftp->ctrl, "ABOR");
	sock_printf(ftp->ctrl, "\r\n");
	sock_flush(ftp->ctrl);
	if(ftp_get_verbosity() == vbDebug)
		ftp_err("--> [%s] ABOR\n", ftp->url->hostname);
	else
		ftp_trace("--> [%s] ABOR\n", ftp->url->hostname);

    /* read remaining bytes from connection */
	while(fp && sock_read(fp, buf, sizeof(buf)) > 0)
		/* LOOP */ ;

	/* we expect a 426 or 226 reply here... */
	ftp_read_reply();
	if(ftp->fullcode != 426 && ftp->fullcode != 226)
		ftp_trace("Huh!? Expected a 426 or 226 reply\n");

	/* ... and a 226 or 225 reply here, respectively */
	/* FIXME: should skip this reply if prev. reply wasn't 426 or 226 ? */
	ftp_read_reply();
	if(ftp->fullcode != 226 && ftp->fullcode != 225)
		ftp_trace("Huh!? Expected a 226 or 225 reply\n");

	return -1;
}
Ejemplo n.º 2
0
static int netchar_open(struct inode* inodp, struct file* fp)
{
	int                ret;
	struct fop_request req;
	struct fop_reply   rep;

	memset(&req, 0, sizeof(req));
	memset(&rep, 0, sizeof(rep));

	_PKI("open....");

	req.call  = FOP_OPEN;
	req.flags = fp->f_flags;
	req.mode  = fp->f_mode;

	ret = sock_write(nc_socket, &req, sizeof(req));

	_PKI("sendmsg: %i", ret);

	ret = sock_read(nc_socket, &rep, sizeof(rep));

	_PKI("recvmsg: %i", ret);
	_PKI("open returning %i", rep.open);

	return rep.open;
}
Ejemplo n.º 3
0
uint16_t proto_receive(proto_t** p, sock_t* s)
{
  proto_t* self = *p;

  uint32_t rc;

  if(self == NULL)
  {
    self = init();
    *p = self;
  }

  while(true)
  {
    rc = sock_read(s);

    if(check_for_message(self, s))
      return get_message_type(self);

    if(rc & (ASIO_ERROR | ASIO_WOULDBLOCK))
      break;
  }

  return PROTO_NOP;
}
Ejemplo n.º 4
0
static int waitreply(int res) {
	char result[1024];
	char *ch, *str;
	int reply = -1;

	ftruncate (2, 0);
	lseek (2, 0, SEEK_SET);
	result[0] = '\0';
	while (sock_ready () && sock_read (word, 512) > 1) {
		str = word;
		if (reply == -1 && (reply = (word[0] == '+'))) {
			if ((ch = strchr (str, '\r')) || (ch = strchr (str, '\n'))) {
				*ch = '\0';
				snprintf (result, 1023, "### %s %d \"%s\"\n", cmd, reply, str);
				str = ch + (ch[1] == '\n' ? 2 : 1);
			}
		}
		// TODO: Fix possible \r\n issues
		if ((ch = strstr (str, "\r\n.")))
			*ch = '\0';
		write (2, str, strlen (str));
	}
	write (2, "\n", 1);
	if (res) {
		if (result[0] == '\0')
			snprintf (result, 1023, "### %s %d \"\"\n", cmd, reply);
		write (1, result, strlen (result));
	}
	return reply;
}
Ejemplo n.º 5
0
int recvChunk( PZ_BUF zBuf, int sockfd, int len)
{
    int i, rlen = 0;
    int i_timeout;

    zBufSetSize(zBuf, zBuf->length + len);
    do
    {
        i_timeout = 10;
        if ((i = sock_read( sockfd, zBuf->buf+zBuf->length, len-rlen, &i_timeout)) <= 0)
            //        if ((i = recv(sockfd, zBuf->buf+zBuf->length, len-rlen, 0)) <= 0)
        {
            return(-1);
        }
        zBuf->length += i;
        rlen += i;
        ZInfo4(DBG_MISC, "\t\tRcvd %d bytes accumulated->%d totallen->%d", i, rlen, len);
    }
    while (rlen < len && i);

    zBuf->buf[zBuf->length] = '\0';
    ZInfo4(DBG_MISC, "\t\tExiting with len->%d", rlen);

    return rlen;
}
Ejemplo n.º 6
0
int sock_read(int sock, char *buff, int bufLen, int ntimeout)
{
	fd_set fds;
	int readret, selrtn;
	struct timeval timeout;

	timeout.tv_sec = ntimeout;
	timeout.tv_usec = 0;

	FD_ZERO(&fds);
	FD_SET(sock, &fds);

	selrtn = select(sock + 1, &fds, NULL, NULL, &timeout);
	if (selrtn < 0)
	{
		write_log("select error:[%d][%s]", errno, strerror(errno));
		return -1;
	}

	if (selrtn == 0)
	{
		write_log("select timeout:[%d][%s]", errno, strerror(errno));		
		return 0;
	}	

	return sock_read(sock, buff, bufLen);
}
Ejemplo n.º 7
0
/*
 * Fill the internal buffer. If an error occurs or if the read
 * operation timed out -1 is returned.
 * @param S A Socket object
 * @param timeout The number of seconds to wait for data to be read
 * @return TRUE (the length of data read) or -1 if an error occured
 */
static int fill(Socket_T S, int timeout) {
        int n;
        S->offset = 0;
        S->length = 0;
        /* Optimizing, assuming a request/response pattern and that a udp_write
         was issued before we are called, we don't have to wait for data */
        if (S->type == SOCK_DGRAM)
                timeout = 0;
        /* Read as much as we can, but only block on the first read */
        while (RBUFFER_SIZE > S->length) {
                if (S->ssl) {
                        n = recv_ssl_socket(S->ssl, S->buffer + S->length, RBUFFER_SIZE-S->length, timeout);
                } else {
                        n = (int)sock_read(S->socket, S->buffer + S->length,  RBUFFER_SIZE-S->length, timeout);
                }
                timeout = 0;
                if (n > 0) {
                        S->length += n;
                        continue;
                }  else if (n < 0) {
                        if (errno == EAGAIN || errno == EWOULDBLOCK || S->type == SOCK_DGRAM) break;
                        return -1;
                } else
                        break;
        }
        return S->length;
}
int __mg_handle_request (int clifd, int req_id, int cli)
{
    int n;
    char* buff;
    size_t len_data;

    if ((n = sock_read (clifd, &len_data, sizeof (size_t))) == SOCKERR_IO)
        return SOCKERR_IO;
    else if (n == SOCKERR_CLOSED) {
        goto error;
    }

    if (len_data <= sizeof (_request_data_buff)) {
        buff = _request_data_buff;
    }
    else {
        buff = malloc (len_data);
        if (buff == NULL)
            return SOCKERR_INVARG;
    }

    if ((n = sock_read (clifd, buff, len_data)) == SOCKERR_IO)
        return SOCKERR_IO;
    else if (n == SOCKERR_CLOSED) {
        goto error;
    }

    if (req_id > MAX_REQID || req_id <= 0 || handlers [req_id - 1] == NULL)
        return SOCKERR_INVARG;

    n = handlers [req_id - 1] (cli, clifd, buff, len_data);

    if (len_data > sizeof (_request_data_buff))
        free (buff);

    if (n == SOCKERR_IO)
        goto error;

    if (req_id == REQID_IAMLIVE && mgClients [cli].has_dirty)
        __mg_check_dirty_znode (cli);

    return n;

error:
    __mg_remove_client (cli, clifd);
    return SOCKERR_CLOSED;
}
Ejemplo n.º 9
0
static ssize_t netchar_read(struct file* fp, char *buffer,
                            size_t length, loff_t* offset)
{
	int                ret;
	struct fop_request req;
	struct fop_reply   rep;
	void*              payload = NULL;

	memset(&req, 0, sizeof(req));
	memset(&rep, 0, sizeof(rep));

	_PKI("read...");

	req.call  = FOP_READ;
	req.count = length;

	ret = sock_write(nc_socket, &req, sizeof(req));

	_PKI("sendmsg: %i", ret);

	ret = sock_read(nc_socket, &rep, sizeof(rep));

	_PKI("recvmsg: %i", ret);
	_PKI("read returning %zi", rep.read);

	if (rep.read > 0) {

		payload = kmalloc(rep.read, GFP_KERNEL);
		if(payload == NULL){
			_PKA("Read Error: kmalloc returned NULL");
			return 0;
		}

		ret = sock_read(nc_socket, payload, rep.read);

		_PKI("payload read returned: %i", ret);

		ret = copy_to_user(buffer, payload, rep.read);

		_PKI("payload copy returned: %i", ret);

		kfree(payload);
		payload = NULL;
	}

	return rep.read;
}
Ejemplo n.º 10
0
/*
 * "background" process handling echo + discard TCP sockets.
 */
static void echo_discard_daemon (void)
{
  sock_type *s = (sock_type*) &tcp_echo_sock;

  if (sock_dataready(s))
  {
    BYTE buf[ETH_MAX_DATA];
    int  len = sock_read (s, buf, sizeof(buf));
    sock_write (s, buf, len);
  }
}
Ejemplo n.º 11
0
/**
 * Wait answer from socket
 *
 * @param __maxlen - max buffer length
 * @param __buf - buffer to store answer
 */
static void
lrvm_ipc_wait_answer (int __maxlen, char *__buf)
{
  struct timespec timestruc;
  int trycount = read_timeout / read_delay;

  if (trycount <= 0)
    {
      trycount = 1;
    }

  timestruc.tv_sec = read_delay / NSEC_COUNT;
  timestruc.tv_nsec = read_delay % NSEC_COUNT;

  for (;;)
    {
      if (sock_read (sock, __maxlen, __buf) > 0)
        break;
      trycount--;
      if (!trycount)
        {
          /* No answer for too long. Terminate executing. */
          term ();
        }
      nanosleep (&timestruc, 0);
    }

  if (!strncmp (__buf, "-ERR", 4))
    {
      /* Got an error */
      if (!exiting)
        {
          /*
           * If not already exiting, try to send bug report to
           * server stuff
           */
          char buf[1024];
          int i, n;

          exiting = 1;
          n = strlen (__buf);
          strcpy (buf, "");

          for (i = 0; i < n - 4; i++)
            {
              buf[i] = __buf[i + 4];
            }
          buf[i] = 0;

          lrvm_ipc_send_command ("exec_error", buf);
        }
      term ();
    }
}
Ejemplo n.º 12
0
Archivo: socket.c Proyecto: lb1a/avfs
/* Reads buflen bytes into buffer until it's full.
 * Returns 0 on success, -1 on error */
int sock_fullread(nsocket *sock, char *buffer, int buflen) 
{
    char *pnt; /* current position within buffer */
    int len;
    pnt = buffer;
    while (buflen > 0) {
	len = sock_read(sock, pnt, buflen);
	if (len < 0) return len;
	buflen -= len;
	pnt += len;
    }
    return 0;
}
Ejemplo n.º 13
0
unsigned int ZION_CALLBACK TcpThreadFunc(void * point)
{
	char *p = (char*)point;
	SOCK_HANDLE handle;
	SOCK_ADDR  sock_addr;
	char read_buf[1024];

	sock_init();
	if(sock_str2addr(p, &sock_addr)==NULL) 
	{
		printf("tcp sock_str2addr function error\n");
		goto FINISH_STATE;
	}


	handle = sock_bind(&sock_addr, 0);
	if(handle == SOCK_INVALID_HANDLE)
	{
		printf("tcp bind function error\n");
		goto ERROR_STATE;
	}

	printf("tcp %s wait for client connect....\n", p);

	handle =  sock_accept(handle, NULL);
	if(handle == SOCK_INVALID_HANDLE)
	{
		printf("tcp socket_accept function error\n");
		goto ERROR_STATE;
	}

	printf("tcp client connect access\n");

	while(1)
	{
		memset(read_buf, 0, sizeof(read_buf));
		//sock_readbuf(handle, (void*)read_buf, sizeof(read_buf));
		sock_read(handle, (void*)read_buf, sizeof(read_buf));
		printf("tcp client send '%s'\n", read_buf);
		sock_write(handle, (void*)read_buf, (int)strlen(read_buf));
	}


ERROR_STATE:
	sock_unbind(handle);
FINISH_STATE:
	sock_final();

	return 0;
}
Ejemplo n.º 14
0
gint socks4_connect(SockInfo *sock, const gchar *hostname, gushort port)
{
	guchar socks_req[1024];
	struct hostent *hp;

	g_return_val_if_fail(sock != NULL, -1);
	g_return_val_if_fail(hostname != NULL, -1);

	debug_print("socks4_connect: connect to %s:%u\n", hostname, port);

	socks_req[0] = 4;
	socks_req[1] = 1;
	*((gushort *)(socks_req + 2)) = htons(port);

	/* lookup */
	if ((hp = my_gethostbyname(hostname)) == NULL) {
		g_warning("socks4_connect: cannot lookup host: %s", hostname);
		return -1;
	}
	if (hp->h_length != 4) {
		g_warning("socks4_connect: invalid address length for host: %s", hostname);
		return -1;
	}
	memcpy(socks_req + 4, (guchar *)hp->h_addr, 4);

	/* userid (empty) */
	socks_req[8] = 0;

	if (sock_write_all(sock, (gchar *)socks_req, 9) != 9) {
		g_warning("socks4_connect: SOCKS4 initial request write failed");
		return -1;
	}

	if (sock_read(sock, (gchar *)socks_req, 8) != 8) {
		g_warning("socks4_connect: SOCKS4 response read failed");
		return -1;
	}
	if (socks_req[0] != 0) {
		g_warning("socks4_connect: SOCKS4 response has invalid version");
		return -1;
	}
	if (socks_req[1] != 90) {
		g_warning("socks4_connect: SOCKS4 connection to %u.%u.%u.%u:%u failed. (%u)", socks_req[4], socks_req[5], socks_req[6], socks_req[7], ntohs(*(gushort *)(socks_req + 2)), socks_req[1]);
		return -1;
	}

	debug_print("socks4_connect: SOCKS4 connection to %s:%u successful.\n", hostname, port);

	return 0;
}
Ejemplo n.º 15
0
static void read_sensors_hddtemp(void)
{
    Socket *s;
    static gchar *old = NULL;
    gchar buffer[1024];
    gint len = 0;

    if ((s = sock_connect("127.0.0.1", 7634))) {
	while (!len)
	    len = sock_read(s, buffer, sizeof(buffer));
        sock_close(s);

	if (len > 2 && buffer[0] == '|' && buffer[1] == '/') {
	    gchar **disks;
	    int i;

	    if (old)
		g_free(old);

	    old = g_strdup("[Hard Disk Temperature]\n");

	    disks = g_strsplit(buffer, "\n", 0);
	    for (i = 0; disks[i]; i++) {
		gchar **fields = g_strsplit(disks[i] + 1, "|", 5);

		/*
		 * 0 -> /dev/hda
		 * 1 -> FUJITSU MHV2080AH
		 * 2 -> 41
		 * 3 -> C
		 */
		old = h_strdup_cprintf("\n%s (%s)=%s\302\260%s\n",
				      old,
				      fields[1], fields[0],
				      fields[2], fields[3]);

		g_strfreev(fields);
	    }

	    g_strfreev(disks);
	}
    } else {
	g_free(old);
	old = NULL;
    }

    if (old) {
	sensors = g_strconcat(sensors, "\n", old, NULL);
    }
}
Ejemplo n.º 16
0
static int FILE_recv_binary(Socket* in, FILE *out)
{
	time_t then = time(0) - 1;
	time_t now;

	ftp_set_close_handler();

	if(foo_hookf)
		foo_hookf(&ftp->ti);
	ftp->ti.begin = false;

	sock_clearerr_in(in);
	clearerr(out);

	char* buf = xmalloc(FTP_BUFSIZ);
	while (!sock_eof(in)) {
		if(wait_for_input() != 0) {
			ftp_trace("wait_for_input() returned non-zero\n");
			break;
		}

    const ssize_t n = sock_read(in, buf, FTP_BUFSIZ);
		if (n <= 0)
			break;

		if(ftp_sigints() > 0) {
			ftp_trace("break due to sigint\n");
			break;
		}

		if(fwrite(buf, sizeof(char), n, out) != n)
			break;

		ftp->ti.size += n;

		if(foo_hookf) {
			now = time(0);
			if(now > then) {
				foo_hookf(&ftp->ti);
				then = now;
			}
		}
	}

	free(buf);
	ftp_set_close_handler();

	return maybe_abort_in(in, out);
}
Ejemplo n.º 17
0
int SocketPeek(SocketRef const socket, uv_buf_t *const out) {
	if(!socket) return UV_EINVAL;
	if(0 == socket->rd->len) {
		FREE(&socket->rdmem);
		int rc = sock_read(socket, READ_BUFFER, socket->rd);
		if(UV_EAGAIN == rc) return rc;
		if(rc < 0) {
			socket->err = rc;
			return rc;
		}
		socket->rdmem = socket->rd->base;
	}
	*out = *socket->rd;
	return 0;
}
Ejemplo n.º 18
0
/*
 * recieve line to zBuf.buf+zBuf.off, return line length
 */
int recvNextLine( int sockfd, PZ_BUF zBuf)
{
    int len = 1;
    int i_timeout = 60;

    while ( sock_read( sockfd, zBuf->buf + zBuf->length, 1, &i_timeout)>0 &&
            zBuf->buf[zBuf->length++] != '\n')
    {
        len++;
        if (zBuf->length+1 >= zBuf->capacity)
            zBufSetSize(zBuf, zBuf->length + BUFSIZE);
    }
    zBuf->buf[zBuf->length] = '\0';

    return len;
}
Ejemplo n.º 19
0
int32_t _connector_read(struct handler_t* h)
{
    char* buffer;
    int32_t nread, nwrite, res;
    connector_t* con = (connector_t*)h;

    nwrite = connbuffer_write_len(con->read_buf);
    assert(nwrite >= 0);

    // read buffer full fail
    if (0 == nwrite) {
        printf("fd[%d] read buffer full.\n", con->h.fd);
        return -1;
    }

    // still full, read fail, reactor will close connector
    if (0 == nwrite) return -1;

    // read socket
    buffer = connbuffer_write_buffer(con->read_buf);
    res = sock_read(con->h.fd, buffer, nwrite);
    if (res < 0) {
        // can't read now
        if (ERR_EAGAIN == ERRNO || ERR_EWOULDBLOCK == ERRNO || ERR_EINTR == ERRNO) {
            return 0;
        } else {
            printf("fd[%d] read errno=%d\n", con->h.fd, ERRNO);
            return -1;
        }
    } else if (0 == res) {
        // printf("fd[%d] peer close\n", con->h.fd);
        return -1;
    } else {
        connbuffer_write_nocopy(con->read_buf, res);
        buffer = connbuffer_read_buffer(con->read_buf);
        nread = connbuffer_read_len(con->read_buf);
        assert(buffer && nread);
        res = con->read_cb(con->h.fd, buffer, nread);
        if (res > 0) {
            connbuffer_read_nocopy(con->read_buf, res);
        } else {
            return res;
        }
    }
    return 0;
}
Ejemplo n.º 20
0
static ssize_t netchar_write(struct file* fp, const char *buffer,
                             size_t length, loff_t* offset)
{
	int                ret;
	struct fop_request req;
	struct fop_reply   rep;
	void*        payload = NULL;

	memset(&req, 0, sizeof(req));
	memset(&rep, 0, sizeof(rep));

	_PKI("write...");

	req.call  = FOP_WRITE;
	req.count = length;

	ret = sock_write(nc_socket, &req, sizeof(req));

	_PKI("sendmsg: %i", ret);

	payload = kmalloc(length, GFP_KERNEL);
	if(payload == NULL){
		_PKA("Write Error: kmalloc returned NULL");
		return 0;
	}
	
	ret = copy_from_user(payload, buffer, length);

	_PKI("payload copy returned: %i", ret);

	ret = sock_write(nc_socket, payload, length);

	kfree(payload);
	payload = NULL;

	_PKI("write data: %i", ret);
	
	ret = sock_read(nc_socket, &rep, sizeof(rep));

	_PKI("recvmsg: %i", ret);
	_PKI("`write returning %zi", rep.write);

	return rep.read;
}
Ejemplo n.º 21
0
http_request_t *
http_request (const char *url, int port) {
  http_request_t *req = NULL;
  socket_t *sock = NULL;
  char *buf = NULL;
  char *data = NULL;
  size_t len = 0;
  size_t size = 0;
  int rc = 0;

  // init
  sock = sock_tcp_client_new(url, port);
  if (NULL == sock) { return NULL; }

  data = (char *) malloc(sizeof(char) * MAX_REQUEST_BUFFER_SIZE);
  if (NULL == data) {
    sock_free(sock);
    return NULL;
  }

  // connect
  rc = sock_connect(sock);
  if (rc < 0) {
    sock_free(sock);
    return NULL;
  }

  // read
  while ((len = sock_read(sock, buf, MAX_REQUEST_BUFFER_SIZE)) > 0) {
    printf("%s\n", buf);
  }

  req = http_request_new((http_socket_t *) sock, buf);
  if (NULL == req) {
    sock_free(sock);
    return NULL;
  }

  sock_close(sock);

  return NULL;
}
Ejemplo n.º 22
0
static int _udpcli_thread_func(void *args)
{
	char buf[128] = "hello,world";
	int ret= 0;

	/* in kthread_create, it blocks all signal. so open it at here */
	allow_signal(SIGKILL);
	allow_signal(SIGTERM);

	if( -1 == sock_udpcli_connect_srv(udpcli_sock, "172.20.1.35", 8080) )
	{
		printk("error: connect to server error\n");
		goto out;
	}
	_udpcli_running  = 1;
	set_current_state(TASK_INTERRUPTIBLE);

	while( !kthread_should_stop() && !signal_pending(current) )
	{
#if 0
		if( -1 == sock_write(udpcli_sock, buf, sizeof(buf), NULL) )
		{
			printk("error: cannot send message\n");
			goto out;
		}
#endif

		if ( 0 < (ret = sock_read(udpcli_sock, buf, sizeof(buf), NULL)) )
		{
			printk("%s: recv len=%d %s\n", __FUNCTION__, ret, buf);
		}else{
			printk("%s: recv error\n", __FUNCTION__);
		}
		ssleep(1);
	}

out:
	_udpcli_running  = 0;
	printk("%s: exit\n", __FUNCTION__);
	return 0;
}
Ejemplo n.º 23
0
Archivo: socket.c Proyecto: lb1a/avfs
int sock_readfile_blocked(nsocket *sock, off_t length,
			  sock_block_reader reader, void *userdata) 
{
    char buffer[BUFSIZ];
    int ret;
    off_t done = 0;
    do {
	ret = sock_read(sock, buffer, BUFSIZ);
	if (ret < 0) {
	    if (length == -1 && ret == SOCK_CLOSED) {
		/* Not an error condition. */
		return 0;
	    }
	    return ret;
	} 
	done += ret;
	sock_call_progress(done, length);
	(*reader)(userdata, buffer, ret);
    } while ((length == -1) || (done < length));
    return 0;
}
Ejemplo n.º 24
0
static int
cmd_ipc                            (int __argc, char **__argv)
{
  char cmd[4096], dummy[1024];
  int sock=console_get_socket ();

  if (__argc!=2)
    {
      console_log ("Usage: ipc <ipc command>\n");
      return 0;
    }

  strcpy (cmd, __argv[1]);

  if (!strcmp (cmd, ""))
    return 0;

  if (sock>0)
    {
      char ans[65536];
      int a;
      if ((a=sock_answer (sock, "%s\n", cmd)))
        goto __fail_;

      if (sock_read (sock, 65536, ans)<0 || MSG_DISCONNECT (ans))
        goto __fail_;

      console_log ("%s", ans);
    } else
      console_log ("Not connected to server.\n");

  trim (cmd, dummy);
  if (!strcmp (dummy, "exit"))
    disconnect_from_server ();

  return 0;
__fail_:
  disconnect_from_server ();
  return 0;
}
Ejemplo n.º 25
0
STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
    mp_int_t max_len = mp_obj_get_int(len_in);
    vstr_t vstr;
    // +1 to accommodate for trailing \0
    vstr_init_len(&vstr, max_len + 1);

    int err;
    mp_uint_t len = sock_read(self_in, vstr.buf, max_len, &err);

    if (len == MP_STREAM_ERROR) {
        vstr_clear(&vstr);
        mp_raise_OSError(err);
    }

    if (len == 0) {
        vstr_clear(&vstr);
        return mp_const_empty_bytes;
    }

    vstr.len = len;
    return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
Ejemplo n.º 26
0
int vsock_fill ( vsock_t *vsock ) {
    int rc;

    if ( vsock == NULL ) {
        error("vsock_fill: bad argument");
        return -1;
    }
    if ( vsock->ibuf == NULL ) {
        error("vsock_fill: buffer not allocated");
        return -1;
    }

    rc  = sock_read( vsock->s, vsock->ibuf, vsock->ilen, vsock->itimeout );

    vsock->iptr = vsock->ibuf;

    if ( rc >= 0 )
        vsock->icnt = rc;
    else 
        vsock->icnt = 0;
    debug("fill buffer with %d chars ", vsock->icnt);
    return rc;
}
Ejemplo n.º 27
0
int recvChunk2( FILE* file, int sockfd, int len)
{
    int i, rlen = 0;
    int i_timeout;
    char            request[1024*64];

    do
    {
        i_timeout = 10;
        if ((i = sock_read( sockfd, request, 1024*64, &i_timeout)) <= 0)
        {
            return(-1);
        }
        rlen += i;
        ZInfo4(DBG_MISC, "\t\tRcvd %d bytes accumulated->%d totallen->%d", i, rlen, len);
        fwrite( request, 1, i, file );
    }
    while (rlen < len && i);

    ZInfo4(DBG_MISC, "\t\tExiting with len->%d", rlen);

    return rlen;
}
Ejemplo n.º 28
0
static int netchar_release(struct inode* inodp, struct file* fp)
{
	int                ret;
	struct fop_request req;
	struct fop_reply   rep;
	
	memset(&req, 0, sizeof(req));
	memset(&rep, 0, sizeof(rep));

	_PKI("release...");

	req.call  = FOP_RELEASE;

	ret = sock_write(nc_socket, &req, sizeof(req));

	_PKI("sendmsg: %i", ret);

	ret = sock_read(nc_socket, &rep, sizeof(rep));

	_PKI("recvmsg: %i", ret);
	_PKI("release returning %i", rep.close);

	return rep.close;
}
Ejemplo n.º 29
0
protocol_s* http1_alloc(intptr_t fd, http_settings_s* settings) {
  validate_mem();
  // HTTP/1.1 should send a busy response
  // if there aren't enough available file descriptors.
  if (sock_max_capacity() - sock_uuid2fd(fd) <= HTTP_BUSY_UNLESS_HAS_FDS)
    goto is_busy;
  // get an http object from the pool
  http1_protocol_s* http = pool_pop();
  // of malloc one
  if (http == NULL)
    http = malloc(HTTP1_PROTOCOL_SIZE);
  // review allocation
  if (http == NULL)
    return NULL;

  // we shouldn't update the `http` protocol as a struct, as this will waste
  // time as the whole buffer will be zeroed out when there is no need.

  // setup parsing state
  http->buffer_pos = 0;
  // setup protocol callbacks
  http->protocol = (protocol_s){
      .service = HTTP1,
      .on_data = (void (*)(intptr_t, protocol_s*))http1_on_data,
      .on_close = (void (*)(protocol_s*))http1_free,
  };
  // setup request data
  http->request = (http_request_s){
      .metadata.max_headers = HTTP1_MAX_HEADER_COUNT,
      .metadata.fd = fd,
      .metadata.owner = http,
  };
  // update settings
  http->settings = settings;
  http->on_request = settings->on_request;
  // set the timeout
  server_set_timeout(fd, settings->timeout);
  return (protocol_s*)http;

is_busy:
  if (settings->public_folder && settings->public_folder_length) {
    size_t p_len = settings->public_folder_length;
    struct stat file_data = {};
    char fname[p_len + 8 + 1];
    memcpy(fname, settings->public_folder, p_len);
    if (settings->public_folder[p_len - 1] == '/' ||
        settings->public_folder[p_len - 1] == '\\')
      p_len--;
    memcpy(fname + p_len, "/503.html", 9);
    p_len += 9;
    if (stat(fname, &file_data))
      goto busy_no_file;
    // check that we have a file and not something else
    if (!S_ISREG(file_data.st_mode) && !S_ISLNK(file_data.st_mode))
      goto busy_no_file;
    int file = open(fname, O_RDONLY);
    if (file == -1)
      goto busy_no_file;
    sock_packet_s* packet;
    packet = sock_checkout_packet();
    memcpy(packet->buffer,
           "HTTP/1.1 503 Service Unavailable\r\n"
           "Content-Type: text/html\r\n"
           "Connection: close\r\n"
           "Content-Length: ",
           94);
    p_len = 94 + http_ul2a(packet->buffer + 94, file_data.st_size);
    memcpy(packet->buffer + p_len, "\r\n\r\n", 4);
    p_len += 4;
    if (BUFFER_PACKET_SIZE - p_len > file_data.st_size) {
      if (read(file, packet->buffer + p_len, file_data.st_size) < 0) {
        close(file);
        sock_free_packet(packet);
        goto busy_no_file;
      }
      close(file);
      packet->length = p_len + file_data.st_size;
      sock_send_packet(fd, packet);
    } else {
      packet->length = p_len;
      sock_send_packet(fd, packet);
      sock_sendfile(fd, file, 0, file_data.st_size);
    }
    return NULL;
  }
busy_no_file:
  sock_write(fd,
             "HTTP/1.1 503 Service Unavailable\r\nContent-Length: "
             "13\r\n\r\nServer Busy.",
             68);
  return NULL;
}

/* *****************************************************************************
HTTP/1.1 protocol bare-bones implementation
*/

#define HTTP_BODY_CHUNK_SIZE 3072  // 4096

/* parse and call callback */
static void http1_on_data(intptr_t uuid, http1_protocol_s* protocol) {
  ssize_t len = 0;
  ssize_t result;
  char buff[HTTP_BODY_CHUNK_SIZE];
  char* buffer;
  http_request_s* request = &protocol->request;
  for (;;) {
    // handle requests with no file data
    if (request->body_file <= 0) {
      // request headers parsing
      if (len == 0) {
        buffer = protocol->buffer;
        // make sure headers don't overflow
        len = sock_read(uuid, buffer + protocol->buffer_pos,
                        HTTP1_MAX_HEADER_SIZE - protocol->buffer_pos);
        // update buffer read position.
        protocol->buffer_pos += len;
      }
      if (len <= 0) {
        return;
      }
      // parse headers
      result =
          http1_parse_request_headers(buffer, protocol->buffer_pos, request);
      // review result
      if (result >= 0) {  // headers comeplete
        // mark buffer position, for HTTP pipelining
        protocol->buffer_pos = result;
        // are we done?
        if (request->content_length == 0 || request->body_str) {
          goto handle_request;
        }
        if (request->content_length > protocol->settings->max_body_size) {
          goto body_to_big;
        }
        // initialize or submit body data
        result =
            http1_parse_request_body(buffer + result, len - result, request);
        if (result >= 0) {
          protocol->buffer_pos += result;
          goto handle_request;
        } else if (result == -1)  // parser error
          goto parser_error;
        goto parse_body;
      } else if (result == -1)  // parser error
        goto parser_error;
      // assume incomplete (result == -2), even if wrong, we're right.
      len = 0;
      continue;
    }
    if (request->body_file > 0) {
    parse_body:
      buffer = buff;
      // request body parsing
      len = sock_read(uuid, buffer, HTTP_BODY_CHUNK_SIZE);
      if (len <= 0)
        return;
      result = http1_parse_request_body(buffer, len, request);
      if (result >= 0) {
        // set buffer pos for piplining support
        protocol->buffer_pos = result;
        goto handle_request;
      } else if (result == -1)  // parser error
        goto parser_error;
      if (len < HTTP_BODY_CHUNK_SIZE)  // pause parser for more data
        return;
      goto parse_body;
    }
    continue;
  handle_request:
    // review required headers / data
    if (request->host == NULL)
      goto bad_request;
    http_settings_s* settings = protocol->settings;
    // call request callback
    if (protocol && settings &&
        (protocol->settings->public_folder == NULL ||
         http_response_sendfile2(NULL, request, settings->public_folder,
                                 settings->public_folder_length, request->path,
                                 request->path_len, settings->log_static))) {
      protocol->on_request(request);
    }
    // clear request state
    http_request_clear(request);
    // rotate buffer for HTTP pipelining
    if (result >= len) {
      len = 0;
    } else {
      memmove(protocol->buffer, buffer + protocol->buffer_pos, len - result);
      len -= result;
    }
    // restart buffer position
    protocol->buffer_pos = 0;
    buffer = protocol->buffer;
  }
  // no routes lead here.
  fprintf(stderr,
          "I am lost on a deserted island, no code can reach me here :-)\n");
  return;  // How did we get here?
parser_error:
  if (request->headers_count == request->metadata.max_headers)
    goto too_big;
bad_request:
  /* handle generally bad requests */
  {
    http_response_s response = http_response_init(request);
    response.status = 400;
    http_response_write_body(&response, "Bad Request", 11);
    http_response_finish(&response);
    sock_close(uuid);
    protocol->buffer_pos = 0;
    return;
  }
too_big:
  /* handle oversized headers */
  {
    http_response_s response = http_response_init(request);
    response.status = 431;
    http_response_write_body(&response, "Request Header Fields Too Large", 31);
    http_response_finish(&response);
    sock_close(uuid);
    protocol->buffer_pos = 0;
    return;
  body_to_big:
    /* handle oversized body */
    {
      http_response_s response = http_response_init(request);
      response.status = 413;
      http_response_write_body(&response, "Payload Too Large", 17);
      http_response_finish(&response);
      sock_close(uuid);
      protocol->buffer_pos = 0;
      return;
    }
  }
}

/* *****************************************************************************
HTTP/1.1 listenning API implementation
*/

#undef http1_listen

static void http1_on_init(http_settings_s* settings) {
  if (settings->timeout == 0)
    settings->timeout = 5;
  if (settings->max_body_size == 0)
    settings->max_body_size = HTTP_DEFAULT_BODY_LIMIT;
  if (settings->public_folder) {
    settings->public_folder_length = strlen(settings->public_folder);
    if (settings->public_folder[0] == '~' &&
        settings->public_folder[1] == '/' && getenv("HOME")) {
      char* home = getenv("HOME");
      size_t home_len = strlen(home);
      char* tmp = malloc(settings->public_folder_length + home_len + 1);
      memcpy(tmp, home, home_len);
      if (home[home_len - 1] == '/')
        --home_len;
      memcpy(tmp + home_len, settings->public_folder + 1,
             settings->public_folder_length);  // copy also the NULL
      settings->public_folder = tmp;
      settings->private_metaflags |= 1;
      settings->public_folder_length = strlen(settings->public_folder);
    }
  }
}
static void http1_on_finish(http_settings_s* settings) {
  if (settings->private_metaflags & 1)
    free((void*)settings->public_folder);
  if (settings->private_metaflags & 2)
    free(settings);
}

int http1_listen(const char* port,
                 const char* address,
                 http_settings_s settings) {
  if (settings.on_request == NULL) {
    fprintf(
        stderr,
        "ERROR: http1_listen requires the .on_request parameter to be set\n");
    exit(11);
  }
  http_settings_s* settings_copy = malloc(sizeof(*settings_copy));
  *settings_copy = settings;
  settings_copy->private_metaflags = 2;
  return server_listen(.port = port, .address = address,
                       .on_start = (void*)http1_on_init,
                       .on_finish = (void*)http1_on_finish,
                       .on_open = (void*)http1_alloc, .udata = settings_copy);
}
Ejemplo n.º 30
0
int main(int argc, char *argv[])
{
    complex_t coord_point, julia_constant;
    double x_max, x_min, y_max, y_min, x_resolution, y_resolution;
    double divergent_limit;
    char file_message[160];
    char filename[100];
    int icount, imax_iterations;
    int ipixels_across, ipixels_down;
    int i, j, k, julia, alternate_equation;
    int imin, imax, jmin, jmax;
    int work[5];
    header_t *result = NULL;
    /* make an integer array of size [N x M] to hold answers. */
    int *in_grid_array, *out_grid_array = NULL;
    int numprocs;
    int  namelen;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int num_colors;
    color_t *colors = NULL;
    MPI_Status status;
    int listener;
    int save_image = 0;
    int optval;
    int num_children = DEFAULT_NUM_SLAVES;
    int master = 1;
    MPI_Comm parent, *child_comm = NULL;
    MPI_Request *child_request = NULL;
    int error_code, error;
    char error_str[MPI_MAX_ERROR_STRING];
    int length;
    int index;
    int pid;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Comm_get_parent(&parent);
    MPI_Get_processor_name(processor_name, &namelen);

    pid = getpid();

    if (parent == MPI_COMM_NULL)
    {
	if (numprocs > 1)
	{
	    printf("Error: only one process allowed for the master.\n");
	    PrintUsage();
	    error_code = MPI_Abort(MPI_COMM_WORLD, -1);
	    exit(error_code);
	}

	printf("Welcome to the Mandelbrot/Julia set explorer.\n");

	master = 1;

	/* Get inputs-- region to view (must be within x/ymin to x/ymax, make sure
	xmax>xmin and ymax>ymin) and resolution (number of pixels along an edge,
	N x M, i.e. 256x256)
	*/

	read_mand_args(argc, argv, &imax_iterations, &ipixels_across, &ipixels_down,
	    &x_min, &x_max, &y_min, &y_max, &julia, &julia_constant.real,
	    &julia_constant.imaginary, &divergent_limit,
	    &alternate_equation, filename, &num_colors, &use_stdin, &save_image,
	    &num_children);
	check_mand_params(&imax_iterations, &ipixels_across, &ipixels_down,
	    &x_min, &x_max, &y_min, &y_max, &divergent_limit, &num_children);

	if (julia == 1) /* we're doing a julia figure */
	    check_julia_params(&julia_constant.real, &julia_constant.imaginary);

	/* spawn slaves */
	child_comm = (MPI_Comm*)malloc(num_children * sizeof(MPI_Comm));
	child_request = (MPI_Request*)malloc(num_children * sizeof(MPI_Request));
	result = (header_t*)malloc(num_children * sizeof(header_t));
	if (child_comm == NULL || child_request == NULL || result == NULL)
	{
	    printf("Error: unable to allocate an array of %d communicators, requests and work objects for the slaves.\n", num_children);
	    error_code = MPI_Abort(MPI_COMM_WORLD, -1);
	    exit(error_code);
	}
	printf("Spawning %d slaves.\n", num_children);
	for (i=0; i<num_children; i++)
	{
	    error = MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, 1,
		MPI_INFO_NULL, 0, MPI_COMM_WORLD, &child_comm[i], &error_code);
	    if (error != MPI_SUCCESS)
	    {
		error_str[0] = '\0';
		length = MPI_MAX_ERROR_STRING;
		MPI_Error_string(error, error_str, &length);
		printf("Error: MPI_Comm_spawn failed: %s\n", error_str);
		error_code = MPI_Abort(MPI_COMM_WORLD, -1);
		exit(error_code);
	    }
	}

	/* send out parameters */
	for (i=0; i<num_children; i++)
	{
	    MPI_Send(&num_colors, 1, MPI_INT, 0, 0, child_comm[i]);
	    MPI_Send(&imax_iterations, 1, MPI_INT, 0, 0, child_comm[i]);
	    MPI_Send(&ipixels_across, 1, MPI_INT, 0, 0, child_comm[i]);
	    MPI_Send(&ipixels_down, 1, MPI_INT, 0, 0, child_comm[i]);
	    MPI_Send(&divergent_limit, 1, MPI_DOUBLE, 0, 0, child_comm[i]);
	    MPI_Send(&julia, 1, MPI_INT, 0, 0, child_comm[i]);
	    MPI_Send(&julia_constant.real, 1, MPI_DOUBLE, 0, 0, child_comm[i]);
	    MPI_Send(&julia_constant.imaginary, 1, MPI_DOUBLE, 0, 0, child_comm[i]);
	    MPI_Send(&alternate_equation, 1, MPI_INT, 0, 0, child_comm[i]);
	}
    }
    else
    {
	master = 0;
	MPI_Recv(&num_colors, 1, MPI_INT, 0, 0, parent, MPI_STATUS_IGNORE);
	MPI_Recv(&imax_iterations, 1, MPI_INT, 0, 0, parent, MPI_STATUS_IGNORE);
	MPI_Recv(&ipixels_across, 1, MPI_INT, 0, 0, parent, MPI_STATUS_IGNORE);
	MPI_Recv(&ipixels_down, 1, MPI_INT, 0, 0, parent, MPI_STATUS_IGNORE);
	MPI_Recv(&divergent_limit, 1, MPI_DOUBLE, 0, 0, parent, MPI_STATUS_IGNORE);
	MPI_Recv(&julia, 1, MPI_INT, 0, 0, parent, MPI_STATUS_IGNORE);
	MPI_Recv(&julia_constant.real, 1, MPI_DOUBLE, 0, 0, parent, MPI_STATUS_IGNORE);
	MPI_Recv(&julia_constant.imaginary, 1, MPI_DOUBLE, 0, 0, parent, MPI_STATUS_IGNORE);
	MPI_Recv(&alternate_equation, 1, MPI_INT, 0, 0, parent, MPI_STATUS_IGNORE);
    }

    if (master)
    {
	colors = malloc((num_colors+1)* sizeof(color_t));
	if (colors == NULL)
	{
	    MPI_Abort(MPI_COMM_WORLD, -1);
	    exit(-1);
	}
	Make_color_array(num_colors, colors);
	colors[num_colors] = 0; /* add one on the top to avoid edge errors */
    }

    /* allocate memory */
    if ( (in_grid_array = (int *)calloc(ipixels_across * ipixels_down, sizeof(int))) == NULL)
    {
	printf("Memory allocation failed for data array, aborting.\n");
	MPI_Abort(MPI_COMM_WORLD, -1);
	exit(-1);
    }

    if (master)
    {
	int istep, jstep;
	int i1[400], i2[400], j1[400], j2[400];
	int ii, jj;
	struct sockaddr_in addr;
	int len;
	char line[1024], *token;

	if ( (out_grid_array = (int *)calloc(ipixels_across * ipixels_down, sizeof(int))) == NULL)
	{
	    printf("Memory allocation failed for data array, aborting.\n");
	    MPI_Abort(MPI_COMM_WORLD, -1);
	    exit(-1);
	}

	srand(getpid());

	if (!use_stdin)
	{
	    addr.sin_family = AF_INET;
	    addr.sin_addr.s_addr = INADDR_ANY;
	    addr.sin_port = htons(DEFAULT_PORT);

	    listener = socket(AF_INET, SOCK_STREAM, 0);
	    if (listener == -1)
	    {
		printf("unable to create a listener socket.\n");
		MPI_Abort(MPI_COMM_WORLD, -1);
		exit(-1);
	    }
	    if (bind(listener, &addr, sizeof(addr)) == -1)
	    {
		addr.sin_port = 0;
		if (bind(listener, &addr, sizeof(addr)) == -1)
		{
		    printf("unable to create a listener socket.\n");
		    MPI_Abort(MPI_COMM_WORLD, -1);
		    exit(-1);
		}
	    }
	    if (listen(listener, 1) == -1)
	    {
		printf("unable to listen.\n");
		MPI_Abort(MPI_COMM_WORLD, -1);
		exit(-1);
	    }
	    len = sizeof(addr);
	    getsockname(listener, &addr, &len);
	    
	    printf("%s listening on port %d\n", processor_name, ntohs(addr.sin_port));
	    fflush(stdout);

	    sock = accept(listener, NULL, NULL);
	    if (sock == -1)
	    {
		printf("unable to accept a socket connection.\n");
		MPI_Abort(MPI_COMM_WORLD, -1);
		exit(-1);
	    }
	    printf("accepted connection from visualization program.\n");
	    fflush(stdout);

#ifdef HAVE_WINDOWS_H
	    optval = 1;
	    setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval));
#endif

	    printf("sending image size to visualizer.\n");
	    sock_write(sock, &ipixels_across, sizeof(int));
	    sock_write(sock, &ipixels_down, sizeof(int));
	    sock_write(sock, &num_colors, sizeof(int));
	    sock_write(sock, &imax_iterations, sizeof(int));
	}

	for (;;)
	{
	    /* get x_min, x_max, y_min, and y_max */
	    if (use_stdin)
	    {
		printf("input xmin ymin xmax ymax max_iter, (0 0 0 0 0 to quit):\n");fflush(stdout);
		fgets(line, 1024, stdin);
		printf("read <%s> from stdin\n", line);fflush(stdout);
		token = strtok(line, " \n");
		x_min = atof(token);
		token = strtok(NULL, " \n");
		y_min = atof(token);
		token = strtok(NULL, " \n");
		x_max = atof(token);
		token = strtok(NULL, " \n");
		y_max = atof(token);
		token = strtok(NULL, " \n");
		imax_iterations = atoi(token);
		/*sscanf(line, "%g %g %g %g", &x_min, &y_min, &x_max, &y_max);*/
		/*scanf("%g %g %g %g", &x_min, &y_min, &x_max, &y_max);*/
	    }
	    else
	    {
		printf("reading xmin,ymin,xmax,ymax.\n");fflush(stdout);
		sock_read(sock, &x_min, sizeof(double));
		sock_read(sock, &y_min, sizeof(double));
		sock_read(sock, &x_max, sizeof(double));
		sock_read(sock, &y_max, sizeof(double));
		sock_read(sock, &imax_iterations, sizeof(int));
	    }
	    printf("x0,y0 = (%f, %f) x1,y1 = (%f,%f) max_iter = %d\n", x_min, y_min, x_max, y_max, imax_iterations);fflush(stdout);

	    /*printf("sending the limits: (%f,%f)(%f,%f)\n", x_min, y_min, x_max, y_max);fflush(stdout);*/
	    /* let everyone know the limits */
	    for (i=0; i<num_children; i++)
	    {
		MPI_Send(&x_min, 1, MPI_DOUBLE, 0, 0, child_comm[i]);
		MPI_Send(&x_max, 1, MPI_DOUBLE, 0, 0, child_comm[i]);
		MPI_Send(&y_min, 1, MPI_DOUBLE, 0, 0, child_comm[i]);
		MPI_Send(&y_max, 1, MPI_DOUBLE, 0, 0, child_comm[i]);
		MPI_Send(&imax_iterations, 1, MPI_INT, 0, 0, child_comm[i]);
	    }

	    /* check for the end condition */
	    if (x_min == x_max && y_min == y_max)
	    {
		/*printf("root bailing.\n");fflush(stdout);*/
		break;
	    }

	    /* break the work up into 400 pieces */
	    istep = ipixels_across / 20;
	    jstep = ipixels_down / 20;
	    if (istep < 1)
		istep = 1;
	    if (jstep < 1)
		jstep = 1;
	    k = 0;
	    for (i=0; i<20; i++)
	    {
		for (j=0; j<20; j++)
		{
		    i1[k] = MIN(istep * i, ipixels_across - 1);
		    i2[k] = MIN((istep * (i+1)) - 1, ipixels_across - 1);
		    j1[k] = MIN(jstep * j, ipixels_down - 1);
		    j2[k] = MIN((jstep * (j+1)) - 1, ipixels_down - 1);
		    k++;
		}
	    }

	    /* shuffle the work */
	    for (i=0; i<500; i++)
	    {
		ii = rand() % 400;
		jj = rand() % 400;
		swap(&i1[ii], &i1[jj]);
		swap(&i2[ii], &i2[jj]);
		swap(&j1[ii], &j1[jj]);
		swap(&j2[ii], &j2[jj]);
	    }

	    /* send a piece of work to each worker (there must be more work than workers) */
	    k = 0;
	    for (i=0; i<num_children; i++)
	    {
		work[0] = k+1;
		work[1] = i1[k]; /* imin */
		work[2] = i2[k]; /* imax */
		work[3] = j1[k]; /* jmin */
		work[4] = j2[k]; /* jmax */

		/*printf("sending work(%d) to %d\n", k+1, i);fflush(stdout);*/
		MPI_Send(work, 5, MPI_INT, 0, 100, child_comm[i]);
		MPI_Irecv(&result[i], 5, MPI_INT, 0, 200, child_comm[i], &child_request[i]);
		k++;
	    }
	    /* receive the results and hand out more work until the image is complete */
	    while (k<400)
	    {
		MPI_Waitany(num_children, child_request, &index, &status);
		memcpy(work, &result[index], 5 * sizeof(int));
		/*printf("master receiving data in k<400 loop.\n");fflush(stdout);*/
		MPI_Recv(in_grid_array, (work[2] + 1 - work[1]) * (work[4] + 1 - work[3]), MPI_INT, 0, 201, child_comm[index], &status);
		/* draw data */
		output_data(in_grid_array, &work[1], out_grid_array, ipixels_across, ipixels_down);
		work[0] = k+1;
		work[1] = i1[k];
		work[2] = i2[k];
		work[3] = j1[k];
		work[4] = j2[k];
		/*printf("sending work(%d) to %d\n", k+1, index);fflush(stdout);*/
		MPI_Send(work, 5, MPI_INT, 0, 100, child_comm[index]);
		MPI_Irecv(&result[index], 5, MPI_INT, 0, 200, child_comm[index], &child_request[index]);
		k++;
	    }
	    /* receive the last pieces of work */
	    /* and tell everyone to stop */
	    for (i=0; i<num_children; i++)
	    {
		MPI_Wait(&child_request[i], &status);
		memcpy(work, &result[i], 5 * sizeof(int));
		/*printf("master receiving data in tail loop.\n");fflush(stdout);*/
		MPI_Recv(in_grid_array, (work[2] + 1 - work[1]) * (work[4] + 1 - work[3]), MPI_INT, 0, 201, child_comm[i], &status);
		/* draw data */
		output_data(in_grid_array, &work[1], out_grid_array, ipixels_across, ipixels_down);
		work[0] = 0;
		work[1] = 0;
		work[2] = 0;
		work[3] = 0;
		work[4] = 0;
		/*printf("sending %d to tell %d to stop\n", work[0], i);fflush(stdout);*/
		MPI_Send(work, 5, MPI_INT, 0, 100, child_comm[i]);
	    }

	    /* tell the visualizer the image is done */
	    if (!use_stdin)
	    {
		work[0] = 0;
		work[1] = 0;
		work[2] = 0;
		work[3] = 0;
		sock_write(sock, work, 4 * sizeof(int));
	    }
	}
    }
    else
    {
	for (;;)
	{
	    /*printf("slave[%d] receiveing bounds.\n", pid);fflush(stdout);*/
	    MPI_Recv(&x_min, 1, MPI_DOUBLE, 0, 0, parent, MPI_STATUS_IGNORE);
	    MPI_Recv(&x_max, 1, MPI_DOUBLE, 0, 0, parent, MPI_STATUS_IGNORE);
	    MPI_Recv(&y_min, 1, MPI_DOUBLE, 0, 0, parent, MPI_STATUS_IGNORE);
	    MPI_Recv(&y_max, 1, MPI_DOUBLE, 0, 0, parent, MPI_STATUS_IGNORE);
	    MPI_Recv(&imax_iterations, 1, MPI_INT, 0, 0, parent, MPI_STATUS_IGNORE);
	    /*printf("slave[%d] received bounding box: (%f,%f)(%f,%f)\n", pid, x_min, y_min, x_max, y_max);fflush(stdout);*/

	    /* check for the end condition */
	    if (x_min == x_max && y_min == y_max)
	    {
		/*printf("slave[%d] done.\n", pid);fflush(stdout);*/
		break;
	    }

	    x_resolution = (x_max-x_min)/ ((double)ipixels_across);
	    y_resolution = (y_max-y_min)/ ((double)ipixels_down);

	    MPI_Recv(work, 5, MPI_INT, 0, 100, parent, &status);
	    /*printf("slave[%d] received work: %d, (%d,%d)(%d,%d)\n", pid, work[0], work[1], work[2], work[3], work[4]);fflush(stdout);*/
	    while (work[0] != 0)
	    {
		imin = work[1];
		imax = work[2];
		jmin = work[3];
		jmax = work[4];

		k = 0;
		for (j=jmin; j<=jmax; ++j)
		{
		    coord_point.imaginary = y_max - j*y_resolution; /* go top to bottom */

		    for (i=imin; i<=imax; ++i)
		    {
			/* Call Mandelbrot routine for each code, fill array with number of iterations. */

			coord_point.real = x_min + i*x_resolution; /* go left to right */
			if (julia == 1)
			{
			    /* doing Julia set */
			    /* julia eq:  z = z^2 + c, z_0 = grid coordinate, c = constant */
			    icount = single_mandelbrot_point(coord_point, julia_constant, imax_iterations, divergent_limit);
			}
			else if (alternate_equation == 1)
			{
			    /* doing experimental form 1 */
			    icount = subtractive_mandelbrot_point(coord_point, julia_constant, imax_iterations, divergent_limit);
			}
			else if (alternate_equation == 2)
			{
			    /* doing experimental form 2 */
			    icount = additive_mandelbrot_point(coord_point, julia_constant, imax_iterations, divergent_limit);
			}
			else
			{
			    /* default to doing Mandelbrot set */
			    /* mandelbrot eq: z = z^2 + c, z_0 = c, c = grid coordinate */
			    icount = single_mandelbrot_point(coord_point, coord_point, imax_iterations, divergent_limit);
			}
			in_grid_array[k] = icount;
			++k;
		    }
		}
		/* send the result to the root */
		/*printf("slave[%d] sending work %d back.\n", pid, work[0]);fflush(stdout);*/
		MPI_Send(work, 5, MPI_INT, 0, 200, parent);
		/*printf("slave[%d] sending work %d data.\n", pid, work[0]);fflush(stdout);*/
		MPI_Send(in_grid_array, (work[2] + 1 - work[1]) * (work[4] + 1 - work[3]), MPI_INT, 0, 201, parent);
		/* get the next piece of work */
		/*printf("slave[%d] receiving new work.\n", pid);fflush(stdout);*/
		MPI_Recv(work, 5, MPI_INT, 0, 100, parent, &status);
		/*printf("slave[%d] received work: %d, (%d,%d)(%d,%d)\n", pid, work[0], work[1], work[2], work[3], work[4]);fflush(stdout);*/
	    }
	}
    }

    if (master && save_image)
    {
	imax_iterations = 0;
	for (i=0; i<ipixels_across * ipixels_down; ++i)
	{
	    /* look for "brightest" pixel value, for image use */
	    if (out_grid_array[i] > imax_iterations)
		imax_iterations = out_grid_array[i];
	}

	if (julia == 0)
	    printf("Done calculating mandelbrot, now creating file\n");
	else
	    printf("Done calculating julia, now creating file\n");
	fflush(stdout);

	/* Print out the array in some appropriate form. */
	if (julia == 0)
	{
	    /* it's a mandelbrot */
	    sprintf(file_message, "Mandelbrot over (%lf-%lf,%lf-%lf), size %d x %d",
		x_min, x_max, y_min, y_max, ipixels_across, ipixels_down);
	}
	else
	{
	    /* it's a julia */
	    sprintf(file_message, "Julia over (%lf-%lf,%lf-%lf), size %d x %d, center (%lf, %lf)",
		x_min, x_max, y_min, y_max, ipixels_across, ipixels_down,
		julia_constant.real, julia_constant.imaginary);
	}

	dumpimage(filename, out_grid_array, ipixels_across, ipixels_down, imax_iterations, file_message, num_colors, colors);
    }

    if (master)
    {
	for (i=0; i<num_children; i++)
	{
	    MPI_Comm_disconnect(&child_comm[i]);
	}
	free(child_comm);
	free(child_request);
	free(colors);
    }

    MPI_Finalize();
    return 0;
}