Beispiel #1
0
/* flush out any data in a stream buffer. Return -1 on failure */
static int flush_buffer(struct stream_info *sinfo, int stream)
{
	int c_type = CTYPE_NONE;
	i64 c_len = sinfo->s[stream].buflen;

	if (seekto(sinfo, sinfo->s[stream].last_head) != 0)
		return -1;
	if (write_i64(sinfo->fd, sinfo->cur_pos) != 0)
		return -1;

	sinfo->s[stream].last_head = sinfo->cur_pos + 17;
	if (seekto(sinfo, sinfo->cur_pos) != 0)
		return -1;

	if (!(control.flags & FLAG_NO_COMPRESS)) {
		if (LZMA_COMPRESS(control.flags))
			lzma_compress_buf(&sinfo->s[stream], &c_type, &c_len);
		else if (control.flags & FLAG_LZO_COMPRESS)
			lzo_compress_buf(&sinfo->s[stream], &c_type, &c_len);
		else if (control.flags & FLAG_BZIP2_COMPRESS)
			bzip2_compress_buf(&sinfo->s[stream], &c_type, &c_len);
		else if (control.flags & FLAG_ZLIB_COMPRESS)
			gzip_compress_buf(&sinfo->s[stream], &c_type, &c_len);
		else if (control.flags & FLAG_ZPAQ_COMPRESS)
			zpaq_compress_buf(&sinfo->s[stream], &c_type, &c_len);
		else fatal("Dunno wtf compression to use!\n");
	}

	if (write_u8(sinfo->fd, c_type) != 0 ||
	    write_i64(sinfo->fd, c_len) != 0 ||
	    write_i64(sinfo->fd, sinfo->s[stream].buflen) != 0 ||
	    write_i64(sinfo->fd, 0) != 0) {
		return -1;
	}
	sinfo->cur_pos += 25;

	if (write_buf(sinfo->fd, sinfo->s[stream].buf, c_len) != 0)
		return -1;
	sinfo->cur_pos += c_len;

	sinfo->s[stream].buflen = 0;

	free(sinfo->s[stream].buf);
	sinfo->s[stream].buf = malloc(sinfo->bufsize);
	if (!sinfo->s[stream].buf)
		return -1;
	return 0;
}
Beispiel #2
0
dsk_err_t nwasp_format(DSK_DRIVER *self, DSK_GEOMETRY *geom,
                                dsk_pcyl_t cylinder, dsk_phead_t head,
                                const DSK_FORMAT *format, unsigned char filler)
{
/*
 * Note that we completely ignore the "format" parameter, since raw NWASP
 * images don't hold track headers.
 */
	NWASP_DSK_DRIVER *nwself;
	unsigned long offset;
	unsigned long trklen;
	dsk_err_t err;

   (void)format;
	if (!self || !geom || self->dr_class != &dc_nwasp) return DSK_ERR_BADPTR;
	nwself = (NWASP_DSK_DRIVER *)self;

	if (!nwself->nw_fp) return DSK_ERR_NOTRDY;
	if (nwself->nw_readonly) return DSK_ERR_RDONLY;

	/* Convert from physical to logical sector. However, unlike the dg_* 
	 * functions, this _always_ uses "SIDES_OUTOUT" mapping */
	offset = 204800L * head + 5120L * cylinder;/* + 512 * skew[sector-1];*/
	trklen = 5120L;

	err = seekto(nwself, offset);
	if (err) return err;
	if (nwself->nw_filesize < offset + trklen)
		nwself->nw_filesize = offset + trklen;

	while (trklen--) 
		if (fputc(filler, nwself->nw_fp) == EOF) return DSK_ERR_SYSERR;	

	return DSK_ERR_OK;
}
Beispiel #3
0
dsk_err_t nwasp_write(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
                             const void *buf, dsk_pcyl_t cylinder,
                              dsk_phead_t head, dsk_psect_t sector)
{
	NWASP_DSK_DRIVER *nwself;
	unsigned long offset;
	dsk_err_t err;

	if (!buf || !self || !geom || self->dr_class != &dc_nwasp) return DSK_ERR_BADPTR;
	nwself = (NWASP_DSK_DRIVER *)self;

	if (!nwself->nw_fp) return DSK_ERR_NOTRDY;
	if (nwself->nw_readonly) return DSK_ERR_RDONLY;

	/* Convert from physical to logical sector. However, unlike the dg_* 
	 * functions, this _always_ uses "SIDES_OUTOUT" mapping */
	offset = 204800L * head + 5120L * cylinder + 512 * skew[sector-1];

	err = seekto(nwself, offset);
	if (err) return err;

	if (fwrite(buf, 1, geom->dg_secsize, nwself->nw_fp) < geom->dg_secsize)
	{
		return DSK_ERR_NOADDR;
	}
	if (nwself->nw_filesize < offset + geom->dg_secsize)
		nwself->nw_filesize = offset + geom->dg_secsize;
	return DSK_ERR_OK;
}
Beispiel #4
0
/*
 * Go forward in 1GB chunks until you can't.
 * Go backwards in 128MB chunks until you can.
 * Go forwards in 1MB chunks until you can't and return that -1.
 */
uint64
disksize(char *disk)
{
	int	fd = open(disk, 0);
	char	buf[512];
	uint64	off = 0;

	if (fd == -1) {
		perror("usage: disksize device");
		return(0);
	}
	/*
	 * Go forward until it doesn't work.
	 */
	for ( ;; ) {
		off += FORWARD;
		if (seekto(fd, off, SEEK_SET) != off) {
			debug((stdout, "seekto(%dM) failed\n", (int)(off>>20)));
			off -= FORWARD;
			break;
		}
		if ((read(fd, buf, sizeof(buf)) != sizeof(buf))) {
			debug((stdout, "read @ %dM failed\n", (int)(off>>20)));
			off -= FORWARD;
			break;
		}
Beispiel #5
0
dsk_err_t logical_write(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
                             const void *buf, dsk_pcyl_t cylinder,
                              dsk_phead_t head, dsk_psect_t sector)
{
	LOGICAL_DSK_DRIVER *lpxself;
	dsk_lsect_t offset;
	dsk_err_t err;

	if (!buf || !self || !geom || self->dr_class != &dc_logical) return DSK_ERR_BADPTR;
	lpxself = (LOGICAL_DSK_DRIVER *)self;

	if (!lpxself->lpx_fp) return DSK_ERR_NOTRDY;
	if (lpxself->lpx_readonly) return DSK_ERR_RDONLY;

	err = dg_ps2ls(geom, cylinder, head, sector, &offset);
	if (err) return err;
	offset *=  geom->dg_secsize;

	err = seekto(lpxself, offset);
	if (err) return err;

	if (fwrite(buf, 1, geom->dg_secsize, lpxself->lpx_fp) < geom->dg_secsize)
	{
		return DSK_ERR_NOADDR;
	}
	if (lpxself->lpx_filesize < offset + geom->dg_secsize)
		lpxself->lpx_filesize = offset + geom->dg_secsize;
	return DSK_ERR_OK;
}
Beispiel #6
0
dsk_err_t posix_write(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
                             const void *buf, dsk_pcyl_t cylinder,
                              dsk_phead_t head, dsk_psect_t sector)
{
	POSIX_DSK_DRIVER *pxself;
	unsigned long offset;
	dsk_err_t err;

	if (!buf || !self || !geom || self->dr_class != &dc_posix) return DSK_ERR_BADPTR;
	pxself = (POSIX_DSK_DRIVER *)self;

	if (!pxself->px_fp) return DSK_ERR_NOTRDY;
	if (pxself->px_readonly) return DSK_ERR_RDONLY;

	/* Convert from physical to logical sector. However, unlike the dg_* 
	 * functions, this _always_ uses "SIDES_ALT" mapping; this is the 
	 * mapping that both the Linux and NT floppy drivers use to convert 
	 * offsets back into C/H/S. */
	offset = (cylinder * geom->dg_heads) + head;	/* Drive track */
	offset *= geom->dg_sectors;
	offset += (sector - geom->dg_secbase);
	offset *=  geom->dg_secsize;

	err = seekto(pxself, offset);
	if (err) return err;

	if (fwrite(buf, 1, geom->dg_secsize, pxself->px_fp) < geom->dg_secsize)
	{
		return DSK_ERR_NOADDR;
	}
	if (pxself->px_filesize < offset + geom->dg_secsize)
		pxself->px_filesize = offset + geom->dg_secsize;
	return DSK_ERR_OK;
}
Beispiel #7
0
/**
 * Read a tag segment with sorting.
 *
 *	@param[in]	gtop	#GTOP structure <br>
 *		Output:	@CODE{gtop->gtp_array}		segment table <br>
 *		Output:	@CODE{gtop->gtp_count}		segment table size <br>
 *		Output:	@CODE{gtop->gtp_index}		segment table index (initial value = 0) <br>
 *		Output:	@CODE{gtop->cur_tagname}	current tag name
 *
 * A segment is a set of tag records which have same tag name. <br>
 * This function read a segment from tag file, sort it and put it on segment table. <br>
 * This function can treat both of standard format and compact format.
 *
 * Sorting is done by three keys.
 *	- 1st key: tag name
 *	- 2nd key: file name
 *	- 3rd key: line number
 *
 * Since all records in a segment have same tag name, you need not think about 1st key.
 */
void
segment_read(GTOP *gtop)
{
	const char *tagline, *fid, *path, *lineno;
	GTP *gtp;
	struct sh_entry *sh;

	/*
	 * Save tag lines.
	 */
	gtop->cur_tagname[0] = '\0';
	while ((tagline = dbop_next(gtop->dbop)) != NULL) {
		VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop);
		/*
		 * get tag name and line number.
		 *
		 * tagline = <file id> <tag name> <line number>
		 */
		if (gtop->cur_tagname[0] == '\0') {
			strlimcpy(gtop->cur_tagname, gtop->dbop->lastkey, sizeof(gtop->cur_tagname));
		} else if (strcmp(gtop->cur_tagname, gtop->dbop->lastkey) != 0) {
			/*
			 * Dbop_next() wil read the same record again.
			 */
			dbop_unread(gtop->dbop);
			break;
		}
		gtp = varray_append(gtop->vb);
		gtp->tagline = pool_strdup(gtop->segment_pool, tagline, 0);
		gtp->tag = (const char *)gtop->cur_tagname;
		/*
		 * convert fid into hashed path name to save memory.
		 */
		fid = (const char *)strmake(tagline, " ");
		path = gpath_fid2path(fid, NULL);
		if (path == NULL)
			die("gtags_first: path not found. (fid=%s)", fid);
		sh = strhash_assign(gtop->path_hash, path, 1);
		gtp->path = sh->name;
		lineno = seekto(gtp->tagline, SEEKTO_LINENO);
		if (lineno == NULL)
			die("illegal tag record.\n%s", tagline);
		gtp->lineno = atoi(lineno);
	}
	/*
	 * Sort tag lines.
	 */
	gtop->gtp_array = varray_assign(gtop->vb, 0, 0);
	gtop->gtp_count = gtop->vb->length;
	gtop->gtp_index = 0;
	if (!(gtop->flags & GTOP_NOSORT))
		qsort(gtop->gtp_array, gtop->gtp_count, sizeof(GTP), compare_tags);
}
Beispiel #8
0
dsk_err_t posix_format(DSK_DRIVER *self, DSK_GEOMETRY *geom,
                                dsk_pcyl_t cylinder, dsk_phead_t head,
                                const DSK_FORMAT *format, unsigned char filler)
{
/*
 * Note that we completely ignore the "format" parameter, since raw POSIX
 * images don't hold track headers.
 */
	POSIX_DSK_DRIVER *pxself;
	unsigned long offset;
	unsigned long trklen;
	dsk_err_t err;

   (void)format;
	if (!self || !geom || self->dr_class != &dc_posix) return DSK_ERR_BADPTR;
	pxself = (POSIX_DSK_DRIVER *)self;

	if (!pxself->px_fp) return DSK_ERR_NOTRDY;
	if (pxself->px_readonly) return DSK_ERR_RDONLY;

	/* Convert from physical to logical sector. However, unlike the dg_* 
	 * functions, this _always_ uses "SIDES_ALT" mapping; this is the 
	 * mapping that both the Linux and NT floppy drivers use to convert 
	 * offsets back into C/H/S. */
	offset = (cylinder * geom->dg_heads) + head;	/* Drive track */
	trklen = geom->dg_sectors * geom->dg_secsize;
	offset *= trklen;

	err = seekto(pxself, offset);
	if (err) return err;
	if (pxself->px_filesize < offset + trklen)
		pxself->px_filesize = offset + trklen;

	while (trklen--) 
		if (fputc(filler, pxself->px_fp) == EOF) return DSK_ERR_SYSERR;	

	return DSK_ERR_OK;
}
Beispiel #9
0
dsk_err_t logical_format(DSK_DRIVER *self, DSK_GEOMETRY *geom,
                                dsk_pcyl_t cylinder, dsk_phead_t head,
                                const DSK_FORMAT *format, unsigned char filler)
{
/*
 * Note that we completely ignore the "format" parameter, since raw LOGICAL
 * images don't hold track headers.
 */
	LOGICAL_DSK_DRIVER *lpxself;
	dsk_lsect_t offset;
	unsigned long trklen;
	dsk_err_t err;

   (void)format;
	if (!self || !geom || self->dr_class != &dc_logical) return DSK_ERR_BADPTR;
	lpxself = (LOGICAL_DSK_DRIVER *)self;

	if (!lpxself->lpx_fp) return DSK_ERR_NOTRDY;
	if (lpxself->lpx_readonly) return DSK_ERR_RDONLY;

	trklen = geom->dg_sectors * geom->dg_secsize;

	err = dg_ps2ls(geom, cylinder, head, geom->dg_secbase, &offset);
	if (err) return err;
	offset *= geom->dg_secsize;

	err = seekto(lpxself, offset);
	if (err) return err;
	if (lpxself->lpx_filesize < offset + trklen)
		lpxself->lpx_filesize = offset + trklen;

	while (trklen--) 
		if (fputc(filler, lpxself->lpx_fp) == EOF) return DSK_ERR_SYSERR;	

	return DSK_ERR_OK;
}
Beispiel #10
0
GeglBuffer *
gegl_buffer_load (const gchar *path)
{
  GeglBuffer *ret;

  LoadInfo *info = g_slice_new0 (LoadInfo);

  info->path = g_strdup (path);
  info->i = g_open (info->path, O_RDONLY, 0770);
  GEGL_NOTE (GEGL_DEBUG_BUFFER_LOAD, "starting to load buffer %s", path);
  if (info->i == -1)
    {
      GEGL_NOTE (GEGL_DEBUG_BUFFER_LOAD, "failed top open %s for reading", path);
      return NULL;
    }

  {
    GeglBufferItem *header = gegl_buffer_read_header (info->i, &info->offset);
    g_assert (header);
    /*memcpy (&(info->header), header, sizeof (GeglBufferHeader));*/
    info->header = *(&header->header);
    info->offset = info->header.next;
    /*g_free (header);*/  /* is there a pointer to a string or something we're missing? */
  }



  info->tile_size    = info->header.tile_width *
                       info->header.tile_height *
                       info->header.bytes_per_pixel;
  info->format       = babl_format (info->header.description);

  ret = g_object_new (GEGL_TYPE_BUFFER,
                      "format", info->format,
                      "tile-width", info->header.tile_width,
                      "tile-height", info->header.tile_height,
                      "height", info->header.height,
                      "width", info->header.width,
                      "path", path,
                      NULL);

  /* sanity check, should probably report error condition and return safely instead
  */
  g_assert (babl_format_get_bytes_per_pixel (info->format) == info->header.bytes_per_pixel);

  info->tiles = gegl_buffer_read_index (info->i, &info->offset);

  /* load each tile */
  {
    GList *iter;
    gint   i = 0;
    for (iter = info->tiles; iter; iter = iter->next)
      {
        GeglBufferTile *entry = iter->data;
        guchar         *data;
        GeglTile       *tile;


        tile = gegl_tile_source_get_tile (GEGL_TILE_SOURCE (ret),
                                          entry->x,
                                          entry->y,
                                          entry->z);

        if (info->offset != entry->offset)
          {
            seekto (info, entry->offset);
          }
        /*g_assert (info->offset == entry->offset);*/


        g_assert (tile);
        gegl_tile_lock (tile);

        data = gegl_tile_get_data (tile);
        g_assert (data);

        {
          ssize_t sz_read = read (info->i, data, info->tile_size);
          if(sz_read != -1)
            info->offset += sz_read;
        }
        /*g_assert (info->offset == entry->offset + info->tile_size);*/

        gegl_tile_unlock (tile);
        gegl_tile_unref (tile);
        i++;
      }
    GEGL_NOTE (GEGL_DEBUG_BUFFER_LOAD, "%i tiles loaded",i);
  }
  GEGL_NOTE (GEGL_DEBUG_BUFFER_LOAD, "buffer loaded %s", info->path);

  load_info_destroy (info);
  return ret;
}
Beispiel #11
0
int
zone(char *disk, int oflag, int bsize)
{
	char	*buf;
	int	usecs;
	int	error;
	int	n;
	int	fd;
	uint64	off;
	int	stride;

	if ((fd = open(disk, oflag)) == -1) {
		perror(disk);
		exit(1);
	}
	buf = valloc(bsize);
	if (!buf) {
		perror("valloc");
		exit(1);
	}
	bzero(buf, bsize);
#ifdef	linux
	flushdisk(fd);
#endif

	/*
	 * We want ZONEPOINTS data points 
	 * but the stride has to be at least 512 and a 512 multiple.
	 * Weird code below for precision.
	 */
	off = disksize(disk);
	off /= ZONEPOINTS;
	stride = off;
	if (stride < 512) stride = 512;
	stride += 511;
	stride >>= 9;
	stride <<= 9;

	/*
	 * Very small disks such as ZIP drives get a 256K blocksize.
	 * As measured on my SCSI ZIP, there seems to be no
	 * difference between 256K and 1MB for sequential reads.
	 * XXX - there is a rotational delay difference but that's tough.
	 */
	if (bsize > stride) bsize = 256<<10;
	if (bsize > stride) stride = bsize;

	off *= ZONEPOINTS;
	debug((stdout, "stride=%d bs=%d size=%dM points=%d\n",
	    stride, bsize, (int)(off >> 20), (int)(off/stride)));

	/*
	 * Read buf's worth of data every stride and time it.
	 * Don't include the rotational delay.
	 * This first I/O outside the loop is to catch read/write permissions.
	 */

#define	IO(a,b,c)	(oflag == 0 ? (n = read(a,b,c)) : (n = write(a,b,c)))

	error = IO(fd, buf, 512);
	if (error == -1) {
		perror(disk);
		exit(1);
	}
	off = 512;
	for ( ;; ) {
		if (IO(fd, buf, 1024) != 1024) {
			exit(0);
		}
		off += 1024;
		start(0);
		if (IO(fd, buf, bsize) != bsize) {
			exit(0);
		}
		usecs = stop(0, 0);
		off += bsize;
		fprintf(stderr, "%.01f %.2f\n",
		    off/1000000.0, (double)bsize/usecs);
		off += stride;
		if (seekto(fd, off)) {
			exit(0);
		}
	}
	exit(0);
}
Beispiel #12
0
int
seek(char *disk, int oflag)
{
	char	*buf;
	int	fd;
	off64_t	size;
	off64_t	begin, end;
	int	usecs;
	int	error;
	int	tot_msec = 0, tot_io = 0;
	int	stride;

	if ((fd = open(disk, oflag)) == -1) {
		perror(disk);
		return (-1);
	}
#ifdef	linux
	flushdisk(fd);
#endif
	size = disksize(disk);
	buf = valloc(IOSIZE);
	bzero(buf, IOSIZE);

	/*
	 * We flip back and forth, in strides of 1MB (typically).
	 * If we have a 100MB fd, that means we do
	 * 1, 99, 2, 98, etc.
	 *
	 * We want around SEEK POINTS data points 
	 * but the stride has to be at least 512 and a 512 multiple.
	 */
	stride = size / SEEKPOINTS;
	if (stride < 512) stride = 512;
	stride += 511;
	stride >>= 9;
	stride <<= 9;

	debug((stdout, "stride=%d size=%dM points=%d\n",
	    stride, (int)(size >> 20), (int)(size/stride)));

	end = size;
	begin = 0;
	seekto(fd, begin);
	IO(fd, buf, IOSIZE);
	while (end >= begin + stride*2) {
		end -= stride;
		start(0);
		seekto(fd, end);
		IO(fd, buf, IOSIZE);
		usecs = stop(0, 0);
		if (usecs > TOOSMALL && usecs < TOOBIG) {
			tot_io++; tot_msec += usecs/1000;
			fprintf(stderr, "%.01f %.02f\n",
			    (end - begin - stride) / 1000000., usecs/1000.);
		}

		begin += stride;
		start(0);
		seekto(fd, begin);
		IO(fd, buf, IOSIZE);
		usecs = stop(0, 0);
		if (usecs > TOOSMALL && usecs < TOOBIG) {
			tot_io++; tot_msec += usecs/1000;
			fprintf(stderr, "%.01f %.02f\n",
			    (end + stride - begin) / 1000000., usecs/1000.);
		}
	}
	/*
	 * This is wrong, it should take the 1/3 stroke seek average.
	avg_msec = (double)tot_msec/tot_io;
	fprintf(stderr, "Average time == %.04f\n", avg_msec);
	 */
	return (0);
}
Beispiel #13
0
/* fill a buffer from a stream - return -1 on failure */
static int fill_buffer(struct stream_info *sinfo, int stream)
{
	uchar c_type;
	i64 header_length;
	i64 u_len, c_len;

	if (seekto(sinfo, sinfo->s[stream].last_head) != 0)
		return -1;

	if (read_u8(sinfo->fd, &c_type) != 0)
		return -1;
	/* Compatibility crap for versions < 0.4 */
	if (control.major_version == 0 && control.minor_version < 4) {
		u32 c_len32, u_len32, last_head32;

		if (read_u32(sinfo->fd, &c_len32) != 0)
			return -1;
		if (read_u32(sinfo->fd, &u_len32) != 0)
			return -1;
		if (read_u32(sinfo->fd, &last_head32) != 0)
			return -1;
		c_len = c_len32;
		u_len = u_len32;
		sinfo->s[stream].last_head = last_head32;
		header_length = 13;
	} else {
		if (read_i64(sinfo->fd, &c_len) != 0)
			return -1;
		if (read_i64(sinfo->fd, &u_len) != 0)
			return -1;
		if (read_i64(sinfo->fd, &sinfo->s[stream].last_head) != 0)
			return -1;
		header_length = 25;
	}

	sinfo->total_read += header_length;

	if (sinfo->s[stream].buf)
		free(sinfo->s[stream].buf);
	sinfo->s[stream].buf = malloc(u_len);
	if (!sinfo->s[stream].buf)
		return -1;
	if (read_buf(sinfo->fd, sinfo->s[stream].buf, c_len) != 0)
		return -1;

	sinfo->total_read += c_len;

	sinfo->s[stream].buflen = u_len;
	sinfo->s[stream].bufp = 0;

	if (c_type != CTYPE_NONE) {
		if (c_type == CTYPE_LZMA) {
			if (lzma_decompress_buf(&sinfo->s[stream], (size_t)c_len))
				return -1;
		} else if (c_type == CTYPE_LZO) {
			if (lzo_decompress_buf(&sinfo->s[stream], c_len))
				return -1;
		} else if (c_type == CTYPE_BZIP2) {
			if (bzip2_decompress_buf(&sinfo->s[stream], c_len))
				return -1;
		} else if (c_type == CTYPE_GZIP) {
			if (gzip_decompress_buf(&sinfo->s[stream], c_len))
				return -1;
		} else if (c_type == CTYPE_ZPAQ) {
			if (zpaq_decompress_buf(&sinfo->s[stream]))
				return -1;
		} else fatal("Dunno wtf decompression type to use!\n");
	}

	return 0;
}