コード例 #1
0
ファイル: alsa.c プロジェクト: aarizkuren/pnmixer
/**
 * Adjusts the current volume and sends a notification (if enabled).
 *
 * @param vol new volume value
 * @param dir select direction (-1 = accurate or first bellow, 0 = accurate,
 * 1 = accurate or first above)
 * @param notify whether to send notification
 * @return 0 on success otherwise negative error code
 */
int
setvol(int vol, int dir, gboolean notify)
{
    long min = 0, max = 0, value;
    int cur_perc = getvol();
    double dvol = 0.01 * vol;

    int err = snd_mixer_selem_get_playback_dB_range(elem, &min, &max);
    if (err < 0 || min >= max || !normalize_vol()) {
        err = snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
        value = lrint_dir(dvol * (max - min), dir) + min;
        snd_mixer_selem_set_playback_volume_all(elem, value);
        if (enable_noti && notify && cur_perc != getvol())
            do_notify_volume(getvol(), FALSE);
        // intentionally set twice
        return snd_mixer_selem_set_playback_volume_all(elem, value);
    }

    if (use_linear_dB_scale(min, max)) {
        value = lrint_dir(dvol * (max - min), dir) + min;
        return snd_mixer_selem_set_playback_dB_all(elem, value, dir);
    }

    if (min != SND_CTL_TLV_DB_GAIN_MUTE) {
        double min_norm = exp10((min - max) / 6000.0);
        dvol = dvol * (1 - min_norm) + min_norm;
    }

    value = lrint_dir(6000.0 * log10(dvol), dir) + max;
    snd_mixer_selem_set_playback_dB_all(elem, value, dir);
    if (enable_noti && notify && cur_perc != getvol())
        do_notify_volume(getvol(), FALSE);
    // intentionally set twice
    return snd_mixer_selem_set_playback_dB_all(elem, value, dir);
}
コード例 #2
0
ファイル: alsa.c プロジェクト: aarizkuren/pnmixer
/**
 * Mutes or unmutes playback and sends a notification (if enabled).
 *
 * @param notify whether to send notification
 */
void
setmute(gboolean notify)
{
    if (!snd_mixer_selem_has_playback_switch(elem))
        return;
    if (ismuted()) {
        snd_mixer_selem_set_playback_switch_all(elem, 0);
        if (enable_noti && notify)
            do_notify_volume(getvol(), TRUE);
    } else {
        snd_mixer_selem_set_playback_switch_all(elem, 1);
        if (enable_noti && notify)
            do_notify_volume(getvol(), FALSE);
    }
}
コード例 #3
0
ファイル: hfs.c プロジェクト: HankG/ciderpress
/*
 * NAME:	hfs->vsetattr()
 * DESCRIPTION:	change volume attributes
 */
int hfs_vsetattr(hfsvol *vol, hfsvolent *ent)
{
  if (getvol(&vol) == -1)
    goto fail;

  if (ent->clumpsz % vol->mdb.drAlBlkSiz != 0)
    ERROR(EINVAL, "illegal clump size");

  /* make sure "blessed" folder exists */

  if (ent->blessed &&
      v_getdthread(vol, ent->blessed, 0, 0) <= 0)
    ERROR(EINVAL, "illegal blessed folder");

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  vol->mdb.drClpSiz      = ent->clumpsz;

  vol->mdb.drCrDate      = d_mtime(ent->crdate);
  vol->mdb.drLsMod       = d_mtime(ent->mddate);
  vol->mdb.drVolBkUp     = d_mtime(ent->bkdate);

  vol->mdb.drFndrInfo[0] = ent->blessed;

  vol->flags |= HFS_VOL_UPDATE_MDB;

  return 0;

fail:
  return -1;
}
コード例 #4
0
ファイル: alsa.c プロジェクト: aarizkuren/pnmixer
/**
 * Callback function for the mixer element which is
 * set in alsaset().
 *
 * @param e mixer element
 * @param mask event mask
 * @return 0 on success otherwise a negative error code
 */
static int
alsa_cb(snd_mixer_elem_t *e, unsigned int mask)
{
    /* Test MASK_REMOVE first, according to Alsa documentation */
    if (mask == SND_CTL_EVENT_MASK_REMOVE) {
        return 0;
    }

    /* Then check if mixer value changed */
    if (mask & SND_CTL_EVENT_MASK_VALUE) {
        int muted;
        get_current_levels();
        muted = ismuted();
        on_volume_has_changed();
        if (enable_noti && external_noti) {
            int vol = getvol();
            if (muted)
                do_notify_volume(vol, FALSE);
            else
                do_notify_volume(vol, TRUE);
        }
    }

    return 0;
}
コード例 #5
0
ファイル: hfs.c プロジェクト: andyvand/fusehfs
/*
 * NAME:	hfs->isopen()
 * DESCRIPTION:	check if a file is open
 * RETURNS: 
 */
int hfs_isopen(hfsvol *vol, const char *path)
{
	hfsfile *file = 0;
	hfsfile *f = 0;
	
	if (getvol(&vol) == -1)
		ERROR(ENODEV, 0);
	
	file = ALLOC(hfsfile, 1);
	if (file == 0)
		ERROR(ENOMEM, 0);
	
	if (v_resolve(&vol, path, &file->cat, &file->parid, file->name, 0) <= 0)
		ERROR(ENOENT, 0);
	
	if (file->cat.cdrType != cdrFilRec)
		ERROR(EISDIR, 0);
	
	// see if it's already open
	ULongInt num = file->cat.u.fil.filFlNum;
	FREE(file);
	for(f = vol->files; f; f = f->next) {
		if (f->cat.u.fil.filFlNum == num) return 1;
	}
	return 0;
	
fail:
	FREE(file);
	return -1;
}
コード例 #6
0
ファイル: hfs.c プロジェクト: HankG/ciderpress
/*
 * NAME:	hfs->mkdir()
 * DESCRIPTION:	create a new directory
 */
int hfs_mkdir(hfsvol *vol, const char *path)
{
  CatDataRec data;
  unsigned long parid;
  char name[HFS_MAX_FLEN + 1];
  int found;

  if (getvol(&vol) == -1)
    goto fail;

  found = v_resolve(&vol, path, &data, &parid, name, 0);
  if (found == -1 || parid == 0)
    goto fail;

  if (found)
    ERROR(EEXIST, 0);

  if (parid == HFS_CNID_ROOTPAR)
    ERROR(EINVAL, 0);

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  return v_mkdir(vol, parid, name);

fail:
  return -1;
}
コード例 #7
0
ファイル: bluemote.c プロジェクト: NovaCygni/aur-mirror
int volume()
{
 int ret, vol;
 char cmd[MAXLEN];
 char buf[MAXLEN]="";

 vol=getvol();
 if(vol==-1) return -1;
 
 sprintf(cmd, "AT*EAID=4,1,\"Volume\",10,%d\r", (int) ((vol/10.0)+.5));
 
 writeport(cmd, strlen(cmd));
 if(waitfor("OK", 1, TIMEOUT) != 1) return -1;

 while(1)
 {
  while((ret = readport(buf, MAXLEN, TIMEOUT)) == -EINTR);
  if(ret <= 0) return -1;
  if(strncmp(buf, "*EAII: 15,",10)==0) setvol(atoi(buf+10));
  if(strncmp(buf, "*EAII: 0", 8)==0 || strncmp(buf, "*EAAI", 5)==0)
  {
   setvol(vol);
   return 0;
  }
  if(strncmp(buf, "*EAII: 4,",9)==0)
  {
   setvol(atoi(buf+9));
   return 1;
  }
 }
}
コード例 #8
0
ファイル: hfs.c プロジェクト: 3a9LL/panda
/*
 * NAME:	hfs->vstat()
 * DESCRIPTION:	return volume statistics
 */
int hfs_vstat(hfsvol *vol, hfsvolent *ent)
{
  if (getvol(&vol) == -1)
    goto fail;

  strcpy(ent->name, vol->mdb.drVN);

  ent->flags     = (vol->flags & HFS_VOL_READONLY) ? HFS_ISLOCKED : 0;

  ent->totbytes  = vol->mdb.drNmAlBlks * vol->mdb.drAlBlkSiz;
  ent->freebytes = vol->mdb.drFreeBks  * vol->mdb.drAlBlkSiz;

  ent->alblocksz = vol->mdb.drAlBlkSiz;
  ent->clumpsz   = vol->mdb.drClpSiz;

  ent->numfiles  = vol->mdb.drFilCnt;
  ent->numdirs   = vol->mdb.drDirCnt;

  ent->crdate    = d_ltime(vol->mdb.drCrDate);
  ent->mddate    = d_ltime(vol->mdb.drLsMod);
  ent->bkdate    = d_ltime(vol->mdb.drVolBkUp);

  ent->blessed   = vol->mdb.drFndrInfo[0];

  return 0;

fail:
  return -1;
}
コード例 #9
0
ファイル: hfs.c プロジェクト: 3a9LL/panda
/*
 * NAME:	hfs->getcwd()
 * DESCRIPTION:	return the current working directory ID
 */
unsigned long hfs_getcwd(hfsvol *vol)
{
  if (getvol(&vol) == -1)
    return 0;

  return vol->cwd;
}
コード例 #10
0
ファイル: status.c プロジェクト: Cornu/dwmstatus
int main(void) {
    char status[100];
    int l = 0;

    if (!(dpy = XOpenDisplay(NULL))) {
        fprintf(stderr, "Cannot open display.\n");
        return 1;
    }

    for (;;sleep(2)) {

        l = getcpu(status, sizeof(status));
        l += gettemp(status + l, sizeof(status) - l);
        l += getmem(status + l, sizeof(status) - l);
        l += getnetwork(status + l, sizeof(status) - l);
        l += getbattery(status + l, sizeof(status) - l);
        l += getvol(status + l, sizeof(status) - l);
        l += getdatetime(status + l, sizeof(status) - l);

        setstatus(status);
    }

    free(status);
    XCloseDisplay(dpy);

    return 0;
}
コード例 #11
0
ファイル: hfs.c プロジェクト: HankG/ciderpress
/*
 * NAME:	hfs->opendir()
 * DESCRIPTION:	prepare to read the contents of a directory
 */
hfsdir *hfs_opendir(hfsvol *vol, const char *path)
{
  hfsdir *dir = 0;
  CatKeyRec key;
  CatDataRec data;
  byte pkey[HFS_CATKEYLEN];

  if (getvol(&vol) == -1)
    goto fail;

  dir = ALLOC(hfsdir, 1);
  if (dir == 0)
    ERROR(ENOMEM, 0);

  dir->vol = vol;

  if (*path == 0)
    {
#ifdef CP_NO_STATIC
      /* meta-directory containing root dirs from all mounted volumes */

      dir->dirid = 0;
      dir->vptr  = hfs_mounts;
#else
      assert(0);
#endif
    }
  else
    {
      if (v_resolve(&vol, path, &data, 0, 0, 0) <= 0)
	goto fail;

      if (data.cdrType != cdrDirRec)
	ERROR(ENOTDIR, 0);

      dir->dirid = data.u.dir.dirDirID;
      dir->vptr  = 0;

      r_makecatkey(&key, dir->dirid, "");
      r_packcatkey(&key, pkey, 0);

      if (bt_search(&vol->cat, pkey, &dir->n) <= 0)
	goto fail;
    }

  dir->prev = 0;
  dir->next = vol->dirs;

  if (vol->dirs)
    vol->dirs->prev = dir;

  vol->dirs = dir;

  return dir;

fail:
  FREE(dir);
  return 0;
}
コード例 #12
0
ファイル: hfs.c プロジェクト: HankG/ciderpress
/*
 * NAME:	hfs->umount()
 * DESCRIPTION:	close an HFS volume
 */
int hfs_umount(hfsvol *vol)
{
  int result = 0;

  if (getvol(&vol) == -1)
    goto fail;

  if (--vol->refs)
    {
      result = v_flush(vol);
      goto done;
    }

  /* close all open files and directories */

  while (vol->files)
    {
      if (hfs_close(vol->files) == -1)
	result = -1;
    }

  while (vol->dirs)
    {
      if (hfs_closedir(vol->dirs) == -1)
	result = -1;
    }

  /* close medium */

  if (v_close(vol) == -1)
    result = -1;

  /* remove from linked list of volumes */

  if (vol->prev)
    vol->prev->next = vol->next;
  if (vol->next)
    vol->next->prev = vol->prev;

  if (vol == hfs_mounts)
    hfs_mounts = vol->next;
  if (vol == curvol)
    curvol = 0;

  FREE(vol);

done:
  return result;

fail:
  return -1;
}
コード例 #13
0
ファイル: hfs.c プロジェクト: andyvand/fusehfs
/*
 * NAME:	hfs->open()
 * DESCRIPTION:	prepare a file for I/O
 */
hfsfile *hfs_open(hfsvol *vol, const char *path)
{
  hfsfile *file = 0;
  hfsfile *f = 0;

  if (getvol(&vol) == -1)
    ERROR(ENODEV, 0);

  file = ALLOC(hfsfile, 1);
  if (file == 0)
    ERROR(ENOMEM, 0);

  if (v_resolve(&vol, path, &file->cat, &file->parid, file->name, 0) <= 0)
	ERROR(ENOENT, 0);

  if (file->cat.cdrType != cdrFilRec)
    ERROR(EISDIR, 0);
	
  // see if it's already open
  for(f = vol->files; f; f = f->next) {
	  if (f->cat.u.fil.filFlNum == file->cat.u.fil.filFlNum) {
		  // already open, increment refcount and return
		  FREE(file);
		  file = f;
		  file->refs++;
		  printf("REOPEN: file %s now has %d refs\n", path, file->refs);
		  return file;
	  }
  }

  /* package file handle for user */
  file->refs  = 1;
  file->vol   = vol;
  file->flags = 0;

  f_selectfork(file, fkData);

  file->prev = 0;
  file->next = vol->files;

  if (vol->files)
    vol->files->prev = file;

  vol->files = file;

  return file;

fail:
  FREE(file);
  return 0;
}
コード例 #14
0
void incvol(const Arg *arg) {
	long min, max;

	snd_mixer_elem_t* elem = getelem(alsachannel);

	snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
    
	int delta = (arg->i*(max-min))/100;
	long vol = getvol(elem);
    int newvol = vol+delta;
    
	if (newvol < min) newvol = min;
	if (newvol > max) newvol = max;

	setvol(newvol, elem);
}
コード例 #15
0
ファイル: hfs.c プロジェクト: 3a9LL/panda
/*
 * NAME:	hfs->stat()
 * DESCRIPTION:	return catalog information for an arbitrary path
 */
int hfs_stat(hfsvol *vol, const char *path, hfsdirent *ent)
{
  CatDataRec data;
  unsigned long parid;
  char name[HFS_MAX_FLEN + 1];

  if (getvol(&vol) == -1 ||
      v_resolve(&vol, path, &data, &parid, name, NULL) <= 0)
    goto fail;

  r_unpackdirent(parid, name, &data, ent);

  return 0;

fail:
  return -1;
}
コード例 #16
0
ファイル: hfs.c プロジェクト: HankG/ciderpress
/*
 * NAME:	hfs->rmdir()
 * DESCRIPTION:	delete an empty directory
 */
int hfs_rmdir(hfsvol *vol, const char *path)
{
  CatKeyRec key;
  CatDataRec data;
  unsigned long parid;
  char name[HFS_MAX_FLEN + 1];
  byte pkey[HFS_CATKEYLEN];

  if (getvol(&vol) == -1 ||
      v_resolve(&vol, path, &data, &parid, name, 0) <= 0)
    goto fail;

  if (data.cdrType != cdrDirRec)
    ERROR(ENOTDIR, 0);

  if (data.u.dir.dirVal != 0)
    ERROR(ENOTEMPTY, 0);

  if (parid == HFS_CNID_ROOTPAR)
    ERROR(EINVAL, 0);

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  /* delete directory record */

  r_makecatkey(&key, parid, name);
  r_packcatkey(&key, pkey, 0);

  if (bt_delete(&vol->cat, pkey) == -1)
    goto fail;

  /* delete thread record */

  r_makecatkey(&key, data.u.dir.dirDirID, "");
  r_packcatkey(&key, pkey, 0);

  if (bt_delete(&vol->cat, pkey) == -1 ||
      v_adjvalence(vol, parid, 1, -1) == -1)
    goto fail;

  return 0;

fail:
  return -1;
}
コード例 #17
0
ファイル: hfs.c プロジェクト: 3a9LL/panda
/*
 * NAME:	hfs->dirinfo()
 * DESCRIPTION:	given a directory ID, return its (name and) parent ID
 */
int hfs_dirinfo(hfsvol *vol, unsigned long *id, char *name)
{
  CatDataRec thread;

  if (getvol(&vol) == -1 ||
      v_getdthread(vol, *id, &thread, NULL) <= 0)
    goto fail;

  *id = thread.u.dthd.thdParID;

  if (name)
    strcpy(name, thread.u.dthd.thdCName);

  return 0;

fail:
  return -1;
}
コード例 #18
0
ファイル: hfs.c プロジェクト: 3a9LL/panda
/*
 * NAME:	hfs->chdir()
 * DESCRIPTION:	change current HFS directory
 */
int hfs_chdir(hfsvol *vol, const char *path)
{
  CatDataRec data;

  if (getvol(&vol) == -1 ||
      v_resolve(&vol, path, &data, NULL, NULL, NULL) <= 0)
    goto fail;

  if (data.cdrType != cdrDirRec)
    ERROR(ENOTDIR, NULL);

  vol->cwd = data.u.dir.dirDirID;

  return 0;

fail:
  return -1;
}
コード例 #19
0
ファイル: hfs.c プロジェクト: HankG/ciderpress
/*
 * NAME:	hfs->setattr()
 * DESCRIPTION:	change a file's attributes
 */
int hfs_setattr(hfsvol *vol, const char *path, const hfsdirent *ent)
{
  CatDataRec data;
  node n;

  if (getvol(&vol) == -1 ||
      v_resolve(&vol, path, &data, 0, 0, &n) <= 0)
    goto fail;

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  r_packdirent(&data, ent);

  return v_putcatrec(&data, &n);

fail:
  return -1;
}
コード例 #20
0
ファイル: main.c プロジェクト: eaglexmw/pnmixer
/**
 * Updates the tray icon. Usually called after volume has been muted
 * or changed.
 */
void
update_tray_icon(void)
{
	int muted;
	int tmpvol = getvol();
	char tooltip[60];
	gchar *active_card_name = (alsa_get_active_card())->name;
	const char *active_channel = alsa_get_active_channel();

	muted = ismuted();

	if (muted == 1) {
		GdkPixbuf *icon;

		if (tmpvol == 0)
			icon = status_icons[VOLUME_OFF];
		else if (tmpvol < 33)
			icon = status_icons[VOLUME_LOW];
		else if (tmpvol < 66)
			icon = status_icons[VOLUME_MEDIUM];
		else
			icon = status_icons[VOLUME_HIGH];
		sprintf(tooltip, _("%s (%s)\nVolume: %d %%"), active_card_name,
			active_channel,
			tmpvol);

		if (vol_meter_row) {
			GdkPixbuf *old_icon = icon_copy;
			icon_copy = gdk_pixbuf_copy(icon);
			draw_vol_meter(icon_copy, draw_offset, 5,
				       (tmpvol * vol_div_factor));
			if (old_icon)
				g_object_unref(old_icon);
			gtk_status_icon_set_from_pixbuf(tray_icon, icon_copy);
		} else
			gtk_status_icon_set_from_pixbuf(tray_icon, icon);
	} else {
		gtk_status_icon_set_from_pixbuf(tray_icon, status_icons[VOLUME_MUTED]);
		sprintf(tooltip, _("%s (%s)\nVolume: %d %%\nMuted"), active_card_name,
			active_channel, tmpvol);
	}
	gtk_status_icon_set_tooltip_text(tray_icon, tooltip);
}
コード例 #21
0
ファイル: hotkeys.c プロジェクト: hyuni/pnmixer
/**
 * This function is called before gdk/gtk can respond
 * to any(!) window event and handles pressed hotkeys.
 *
 * @param gdk_xevent the native event to filter
 * @param event the GDK event to which the X event will be translated
 * @param data user data set when the filter was installed
 * @return a GdkFilterReturn value, should be GDK_FILTER_CONTINUE only
 */
static GdkFilterReturn
key_filter(GdkXEvent *gdk_xevent,
		G_GNUC_UNUSED GdkEvent *event,
		G_GNUC_UNUSED gpointer data)
{
	int type;
	guint key, state;
	XKeyEvent *xevent;
	//gboolean bResult;

	xevent = gdk_xevent;
	type = xevent->type;

	if (type == KeyPress) {
		key = ((XKeyEvent *) xevent)->keycode;
		state = ((XKeyEvent *) xevent)->state;

		if ((int) key == volMuteKey && checkModKey(state, volMuteMods)) {
			setmute(enable_noti && hotkey_noti);
			on_volume_has_changed();
			return GDK_FILTER_CONTINUE;
		} else {
			int cv = getvol();
			if ((int) key == volUpKey && checkModKey(state, volUpMods)) {
				setvol(cv + volStep, 1, enable_noti && hotkey_noti);
			} else if ((int) key == volDownKey && checkModKey(state, volDownMods)) {
				setvol(cv - volStep, -1, enable_noti && hotkey_noti);
			}
			// just ignore unknown hotkeys

			if (ismuted() == 0)
				setmute(enable_noti && hotkey_noti);

			on_volume_has_changed();

			// this will set the slider value
			get_current_levels();
		}
	}
	return GDK_FILTER_CONTINUE;
}
コード例 #22
0
ファイル: hfs.c プロジェクト: 3a9LL/panda
/*
 * NAME:	hfs->setcwd()
 * DESCRIPTION:	set the current working directory ID
 */
int hfs_setcwd(hfsvol *vol, unsigned long id)
{
  if (getvol(&vol) == -1)
    goto fail;

  if (id == vol->cwd)
    goto done;

  /* make sure the directory exists */

  if (v_getdthread(vol, id, NULL, NULL) <= 0)
    goto fail;

  vol->cwd = id;

done:
  return 0;

fail:
  return -1;
}
コード例 #23
0
ファイル: hfs.c プロジェクト: HankG/ciderpress
/*
 * NAME:	hfs->flush()
 * DESCRIPTION:	flush all pending changes to an HFS volume
 */
int hfs_flush(hfsvol *vol)
{
  hfsfile *file;

  if (getvol(&vol) == -1)
    goto fail;

  for (file = vol->files; file; file = file->next)
    {
      if (f_flush(file) == -1)
	goto fail;
    }

  if (v_flush(vol) == -1)
    goto fail;

  return 0;

fail:
  return -1;
}
コード例 #24
0
ファイル: hfs.c プロジェクト: HankG/ciderpress
/*
 * NAME:	hfs->callback_close()
 * DESCRIPTION:	close an HFS volume
 */
int hfs_callback_close(hfsvol *vol)
{
  int result = 0;

  if (getvol(&vol) == -1)
    goto fail;

  if (--vol->refs)
    {
      result = v_flush(vol);
      goto done;
    }

  /* close all open files and directories */

  while (vol->files)
    {
      if (hfs_close(vol->files) == -1)
	result = -1;
    }

  while (vol->dirs)
    {
      if (hfs_closedir(vol->dirs) == -1)
	result = -1;
    }

  /* close medium */

  if (v_close(vol) == -1)
    result = -1;

  FREE(vol);

done:
  return result;

fail:
  return -1;
}
コード例 #25
0
ファイル: hotkeys.c プロジェクト: Cw1X/pnmixer
static
GdkFilterReturn key_filter(GdkXEvent *gdk_xevent, GdkEvent *event,
			   gpointer data) {
  int type;
  unsigned int key,state;
  XKeyEvent *xevent;
  //gboolean bResult;

  xevent = gdk_xevent;
  type = xevent->type;

  if (type == KeyPress) {
    key = ((XKeyEvent *)xevent)->keycode;
    state = ((XKeyEvent *)xevent)->state;

    if (key == volMuteKey && state == volMuteMods) {
      setmute(enable_noti&&hotkey_noti);
      get_mute_state(TRUE);
      return GDK_FILTER_CONTINUE;
    } else {
      int cv = getvol();
      if (key == volUpKey && state == volUpMods) {
	setvol(cv+volStep,enable_noti&&hotkey_noti);
      }
      else if (key == volDownKey && state == volDownMods) {
	setvol(cv-volStep,enable_noti&&hotkey_noti);
      } 
      // just ignore unknown hotkeys

      if (get_mute_state(TRUE) == 0)
	setmute(enable_noti&&hotkey_noti);

      // this will set the slider value
      get_current_levels();
    }
  }
  return GDK_FILTER_CONTINUE;
}
コード例 #26
0
ファイル: hfs.c プロジェクト: 3a9LL/panda
/*
 * NAME:	hfs->open()
 * DESCRIPTION:	prepare a file for I/O
 */
hfsfile *hfs_open(hfsvol *vol, const char *path)
{
  hfsfile *file = NULL;

  if (getvol(&vol) == -1)
    goto fail;

  file = ALLOC(hfsfile, 1);
  if (file == NULL)
    ERROR(ENOMEM, NULL);

  if (v_resolve(&vol, path, &file->cat, &file->parid, file->name, NULL) <= 0)
    goto fail;

  if (file->cat.cdrType != cdrFilRec)
    ERROR(EISDIR, NULL);

  /* package file handle for user */

  file->vol   = vol;
  file->flags = 0;

  f_selectfork(file, fkData);

  file->prev = NULL;
  file->next = vol->files;

  if (vol->files)
    vol->files->prev = file;

  vol->files = file;

  return file;

fail:
  FREE(file);
  return NULL;
}
コード例 #27
0
ファイル: main.c プロジェクト: jubalh/pnmixer
/**
 * Checks whether playback is muted, updates the icon
 * and returns the result of ismuted().
 *
 * @param set_check whether the GtkCheckButton 'Mute' on the
 * volume popup_window is updated
 * @return result of ismuted()
 */
int get_mute_state(gboolean set_check) {
  int muted;
  int tmpvol = getvol();
  char tooltip [60];

  muted = ismuted();

  if( muted == 1 ) {
    GdkPixbuf *icon;
    if (set_check)
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mute_check), FALSE);
    if (tmpvol < 33)
      icon = status_icons[1];
    else if (tmpvol < 66)
      icon = status_icons[2];
    else
      icon = status_icons[3];
    sprintf(tooltip, _("Volume: %d %%"), tmpvol);

    if (vol_meter_row) {
      GdkPixbuf* old_icon = icon_copy;
      icon_copy = gdk_pixbuf_copy(icon);
      draw_vol_meter(icon_copy,draw_offset,5,(tmpvol*vol_div_factor));
      if (old_icon)
	g_object_unref(old_icon);
      gtk_status_icon_set_from_pixbuf(tray_icon, icon_copy);
    } else
      gtk_status_icon_set_from_pixbuf(tray_icon, icon);
  } else {
    if (set_check)
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mute_check), TRUE);
    gtk_status_icon_set_from_pixbuf(tray_icon, status_icons[0]);
    sprintf(tooltip, _("Volume: %d %%\nMuted"), tmpvol);
  }
  gtk_status_icon_set_tooltip_text(tray_icon, tooltip);
  return muted;
}
コード例 #28
0
ファイル: tape.c プロジェクト: Alkzndr/freebsd
/*
 * Find an inode header.
 * Complain if had to skip.
 */
static void
findinode(struct s_spcl *header)
{
	static long skipcnt = 0;
	long i;
	char buf[TP_BSIZE];
	int htype;

	curfile.name = "<name unknown>";
	curfile.action = UNKNOWN;
	curfile.mode = 0;
	curfile.ino = 0;
	do {
		htype = header->c_type;
		switch (htype) {

		case TS_ADDR:
			/*
			 * Skip up to the beginning of the next record
			 */
			for (i = 0; i < header->c_count; i++)
				if (header->c_addr[i])
					readtape(buf);
			while (gethead(header) == FAIL ||
			    _time64_to_time(header->c_date) != dumpdate) {
				skipcnt++;
				if (Dflag) {
					byteslide++;
					if (byteslide < TP_BSIZE) {
						blkcnt--;
						blksread--;
					} else 
						byteslide = 0;
				}
			}
			break;

		case TS_INODE:
			curfile.mode = header->c_mode;
			curfile.uid = header->c_uid;
			curfile.gid = header->c_gid;
			curfile.file_flags = header->c_file_flags;
			curfile.rdev = header->c_rdev;
			curfile.atime_sec = header->c_atime;
			curfile.atime_nsec = header->c_atimensec;
			curfile.mtime_sec = header->c_mtime;
			curfile.mtime_nsec = header->c_mtimensec;
			curfile.birthtime_sec = header->c_birthtime;
			curfile.birthtime_nsec = header->c_birthtimensec;
			curfile.extsize = header->c_extsize;
			curfile.size = header->c_size;
			curfile.ino = header->c_inumber;
			break;

		case TS_END:
			/* If we missed some tapes, get another volume. */
			if (tapesread & (tapesread + 1)) {
				getvol(0);
				continue;
			}
			curfile.ino = maxino;
			break;

		case TS_CLRI:
			curfile.name = "<file removal list>";
			break;

		case TS_BITS:
			curfile.name = "<file dump list>";
			break;

		case TS_TAPE:
			if (Dflag)
				fprintf(stderr, "unexpected tape header\n");
			else
				panic("unexpected tape header\n");

		default:
			if (Dflag)
				fprintf(stderr, "unknown tape header type %d\n",
				    spcl.c_type);
			else
				panic("unknown tape header type %d\n",
				    spcl.c_type);
			while (gethead(header) == FAIL ||
			    _time64_to_time(header->c_date) != dumpdate) {
				skipcnt++;
				if (Dflag) {
					byteslide++;
					if (byteslide < TP_BSIZE) {
						blkcnt--;
						blksread--;
					} else 
						byteslide = 0;
				}
			}

		}
	} while (htype == TS_ADDR);
	if (skipcnt > 0)
		fprintf(stderr, "resync restore, skipped %ld %s\n",
		    skipcnt, Dflag ? "bytes" : "blocks");
	skipcnt = 0;
}
コード例 #29
0
ファイル: tape.c プロジェクト: Alkzndr/freebsd
/*
 * Read TP_BSIZE blocks from the input.
 * Handle read errors, and end of media.
 */
static void
readtape(char *buf)
{
	long rd, newvol, i, oldnumtrec;
	int cnt, seek_failed;

	if (blkcnt + (byteslide > 0) < numtrec) {
		memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE) + byteslide], (long)TP_BSIZE);
		blksread++;
		tapeaddr++;
		return;
	}
	if (numtrec > 0)
		memmove(&tapebuf[-TP_BSIZE],
		    &tapebuf[(numtrec-1) * TP_BSIZE], (long)TP_BSIZE);
	oldnumtrec = numtrec;
	for (i = 0; i < ntrec; i++)
		((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0;
	if (numtrec == 0)
		numtrec = ntrec;
	cnt = ntrec * TP_BSIZE;
	rd = 0;
getmore:
#ifdef RRESTORE
	if (host)
		i = rmtread(&tapebuf[rd], cnt);
	else
#endif
		i = read(mt, &tapebuf[rd], cnt);
	/*
	 * Check for mid-tape short read error.
	 * If found, skip rest of buffer and start with the next.
	 */
	if (!pipein && !pipecmdin && numtrec < ntrec && i > 0) {
		dprintf(stdout, "mid-media short read error.\n");
		numtrec = ntrec;
	}
	/*
	 * Handle partial block read.
	 */
	if ((pipein || pipecmdin) && i == 0 && rd > 0)
		i = rd;
	else if (i > 0 && i != ntrec * TP_BSIZE) {
		if (pipein || pipecmdin) {
			rd += i;
			cnt -= i;
			if (cnt > 0)
				goto getmore;
			i = rd;
		} else {
			/*
			 * Short read. Process the blocks read.
			 */
			if (i % TP_BSIZE != 0)
				vprintf(stdout,
				    "partial block read: %ld should be %ld\n",
				    i, ntrec * TP_BSIZE);
			numtrec = i / TP_BSIZE;
		}
	}
	/*
	 * Handle read error.
	 */
	if (i < 0) {
		fprintf(stderr, "Tape read error while ");
		switch (curfile.action) {
		default:
			fprintf(stderr, "trying to set up tape\n");
			break;
		case UNKNOWN:
			fprintf(stderr, "trying to resynchronize\n");
			break;
		case USING:
			fprintf(stderr, "restoring %s\n", curfile.name);
			break;
		case SKIP:
			fprintf(stderr, "skipping over inode %ju\n",
			    (uintmax_t)curfile.ino);
			break;
		}
		if (!yflag && !reply("continue"))
			done(1);
		i = ntrec * TP_BSIZE;
		memset(tapebuf, 0, i);
#ifdef RRESTORE
		if (host)
			seek_failed = (rmtseek(i, 1) < 0);
		else
#endif
			seek_failed = (lseek(mt, i, SEEK_CUR) == (off_t)-1);

		if (seek_failed) {
			fprintf(stderr,
			    "continuation failed: %s\n", strerror(errno));
			done(1);
		}
	}
	/*
	 * Handle end of tape.
	 */
	if (i == 0) {
		vprintf(stdout, "End-of-tape encountered\n");
		if (!pipein) {
			newvol = volno + 1;
			volno = 0;
			numtrec = 0;
			getvol(newvol);
			readtape(buf);
			return;
		}
		if (rd % TP_BSIZE != 0)
			panic("partial block read: %ld should be %ld\n",
				rd, ntrec * TP_BSIZE);
		terminateinput();
		memmove(&tapebuf[rd], &endoftapemark, (long)TP_BSIZE);
	}
	if (oldnumtrec == 0)
		blkcnt = 0;
	else
		blkcnt -= oldnumtrec;
	memmove(buf,
	    &tapebuf[(blkcnt++ * TP_BSIZE) + byteslide], (long)TP_BSIZE);
	blksread++;
	tapeaddr++;
}
コード例 #30
0
ファイル: pkgtrans.c プロジェクト: apprisi/illumos-gate
static int
pkgxfer(char *srcinst, int options)
{
	int	r;
	struct pkginfo info;
	FILE	*fp, *pp;
	char	*pt, *src, *dst;
	char	dstdir[PATH_MAX],
		temp[PATH_MAX],
		srcdir[PATH_MAX],
		cmd[CMDSIZE],
		pkgname[NON_ABI_NAMELNGTH];
	int	i, n, part, nparts, maxpartsize, curpartcnt, iscomp;
	char	volnos[128], tmpvol[128];
	struct	statvfs64 svfsb;
	longlong_t free_blocks;
	struct	stat	srcstat;

	info.pkginst = NULL; /* required initialization */

	/*
	 * when this routine is entered, the first part of
	 * the package to transfer is already available in
	 * the directory indicated by 'src' --- unless the
	 * source device is a datstream, in which case only
	 * the pkginfo and pkgmap files are available in 'src'
	 */
	src = srcdev.dirname;
	dst = dstdev.dirname;

	if (!(options & PT_SILENT))
		(void) fprintf(stderr, pkg_gt(MSG_TRANSFER), srcinst);
	(void) strlcpy(dstinst, srcinst, sizeof (dstinst));

	if (!(options & PT_ODTSTREAM)) {
		/* destination is a (possibly mounted) directory */
		(void) snprintf(dstdir, sizeof (dstdir),
		    "%s/%s", dst, dstinst);

		/*
		 * need to check destination directory to assure
		 * that we will not be duplicating a package which
		 * already resides there (though we are allowed to
		 * overwrite the same version)
		 */
		pkgdir = src;
		if (fpkginfo(&info, srcinst)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_NOEXISTS), srcinst);
			(void) fpkginfo(&info, NULL);
			return (1);
		}
		pkgdir = dst;

		(void) strlcpy(temp, srcinst, sizeof (temp));
		if (pt = strchr(temp, '.'))
			*pt = '\0';
		(void) strlcat(temp, ".*", sizeof (temp));

		if (pt = fpkginst(temp, info.arch, info.version)) {
			/*
			 * the same instance already exists, although
			 * its pkgid might be different
			 */
			if (options & PT_OVERWRITE) {
				(void) strlcpy(dstinst, pt, sizeof (dstinst));
				(void) snprintf(dstdir, sizeof (dstdir),
				    "%s/%s", dst, dstinst);
			} else {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_DUPVERS), srcinst);
				(void) fpkginfo(&info, NULL);
				(void) fpkginst(NULL);
				return (2);
			}
		} else if (options & PT_RENAME) {
			/*
			 * find next available instance by appending numbers
			 * to the package abbreviation until the instance
			 * does not exist in the destination directory
			 */
			if (pt = strchr(temp, '.'))
				*pt = '\0';
			for (i = 2; (access(dstdir, 0) == 0); i++) {
				(void) snprintf(dstinst, sizeof (dstinst),
				    "%s.%d", temp, i);
				(void) snprintf(dstdir, sizeof (dstdir),
				    "%s/%s", dst, dstinst);
			}
		} else if (options & PT_OVERWRITE) {
			/*
			 * we're allowed to overwrite, but there seems
			 * to be no valid package to overwrite, and we are
			 * not allowed to rename the destination, so act
			 * as if we weren't given permission to overwrite
			 * --- this keeps us from removing a destination
			 * instance which is named the same as the source
			 * instance, but really reflects a different pkg!
			 */
			options &= (~PT_OVERWRITE);
		}
		(void) fpkginfo(&info, NULL);
		(void) fpkginst(NULL);

		if (ckoverwrite(dst, dstinst, options))
			return (2);

		if (isdir(dstdir) && mkdir(dstdir, 0755)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_MKDIR), dstdir);
			return (1);
		}

		(void) snprintf(srcdir, sizeof (srcdir),
		    "%s/%s", src, srcinst);
		if (stat(srcdir, &srcstat) != -1) {
			if (chmod(dstdir, (srcstat.st_mode & S_IAMB)) == -1) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_CHMODDIR), dstdir);
				return (1);
			}
		} else {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_STATDIR), srcdir);
			return (1);
		}
	}

	if (!(options & PT_SILENT) && strcmp(dstinst, srcinst))
		(void) fprintf(stderr, pkg_gt(MSG_RENAME), dstinst);

	(void) snprintf(srcdir, sizeof (srcdir), "%s/%s", src, srcinst);
	if (chdir(srcdir)) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_CHDIR), srcdir);
		return (1);
	}

	if (ids_name) {	/* unpack the datatstream into a directory */
		/*
		 * transfer pkginfo & pkgmap first
		 */
		(void) snprintf(cmd, sizeof (cmd),
		    "%s -pudm %s", CPIOPROC, dstdir);
		if ((pp = epopen(cmd, "w")) == NULL) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_POPEN), cmd, errno);
			return (1);
		}
		(void) fprintf(pp, "%s\n%s\n", PKGINFO, PKGMAP);

		(void) sighold(SIGINT);
		(void) sighold(SIGHUP);
		r = epclose(pp);
		(void) sigrelse(SIGINT);
		(void) sigrelse(SIGHUP);

		if (r != 0) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_PCLOSE), cmd, errno);
			return (1);
		}

		if (options & PT_INFO_ONLY)
			return (0); /* don't transfer objects */

		if (chdir(dstdir)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_CHDIR), dstdir);
			return (1);
		}

		/*
		 * for each part of the package, use cpio() to
		 * unpack the archive into the destination directory
		 */
		nparts = ds_findpkg(srcdev.cdevice, srcinst);
		if (nparts < 0) {
			progerr(pkg_gt(ERR_TRANSFER));
			return (1);
		}
		for (part = 1; part <= nparts; /* void */) {
			if (ds_getpkg(srcdev.cdevice, part, dstdir)) {
				progerr(pkg_gt(ERR_TRANSFER));
				return (1);
			}
			part++;
			if (dstdev.mount) {
				(void) chdir("/");
				if (pkgumount(&dstdev))
					return (1);
				if (part <= nparts) {
					if (n = pkgmount(&dstdev, NULL, part+1,
					    nparts, 1))
						return (n);
					if (ckoverwrite(dst, dstinst, options))
						return (1);
					if (isdir(dstdir) &&
					    mkdir(dstdir, 0755)) {
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_MKDIR),
						    dstdir);
						return (1);
					}
					/*
					 * since volume is removable, each part
					 * must contain a duplicate of the
					 * pkginfo file to properly identify the
					 * volume
					 */
					if (chdir(srcdir)) {
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_CHDIR),
						    srcdir);
						return (1);
					}
					if ((pp = epopen(cmd, "w")) == NULL) {
						rpterr();
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_POPEN),
						    cmd, errno);
						return (1);
					}
					(void) fprintf(pp, "pkginfo");

					(void) sighold(SIGINT);
					(void) sighold(SIGHUP);
					r = epclose(pp);
					(void) sigrelse(SIGINT);
					(void) sigrelse(SIGHUP);

					if (r != 0) {
						rpterr();
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_PCLOSE),
						    cmd, errno);
						return (1);
					}
					if (chdir(dstdir)) {
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_CHDIR),
						    dstdir);
						return (1);
					}
				}
			}
		}
		return (0);
	}

	if ((fp = fopen(PKGMAP, "r")) == NULL) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_NOPKGMAP), srcinst);
		return (1);
	}

	nparts = 1;
	if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize))
		return (1);
	else
		(void) fclose(fp);

	if (srcdev.mount) {
		if (ckvolseq(srcdir, 1, nparts)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_SEQUENCE));
			return (1);
		}
	}

	/* write each part of this package */
	if (options & PT_ODTSTREAM) {
		char line[128];
		(void) mgets(line, 128);
		curpartcnt = -1;
		/* LINTED E_SEC_SCANF_UNBOUNDED_COPY */
		if (sscanf(line, "%s %d %d %[ 0-9]", pkgname, &nparts,
		    &maxpartsize, volnos) == 4) {
			(void) sscanf(volnos,
			    "%d %[ 0-9]", &curpartcnt, tmpvol);
			(void) strlcpy(volnos, tmpvol, sizeof (volnos));
		}
	}

	for (part = 1; part <= nparts; /* void */) {
		if (curpartcnt == 0 && (options & PT_ODTSTREAM)) {
			char prompt[128];
			int index;
			ds_volno++;
			(void) ds_close(0);
			(void) sprintf(prompt,
			    pkg_gt("Insert %%v %d of %d into %%p"),
			    ds_volno, ds_volcnt);
			if (n = getvol(ods_name, NULL, DM_FORMAT, prompt))
				return (n);
			if ((ds_fd = open(dstdev.cdevice, O_WRONLY)) < 0) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
				    errno);
				return (1);
			}
			if (ds_ginit(dstdev.cdevice) < 0) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
				    errno);
				(void) ds_close(0);
				return (1);
			}

			(void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol);
			(void) strlcpy(volnos, tmpvol, sizeof (volnos));
			curpartcnt += index;
		}

		if (options & PT_INFO_ONLY)
			nparts = 0;

		if (part == 1) {
			(void) snprintf(cmd, sizeof (cmd),
			    "find %s %s", PKGINFO, PKGMAP);
			if (nparts && (isdir(INSTALL) == 0)) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, INSTALL, sizeof (cmd));
			}
		} else
			(void) snprintf(cmd, sizeof (cmd), "find %s", PKGINFO);

		if (nparts > 1) {
			(void) snprintf(temp, sizeof (temp),
			    "%s.%d", RELOC, part);
			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, temp, sizeof (cmd));
			}
			(void) snprintf(temp, sizeof (temp),
			    "%s.%d", ROOT, part);
			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, temp, sizeof (cmd));
			}
			(void) snprintf(temp, sizeof (temp),
			    "%s.%d", ARCHIVE, part);
			if (isdir(temp) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, temp, sizeof (cmd));
			}
		} else if (nparts) {
			for (i = 0; reloc_names[i] != NULL; i++) {
				if (iscpio(reloc_names[i], &iscomp) ||
				    isdir(reloc_names[i]) == 0) {
					(void) strlcat(cmd, " ", sizeof (cmd));
					(void) strlcat(cmd, reloc_names[i],
					    sizeof (cmd));
				}
			}
			for (i = 0; root_names[i] != NULL; i++) {
				if (iscpio(root_names[i], &iscomp) ||
				    isdir(root_names[i]) == 0) {
					(void) strlcat(cmd, " ", sizeof (cmd));
					(void) strlcat(cmd, root_names[i],
					    sizeof (cmd));
				}
			}
			if (isdir(ARCHIVE) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, ARCHIVE, sizeof (cmd));
			}
		}
		if (options & PT_ODTSTREAM) {
			(void) snprintf(cmd + strlen(cmd),
			    sizeof (cmd) - strlen(cmd),
			    " -print | %s -ocD -C %d",
			    CPIOPROC, (int)BLK_SIZE);
		} else {
			if (statvfs64(dstdir, &svfsb) == -1) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_STATVFS), dstdir, errno);
				return (1);
			}

			free_blocks = (((long)svfsb.f_frsize > 0) ?
			    howmany(svfsb.f_frsize, DEV_BSIZE) :
			    howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail;

			if ((has_comp_size ? compressedsize : maxpartsize) >
			    free_blocks) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_NOSPACE),
				    has_comp_size ?
				    (long)compressedsize : (long)maxpartsize,
				    free_blocks);
				return (1);
			}
			(void) snprintf(cmd + strlen(cmd),
			    sizeof (cmd) - strlen(cmd),
			    " -print | %s -pdum %s",
			    CPIOPROC, dstdir);
		}

		n = esystem(cmd, -1, (options & PT_ODTSTREAM) ? ds_fd : -1);
		if (n) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
			return (1);
		}

		part++;
		if (srcdev.mount && (nparts > 1)) {
			/* unmount current source volume */
			(void) chdir("/");
			if (pkgumount(&srcdev))
				return (1);
			/* loop until volume is mounted successfully */
			while (part <= nparts) {
				/* read only */
				n = pkgmount(&srcdev, NULL, part, nparts, 1);
				if (n)
					return (n);
				if (chdir(srcdir)) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_CORRUPT));
					(void) chdir("/");
					(void) pkgumount(&srcdev);
					continue;
				}
				if (ckvolseq(srcdir, part, nparts)) {
					(void) chdir("/");
					(void) pkgumount(&srcdev);
					continue;
				}
				break;
			}
		}
		if (!(options & PT_ODTSTREAM) && dstdev.mount) {
			/* unmount current volume */
			if (pkgumount(&dstdev))
				return (1);
			/* loop until next volume is mounted successfully */
			while (part <= nparts) {
				/* writable */
				n = pkgmount(&dstdev, NULL, part, nparts, 1);
				if (n)
					return (n);
				if (ckoverwrite(dst, dstinst, options))
					continue;
				if (isdir(dstdir) && mkdir(dstdir, 0755)) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_MKDIR), dstdir);
					continue;
				}
				break;
			}
		}

		if ((options & PT_ODTSTREAM) && part <= nparts) {
			if (curpartcnt >= 0 && part > curpartcnt) {
				char prompt[128];
				int index;
				ds_volno++;
				if (ds_close(0))
					return (1);
				(void) sprintf(prompt,
				    pkg_gt("Insert %%v %d of %d into %%p"),
				    ds_volno, ds_volcnt);
				if (n = getvol(ods_name, NULL, DM_FORMAT,
				    prompt))
					return (n);
				if ((ds_fd = open(dstdev.cdevice, 1)) < 0) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_OPEN),
					    dstdev.cdevice, errno);
					return (1);
				}
				if (ds_ginit(dstdev.cdevice) < 0) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_OPEN),
					    dstdev.cdevice, errno);
					(void) ds_close(0);
					return (1);
				}

				(void) sscanf(volnos, "%d %[ 0-9]", &index,
				    tmpvol);
				(void) strlcpy(volnos, tmpvol, sizeof (volnos));
				curpartcnt += index;
			}
		}

	}
	return (0);
}