Exemple #1
0
value netsys_peek_peer_credentials(value fd) {
    CAMLparam1(fd);
    CAMLlocal1(result);
    int uid;
    int gid;

#ifdef SO_PASSCRED
    /* Linux */
    {
	int one = 1;
        struct msghdr msg;
        struct cmsghdr *cmp;
        struct ucred *sc;
	char buf[CMSG_SPACE(sizeof(*sc))];
	struct iovec iov;
	char iovbuf[1];

	if (setsockopt(Int_val(fd),
		       SOL_SOCKET,
		       SO_PASSCRED,
		       &one,
		       sizeof(one)) < 0) {
	    uerror("setsockopt", Nothing);
	};

	memset(&msg, 0, sizeof msg);

	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = buf;
	msg.msg_controllen = sizeof(buf);

	iov.iov_base = iovbuf;
	iov.iov_len = 1;

	/* Linux requires that at least one byte must be transferred.
	 * So we initialize the iovector for exactly one byte.
	 */

	if (recvmsg(Int_val(fd), &msg, MSG_PEEK) < 0) {
	    uerror("recvmsg", Nothing);
	};

	if (msg.msg_controllen == 0 ||
	    (msg.msg_flags & MSG_CTRUNC) != 0) {
	    raise_not_found();
	};
	cmp = CMSG_FIRSTHDR(&msg);
	if (cmp->cmsg_level != SOL_SOCKET ||
	    cmp->cmsg_type != SCM_CREDENTIALS) {
	    raise_not_found();
	};

	sc = (struct ucred *) CMSG_DATA(cmp);

	uid = sc->uid;
	gid = sc->gid;
    }
#else
#ifdef LOCAL_CREDS
    /* NetBSD */
    /* The following code has been copied from libc: rpc/svc_vc.c
     * TODO: The following code does not work. No idea why.
     * msg_controllen is always 0. Maybe the socket option must be
     * set earlier (but that would be very strange).
     */
    {
	int one = 1;
        struct msghdr msg;
        struct cmsghdr *cmp;
        void *crmsg = NULL;
        struct sockcred *sc;
        socklen_t crmsgsize;
	struct iovec iov;
	char buf;

	if (setsockopt(Int_val(fd),
		       SOL_SOCKET,
		       LOCAL_CREDS,
		       &one,
		       sizeof(one)) < 0) {
	    uerror("setsockopt", Nothing);
	};

	memset(&msg, 0, sizeof msg);
	crmsgsize = CMSG_SPACE(SOCKCREDSIZE(NGROUPS_MAX));
	crmsg = stat_alloc(crmsgsize);

	memset(crmsg, 0, crmsgsize);
	msg.msg_control = crmsg;
	msg.msg_controllen = crmsgsize;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;

	iov.iov_base = &buf;
	iov.iov_len = 1;

	if (recvmsg(Int_val(fd), &msg, MSG_PEEK) < 0) {
	    stat_free(crmsg);
	    uerror("recvmsg", Nothing);
	};

	if (msg.msg_controllen == 0 ||
	    (msg.msg_flags & MSG_CTRUNC) != 0) {
	    stat_free(crmsg);
	    raise_not_found();
	};
	cmp = CMSG_FIRSTHDR(&msg);
	if (cmp->cmsg_level != SOL_SOCKET ||
	    cmp->cmsg_type != SCM_CREDS) {
	    stat_free(crmsg);
	    raise_not_found();
	};

	sc = (struct sockcred *)(void *)CMSG_DATA(cmp);

	uid = sc->sc_euid;
	gid = sc->sc_egid;
	free(crmsg);
    }
#else
    invalid_argument("peek_peer_credentials");
#endif
#endif

    /* Allocate a pair, and put the result into it: */
    result = alloc_tuple(2);
    Store_field(result, 0, Val_int(uid));
    Store_field(result, 1, Val_int(gid));

    CAMLreturn(result);
}
Exemple #2
0
read_JPEG_file (value name)
{
  CAMLparam1(name);
  CAMLlocal1(res);

  char *filename;
  /* This struct contains the JPEG decompression parameters and pointers to
   * working space (which is allocated as needed by the JPEG library).
   */
  struct jpeg_decompress_struct cinfo;
  /* We use our private extension JPEG error handler.
   * Note that this struct must live as long as the main JPEG parameter
   * struct, to avoid dangling-pointer problems.
   */
  struct my_error_mgr jerr;
  /* More stuff */
  FILE * infile;		/* source file */
  JSAMPARRAY buffer;		/* Output row buffer */
  int row_stride;		/* physical row width in output buffer */
  int i;

  filename= String_val( name );

  /* In this example we want to open the input file before doing anything else,
   * so that the setjmp() error recovery below can assume the file is open.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to read binary files.
   */

  if ((infile = fopen(filename, "rb")) == NULL) {
    failwith("failed to open jpeg file");
  }

  /* Step 1: allocate and initialize JPEG decompression object */

  /* We set up the normal JPEG error routines, then override error_exit. */
  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp(jerr.setjmp_buffer)) {
    /* If we get here, the JPEG code has signaled an error.
     * We need to clean up the JPEG object, close the input file, and return.
     */
    fprintf(stderr, "Exiting...");
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    exit(-1);
    failwith(jpg_error_message);
  }
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress(&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src(&cinfo, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  (void) jpeg_read_header(&cinfo, TRUE);

  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  cinfo.out_color_space = JCS_RGB;

  /* Step 5: Start decompressor */

  (void) jpeg_start_decompress(&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */ 
  /* JSAMPLEs per row in output buffer */

  if( oversized(cinfo.output_width, cinfo.output_components) ){
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    failwith_oversized("jpeg");
  }

  row_stride = cinfo.output_width * cinfo.output_components;

  /* Make a one-row-high sample array that will go away when done with image */
  buffer = (*cinfo.mem->alloc_sarray)
		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 
		 cinfo.output_height );

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  while (cinfo.output_scanline < cinfo.output_height) {
    /* jpeg_read_scanlines expects an array of pointers to scanlines.
     * Here the array is only one element long, but you could ask for
     * more than one scanline at a time if that's more convenient.
     */
    jpeg_read_scanlines(&cinfo, buffer + cinfo.output_scanline, 1); 
  }

  if( oversized(row_stride, cinfo.output_height) ){
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    failwith_oversized("jpeg");
  }

  {
    CAMLlocalN(r,3);
    r[0] = Val_int(cinfo.output_width);
    r[1] = Val_int(cinfo.output_height);
    r[2] = alloc_string ( row_stride * cinfo.output_height );
    for(i=0; i<cinfo.output_height; i++){
      memcpy( String_val(r[2]) + i * row_stride, 
	       buffer[i], row_stride);
    }
    res = alloc_tuple(3);
    for(i=0; i<3; i++) Field(res, i) = r[i];
  }

  /* Step 7: Finish decompression */

  (void) jpeg_finish_decompress(&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress(&cinfo);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  fclose(infile);

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
   */

  /* And we're done! */
  CAMLreturn(res);
}
Exemple #3
0
value 
ml_getrlimit(value resource) 
{
#ifdef HAVE_GETRLIMIT
  CAMLparam1(resource);
  CAMLlocal1(retval);
  int r;
  struct rlimit lim;

  switch (Int_val(resource)) {
  case 0:
#ifdef RLIMIT_CPU
    r = RLIMIT_CPU;
#else
    r = -1;
#endif
    break;
  case 1:
#ifdef RLIMIT_FSIZE
    r = RLIMIT_FSIZE;
#else
    r = -1;
#endif
    break;
  case 2:
#ifdef RLIMIT_DATA
    r = RLIMIT_DATA;
#else
    r = -1;
#endif
    break;
  case 3:
#ifdef RLIMIT_STACK
    r = RLIMIT_STACK;
#else
    r = -1;
#endif
    break;
  case 4:
#ifdef RLIMIT_CORE
    r = RLIMIT_CORE;
#else
    r = -1;
#endif
    break;
  case 5:
#ifdef RLIMIT_RSS
    r = RLIMIT_RSS;
#else
    r = -1;
#endif
    break;
  case 6:
#ifdef RLIMIT_NPROC
    r = RLIMIT_NPROC;
#else
    r = -1;
#endif
    break;
  case 7:
#ifdef RLIMIT_NOFILE
    r = RLIMIT_NOFILE;
#elif RLIMIT_OFILE
    r = RLIMIT_OFILE:
#else
    r = -1;
#endif
    break;
  case 8:
#ifdef RLIMIT_MEMLOCK
    r = RLIMIT_MEMLOCK;
#else
    r = -1;
#endif
    break;
  case 9:
#ifdef RLIMIT_AS
    r = RLIMIT_AS;
#else
    r = -1;
#endif
    break;
  default:
    errno = EINVAL;
    uerror("getrlimit", Nothing);    
  }

  if (getrlimit(r, &lim) < 0) 
    uerror("getrlimit", Nothing);

  
  retval = alloc_tuple(2);
  Field(retval, 0) = Val_int(lim.rlim_cur);
  Field(retval, 1) = Val_int(lim.rlim_max);

  CAMLreturn(retval);

#else
  failwith("getrlimit unimplemented");
#endif
}
Exemple #4
0
value xdiff_revpatch( value old_data, value patch) 
{
    CAMLparam2 (old_data, patch);
    CAMLlocal1(res);
    mmfile_t mf1, mf2, mf3, mf4;
    xdemitcb_t ecb, rjecb;
    long new_size, rej_size;


    res = alloc_tuple(2);

    if (xdlt_store_mmfile(String_val(old_data), string_length(old_data), &mf1) < 0) {
        sprintf(ELINE, "%s:%d failed", __FILE__, __LINE__);
        failwith(ELINE);
    }
    if (xdlt_store_mmfile(String_val(patch), string_length(patch), &mf2) < 0) {
        xdl_free_mmfile(&mf1);
        sprintf(ELINE, "%s:%d failed", __FILE__, __LINE__);
        failwith(ELINE);
    }
    if (xdl_init_mmfile(&mf3, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0) {
        xdl_free_mmfile(&mf1);
        xdl_free_mmfile(&mf2);
        sprintf(ELINE, "%s:%d failed", __FILE__, __LINE__);
        failwith(ELINE);
    }
    if (xdl_init_mmfile(&mf4, XDLT_STD_BLKSIZE, XDL_MMF_ATOMIC) < 0) {
        xdl_free_mmfile(&mf1);
        xdl_free_mmfile(&mf2);
        xdl_free_mmfile(&mf3);
        sprintf(ELINE, "%s:%d failed", __FILE__, __LINE__);
        failwith(ELINE);
    }
    ecb.priv = &mf3;
    ecb.outf = xdlt_outf;
    rjecb.priv = &mf4;
    rjecb.outf = xdlt_outf;

    if (xdl_patch(&mf1, &mf2, XDL_PATCH_REVERSE, &ecb, &rjecb) < 0) {
        xdl_free_mmfile(&mf1);
        xdl_free_mmfile(&mf2);
        xdl_free_mmfile(&mf3);
        xdl_free_mmfile(&mf4);
        sprintf(ELINE, "%s:%d failed", __FILE__, __LINE__);
        failwith(ELINE);
    }
    new_size = xdlt_mmfile_size(&mf3);
    rej_size = xdlt_mmfile_size(&mf4);
    Field(res, 0) = alloc_string(new_size);
    Field(res, 1) = alloc_string(rej_size);
    if (xdlt_read_mmfile(String_val(Field(res, 0)), &mf3) < 0) {
        xdl_free_mmfile(&mf1);
        xdl_free_mmfile(&mf2);
        xdl_free_mmfile(&mf3);
        xdl_free_mmfile(&mf4);
        sprintf(ELINE, "%s:%d failed", __FILE__, __LINE__);
        failwith(ELINE);
    }
    if (xdlt_read_mmfile(String_val(Field(res, 1)), &mf4) < 0) {
        xdl_free_mmfile(&mf1);
        xdl_free_mmfile(&mf2);
        xdl_free_mmfile(&mf3);
        xdl_free_mmfile(&mf4);
        sprintf(ELINE, "%s:%d failed", __FILE__, __LINE__);
        failwith(ELINE);
    }

    xdl_free_mmfile(&mf1);
    xdl_free_mmfile(&mf2);
    xdl_free_mmfile(&mf3);
    xdl_free_mmfile(&mf4);

    CAMLreturn(res);
}
Exemple #5
0
value netsys_get_peer_credentials(value fd) {
    CAMLparam1(fd);
    CAMLlocal1(result);

#if defined(HAVE_GETPEEREID) || defined(SO_PEERCRED) || defined(HAVE_GETPEERUCRED)
    uid_t uid;
    gid_t gid;
#else
    int uid;
    int gid;
#endif

#if defined(HAVE_GETPEEREID)
    /* BSD, AIX, Cygwin */
    /* http://cr.yp.to/docs/secureipc.html */
    if (getpeereid(Int_val(fd), &uid, &gid) != 0) {
	uerror("getpeereid", Nothing);
    }

#elif defined(SO_PEERCRED)
    /* Linux */
    {
	socklen_t len;
	struct ucred credentials;

	len = sizeof(struct ucred);
	if (getsockopt(Int_val(fd),
		       SOL_SOCKET,
		       SO_PEERCRED,
		       &credentials,
		       &len) == -1) {
	    uerror("getsockopt",Nothing);
	};
	uid = credentials.uid;       /* Effective user ID */
	gid = credentials.gid;       /* Effective group ID */
    }
#elif defined(HAVE_GETPEERUCRED)
    /* Solaris */
    { 
	ucred_t    *ucred;
	ucred = NULL;			/* must be initialized to NULL */
	if (getpeerucred(Int_val(fd), &ucred) == -1) {
	    uerror("getpeerucred",Nothing);
	};
	if ((uid = ucred_geteuid(ucred)) == -1) {
	    uerror("ucred_geteuid",Nothing);
	    ucred_free(ucred);
	};
	if ((gid = ucred_getegid(ucred)) == -1) {
	    uerror("ucred_getegid",Nothing);
	    ucred_free(ucred);
	};
	ucred_free(ucred);
    }
#else
    invalid_argument("get_peer_credentials");
#endif

    /* Allocate a pair, and put the result into it: */
    result = alloc_tuple(2);
    Store_field(result, 0, Val_int(uid));
    Store_field(result, 1, Val_int(gid));

    CAMLreturn(result);
}
Exemple #6
0
    s->sockaddr_inet.sin_addr.s_addr = 
      *((s_addr_t*) Mlsaddr_sapval(sinaddrport));
    /* Maybe this should be htonl? / sestoft */
    s->sockaddr_inet.sin_port = htons(Int_val(Port_sapval(sinaddrport)));
    break;
  }
  }
} 

/* Warning: allocates in the heap, may cause a GC */
/* ML result type: addr */
static value newaddr(int len, int namespace, value addrdata) {
  value res;
  Push_roots(r,1)
  r[0] = addrdata;
  res = alloc_tuple(3);
  Data_addrval(res) = r[0];
  Size_addrval(res) = Val_int(len);
  Nspace_addrval(res) = Val_int(namespace);
  Pop_roots();
  return (value) res;
} 

/* Warning: allocates in the heap, may cause a GC */
/* Return type: sinaddrport = int * ml_s_addr */
value newsinaddrport(s_addr_t sa, value port) {
  value res;
  Push_roots(r,1);  
  r[0] = alloc_tuple(2); 
    
  Field(r[0], 0) = 0; /* to please the gc */
Exemple #7
0
CAMLprim value open_jpeg_file_for_read_start(value jpegh) {
  CAMLparam1(jpegh);
  CAMLlocal1(res);
  struct jpeg_decompress_struct* cinfop;
  struct my_error_mgr *jerrp;
  FILE *infile;
  int i;

  cinfop = (struct jpeg_decompress_struct *) Field(jpegh, 0);
  infile = (FILE *) Field(jpegh, 1);
  jerrp = (struct my_error_mgr *) Field(jpegh, 2);

  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  cinfop->out_color_space = JCS_RGB;

  /* Step 5: Start decompressor */

  (void) jpeg_start_decompress(cinfop);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */ 
  /* JSAMPLEs per row in output buffer */

  /* row_stride = cinfop->output_width * cinfop->output_components; */

  { 
    CAMLlocalN(r,3);
    // CR jfuruse: integer overflow
    r[0] = Val_int(cinfop->output_width);
    r[1] = Val_int(cinfop->output_height);
    r[2] = alloc_tuple(3);
    Field(r[2], 0) = (value)cinfop;
    Field(r[2], 1) = (value)infile;
    Field(r[2], 2) = (value)jerrp;
    res = alloc_tuple(3);
    for(i=0; i<3; i++) Field(res, i) = r[i];
  }
#ifdef DEBUG_JPEG
  fprintf(stderr, "cinfop= %d infile= %d %d %d \n", cinfop, infile, cinfop->output_scanline, cinfop->output_height); 
  fflush(stderr);
#endif
  CAMLreturn(res);
}
Exemple #8
0
CAMLprim value open_jpeg_file_for_read(value name) {
  CAMLparam1(name);
  CAMLlocal1(res);

  char *filename;
  /* This struct contains the JPEG decompression parameters and pointers to
   * working space (which is allocated as needed by the JPEG library).
   */
  struct jpeg_decompress_struct* cinfop;
  /* We use our private extension JPEG error handler.
   * Note that this struct must live as long as the main JPEG parameter
   * struct, to avoid dangling-pointer problems.
   */
  struct my_error_mgr *jerrp;
  /* More stuff */
  FILE * infile;		/* source file */
  int i;

  filename= String_val(name);

  if ((infile = fopen(filename, "rb")) == NULL) {
    failwith("failed to open jpeg file");
  }

  cinfop = malloc(sizeof (struct jpeg_decompress_struct));
  jerrp = malloc(sizeof (struct my_error_mgr));

  /* In this example we want to open the input file before doing anything else,
   * so that the setjmp() error recovery below can assume the file is open.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to read binary files.
   */


  /* Step 1: allocate and initialize JPEG decompression object */

  /* We set up the normal JPEG error routines, then override error_exit. */
  cinfop->err = jpeg_std_error(&jerrp->pub);
  jerrp->pub.error_exit = my_error_exit;
  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp(jerrp->setjmp_buffer)) {
    /* If we get here, the JPEG code has signaled an error.
     * We need to clean up the JPEG object, close the input file, and return.
     */
    jpeg_destroy_decompress(cinfop);
    free(jerrp);
    fclose(infile);
    failwith(jpg_error_message);
  }
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress(cinfop);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src(cinfop, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  (void) jpeg_read_header(cinfop, TRUE);

  { 
    CAMLlocalN(r,3);
    r[0] = Val_int(cinfop->image_width);
    r[1] = Val_int(cinfop->image_height);
    r[2] = alloc_tuple(3);
    Field(r[2], 0) = (value)cinfop;
    Field(r[2], 1) = (value)infile;
    Field(r[2], 2) = (value)jerrp;
    res = alloc_tuple(3);
    for(i=0; i<3; i++) Field(res, i) = r[i];
  }
  CAMLreturn(res);
}
Exemple #9
0
value mkexn0val(value exnname) {
  value exnval = alloc_tuple(2);
  modify(&Field(exnval, 0), Field(global_data, exnname));
  modify(&Field(exnval, 1), Val_unit);
  return exnval;
}
Exemple #10
0
EXTERNML value msocket_rtsignals(value dummy) {
  value res = alloc_tuple(2);
  Field(res, 0) = Val_long(SIGRTMIN);
  Field(res, 1) = Val_long(SIGRTMAX);
  return res;
}