Esempio n. 1
0
static int myfetch(struct dbengine *db,
                   const char *key, size_t keylen,
                   const char **data, size_t *datalen,
                   struct txn **mytid)
{
    int r = 0;
    int offset;
    unsigned long len;
    struct buf keybuf = BUF_INITIALIZER;

    assert(db);

    if (data) *data = NULL;
    if (datalen) *datalen = 0;

    r = starttxn_or_refetch(db, mytid);
    if (r) return r;

    encode(key, keylen, &keybuf);

    offset = bsearch_mem_mbox(keybuf.s, db->base, db->size, 0, &len);

    if (len) {
        if (data) {
            decode(db->base + offset + keybuf.len + 1,
                   /* subtract one for \t, and one for the \n */
                   len - keybuf.len - 2,
                   &db->data);
            if (data) *data = DATA(db);
            if (datalen) *datalen = DATALEN(db);
        }
    } else {
        r = CYRUSDB_NOTFOUND;
    }

    buf_free(&keybuf);
    return r;
}
Esempio n. 2
0
static int
usalo_send(SCSI *usalp)
{
	struct usal_cmd	*sp = usalp->scmd;
	int	ret;
	int	i;
	int	amt = sp->cdb_len;
	int flags;
#ifndef	USE_DSLIB
	struct dsreq	ds;
	struct dsreq	*dsp = &ds;

	dsp->ds_iovbuf = 0;
	dsp->ds_iovlen = 0;
#endif

	if (usalp->fd < 0) {
		sp->error = SCG_FATAL;
		return (0);
	}

	flags = DSRQ_SENSE;
	if (sp->flags & SCG_RECV_DATA)
		flags |= DSRQ_READ;
	else if (sp->size > 0)
		flags |= DSRQ_WRITE;

	dsp->ds_flags	= flags;
	dsp->ds_link	= 0;
	dsp->ds_synch	= 0;
	dsp->ds_ret  	= 0;

	DATABUF(dsp) 	= sp->addr;
	DATALEN(dsp)	= sp->size;
	CMDBUF(dsp)	= (void *) &sp->cdb;
	CMDLEN(dsp)	= sp->cdb_len;
	SENSEBUF(dsp)	= (caddr_t)sp->u_sense.cmd_sense;
	SENSELEN(dsp)	= sizeof (sp->u_sense.cmd_sense);
	TIME(dsp)	= (sp->timeout * 1000) + 100;

	errno		= 0;
	sp->ux_errno	= 0;
	sp->sense_count	= 0;

#ifdef	USE_DSLIB
	ret = doscsireq(usalp->fd, dsp);
#else
	ret = usal_sendreq(usalp, sp, dsp);
#endif

	if (RET(dsp) != DSRT_DEVSCSI)
		ret = 0;

	if (RET(dsp)) {
		if (RET(dsp) == DSRT_SHORT) {
			sp->resid = DATALEN(dsp)- DATASENT(dsp);
		} else if (errno) {
			sp->ux_errno = errno;
		} else {
			sp->ux_errno = EIO;
		}

		sp->u_scb.cmd_scb[0] = STATUS(dsp);

		sp->sense_count = SENSESENT(dsp);
		if (sp->sense_count > SCG_MAX_SENSE)
			sp->sense_count = SCG_MAX_SENSE;

	}
	switch (RET(dsp)) {

	default:
		sp->error = SCG_RETRYABLE;	break;

	case 0:			/* OK					*/
	case DSRT_SHORT:	/* not implemented			 */
		sp->error = SCG_NO_ERROR;	break;

	case DSRT_UNIMPL:	/* not implemented			*/
	case DSRT_REVCODE:	/* software obsolete must recompile 	*/
	case DSRT_NOSEL:
		sp->u_scb.cmd_scb[0] = 0;
		sp->error = SCG_FATAL;		break;

	case DSRT_TIMEOUT:
		sp->u_scb.cmd_scb[0] = 0;
		sp->error = SCG_TIMEOUT;	break;
	}
	return (ret);
}
Esempio n. 3
0
static int foreach(struct dbengine *db,
                   const char *prefix, size_t prefixlen,
                   foreach_p *goodp,
                   foreach_cb *cb, void *rock,
                   struct txn **mytid)
{
    int r = CYRUSDB_OK;
    int offset;
    unsigned long len;
    const char *p, *pend;
    const char *dataend;

    /* for use inside the loop, but we need the values to be retained
     * from loop to loop */
    struct buf keybuf = BUF_INITIALIZER;
    int dontmove = 0;

    /* For when we have a transaction running */
    struct buf savebuf = BUF_INITIALIZER;

    /* for the local iteration so that the db can change out from under us */
    const char *dbbase = NULL;
    size_t dblen = 0;
    int dbfd = -1;

    struct buf prefixbuf = BUF_INITIALIZER;

    r = starttxn_or_refetch(db, mytid);
    if (r) return r;

    if (!mytid) {
        /* No transaction, use the fast method to avoid stomping on our
         * memory map if changes happen */
        dbfd = dup(db->fd);
        if(dbfd == -1) return CYRUSDB_IOERROR;

        map_refresh(dbfd, 1, &dbbase, &dblen, db->size, db->fname, 0);

        /* drop our read lock on the file, since we don't really care
         * if it gets replaced out from under us, our mmap stays on the
         * old version */
        lock_unlock(db->fd, db->fname);
    }
    else {
        /* use the same variables as in the no transaction case, just to
         * get things set up */
        dbbase = db->base;
        dblen = db->len;
    }

    if (prefix) {
        encode(prefix, prefixlen, &prefixbuf);
        offset = bsearch_mem_mbox(prefixbuf.s, dbbase, db->size, 0, &len);
    }
    else {
        offset = 0;
    }

    p = dbbase + offset;
    pend = dbbase + db->size;

    while (p < pend) {
        if (!dontmove) {
            GETENTRY(p)
        }
        else dontmove = 0;

        /* does it still match prefix? */
        if (keybuf.len < (size_t) prefixbuf.len) break;
        if (prefixbuf.len && memcmp(keybuf.s, prefixbuf.s, prefixbuf.len)) break;

        if (!goodp || goodp(rock, keybuf.s, keybuf.len, DATA(db), DATALEN(db))) {
            unsigned long ino = db->ino;
            unsigned long sz = db->size;

            if(mytid) {
                /* transaction present, this means we do the slow way */
                buf_copy(&savebuf, &keybuf);
            }

            /* make callback */
            r = cb(rock, keybuf.s, keybuf.len, DATA(db), DATALEN(db));
            if (r) break;

            if (mytid) {
                /* reposition? (we made a change) */
                if (!(ino == db->ino && sz == db->size)) {
                    /* something changed in the file; reseek */
                    buf_cstring(&savebuf);
                    offset = bsearch_mem_mbox(savebuf.s, db->base, db->size,
                                              0, &len);
                    p = db->base + offset;

                    GETENTRY(p);

                    /* 'key' might not equal 'savebuf'.  if it's different,
                       we want to stay where we are.  if it's the same, we
                       should move on to the next one */
                    if (!buf_cmp(&savebuf, &keybuf)) {
                        p = dataend + 1;
                    }
                    else {
                        /* 'savebuf' got deleted, so we're now pointing at the
                           right thing */
                        dontmove = 1;
                    }
                }
            }
        }

        p = dataend + 1;
    }

    if (!mytid) {
        /* cleanup the fast method */
        map_free(&dbbase, &dblen);
        close(dbfd);
    }

    buf_free(&savebuf);
    buf_free(&keybuf);
    buf_free(&prefixbuf);
    return r;
}
/*
  ok, let's play a .voc file
*/
static int
vplay (int fd, int ofs, char *name)
{
  int l, real_l;
  BlockType *bp;
  Voice_data *vd;
  Ext_Block *eb;
  u_long nextblock, in_buffer;
  u_char *data = audiobuf;
  char was_extended = 0, output = 0;
  u_short *sp, repeat = 0;
  u_long silence;
  int filepos = 0;
  char one_chn = 0;

#define COUNT(x)	nextblock -= x; in_buffer -=x ;data += x

  /* first SYNC the dsp */
  sync_dsp ();

  if (!quiet_mode)
    fprintf (stderr, "Playing Creative Labs Voice file ...\n");

  /* first we waste the rest of header, ugly but we don't need seek */
  while (ofs > abuf_size)
    {
      read (fd, (char *) audiobuf, abuf_size);
      ofs -= abuf_size;
    }
  if (ofs)
    read (fd, audiobuf, ofs);

  /* .voc files are 8 bit (now) */
  samplesize = VOC_SAMPLESIZE;
  ioctl (audio, SNDCTL_DSP_SETFMT, &samplesize);
  if (samplesize != VOC_SAMPLESIZE)
    {
      fprintf (stderr, "Unable to set 8 bit sample size!\n");
      return -1;
    }
  /* and there are MONO by default */
  dsp_stereo = MODE_MONO;
  ioctl (audio, SNDCTL_DSP_STEREO, &dsp_stereo);

  in_buffer = nextblock = 0;
  while (1)
    {
    Fill_the_buffer:		/* need this for repeat */
      if (in_buffer < 32)
	{
	  /* move the rest of buffer to pos 0 and fill the audiobuf up */
	  if (in_buffer)
	    memcpy ((char *) audiobuf, data, in_buffer);
	  data = audiobuf;
	  if ((l =
	       read (fd, (char *) audiobuf + in_buffer,
		     abuf_size - in_buffer)) > 0)
	    in_buffer += l;
	  else if (!in_buffer)
	    {
	      /* the file is truncated, so simulate 'Terminator' 
	         and reduce the datablock for save landing */
	      nextblock = audiobuf[0] = 0;
	      if (l == -1)
		{
		  perror (name);
		  return -1;
		}
	    }
	}
      while (!nextblock)
	{			/* this is a new block */
	  bp = (BlockType *) data;
	  COUNT (sizeof (BlockType));
	  nextblock = DATALEN (bp);
	  if (output && !quiet_mode)
	    fprintf (stderr, "\n");	/* write /n after ASCII-out */
	  output = 0;
	  switch (bp->type)
	    {
	    case 0:
	      d_printf ((stderr, "Terminator\n"));
	      return -1;	/* VOC-file stop */
	    case 1:
	      vd = (Voice_data *) data;
	      COUNT (sizeof (Voice_data));
	      /* we need a SYNC, before we can set new SPEED, STEREO ... */
	      sync_dsp ();

	      if (!was_extended)
		{
		  dsp_speed = (int) (vd->tc);
		  dsp_speed = 1000000 / (256 - dsp_speed);
		  d_printf ((stderr, "Voice data %d Hz\n", dsp_speed));
		  if (vd->pack)
		    {		/* /dev/dsp can't it */
		      fprintf (stderr, "Can't play packed .voc files\n");
		      return -1;
		    }
		  if (dsp_stereo)
		    {		/* if we are in Stereo-Mode, switch back */
		      dsp_stereo = MODE_MONO;
		      ioctl (audio, SNDCTL_DSP_STEREO, &dsp_stereo);
		    }
		}
	      else
		{		/* there was extended block */
		  if (one_chn)	/* if one Stereo fails, why test another ? */
		    dsp_stereo = MODE_MONO;
		  else if (dsp_stereo)
		    {		/* want Stereo */
		      /* shit, my MACRO dosn't work here */
#ifdef OSS_VERSION
		      if (ioctl (audio, SNDCTL_DSP_STEREO, &dsp_stereo) < 0)
			{
#else
		      if (dsp_stereo !=
			  ioctl (audio, SNDCTL_DSP_STEREO, dsp_stereo))
			{
#endif
			  dsp_stereo = MODE_MONO;
			  fprintf (stderr,
				   "Can't play in Stereo; playing only one channel\n");
			  one_chn = 1;
			}
		    }
		  was_extended = 0;
		}
	      if (set_dsp_speed (&dsp_speed) < 0)
		return -1;
	      break;
	    case 2:		/* nothing to do, pure data */
	      d_printf ((stderr, "Voice continuation\n"));
	      break;
	    case 3:		/* a silence block, no data, only a count */
	      sp = (u_short *) data;
	      COUNT (sizeof (u_short));
	      dsp_speed = (int) (*data);
	      COUNT (1);
	      dsp_speed = 1000000 / (256 - dsp_speed);
	      sync_dsp ();
	      if (set_dsp_speed (&dsp_speed) < 0)
		return -1;
	      silence = (((u_long) * sp) * 1000) / dsp_speed;
	      d_printf ((stderr, "Silence for %ld ms\n", silence));
	      break;
	    case 4:		/* a marker for syncronisation, no effect */
	      sp = (u_short *) data;
	      COUNT (sizeof (u_short));
	      d_printf ((stderr, "Marker %d\n", *sp));
	      break;
	    case 5:		/* ASCII text, we copy to stderr */
	      output = 1;
	      d_printf ((stderr, "ASCII - text :\n"));
	      break;
	    case 6:		/* repeat marker, says repeatcount */
	      /* my specs don't say it: maybe this can be recursive, but
	         I don't think somebody use it */
	      repeat = *(u_short *) data;
	      COUNT (sizeof (u_short));
	      d_printf ((stderr, "Repeat loop %d times\n", repeat));
	      if (filepos >= 0)	/* if < 0, one seek fails, why test another */
		if ((filepos = lseek (fd, 0, 1)) < 0)
		  {
		    fprintf (stderr,
			     "Can't play loops; %s isn't seekable\n", name);
		    repeat = 0;
		  }
		else
		  filepos -= in_buffer;	/* set filepos after repeat */
	      else
		repeat = 0;
	      break;
	    case 7:		/* ok, lets repeat that be rewinding tape */
	      if (repeat)
		{
		  if (repeat != 0xFFFF)
		    {
		      d_printf ((stderr, "Repeat loop %d\n", repeat));
		      --repeat;
		    }
		  else
		    d_printf ((stderr, "Neverending loop\n"));
		  lseek (fd, filepos, 0);
		  in_buffer = 0;	/* clear the buffer */
		  goto Fill_the_buffer;
		}
	      else
		d_printf ((stderr, "End repeat loop\n"));
	      break;
	    case 8:		/* the extension to play Stereo, I have SB 1.0 :-( */
	      was_extended = 1;
	      eb = (Ext_Block *) data;
	      COUNT (sizeof (Ext_Block));
	      dsp_speed = (int) (eb->tc);
	      dsp_speed = 256000000L / (65536 - dsp_speed);
	      dsp_stereo = eb->mode;
	      if (dsp_stereo == MODE_STEREO)
		dsp_speed = dsp_speed >> 1;
	      if (eb->pack)
		{		/* /dev/dsp can't it */
		  fprintf (stderr, "Can't play packed .voc files\n");
		  return -1;
		}
	      d_printf ((stderr, "Extended block %s %d Hz\n",
			 (eb->mode ? "Stereo" : "Mono"), dsp_speed));
	      break;
	    default:
	      fprintf (stderr, "Unknown blocktype %d. terminate.\n",
		       bp->type);
	      return -1;
	    }			/* switch (bp->type) */
	}			/* while (! nextblock)  */
      /* put nextblock data bytes to dsp */
      l = min (in_buffer, nextblock);
      if (l)
	{
	  if (output && !quiet_mode)
	    write (2, data, l);	/* to stderr */
	  else
	    {
	      real_l = one_chn ? one_channel (data, l, one_chn, 0) : l;
	      if (write (audio, data, real_l) != real_l)
		{
		  perror (AUDIO);
		  return -1;
		}
	    }
	  COUNT (l);
	}
    }				/* while(1) */
}

/* that was a big one, perhaps somebody split it :-) */

/* setting the globals for playing raw data */
static void
init_raw_data (void)
{
  timelimit = raw_info.timelimit;
  dsp_speed = raw_info.dsp_speed;
  dsp_stereo = raw_info.dsp_stereo;
  samplesize = raw_info.samplesize;
}
Esempio n. 5
0
/**
 * 固定処理A(デバイス判定)
 * @param fd 対象ファイルディスクリプタ
 * @return TunerType チューナの種別
 */
TunerType
FriioWhiteWrapper::UsbProcFixInitA(int fd)
{
  TunerType type;
  uint8_t buf[2];
 
  /* 共通初期化処理 */
  usb_ctrl_sends(fd,  usbinit_common, DATALEN(usbinit_common), NULL, 0);

  /* Express判定 
     0x1200と0x9000に送信して、双方とも0xff,0xffの場合は白か黒。
     Expressの場合は、片方0x01,0xb3が帰って来る */
  usb_ctrl_sends(fd, usbinit_expcheck_s1, DATALEN(usbinit_expcheck_s1), NULL, 0);
  usb_ctrl_sends(fd, usbinit_expcheck_r1, DATALEN(usbinit_expcheck_r1), buf, 2);
  
  /* Expressは0x01,0xb3が帰って来る */
  if(buf[0] != 0xff && buf[1] != 0xff) {
    /* Epress終了処理 */
    usb_ctrl_sends(fd, usbinit_expok, DATALEN(usbinit_expok), NULL, 0);
    /* tuner初期化 */
    tuner = new FriioExpress();
    copyinstance(fd);
    /* 扱いとしてはWHITEと一緒 */
    type = TUNER_FRIIO_WHITE;
    return type;
  }

  usb_ctrl_sends(fd, usbinit_expcheck_s2, DATALEN(usbinit_expcheck_s2), NULL, 0);
  usb_ctrl_sends(fd, usbinit_expcheck_r2, DATALEN(usbinit_expcheck_r2), buf, 2);
  
  /* Expressは0x01,0xb3が帰って来る */
  if(buf[0] != 0xff && buf[1] != 0xff) {
    /* Epress終了処理 */
    usb_ctrl_sends(fd, usbinit_expok, DATALEN(usbinit_expok), NULL, 0);
    /* tuner初期化 */
    tuner = new FriioExpress();
    copyinstance(fd);
    /* 扱いとしてはWHITEと一緒 */
    type = TUNER_FRIIO_WHITE;
    return type;
  }

  /* 白黒共通初期化処理 */
  usb_ctrl_sends(fd, usbinit_bw, DATALEN(usbinit_bw), NULL, 0);
  
  /* 白黒判定 */
  usb_ctrl_sends(fd, usbinit_bwcheck, DATALEN(usbinit_bwcheck), buf, 1);

  /* 黒は0x00が帰って来る */
  if(buf[0] == 0x00) {
    type = TUNER_FRIIO_BLACK;
    /* 黒は以下が追加されるみたい */
    usb_ctrl_sends(fd, usbinit_black, DATALEN(usbinit_black), NULL, 0);
  } else {
    /* tuner初期化 */
    tuner = new FriioWhite();
    copyinstance(fd);
    type = TUNER_FRIIO_WHITE;
  }
  
  /* 白黒共通終了処理 = Epress終了処理の最後 */
  usb_ctrl_sends(fd, usbinit_bwok, DATALEN(usbinit_bwok), NULL, 0);
  
  return type;
}