Exemple #1
0
int my_open(const char* path)
{
	default_open(path);
	check_device(drv.device);
	set_rc_protocol(drv.device);
	return 0;
}
Exemple #2
0
int
eject_media(cd_device *dev)
{
	if (vol_running) {
		/* If there is a media, try using DKIOCEJECT 1st */
		if (check_device(dev, CHECK_NO_MEDIA) == 0) {
			if (ioctl(dev->d_fd, DKIOCEJECT, 0) == 0) {
				return (1);
			}
		}
	}
	if (load_unload(dev->d_fd, 0) == 0) {
		/* if eject fails */
		if ((uscsi_status == 2) && (ASC(rqbuf) == 0x53)) {
			/*
			 * check that eject is not blocked on the device
			 */
			if (!prevent_allow_mr(dev->d_fd, 1))
				return (0);
			return (load_unload(dev->d_fd, 0));
		}
		return (0);
	}
	return (1);
}
static char *find_device(void)
{
	char *path = NULL;
	DIR *dir;

	dir = opendir("/sys/bus/usb/devices");
	if (!dir)
		return NULL;

	while (1) {
		struct dirent *d;

		d = readdir(dir);
		if (!d)
			break;

		if ((!isdigit(d->d_name[0]) && strncmp(d->d_name, "usb", 3))
						|| strchr(d->d_name, ':'))
			continue;

		path = check_device(d->d_name);
		if (path)
			break;
	}

	closedir(dir);

	return path;
}
Exemple #4
0
int nwipe_device_scan( nwipe_context_t*** c )
{
	/**
	 * Scans the the filesystem for storage device names.
	 *
	 * @parameter device_names  A reference to a null array pointer.
	 * @modifies  device_names  Populates device_names with an array of nwipe_contect_t
	 * @returns                 The number of strings in the device_names array.
	 *
	 */

	PedDevice* dev = NULL;
        ped_device_probe_all();
	
	int dcount = 0;

        while ((dev = ped_device_get_next (dev)))
        {
                if (check_device(c, dev, dcount))
                        dcount++;
	}

	/* Return the number of devices that were found. */
	return dcount;

} /* nwipe_device_scan */
Exemple #5
0
int nwipe_device_get( nwipe_context_t*** c, char **devnamelist, int ndevnames )
{
	/**
	 * Gets information about devices
	 *
	 * @parameter device_names  A reference to a null array pointer.
	 * @parameter devnamelist   An array of string pointers to the device names
	 * @parameter ndevnames     Number of elements in devnamelist
	 * @modifies  device_names  Populates device_names with an array of nwipe_contect_t
	 * @returns                 The number of strings in the device_names array.
	 *
	 */

	PedDevice* dev = NULL;
	
	int i;
	int dcount = 0;

	for(i = 0; i < ndevnames; i++) {

		dev = ped_device_get(devnamelist[i]);
		if (!dev)
			break;

                if (check_device(c, dev, dcount))
                        dcount++;
	}

	/* Return the number of devices that were found. */
	return dcount;

} /* nwipe_device_get */
Exemple #6
0
int
eject_media(cd_device *dev)
{
	if (vol_running) {
		/* If there is a media, try using DKIOCEJECT 1st */
		if (check_device(dev, CHECK_NO_MEDIA) == 0) {
			/*
			 * The check_device() call will issue
			 * a TEST UNIT READY (TUR) and retry many
			 * times when a DVD-R is present. The DKIOCEJECT
			 * ioctl will subsequently fail causing us to
			 * issue the LOAD/UNLOAD SCSI command to the device
			 * with out ejecting the media. Insted of letting
			 * this happen, issue a reset to the device before
			 * issuing the DKIOCEJCET ioctl.
			 */
			if (device_type == DVD_MINUS)
				reset_dev(dev->d_fd);

			if (ioctl(dev->d_fd, DKIOCEJECT, 0) == 0) {
				return (1);
			}
		}
	}
	if (load_unload(dev->d_fd, 0) == 0) {
		/* if eject fails */
		if ((uscsi_status == 2) && (ASC(rqbuf) == 0x53)) {
			/*
			 * check that eject is not blocked on the device
			 */
			if (!prevent_allow_mr(dev->d_fd, 1))
				return (0);
			return (load_unload(dev->d_fd, 0));
		}
		return (0);
	}
	return (1);
}
Exemple #7
0
/******************************************************** 
 * scan devices under a specific bus
 *******************************************************/ 
int bus_scan(char *bus, ipod_device_t *dev)
{
	int fd;
	struct dirent *child;
	char nodename[24];
	int ret = -EINVAL;
	DIR *dir = opendir(bus);

	if (NULL == dir)
	{
		ERROR("Directory %s does not exist!\n", bus);
		return ret;
	}

	while ((child = readdir(dir)) != NULL)
	{
		/* skip all items un-wanted */
		if (child->d_name[0] == '.')
			continue;

		/* get the child node name */
		sprintf(nodename, "%s/%s", bus, child->d_name);

		/* open the child node */
		fd = open(nodename, O_RDWR);
		if (fd < 0)
			continue;

		/* check if it is a Apple device */
		if (check_device(fd, &dev->dev_desc))
			return fd;

		/* not Apple device, close the handle */
		close(fd);
	}

	return ret;
}
Exemple #8
0
int
main ()
{
  libusb_context *context;
  libusb_device **devs;
  int i, count;

  if (libusb_init (&context))
    {
      fprintf (stderr, "libusb init failure\n");
      exit (1);
    }
  libusb_set_debug (context, 0);
  printf ("Possible addresses for KNX USB devices:\n");
  count = libusb_get_device_list (context, &devs);

  for (i = 0; i < count; i++)
    {
      check_device (devs[i]);
    }

  libusb_free_device_list (devs, 1);
  libusb_exit (context);
}
Exemple #9
0
int F848008(TRUSERID *handle,int iRequest,ST_PACK *in_pack,int *pRetCode,char *szMsg)
{
	int ret = 0;
	T_t_door_device_cardlist tDoorDeviceCardlist;
	T_t_door_oper_right	tDoorOperRight;

	memset(&tDoorDeviceCardlist,0,sizeof(tDoorDeviceCardlist));
	memset(&tDoorOperRight,0,sizeof(tDoorOperRight));

	getsysdate(tDoorDeviceCardlist.tx_date);
	getsystime(tDoorDeviceCardlist.tx_time);
	tDoorDeviceCardlist.cardno=in_pack->lvol1;
	des2src(tDoorDeviceCardlist.deviceid,in_pack->sname);
	des2src(tDoorDeviceCardlist.status,"1");					//0-增加1-删除
	des2src(tDoorDeviceCardlist.send_flag,"0");				//0-未发送1-已发送

	if(tDoorDeviceCardlist.cardno<1)
	{
		*pRetCode= E_INPUT_CARDNO_CANNOT_NULL;
		goto L_RETU;
	}
	ret=check_device(tDoorDeviceCardlist.deviceid);
	if(ret)
	{
		*pRetCode=ret;
		writelog(LOG_ERR,"check_device err[%d]deviceid[%s]",ret,tDoorDeviceCardlist.deviceid);
		goto L_RETU;
	}
	ret=chk_oper(in_pack->scust_limit);
	if(ret)
	{
		*pRetCode=ret;
		writelog(LOG_ERR,"chk_oper err[%d]in_pack->scust_limit[%s]",ret,in_pack->scust_limit);
		goto L_RETU;
	}
//检查权限
	ret=DB_t_door_oper_right_read_by_oper_no_and_deviceid(in_pack->scust_limit,tDoorDeviceCardlist.deviceid,&tDoorOperRight);
	if(ret)
	{
		writelog(LOG_ERR,"oper [%s]deviceid[%s]ret[%d]",in_pack->scust_limit,tDoorDeviceCardlist.deviceid,ret);
		if(DB_NOTFOUND==ret)
			*pRetCode=E_OPER_NO_RIGHT_FOR_DEVICE;
		else
			*pRetCode=E_DB_DOOR_OPER_RIGHT_R;
		goto L_RETU;
	}
	ret=GetNewVolume(KEYTYPE_DOOR_CARDLIST,tDoorDeviceCardlist.version);
	if(ret)
	{
		*pRetCode=ret;
		writelog(LOG_ERR,"GetNewVolume err[%d]",ret);
		goto L_RETU;
	}
	//如果记录已经存在则更新该记录
	ret=DB_t_door_device_cardlist_update_by_deviceid_and_cardno(tDoorDeviceCardlist.deviceid, tDoorDeviceCardlist.cardno,&tDoorDeviceCardlist);
	if(ret)
	{
		writelog(LOG_ERR,"deviceid[%s],cardno[%d]",tDoorDeviceCardlist.deviceid, tDoorDeviceCardlist.cardno);
		if(DB_NOTFOUND==ret)
			*pRetCode=E_CARDNO_CARDLIST_NOT_EXIST;
		else
			*pRetCode=E_DB_DOOR_CARDLIST_U;
		goto L_RETU;
	}
	in_pack->lvol3=tDoorDeviceCardlist.cardno;
	des2src(in_pack->sdate0,tDoorDeviceCardlist.deviceid);
	in_pack->lvol5=1;
	ret = F930117(handle,iRequest,in_pack,pRetCode,szMsg);
	if (ret)
	{
		writelog(LOG_ERR,"F930117 ret[%d]",ret);
		goto L_RETU;
	}
	return 0;
L_RETU:
	return  -1;
}
Exemple #10
0
int send_ra(struct Interface *iface, struct in6_addr *dest)
{
	struct in6_addr all_hosts_addr = {{{0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}};
	struct nd_router_advert *radvert;
	struct AdvPrefix *prefix;
	struct AdvRoute *route;
	struct AdvRDNSS *rdnss;
	struct AdvDNSSL *dnssl;
	struct AdvLowpanCo *lowpanco;
	struct AdvAbro *abroo;
	struct timespec time_now;
	int64_t secs_since_last_ra;
	char addr_str[INET6_ADDRSTRLEN];

	unsigned char buff[MSG_SIZE_SEND];
	size_t buff_dest = 0;
	size_t len = 0;
	ssize_t err;

	update_device_info(iface);

	/* First we need to check that the interface hasn't been removed or deactivated */
	if (check_device(iface) < 0) {
		if (iface->IgnoreIfMissing)	/* a bit more quiet warning message.. */
			dlog(LOG_DEBUG, 4, "interface %s does not exist, ignoring the interface", iface->Name);
		else {
			flog(LOG_WARNING, "interface %s does not exist, ignoring the interface", iface->Name);
		}
		iface->HasFailed = 1;
		/* not really a 'success', but we need to schedule new timers.. */
		return 0;
	} else {
		/* check_device was successful, act if it has failed previously */
		if (iface->HasFailed == 1) {
			flog(LOG_WARNING, "interface %s seems to have come back up, trying to reinitialize", iface->Name);
			iface->HasFailed = 0;
			/*
			 * return -1 so timer_handler() doesn't schedule new timers,
			 * reload_config() will kick off new timers anyway.  This avoids
			 * timer list corruption.
			 */
			reload_config();
			return -1;
		}
	}

	/* Make sure that we've joined the all-routers multicast group */
	if (!disableigmp6check && check_allrouters_membership(iface) < 0)
		flog(LOG_WARNING, "problem checking all-routers membership on %s", iface->Name);

	if (!iface->AdvSendAdvert) {
		dlog(LOG_DEBUG, 2, "AdvSendAdvert is off for %s", iface->Name);
		return 0;
	}

	dlog(LOG_DEBUG, 3, "sending RA on %s", iface->Name);

	if (dest == NULL) {
		dest = (struct in6_addr *)&all_hosts_addr;
		clock_gettime(CLOCK_MONOTONIC, &iface->last_multicast);
	}

	clock_gettime(CLOCK_MONOTONIC, &time_now);
	secs_since_last_ra = timespecdiff(&time_now, &iface->last_ra_time) / 1000;
	if (secs_since_last_ra < 0) {
		secs_since_last_ra = 0;
		flog(LOG_WARNING, "clock_gettime(CLOCK_MONOTONIC) went backwards!");
	}
	iface->last_ra_time = time_now;

	memset(buff, 0, sizeof(buff));
	radvert = (struct nd_router_advert *)buff;

	send_ra_inc_len(&len, sizeof(struct nd_router_advert));

	radvert->nd_ra_type = ND_ROUTER_ADVERT;
	radvert->nd_ra_code = 0;
	radvert->nd_ra_cksum = 0;

	radvert->nd_ra_curhoplimit = iface->AdvCurHopLimit;
	radvert->nd_ra_flags_reserved = (iface->AdvManagedFlag) ? ND_RA_FLAG_MANAGED : 0;
	radvert->nd_ra_flags_reserved |= (iface->AdvOtherConfigFlag) ? ND_RA_FLAG_OTHER : 0;
	/* Mobile IPv6 ext */
	radvert->nd_ra_flags_reserved |= (iface->AdvHomeAgentFlag) ? ND_RA_FLAG_HOME_AGENT : 0;

	if (iface->cease_adv) {
		radvert->nd_ra_router_lifetime = 0;
	} else {
		/* if forwarding is disabled, send zero router lifetime */
		radvert->nd_ra_router_lifetime = !check_ip6_forwarding()? htons(iface->AdvDefaultLifetime) : 0;
	}
	radvert->nd_ra_flags_reserved |= (iface->AdvDefaultPreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK;

	radvert->nd_ra_reachable = htonl(iface->AdvReachableTime);
	radvert->nd_ra_retransmit = htonl(iface->AdvRetransTimer);

	prefix = iface->AdvPrefixList;

	/*
	 *      add prefix options
	 */

	while (prefix) {
		if (prefix->enabled && (!prefix->DecrementLifetimesFlag || prefix->curr_preferredlft > 0)) {
			struct nd_opt_prefix_info *pinfo;

			pinfo = (struct nd_opt_prefix_info *)(buff + len);

			send_ra_inc_len(&len, sizeof(*pinfo));

			pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
			pinfo->nd_opt_pi_len = 4;
			pinfo->nd_opt_pi_prefix_len = prefix->PrefixLen;

			pinfo->nd_opt_pi_flags_reserved = (prefix->AdvOnLinkFlag) ? ND_OPT_PI_FLAG_ONLINK : 0;
			pinfo->nd_opt_pi_flags_reserved |= (prefix->AdvAutonomousFlag) ? ND_OPT_PI_FLAG_AUTO : 0;
			/* Mobile IPv6 ext */
			pinfo->nd_opt_pi_flags_reserved |= (prefix->AdvRouterAddr) ? ND_OPT_PI_FLAG_RADDR : 0;

			if (iface->cease_adv && prefix->DeprecatePrefixFlag) {
				/* RFC4862, 5.5.3, step e) */
				if (prefix->curr_validlft < MIN_AdvValidLifetime) {
					if (prefix->DecrementLifetimesFlag) {
						decrement_lifetime(secs_since_last_ra,
						&prefix->curr_validlft);
					}
					pinfo->nd_opt_pi_valid_time = htonl(prefix->curr_validlft);
				} else {
					pinfo->nd_opt_pi_valid_time = htonl(MIN_AdvValidLifetime);
				}
				pinfo->nd_opt_pi_preferred_time = 0;
			} else {
				if (prefix->DecrementLifetimesFlag) {
					decrement_lifetime(secs_since_last_ra, &prefix->curr_validlft);

					decrement_lifetime(secs_since_last_ra, &prefix->curr_preferredlft);
					if (prefix->curr_preferredlft == 0)
						cease_adv_pfx_msg(iface->Name, &prefix->Prefix, prefix->PrefixLen);
				}
				pinfo->nd_opt_pi_valid_time = htonl(prefix->curr_validlft);
				pinfo->nd_opt_pi_preferred_time = htonl(prefix->curr_preferredlft);

			}
			pinfo->nd_opt_pi_reserved2 = 0;

			memcpy(&pinfo->nd_opt_pi_prefix, &prefix->Prefix, sizeof(struct in6_addr));
			print_addr(&prefix->Prefix, addr_str);
			dlog(LOG_DEBUG, 5, "adding prefix %s to advert for %s with %u seconds(s) valid lifetime and %u seconds(s) preferred time",
				addr_str, iface->Name, ntohl(pinfo->nd_opt_pi_valid_time), ntohl(pinfo->nd_opt_pi_preferred_time));
		}

		prefix = prefix->next;
	}

	route = iface->AdvRouteList;

	/*
	 *      add route options
	 */

	while (route) {
		struct nd_opt_route_info_local *rinfo;

		rinfo = (struct nd_opt_route_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(*rinfo));

		rinfo->nd_opt_ri_type = ND_OPT_ROUTE_INFORMATION;
		/* XXX: the prefixes are allowed to be sent in smaller chunks as well */
		rinfo->nd_opt_ri_len = 3;
		rinfo->nd_opt_ri_prefix_len = route->PrefixLen;

		rinfo->nd_opt_ri_flags_reserved = (route->AdvRoutePreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK;
		if (iface->cease_adv && route->RemoveRouteFlag) {
			rinfo->nd_opt_ri_lifetime = 0;
		} else {
			rinfo->nd_opt_ri_lifetime = htonl(route->AdvRouteLifetime);
		}

		memcpy(&rinfo->nd_opt_ri_prefix, &route->Prefix, sizeof(struct in6_addr));

		route = route->next;
	}

	rdnss = iface->AdvRDNSSList;

	/*
	 *      add rdnss options
	 */

	while (rdnss) {
		struct nd_opt_rdnss_info_local *rdnssinfo;

		rdnssinfo = (struct nd_opt_rdnss_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(*rdnssinfo) - (3 - rdnss->AdvRDNSSNumber) * sizeof(struct in6_addr));

		rdnssinfo->nd_opt_rdnssi_type = ND_OPT_RDNSS_INFORMATION;
		rdnssinfo->nd_opt_rdnssi_len = 1 + 2 * rdnss->AdvRDNSSNumber;
		rdnssinfo->nd_opt_rdnssi_pref_flag_reserved = 0;

		if (iface->cease_adv && rdnss->FlushRDNSSFlag) {
			rdnssinfo->nd_opt_rdnssi_lifetime = 0;
		} else {
			rdnssinfo->nd_opt_rdnssi_lifetime = htonl(rdnss->AdvRDNSSLifetime);
		}

		memcpy(&rdnssinfo->nd_opt_rdnssi_addr1, &rdnss->AdvRDNSSAddr1, sizeof(struct in6_addr));
		memcpy(&rdnssinfo->nd_opt_rdnssi_addr2, &rdnss->AdvRDNSSAddr2, sizeof(struct in6_addr));
		memcpy(&rdnssinfo->nd_opt_rdnssi_addr3, &rdnss->AdvRDNSSAddr3, sizeof(struct in6_addr));

		rdnss = rdnss->next;
	}

	dnssl = iface->AdvDNSSLList;

	/*
	 *      add dnssl options
	 */

	while (dnssl) {
		struct nd_opt_dnssl_info_local *dnsslinfo;
		int const start_len = len;
		int i;

		dnsslinfo = (struct nd_opt_dnssl_info_local *)(buff + len);

		send_ra_inc_len(&len, sizeof(dnsslinfo->nd_opt_dnssli_type) +
				sizeof(dnsslinfo->nd_opt_dnssli_len) + sizeof(dnsslinfo->nd_opt_dnssli_reserved) + sizeof(dnsslinfo->nd_opt_dnssli_lifetime)
		    );

		dnsslinfo->nd_opt_dnssli_type = ND_OPT_DNSSL_INFORMATION;
		dnsslinfo->nd_opt_dnssli_reserved = 0;

		if (iface->cease_adv && dnssl->FlushDNSSLFlag) {
			dnsslinfo->nd_opt_dnssli_lifetime = 0;
		} else {
			dnsslinfo->nd_opt_dnssli_lifetime = htonl(dnssl->AdvDNSSLLifetime);
		}

		for (i = 0; i < dnssl->AdvDNSSLNumber; i++) {
			char *label;
			int label_len;

			label = dnssl->AdvDNSSLSuffixes[i];

			while (label[0] != '\0') {
				if (strchr(label, '.') == NULL)
					label_len = strlen(label);
				else
					label_len = strchr(label, '.') - label;

				buff_dest = len;
				send_ra_inc_len(&len, 1);
				buff[buff_dest] = label_len;

				buff_dest = len;
				send_ra_inc_len(&len, label_len);
				memcpy(buff + buff_dest, label, label_len);

				label += label_len;

				if (label[0] == '.')
					label++;
				if (label[0] == '\0') {
					buff_dest = len;
					send_ra_inc_len(&len, 1);
					buff[buff_dest] = 0;
				}
			}
		}

		dnsslinfo->nd_opt_dnssli_len = (len - start_len) / 8;

		if ((len - start_len) % 8 != 0) {
			send_ra_inc_len(&len, 8 - (len - start_len) % 8);
			++dnsslinfo->nd_opt_dnssli_len;
		}

		dnssl = dnssl->next;
	}

	/*
	 *      add MTU option
	 */

	if (iface->AdvLinkMTU != 0) {
		struct nd_opt_mtu *mtu;

		mtu = (struct nd_opt_mtu *)(buff + len);

		send_ra_inc_len(&len, sizeof(*mtu));

		mtu->nd_opt_mtu_type = ND_OPT_MTU;
		mtu->nd_opt_mtu_len = 1;
		mtu->nd_opt_mtu_reserved = 0;
		mtu->nd_opt_mtu_mtu = htonl(iface->AdvLinkMTU);
	}

	/*
	 * add Source Link-layer Address option
	 */

	if (iface->AdvSourceLLAddress && iface->if_hwaddr_len > 0) {
		/*
		4.6.1.  Source/Target Link-layer Address

		      0                   1                   2                   3
		      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
		     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		     |     Type      |    Length     |    Link-Layer Address ...
		     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

		   Fields:

		      Type
				     1 for Source Link-layer Address
				     2 for Target Link-layer Address

		      Length         The length of the option (including the type and
				     length fields) in units of 8 octets.  For example,
				     the length for IEEE 802 addresses is 1 [IPv6-
				     ETHER].

		      Link-Layer Address
				     The variable length link-layer address.

				     The content and format of this field (including
				     byte and bit ordering) is expected to be specified
				     in specific documents that describe how IPv6
				     operates over different link layers.  For instance,
				     [IPv6-ETHER].

		*/
		/* +2 for the ND_OPT_SOURCE_LINKADDR and the length (each occupy one byte) */
		size_t const sllao_bytes = (iface->if_hwaddr_len / 8) + 2;
		size_t const sllao_len = (sllao_bytes + 7) / 8;
		uint8_t *sllao = (uint8_t *) (buff + len);

		send_ra_inc_len(&len, sllao_len * 8);

		*sllao++ = ND_OPT_SOURCE_LINKADDR;
		*sllao++ = (uint8_t) sllao_len;

		/* if_hwaddr_len is in bits, so divide by 8 to get the byte count. */
		memcpy(sllao, iface->if_hwaddr, iface->if_hwaddr_len / 8);
	}

	/*
	 * Mobile IPv6 ext: Advertisement Interval Option to support
	 * movement detection of mobile nodes
	 */

	if (iface->AdvIntervalOpt) {
		struct AdvInterval a_ival;
		uint32_t ival;
		if (iface->MaxRtrAdvInterval < Cautious_MaxRtrAdvInterval) {
			ival = ((iface->MaxRtrAdvInterval + Cautious_MaxRtrAdvInterval_Leeway) * 1000);

		} else {
			ival = (iface->MaxRtrAdvInterval * 1000);
		}
		a_ival.type = ND_OPT_RTR_ADV_INTERVAL;
		a_ival.length = 1;
		a_ival.reserved = 0;
		a_ival.adv_ival = htonl(ival);

		buff_dest = len;
		send_ra_inc_len(&len, sizeof(a_ival));
		memcpy(buff + buff_dest, &a_ival, sizeof(a_ival));
	}

	/*
	 * Mobile IPv6 ext: Home Agent Information Option to support
	 * Dynamic Home Agent Address Discovery
	 */

	if (iface->AdvHomeAgentInfo && (iface->AdvMobRtrSupportFlag || iface->HomeAgentPreference != 0 || iface->HomeAgentLifetime != iface->AdvDefaultLifetime)) {
		struct HomeAgentInfo ha_info;
		ha_info.type = ND_OPT_HOME_AGENT_INFO;
		ha_info.length = 1;
		ha_info.flags_reserved = (iface->AdvMobRtrSupportFlag) ? ND_OPT_HAI_FLAG_SUPPORT_MR : 0;
		ha_info.preference = htons(iface->HomeAgentPreference);
		ha_info.lifetime = htons(iface->HomeAgentLifetime);

		buff_dest = len;
		send_ra_inc_len(&len, sizeof(ha_info));
		memcpy(buff + buff_dest, &ha_info, sizeof(ha_info));
	}

	lowpanco = iface->AdvLowpanCoList;

	/*
	 * Add 6co option
	 */

	if (lowpanco) {
		struct nd_opt_6co *co;
		co = (struct nd_opt_6co *)(buff + len);

		send_ra_inc_len(&len, sizeof(*co));

		co->nd_opt_6co_type = ND_OPT_6CO;
		co->nd_opt_6co_len = 3;
		co->nd_opt_6co_context_len = lowpanco->ContextLength;
		co->nd_opt_6co_c = lowpanco->ContextCompressionFlag;
		co->nd_opt_6co_cid = lowpanco->AdvContextID;
		co->nd_opt_6co_valid_lifetime = lowpanco->AdvLifeTime;
		co->nd_opt_6co_con_prefix = lowpanco->AdvContextPrefix;
	}

	abroo = iface->AdvAbroList;

	/*
	 * Add ABRO option
	 */

	if (abroo) {
		struct nd_opt_abro *abro;
		abro = (struct nd_opt_abro *)(buff + len);

		send_ra_inc_len(&len, sizeof(*abro));

		abro->nd_opt_abro_type = ND_OPT_ABRO;
		abro->nd_opt_abro_len = 3;
		abro->nd_opt_abro_ver_low = abroo->Version[1];
		abro->nd_opt_abro_ver_high = abroo->Version[0];
		abro->nd_opt_abro_valid_lifetime = abroo->ValidLifeTime;
		abro->nd_opt_abro_6lbr_address = abroo->LBRaddress;
	}

	err = really_send(dest, iface->if_index, iface->if_addr, buff, len);

	if (err < 0) {
		if (!iface->IgnoreIfMissing || !(errno == EINVAL || errno == ENODEV))
			flog(LOG_WARNING, "sendmsg: %s", strerror(errno));
		else
			dlog(LOG_DEBUG, 3, "sendmsg: %s", strerror(errno));
	}

	return 0;
}
Exemple #11
0
XDeviceInfo*
find_device_info(char *name)
{
	XDeviceInfo    *devices;
	XDeviceInfo    *found = NULL;
	int		i, max_id;
	int		num_devices, num_found;
	Bool		is_id = True;
	XID		id = (XID)-1;
	const char	       *errstr;

	devices = XListInputDevices(display, &num_devices);
	max_id = 0;
	for (i = 0; i < num_devices; i++)
		if (devices[i].id > max_id)
			max_id = devices[i].id;


	if (name != NULL) {
		for(i = 0; i < strlen(name); i++) {
			if (!isdigit(name[i])) {
				is_id = False;
				break;
			}
		}
		if (is_id) {
			id = strtonum(name, 0, max_id, &errstr);
			if (errstr != NULL) {
				fprintf(stderr, "Invalid device id %s: %s\n",
				    name, errstr);
				exit(1);
			}
		}
	}

	num_found = 0;
	for(i = 0; i < num_devices; i++) {
		if (devices[i].use != IsXExtensionPointer)
			continue;
		if (name == NULL) {
			if (check_device(&devices[i])) {
				found = &devices[i];
				num_found++;
			}
			continue;
		}
		if ((!is_id && strcmp(devices[i].name, name) == 0) ||
		    (is_id && devices[i].id == id)) {
			found = &devices[i];
			num_found++;
		}
	}
	if (num_found > 1) {
		fprintf(stderr,
		    "Error: found multiple matching devices.\n"
		    "To ensure the correct one is selected, please use "
		    "the device ID instead.\n");
		return NULL;
	}
	return found;
}
Exemple #12
0
void
write_fini(void)
{
	print_n_flush(gettext("Finalizing (Can take several minutes)..."));
	/* Some drives don't like this while in test write mode */
	if (!simulation) {
		if (!finalize(target)) {
			/*
			 * It is possible that the drive is busy writing the
			 * buffered portion. So do not get upset yet.
			 */
			(void) sleep(10);
			if (!finalize(target)) {
				if (debug) {
					(void) printf("status %x, %x/%x/%x\n",
					    uscsi_status, SENSE_KEY(rqbuf),
					    ASC(rqbuf), ASCQ(rqbuf));
				}

				/*
				 * Different vendor drives return different
				 * sense error info for CLOSE SESSION command.
				 * The Panasonic drive that we are using is
				 * one such drive.
				 */
				if (device_type == DVD_MINUS) {
					if (verbose) {
						(void) printf(
						    "skipping finalizing\n");
					}
				} else {

			/* l10n_NOTE : 'failed' as in finishing up...failed  */
					(void) printf(gettext("failed.\n"));

					err_msg(gettext(
					    "Could not finalize the disc.\n"));
					exit(1);
				}


			}
		}
		if (vol_running) {
			(void) eject_media(target);
		}
	} else if (check_device(target, CHECK_MEDIA_IS_NOT_BLANK)) {
		/*
		 * Some drives such as the pioneer A04 will retain a
		 * ghost TOC after a simulation write is done. The
		 * media will actually be blank, but the drive will
		 * report a TOC. There is currently no other way to
		 * re-initialize the media other than ejecting or
		 * to ask the drive to clear the leadout. The laser
		 * is currently off so nothing is written to the
		 * media (on a good behaving drive).
		 * NOTE that a device reset does not work to make
		 * the drive re-initialize the media.
		 */

		blanking_type = "clear_ghost";
		blank();

	}
	/* l10n_NOTE : 'done' as in "Finishing up...done"  */
	(void) printf(gettext("done.\n"));
}
Exemple #13
0
static void
amstar_estimate(
    application_argument_t *argument)
{
    GPtrArray  *argv_ptr;
    char       *cmd = NULL;
    int         nullfd;
    int         pipefd;
    FILE       *dumpout = NULL;
    off_t       size = -1;
    char        line[32768];
    char       *errmsg = NULL;
    char       *qerrmsg;
    char       *qdisk;
    amwait_t    wait_status;
    int         starpid;
    amregex_t  *rp;
    times_t     start_time;
    int         level = 0;
    GSList     *levels = NULL;

    if (!argument->level) {
	fprintf(stderr, "ERROR No level argument\n");
	error(_("No level argument"));
    }
    if (!argument->dle.disk) {
	fprintf(stderr, "ERROR No disk argument\n");
	error(_("No disk argument"));
    }
    if (!argument->dle.device) {
	fprintf(stderr, "ERROR No device argument\n");
	error(_("No device argument"));
    }

    if (argument->dle.include_list &&
	argument->dle.include_list->nb_element >= 0) {
	fprintf(stderr, "ERROR include-list not supported for backup\n");
    }

    if (check_device(argument) == 0) {
	return;
    }

    qdisk = quote_string(argument->dle.disk);
    if (argument->calcsize) {
	char *dirname;

	if (star_directory) {
	    dirname = amname_to_dirname(star_directory);
	} else {
	    dirname = amname_to_dirname(argument->dle.device);
	}
	run_calcsize(argument->config, "STAR", argument->dle.disk, dirname,
		     argument->level, NULL, NULL);
	return;
    }

    if (!star_path) {
	errmsg = vstrallocf(_("STAR-PATH not defined"));
	goto common_error;
    }
    cmd = stralloc(star_path);

    start_time = curclock();

    for (levels = argument->level; levels != NULL; levels = levels->next) {
	level = GPOINTER_TO_INT(levels->data);
	argv_ptr = amstar_build_argv(argument, level, CMD_ESTIMATE);

	if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
	    errmsg = vstrallocf(_("Cannot access /dev/null : %s"),
				strerror(errno));
	    goto common_error;
	}

	starpid = pipespawnv(cmd, STDERR_PIPE, 1,
			     &nullfd, &nullfd, &pipefd,
			     (char **)argv_ptr->pdata);

	dumpout = fdopen(pipefd,"r");
	if (!dumpout) {
	    errmsg = vstrallocf(_("Can't fdopen: %s"), strerror(errno));
	    goto common_error;
	}

	size = (off_t)-1;
	while (size < 0 && (fgets(line, sizeof(line), dumpout)) != NULL) {
	    if (line[strlen(line)-1] == '\n') /* remove trailling \n */
		line[strlen(line)-1] = '\0';
	    if (line[0] == '\0')
		continue;
	    dbprintf("%s\n", line);
	    /* check for size match */
	    /*@ignore@*/
	    for(rp = re_table; rp->regex != NULL; rp++) {
		if(match(rp->regex, line)) {
		    if (rp->typ == DMP_SIZE) {
			size = ((the_num(line, rp->field)*rp->scale+1023.0)/1024.0);
			if(size < 0.0)
			    size = 1.0;             /* found on NeXT -- sigh */
		    }
		    break;
		}
	    }
	    /*@end@*/
	}

	while ((fgets(line, sizeof(line), dumpout)) != NULL) {
	    dbprintf("%s", line);
	}

	dbprintf(".....\n");
	dbprintf(_("estimate time for %s level %d: %s\n"),
		 qdisk,
		 level,
		 walltime_str(timessub(curclock(), start_time)));
	if(size == (off_t)-1) {
	    errmsg = vstrallocf(_("no size line match in %s output"),
				cmd);
	    dbprintf(_("%s for %s\n"), errmsg, qdisk);
	    dbprintf(".....\n");
	} else if(size == (off_t)0 && argument->level == 0) {
	    dbprintf(_("possible %s problem -- is \"%s\" really empty?\n"),
		     cmd, argument->dle.disk);
	    dbprintf(".....\n");
	}
	dbprintf(_("estimate size for %s level %d: %lld KB\n"),
		 qdisk,
		 level,
		 (long long)size);

	kill(-starpid, SIGTERM);

	dbprintf(_("waiting for %s \"%s\" child\n"), cmd, qdisk);
	waitpid(starpid, &wait_status, 0);
	if (WIFSIGNALED(wait_status)) {
	    errmsg = vstrallocf(_("%s terminated with signal %d: see %s"),
				cmd, WTERMSIG(wait_status), dbfn());
	} else if (WIFEXITED(wait_status)) {
	    if (WEXITSTATUS(wait_status) != 0) {
		errmsg = vstrallocf(_("%s exited with status %d: see %s"),
				    cmd, WEXITSTATUS(wait_status), dbfn());
	    } else {
		/* Normal exit */
	    }
	} else {
	    errmsg = vstrallocf(_("%s got bad exit: see %s"), cmd, dbfn());
	}
	dbprintf(_("after %s %s wait\n"), cmd, qdisk);

	g_ptr_array_free_full(argv_ptr);

	aclose(nullfd);
	afclose(dumpout);

	fprintf(stdout, "%d %lld 1\n", level, (long long)size);
    }
    amfree(qdisk);
    amfree(cmd);
    return;

common_error:
    dbprintf("%s\n", errmsg);
    qerrmsg = quote_string(errmsg);
    amfree(qdisk);
    dbprintf("%s", errmsg);
    fprintf(stdout, "ERROR %s\n", qerrmsg);
    amfree(errmsg);
    amfree(qerrmsg);
    amfree(cmd);
}
int main(int argc, char* argv[]) {
	int opt = 0;
	int optindex = 0;
	char* ipsw = NULL;
	char* uuid = NULL;
	int tss_enabled = 0;

	// create an instance of our context
	struct idevicerestore_client_t* client = (struct idevicerestore_client_t*) malloc(sizeof(struct idevicerestore_client_t));
	if (client == NULL) {
		error("ERROR: Out of memory\n");
		return -1;
	}
	memset(client, '\0', sizeof(struct idevicerestore_client_t));

	while ((opt = getopt_long(argc, argv, "dhcexu:", longopts, &optindex)) > 0) {
		switch (opt) {
		case 'h':
			usage(argc, argv);
			return 0;

		case 'd':
			client->flags |= FLAG_DEBUG;
			idevicerestore_debug = 1;
			break;

		case 'e':
			client->flags |= FLAG_ERASE;
			break;

		case 'c':
			client->flags |= FLAG_CUSTOM;
			break;

		case 'x':
			client->flags |= FLAG_EXCLUDE;
			break;

		case 'u':
			uuid = optarg;
			break;

		default:
			usage(argc, argv);
			return -1;
		}
	}

	if ((argc-optind) == 1) {
		argc -= optind;
		argv += optind;

		ipsw = argv[0];
	} else {
		usage(argc, argv);
		return -1;
	}

	if (client->flags & FLAG_DEBUG) {
		idevice_set_debug_level(1);
		irecv_set_debug_level(1);
	}

	client->uuid = uuid;
	client->ipsw = ipsw;

	// check which mode the device is currently in so we know where to start
	if (check_mode(client) < 0 || client->mode->index == MODE_UNKNOWN) {
		error("ERROR: Unable to discover device mode. Please make sure a device is attached.\n");
		return -1;
	}
	info("Found device in %s mode\n", client->mode->string);

	// discover the device type
	if (check_device(client) < 0 || client->device->index == DEVICE_UNKNOWN) {
		error("ERROR: Unable to discover device type\n");
		return -1;
	}
	info("Identified device as %s\n", client->device->product);

	if (client->mode->index == MODE_RESTORE) {
		if (restore_reboot(client) < 0) {
			error("ERROR: Unable to exit restore mode\n");
			return -1;
		}
	}

	// extract buildmanifest
	plist_t buildmanifest = NULL;
	info("Extracting BuildManifest from IPSW\n");
	if (ipsw_extract_build_manifest(ipsw, &buildmanifest, &tss_enabled) < 0) {
		error("ERROR: Unable to extract BuildManifest from %s\n", ipsw);
		return -1;
	}

	/* print iOS information from the manifest */
	build_manifest_print_information(buildmanifest);

	if (client->flags & FLAG_CUSTOM) {
		/* prevent signing custom firmware */
		tss_enabled = 0;
		info("Custom firmware requested. Disabled TSS request.\n");
	}

	// choose whether this is an upgrade or a restore (default to upgrade)
	client->tss = NULL;
	plist_t build_identity = NULL;
	if (client->flags & FLAG_ERASE) {
		build_identity = build_manifest_get_build_identity(buildmanifest, 0);
		if (build_identity == NULL) {
			error("ERROR: Unable to find any build identities\n");
			plist_free(buildmanifest);
			return -1;
		}
	} else {
		// loop through all build identities in the build manifest
		// and list the valid ones
		int i = 0;
		int valid_builds = 0;
		int build_count = build_manifest_get_identity_count(buildmanifest);
		for (i = 0; i < build_count; i++) {
			build_identity = build_manifest_get_build_identity(buildmanifest, i);
			valid_builds++;
		}
	}

	/* print information about current build identity */
	build_identity_print_information(build_identity);

	/* retrieve shsh blobs if required */
	if (tss_enabled) {
		debug("Getting device's ECID for TSS request\n");
		/* fetch the device's ECID for the TSS request */
		if (get_ecid(client, &client->ecid) < 0) {
			error("ERROR: Unable to find device ECID\n");
			return -1;
		}
		info("Found ECID %llu\n", client->ecid);

		if (get_shsh_blobs(client, client->ecid, build_identity, &client->tss) < 0) {
			error("ERROR: Unable to get SHSH blobs for this device\n");
			return -1;
		}
	}

	/* verify if we have tss records if required */
	if ((tss_enabled) && (client->tss == NULL)) {
		error("ERROR: Unable to proceed without a TSS record.\n");
		plist_free(buildmanifest);
		return -1;
	}

	// Extract filesystem from IPSW and return its name
	char* filesystem = NULL;
	if (ipsw_extract_filesystem(client->ipsw, build_identity, &filesystem) < 0) {
		error("ERROR: Unable to extract filesystem from IPSW\n");
		if (client->tss)
			plist_free(client->tss);
		plist_free(buildmanifest);
		return -1;
	}

	// if the device is in normal mode, place device into recovery mode
	if (client->mode->index == MODE_NORMAL) {
		info("Entering recovery mode...\n");
		if (normal_enter_recovery(client) < 0) {
			error("ERROR: Unable to place device into recovery mode\n");
			if (client->tss)
				plist_free(client->tss);
			plist_free(buildmanifest);
			return -1;
		}
	}

	// if the device is in DFU mode, place device into recovery mode
	if (client->mode->index == MODE_DFU) {
		if (dfu_enter_recovery(client, build_identity) < 0) {
			error("ERROR: Unable to place device into recovery mode\n");
			plist_free(buildmanifest);
			if (client->tss)
				plist_free(client->tss);
			return -1;
		}
	}

	// if the device is in recovery mode, place device into restore mode
	if (client->mode->index == MODE_RECOVERY) {
		if (recovery_enter_restore(client, build_identity) < 0) {
			error("ERROR: Unable to place device into restore mode\n");
			plist_free(buildmanifest);
			if (client->tss)
				plist_free(client->tss);
			return -1;
		}
	}

	// device is finally in restore mode, let's do this
	if (client->mode->index == MODE_RESTORE) {
		info("Restoring device... \n");
		if (restore_device(client, build_identity, filesystem) < 0) {
			error("ERROR: Unable to restore device\n");
			return -1;
		}
	}

	info("Cleaning up...\n");
	if (filesystem)
		unlink(filesystem);

	info("DONE\n");
	return 0;
}
/* Set up all the radvd internal stuff from our own configuration */
int radvd_init(char *ifname, struct config *c) {
  struct AdvPrefix *prefix;
  sigset_t oset, nset;


  if (log_open(L_STDERR, "radvd", NULL, -1) < 0) {
    error("log_open\n");
    return -1;
  }
  srand((unsigned int)time(NULL));
  info("starting radvd on device %s\n", ifname);

  sock = open_icmpv6_socket();
  if (sock < 0) {
    error("open_icmpv6_socket\n");
    return -1;
  }
  sigemptyset(&nset);
  sigaddset(&nset, SIGALRM);
  sigprocmask(SIG_UNBLOCK, &nset, &oset);
  if (sigismember(&oset, SIGALRM))
    flog(LOG_WARNING, "SIGALRM has been unblocked. Your startup environment might be wrong.");


  /* setup the radvd struct Interface to know about all our defaults */
  iface = malloc(sizeof(struct Interface));
  if (iface == NULL)
    return -1;

  iface_init_defaults(iface);
  strncpy(iface->Name, ifname, IFNAMSIZ-1);
  iface->Name[IFNAMSIZ-1] = '\0';

  iface->next = NULL;
  iface->AdvSendAdvert = 1;

  /* check the interface exists... this probably shouldn't fail */
  if (check_device(sock, iface) < 0) {
    error("check_device!\n");
    return -1;
  }
  
  if (setup_deviceinfo(sock, iface) < 0) {
    error("setup_deviceinfo\n");
    return -1;
  }
  if (check_iface(iface) < 0) {
    error("check_iface\n");
    return -1;
  }
  if (setup_linklocal_addr(sock, iface) < 0) {
    error("setup_linklocal_addr\n");
    return -1;
  }
  if (setup_allrouters_membership(sock, iface) < 0) {
    error("setup_allrouters_membership\n");
    return -1;
  }


  /* set up the prefix we're advertising from the config struct we get passed in. */
  prefix = malloc(sizeof(struct AdvPrefix));
  if (prefix == NULL)
    return -1;

  prefix_init_defaults(prefix);
  prefix->PrefixLen = 64;
  memcpy(&prefix->Prefix, c->router_addr.s6_addr, sizeof(struct in6_addr));
  prefix->next = NULL;

  iface->AdvPrefixList = prefix;


  // config_interface();
  radvd_kickoff_adverts();

  set_debuglevel(0);

  return sock;
}
Exemple #16
0
static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct snd_set_device_msg dmsg;
	struct snd_set_volume_msg vmsg;
	struct snd_device_config dev;
	struct snd_volume_config vol;
	struct snd_ctxt *snd = file->private_data;
	int rc = 0;
	
	mutex_lock(&snd->lock);
	switch (cmd) {
	case SND_SET_DEVICE:
		if (copy_from_user(&dev, (void *) arg, sizeof(dev))) {
			rc = -EFAULT;
			break;
		}

		if (check_mute(dev.ear_mute) ||
				check_mute(dev.mic_mute) ) {
			pr_err("snd_ioctl set device: invalid mute status.\n");
			rc = -EINVAL;
			break;
		}

                /* Prevent wrong device to make the snd processor crashing */
                check_device(&dev.device);
		if(force_headset && (force_headset==2))
		   dev.device=2;

		dmsg.args.device = cpu_to_be32(dev.device);
		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
		dmsg.args.cb_func = -1;
		dmsg.args.client_data = 0;

		//pr_info("snd_set_device %d %d %d\n", dev.device, dev.ear_mute, dev.mic_mute);
		printk("TEST snd_set_device %d %d %d\n", dev.device, dev.ear_mute, dev.mic_mute);	

		if(!snd->ept) {
			pr_err("No sound endpoint found, can't set snd_device");
			return -EIO;
		}
	
		msm_rpc_setup_req(&dmsg.hdr, RPC_SND_PROG, RPC_SND_VERS,
			  SND_SET_DEVICE_PROC);
						 
		rc = msm_rpc_write(snd->ept, &dmsg, sizeof(dmsg));
		htc_pwrsink_audio_path_set(dmsg.args.device);
		break;

	case SND_SET_VOLUME:
		if (copy_from_user(&vol, (void *) arg, sizeof(vol))) {
			rc = -EFAULT;
			break;
		}
		
		vmsg.args.device = cpu_to_be32(vol.device);
		vmsg.args.method = cpu_to_be32(vol.method);
		if (vol.method != SND_METHOD_VOICE && vol.method != SND_METHOD_AUDIO) {
			pr_err("snd_ioctl set volume: invalid method.\n");
			rc = -EINVAL;
			break;
		}

		vmsg.args.volume = cpu_to_be32(vol.volume);
		vmsg.args.cb_func = -1;
		vmsg.args.client_data = 0;

		//pr_info("snd_set_volume %d %d %d\n", vol.device, vol.method, vol.volume);
		printk("snd_set_volume %d %d %d\n", vol.device, vol.method, vol.volume);

		msm_rpc_setup_req(&vmsg.hdr, RPC_SND_PROG, RPC_SND_VERS, SND_SET_VOLUME_PROC);
		rc = msm_rpc_write(snd->ept, &vmsg, sizeof(vmsg));

		break;
		
	case SND_GET_NUM_ENDPOINTS:
		if (copy_to_user((void __user *)arg,
				&snd->snd_epts->num, sizeof(unsigned))) {
			pr_err("snd_ioctl get endpoint: invalid pointer.\n");
			rc = -EFAULT;
		}
		break;

	case SND_GET_ENDPOINT:
		rc = get_endpoint(snd, arg);
		break;
		
	default:
		pr_err("snd_ioctl unknown command.\n");
		rc = -EINVAL;
		break;
	}
	mutex_unlock(&snd->lock);

	return rc;
}
Exemple #17
0
/*
 * Initialize device for track-at-once mode of writing. All of the data will
 * need to be written to the track without interruption.
 * This initialized TAO by setting page code 5 and speed.
 */
void
write_init(int mode)
{
	(void) printf(gettext("Initializing device"));
	if (simulation)
		(void) printf(gettext("(Simulation mode)"));
	print_n_flush("...");

	get_media_type(target->d_fd);

	/* DVD- requires DAO mode */
	if (device_type == DVD_MINUS) {
		write_mode = DAO_MODE;
	}

	/* DVD+ and DVD- have no support for AUDIO, bail out */
	if ((mode == TRACK_MODE_AUDIO) && (device_type != CD_RW)) {
		err_msg(gettext("Audio mode is only supported for CD media\n"));
		exit(1);
	}
	if (simulation &&
	    check_device(target, CHECK_MEDIA_IS_NOT_BLANK) &&
	    !check_device(target, CHECK_MEDIA_IS_NOT_ERASABLE) &&
	    device_type != DVD_PLUS_W) {
		/*
		 * If we were in simulation mode, and media wasn't blank,
		 * but medium was erasable, then cdrw goes to erase the
		 * contents of the media after the simulation writing in order
		 * to cleanup the ghost TOC (see write_fini() calls blank()).
		 * This is bad because it removes existing data if media was
		 * multi-session. Therefore, we no longer allow simulation
		 * writing if such condition is met. we don't blank the DVD+RW
		 * media, so DVD+RWs are fine.
		 */
		err_msg(gettext(
		    "Cannot perform simulation for non-blank media\n"));
		exit(1);
	}

	if (!prepare_for_write(target, mode, simulation, keep_disc_open)) {
		/* l10n_NOTE : 'failed' as in Initializing device...failed  */
		(void) printf(gettext("failed.\n"));
		err_msg(gettext("Cannot initialize device for write\n"));
		exit(1);
	}
	/* l10n_NOTE : 'done' as in "Initializing device...done"  */
	(void) printf(gettext("done.\n"));

	/* if speed change option was used (-p) then try to set the speed */
	if (requested_speed != 0) {
		if (verbose)
			(void) printf(gettext("Trying to set speed to %dX.\n"),
			    requested_speed);
		if (target->d_speed_ctrl(target, SET_WRITE_SPEED,
		    requested_speed) == 0) {
			err_msg(gettext("Unable to set speed.\n"));
			exit(1);
		}
		if (verbose) {
			int speed;
			speed = target->d_speed_ctrl(target,
			    GET_WRITE_SPEED, 0);
			if (speed == requested_speed) {
				(void) printf(gettext("Speed set to %dX.\n"),
				    speed);
			} else if (speed == 0) {
				(void) printf(gettext("Could not obtain "
				    "current Write Speed.\n"));
			} else {
				(void) printf(
				gettext("Speed set to closest approximation "
				    "of %dX allowed by device (%dX).\n"),
				    requested_speed, speed);
			}
		}
	}
}
Exemple #18
0
int F848006(TRUSERID *handle,int iRequest,ST_PACK *in_pack,int *pRetCode,char *szMsg)
{
	int ret = 0;
	int card_status = 0;
	T_t_door_device_cardlist tDoorDeviceCardlist;
	T_t_door_oper_right	tDoorOperRight;

	memset(&tDoorDeviceCardlist,0,sizeof(tDoorDeviceCardlist));
	memset(&tDoorOperRight,0,sizeof(tDoorOperRight));

	getsysdate(tDoorDeviceCardlist.tx_date);
	getsystime(tDoorDeviceCardlist.tx_time);
	tDoorDeviceCardlist.cardno=in_pack->lvol1;
	des2src(tDoorDeviceCardlist.deviceid,in_pack->sname);
	des2src(tDoorDeviceCardlist.status,"0");					//0-增加1-删除
	des2src(tDoorDeviceCardlist.send_flag,"0");				//0-未发送1-已发送

	ret=check_device(tDoorDeviceCardlist.deviceid);
	if(ret)
	{
		*pRetCode=ret;
		writelog(LOG_ERR,"check_device err[%d]deviceid[%s]",ret,tDoorDeviceCardlist.deviceid);
		goto L_RETU;
	}
	ret=check_cardno(tDoorDeviceCardlist.cardno);
	if(ret)
	{
		card_status = ret;
		if(!(E_CARDNO_LOST == ret || E_CARDNO_FREEZE == ret))
		{
			*pRetCode=ret;
			writelog(LOG_ERR,"check_cardno err[%d]cardno[%s]",ret,tDoorDeviceCardlist.cardno);
			goto L_RETU;
		}
	}
	ret=chk_oper(in_pack->scust_limit);
	if(ret)
	{
		*pRetCode=ret;
		writelog(LOG_ERR,"chk_oper err[%d]in_pack->scust_limit[%s]",ret,in_pack->scust_limit);
		goto L_RETU;
	}
//检查权限
	ret=DB_t_door_oper_right_read_by_oper_no_and_deviceid(in_pack->scust_limit,tDoorDeviceCardlist.deviceid,&tDoorOperRight);
	if(ret)
	{
		writelog(LOG_ERR,"oper [%s]deviceid[%s]ret[%d]",in_pack->scust_limit,tDoorDeviceCardlist.deviceid,ret);
		if(DB_NOTFOUND==ret)
			*pRetCode=E_OPER_NO_RIGHT_FOR_DEVICE;
		else
			*pRetCode=E_DB_DOOR_OPER_RIGHT_R;
		goto L_RETU;
	}
	ret=GetNewVolume(KEYTYPE_DOOR_CARDLIST,tDoorDeviceCardlist.version);
	if(ret)
	{
		*pRetCode=ret;
		writelog(LOG_ERR,"GetNewVolume err[%d]",ret);
		goto L_RETU;
	}
	des2src(tDoorDeviceCardlist.stuempno,in_pack->semail);
	// 关闭 db_chk_err
	g_dbchkerr = 0;
	ret=DB_t_door_device_cardlist_add(&tDoorDeviceCardlist);
	// 调用完后,重新打开 db_chk_err
	g_dbchkerr = 1;
	
	if(ret)
	{
		//如果记录已经存在则更新该记录
		if(DB_REPEAT==ret)
		{
			writelog(LOG_DEBUG,"update deviceid[%s],cardno[%d]",tDoorDeviceCardlist.deviceid, tDoorDeviceCardlist.cardno);
			ret=DB_t_door_device_cardlist_update_by_deviceid_and_cardno(tDoorDeviceCardlist.deviceid, tDoorDeviceCardlist.cardno,&tDoorDeviceCardlist);
			if(ret)
			{
				writelog(LOG_ERR,"deviceid[%s],cardno[%d]",tDoorDeviceCardlist.deviceid, tDoorDeviceCardlist.cardno);
				if(DB_NOTFOUND==ret)
					*pRetCode=E_DB_DOOR_CARDLIST_N;
				else
					*pRetCode=E_DB_DOOR_CARDLIST_U;
				goto L_RETU;
			}
		}
	}
	// 如果卡状态正常,下传名单
	if(0 == card_status)
	{
		in_pack->lvol3=tDoorDeviceCardlist.cardno;
		des2src(in_pack->sdate0,tDoorDeviceCardlist.deviceid);
		in_pack->lvol5=0;
		ret = F930117(handle,iRequest,in_pack,pRetCode,szMsg);
		if (ret)
		{
			writelog(LOG_ERR,"F930117 ret[%d]",ret);
			goto L_RETU;
		}
	}
	return 0;
L_RETU:
	return  -1;
}
Exemple #19
0
int EDF_annotations::get_annotations(int file_num, struct edfhdrblock *edf_hdr, struct annotationblock **annotslist, int read_nk_trigger_signal)
{
  int i, j, k, p, r=0, n,
      edfsignals,
      datarecords,
      recordsize,
      discontinuous,
      *annot_ch,
      nr_annot_chns,
      max,
      onset,
      duration,
      duration_start,
      zero,
      max_tal_ln,
      error,
      annots_in_record,
      annots_in_tal,
      samplesize=2,
      nk_triggers_smpls=0,
      nk_triggers_bufoffset=0,
      nk_triggers_enabled=0,
      nk_triggers_channel=0,
      nk_triggers_cnt=0,
      sf,
      progress_steps;

  unsigned short nk_triggerfields=0,
                 nk_old_triggerfields=0;

  char *scratchpad,
       *cnv_buf,
       *time_in_txt,
       *duration_in_txt,
       nk_triggerlabel[16][32];


  long long data_record_duration,
            elapsedtime,
            time_tmp=0LL,
            nk_trigger_sample_duration=0LL;

  FILE *inputfile;

  struct edfparamblock *edfparam;

  struct annotationblock *new_annotation=NULL,
                         *temp_annotation;



  inputfile = edf_hdr->file_hdl;
  edfsignals = edf_hdr->edfsignals;
  recordsize = edf_hdr->recordsize;
  edfparam = edf_hdr->edfparam;
  nr_annot_chns = edf_hdr->nr_annot_chns;
  datarecords = edf_hdr->datarecords;
  data_record_duration = edf_hdr->long_data_record_duration;
  discontinuous = edf_hdr->discontinuous;
  annot_ch = edf_hdr->annot_ch;

  if(edf_hdr->edfplus)
  {
    samplesize = 2;
  }
  if(edf_hdr->bdfplus)
  {
    samplesize = 3;
  }

  if((edf_hdr->edfplus) && (read_nk_trigger_signal))
  {
    if(data_record_duration == 1000000LL)
    {
      if(check_device(edf_hdr->plus_equipment) == 0)
      {
        for(i=0; i<edfsignals; i++)
        {
          if(!strcmp(edfparam[i].label, "Events/Markers  "))
          {
            sf = edf_hdr->edfparam[i].smp_per_record;

            error = 1;

            switch(sf)
            {
              case  10 : error = 0;
                         break;
              case  20 : error = 0;
                         break;
              case  50 : error = 0;
                         break;
              case 100 : error = 0;
                         break;
            }

            for(j=0; j<edfsignals; j++)
            {
              if(edf_hdr->edfparam[j].smp_per_record != sf)
              {
                if(!edf_hdr->edfparam[j].annotation)
                {
                  error = 1;
                }
              }
            }

            if(edf_hdr->nr_annot_chns != 1)  error = 1;

            if(!error)
            {
              nk_triggers_channel = i;

              nk_triggers_bufoffset = edfparam[nk_triggers_channel].buf_offset;

              nk_triggers_smpls = edfparam[nk_triggers_channel].smp_per_record;

              nk_trigger_sample_duration = data_record_duration / (long long)nk_triggers_smpls;

              strcpy(nk_triggerlabel[0], "CAL mode");
              strcpy(nk_triggerlabel[1], "RESET condition");
              strcpy(nk_triggerlabel[2], "External mark");
              strcpy(nk_triggerlabel[3], "Photo/HV mark");
              strcpy(nk_triggerlabel[4], "Remote mark");
              strcpy(nk_triggerlabel[5], "HV mark");
              strcpy(nk_triggerlabel[6], "DC trigger 9");
              strcpy(nk_triggerlabel[7], "DC trigger 10");
              strcpy(nk_triggerlabel[8], "DC trigger 11");
              strcpy(nk_triggerlabel[9], "DC trigger 12");
              strcpy(nk_triggerlabel[10], "DC trigger 13");
              strcpy(nk_triggerlabel[11], "DC trigger 14");
              strcpy(nk_triggerlabel[12], "DC trigger 15");
              strcpy(nk_triggerlabel[13], "DC trigger 16");
              strcpy(nk_triggerlabel[14], "");
              strcpy(nk_triggerlabel[15], "");

              nk_triggers_enabled = 1;

              edf_hdr->genuine_nk = 1;

              break;
            }
          }
        }
      }
    }
  }

  cnv_buf = (char *)calloc(1, recordsize);
  if(cnv_buf==NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(cnv_buf)");
    messagewindow.exec();
    return(1);
  }

  max_tal_ln = 0;

  for(i=0; i<nr_annot_chns; i++)
  {
    if(max_tal_ln<edfparam[annot_ch[i]].smp_per_record * samplesize)  max_tal_ln = edfparam[annot_ch[i]].smp_per_record * samplesize;
  }

  if(max_tal_ln<128)  max_tal_ln = 128;

  scratchpad = (char *)calloc(1, max_tal_ln + 3);
  if(scratchpad==NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(scratchpad)");
    messagewindow.exec();
    free(cnv_buf);
    return(1);
  }

  time_in_txt = (char *)calloc(1, max_tal_ln + 3);
  if(time_in_txt==NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(time_in_txt)");
    messagewindow.exec();
    free(cnv_buf);
    free(scratchpad);
    return(1);
  }

  duration_in_txt = (char *)calloc(1, max_tal_ln + 3);
  if(duration_in_txt==NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(duration_in_txt)");
    messagewindow.exec();
    free(cnv_buf);
    free(scratchpad);
    free(time_in_txt);
    return(1);
  }

  if(fseeko(inputfile, (long long)((edfsignals + 1) * 256), SEEK_SET))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when reading inputfile annotations. (fseek())");
    messagewindow.exec();
    free(cnv_buf);
    free(scratchpad);
    free(time_in_txt);
    free(duration_in_txt);
    return(2);
  }

  QProgressDialog progress("Scanning file for annotations...", "Abort", 0, datarecords);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(200);

  progress_steps = datarecords / 100;
  if(progress_steps < 1)
  {
    progress_steps = 1;
  }

  elapsedtime = 0;

  for(i=0; i<datarecords; i++)
  {
    if(!(i%progress_steps))
    {
      progress.setValue(i);

      qApp->processEvents();

      if(progress.wasCanceled() == true)
      {
        edf_hdr->annots_not_read = 1;

        free(cnv_buf);
        free(scratchpad);
        free(time_in_txt);
        free(duration_in_txt);
        return(11);
      }
    }

    if(fread(cnv_buf, recordsize, 1, inputfile)!=1)
    {
      progress.reset();
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading inputfile annotations. (fread())");
      messagewindow.exec();
      free(cnv_buf);
      free(scratchpad);
      free(time_in_txt);
      free(duration_in_txt);
      return(2);
    }


/************** process annotationsignals (if any) **************/

    error = 0;

    for(r=0; r<nr_annot_chns; r++)
    {
      n = 0;
      zero = 0;
      onset = 0;
      duration = 0;
      duration_start = 0;
      scratchpad[0] = 0;
      annots_in_tal = 0;
      annots_in_record = 0;

      p = edfparam[annot_ch[r]].buf_offset;
      max = edfparam[annot_ch[r]].smp_per_record * samplesize;

/************** process one annotation signal ****************/

      if(cnv_buf[p + max - 1]!=0)
      {
        error = 5;
        goto END;
      }

      if(!r)  /* if it's the first annotation signal, then check */
      {       /* the timekeeping annotation */
        error = 1;

        for(k=0; k<(max-2); k++)
        {
          scratchpad[k] = cnv_buf[p + k];

          if(scratchpad[k]==20)
          {
            if(cnv_buf[p + k + 1]!=20)
            {
              error = 6;
              goto END;
            }
            scratchpad[k] = 0;
            if(is_onset_number(scratchpad))
            {
              error = 36;
              goto END;
            }
            else
            {
              time_tmp = get_long_time(scratchpad);
              if(i)
              {
                if(discontinuous)
                {
                  if((time_tmp-elapsedtime)<data_record_duration)
                  {
                    error = 4;
                    goto END;
                  }
                }
                else
                {
                  if((time_tmp-elapsedtime)!=data_record_duration)
                  {
                    error = 3;
                    goto END;
                  }
                }
              }
              else
              {
                if(time_tmp>=TIME_DIMENSION)
                {
                  error = 2;
                  goto END;
                }
                else
                {
                  edf_hdr->starttime_offset = time_tmp;
                }
              }
              elapsedtime = time_tmp;
              error = 0;
              break;
            }
          }
        }
      }

      for(k=0; k<max; k++)
      {
        scratchpad[n] = cnv_buf[p + k];

        if(!scratchpad[n])
        {
          if(!zero)
          {
            if(k)
            {
              if(cnv_buf[p + k - 1]!=20)
              {
                error = 33;
                goto END;
              }
            }
            n = 0;
            onset = 0;
            duration = 0;
            duration_start = 0;
            scratchpad[0] = 0;
            annots_in_tal = 0;
          }
          zero++;
          continue;
        }
        if(zero>1)
        {
          error = 34;
          goto END;
        }
        zero = 0;

        if((scratchpad[n]==20)||(scratchpad[n]==21))
        {
          if(scratchpad[n]==21)
          {
            if(duration||duration_start||onset||annots_in_tal)
            {               /* it's not allowed to have multiple duration fields */
              error = 35;   /* in one TAL or to have a duration field which is   */
              goto END;     /* not immediately behind the onsetfield             */
            }
            duration_start = 1;
          }

          if((scratchpad[n]==20)&&onset&&(!duration_start))
          {
            if(r||annots_in_record)
            {
              if(n >= 0)
              {
                new_annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
                if(new_annotation==NULL)
                {
                  progress.reset();
                  QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred while reading annotations.");
                  messagewindow.exec();
                  free(cnv_buf);
                  free(scratchpad);
                  free(time_in_txt);
                  free(duration_in_txt);
                  return(1);
                }

                new_annotation->next_annotation = NULL;
                new_annotation->file_num = file_num;

                new_annotation->annotation[0] = 0;

                if(duration)  strcpy(new_annotation->duration, duration_in_txt);
                else  new_annotation->duration[0] = 0;

                for(j=0; j<n; j++)
                {
                  if(j==MAX_ANNOTATION_LEN)  break;
                  new_annotation->annotation[j] = scratchpad[j];
                }
                new_annotation->annotation[j] = 0;

                new_annotation->file_num = edf_hdr->file_num;

                new_annotation->onset = get_long_time(time_in_txt);

                if(*annotslist!=NULL)
                {
                  temp_annotation = *annotslist;
                  while(temp_annotation->next_annotation)  temp_annotation = temp_annotation->next_annotation;

                  new_annotation->former_annotation = temp_annotation;
                  temp_annotation->next_annotation = new_annotation;
                }
                else
                {
                  new_annotation->former_annotation = NULL;
                  *annotslist = new_annotation;
                }
              }
            }

            annots_in_tal++;
            annots_in_record++;
            n = 0;
            continue;
          }

          if(!onset)
          {
            scratchpad[n] = 0;
            if(is_onset_number(scratchpad))
            {
              error = 36;
              goto END;
            }
            onset = 1;
            n = 0;
            strcpy(time_in_txt, scratchpad);
            continue;
          }

          if(duration_start)
          {
            scratchpad[n] = 0;
            if(is_duration_number(scratchpad))
            {
              error = 37;
              goto END;
            }

            for(j=0; j<n; j++)
            {
              if(j==15)  break;
              duration_in_txt[j] = scratchpad[j];
              if((duration_in_txt[j]<32)||(duration_in_txt[j]>126))
              {
                duration_in_txt[j] = '.';
              }
            }
            duration_in_txt[j] = 0;

            duration = 1;
            duration_start = 0;
            n = 0;
            continue;
          }
        }

        n++;
      }

 END:

/****************** end ************************/

      if(error)
      {
        progress.reset();
        QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not read annotations because there is an EDF or BDF incompatibility in this file.\n"
                                                                  "For more information, run the EDF/BDF compatibility checker in the Tools menu.");
        messagewindow.exec();
        free(cnv_buf);
        free(scratchpad);
        free(time_in_txt);
        free(duration_in_txt);
        return(9);
      }
    }

/************** process NK triggers ****************/

    if(nk_triggers_enabled)
    {
      if(nk_triggers_cnt < 100000)
      {
        for(k=0; k<nk_triggers_smpls; k++)
        {
          nk_triggerfields = *((unsigned char *)cnv_buf + nk_triggers_bufoffset + (k * 2) + 1);

          nk_triggerfields <<= 8;

          nk_triggerfields += *((unsigned char *)cnv_buf + nk_triggers_bufoffset + (k * 2));

          for(j=0; j<14; j++)
          {
            if((nk_triggerfields & (1 << j)) && (!(nk_old_triggerfields & (1 << j))))
            {
              nk_triggers_cnt++;

              new_annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
              if(new_annotation==NULL)
              {
                progress.reset();
                QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred while reading annotations.");
                messagewindow.exec();
                free(cnv_buf);
                free(scratchpad);
                free(time_in_txt);
                free(duration_in_txt);
                return(1);
              }

              new_annotation->file_num = edf_hdr->file_num;
              new_annotation->next_annotation = NULL;
              new_annotation->file_num = file_num;
              strcpy(new_annotation->annotation, nk_triggerlabel[j]);

              new_annotation->onset = ((long long)i * data_record_duration) + ((long long)k * nk_trigger_sample_duration);

              new_annotation->onset += edf_hdr->starttime_offset;

              new_annotation->ident = (1 << ANNOT_ID_NK_TRIGGER);

              if(*annotslist!=NULL)
              {
                temp_annotation = *annotslist;
                while(temp_annotation->next_annotation)  temp_annotation = temp_annotation->next_annotation;

                new_annotation->former_annotation = temp_annotation;
                temp_annotation->next_annotation = new_annotation;
              }
              else
              {
                new_annotation->former_annotation = NULL;
                *annotslist = new_annotation;
              }
            }
          }

          nk_old_triggerfields = nk_triggerfields;
        }
      }

      edf_hdr->nk_triggers_read = 1;
    }
  }

  edfplus_annotation_sort(&annotslist[file_num]);

  progress.reset();

  free(cnv_buf);
  free(scratchpad);
  free(time_in_txt);
  free(duration_in_txt);

  return(0);
}
Exemple #20
0
void
info(void)
{
	uchar_t *toc, *p, *conf;
	int ret, toc_size;
	uint_t bsize;
	size_t cap = 0;
	char *msg;
	struct track_info *ti;

	msg = gettext("Cannot read Table of contents\n");

	get_media_type(target->d_fd);

	(void) printf(gettext("\nDevice : %.8s %.16s\n"),
	    &target->d_inq[8], &target->d_inq[16]);
	(void) printf(gettext("Firmware : Rev. %.4s (%.12s)\n"),
	    &target->d_inq[32], &target->d_inq[36]);

	if (check_device(target, CHECK_DEVICE_NOT_READY)) {
		(void) check_device(target, CHECK_NO_MEDIA |
		    EXIT_IF_CHECK_FAILED);
		(void) check_device(target, CHECK_DEVICE_NOT_READY |
		    EXIT_IF_CHECK_FAILED);
	}

	if (verbose != 0) {
		/*
		 * Determine the media type by reading the active profile
		 * from the profile list.
		 */
		(void) printf(gettext("Media Type : "));

		conf = (uchar_t *)my_zalloc(MMC_FTR_HDR_LEN);

		if (get_configuration(target->d_fd, MMC_FTR_PRFL_LIST,
		    MMC_FTR_HDR_LEN, conf))
			print_profile_name(read_scsi16(&conf[6]), 0, 1);
		else
			(void) printf(gettext("UNKNOWN\n"));

		free(conf);

		/*
		 * Get the start address of the last possible lead out.
		 */
		cap = get_last_possible_lba(target);

		/*
		 * The start address of the last possible leadout will only
		 * be zero if the disc is full or this drive does not support
		 * this method of determining capacity.
		 */
		if (cap == 0)
			cap = read_format_capacity(target->d_fd, &bsize);

		/*
		 * Since both methods of determining the capacity of the
		 * media count the correct number of blocks, just multiply
		 * the capacity by the block size.
		 */
		cap *= target->d_blksize;

		if (device_type == CD_RW) {
			(void) printf(gettext("Media Capacity : %.2f MB "),
			    ((double)cap/ONE_MB_BASE2));
		} else {
			/*
			 * For DVD's make sure we print out "Formatted Media
			 * Capacity". Don't do this for CD-RWs as only
			 * DVDs are formatted.
			 */
			(void) printf(gettext("Formatted Media Capacity : "
			    "%.2f GB "), ((double)cap/ONE_GB_BASE10));
		}

		cap /= target->d_blksize;
		(void) printf(gettext("(%u blocks)\n"), (uint_t)cap);
	}

	if (!check_device(target, CHECK_MEDIA_IS_NOT_BLANK)) {
		(void) printf(gettext("Media is blank\n"));
		exit(0);
	}

	/*  Find out the number of entries in the toc */
	toc = (uchar_t *)my_zalloc(12);
	if (!read_toc(target->d_fd, 0, 1, 4, toc)) {
		err_msg(msg);
	} else {
		toc_size = 256*toc[0] + toc[1] + 2;
		free(toc);

		/* allocate enough space for each track entry */
		toc = (uchar_t *)my_zalloc(toc_size);

		if (!read_toc(target->d_fd, 0, 1, toc_size, toc)) {
			err_msg(msg);
			exit(1);
		}
		(void) printf("\n");

		/* l10n_NOTE : Preserve column numbers of '|' character */
		(void) printf(gettext("Track No. |Type    |Start address\n"));
		(void) printf("----------+--------+-------------\n");


		/* look at each track and display it's type. */

		for (p = &toc[4]; p < (toc + toc_size); p += 8) {
			if (p[2] != 0xAA)
				(void) printf(" %-3d      |", p[2]);
			else
				(void) printf("Leadout   |");
			(void) printf("%s   |", (p[1] & 4) ? gettext("Data ") :
			    gettext("Audio"));
			(void) printf("%u\n", read_scsi32(&p[4]));
		}
	}
	(void) printf("\n");
	ret = read_toc(target->d_fd, 1, 0, 12, toc);
	if ((ret == 0) || (toc[1] != 0x0a))
		/* For ATAPI drives or old Toshiba drives */
		ret = read_toc_as_per_8020(target->d_fd, 1, 0, 12, toc);

	if (ret && (toc[1] == 0x0a)) {
		(void) printf(gettext("Last session start address: %u\n"),
		    read_scsi32(&toc[8]));
	}
	free(toc);
	ti = (struct track_info *)my_zalloc(sizeof (struct track_info));

	if (build_track_info(target, -1, ti) && (ti->ti_flags & TI_NWA_VALID)) {
		(void) printf(gettext("Next writable address: %u\n"),
		    ti->ti_nwa);
	}
	free(ti);
	exit(0);
}
Exemple #21
0
void UI_NK2EDFwindow::SelectFileButton()
{
  FILE *inputfile=NULL,
       *outputfile=NULL,
       *logfile=NULL,
       *pntfile=NULL;

  int i, j, k,
      error,
      ctl_block_cnt,
      datablock_cnt,
      total_blocks,
      edfplus,
      n_logs=0,
      n_sublogs=0,
      total_logs=0,
      n_logblocks=0,
      ctlblock_address,
      wfmblock_address,
      logblock_address,
      read_subevents=0;

  char txt_string[2048],
       path[MAX_PATH_LENGTH],
       outputpath[MAX_PATH_LENGTH],
       logfilepath[MAX_PATH_LENGTH],
       pntfilepath[MAX_PATH_LENGTH],
       *log_buf=NULL,
       *sublog_buf=NULL,
       scratchpad[256];


  pushButton1->setEnabled(false);

  edfplus = checkBox1->checkState();

  total_elapsed_time = 0;

  strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "EEG files (*.eeg *.EEG)").toLocal8Bit().data());

  if(!strcmp(path, ""))
  {
    pushButton1->setEnabled(true);
    return;
  }

  get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH);

  inputfile = fopeno(path, "rb");
  if(inputfile==NULL)
  {
    snprintf(txt_string, 2048, "can not open file %s for reading.\n", path);
    textEdit1->append(QString::fromLocal8Bit(txt_string));
    pushButton1->setEnabled(true);
    return;
  }

/***************** check if the EEG file is valid ******************************/

  rewind(inputfile);
  if(fread(scratchpad, 16, 1, inputfile)!=1)
  {
    textEdit1->append("error reading .eeg file.\n");
    fclose(inputfile);
    pushButton1->setEnabled(true);
    return;
  }
  scratchpad[16] = 0;
  if(check_device(scratchpad))
  {
    snprintf(txt_string, 2048, "error, deviceblock has unknown signature: \"%s\"\n", scratchpad);
    textEdit1->append(txt_string);
    fclose(inputfile);
    pushButton1->setEnabled(true);
    return;
  }
  fseeko(inputfile, 0x0081LL, SEEK_SET);
  if(fread(scratchpad, 16, 1, inputfile)!=1)
  {
    textEdit1->append("error reading .eeg file.\n");
    fclose(inputfile);
    pushButton1->setEnabled(true);
    return;
  }
  scratchpad[16] = 0;
  if(check_device(scratchpad))
  {
    snprintf(txt_string, 2048, "error, controlblock has unknown signature: \"%s\"\n", scratchpad);
    textEdit1->append(txt_string);
    fclose(inputfile);
    pushButton1->setEnabled(true);
    return;
  }
  fseeko(inputfile, 0x17feLL, SEEK_SET);
  if(fgetc(inputfile)!=0x01)
  {
    snprintf(txt_string, 2048, "error, waveformdatablock has wrong signature.\n");
    textEdit1->append(txt_string);
    fclose(inputfile);
    pushButton1->setEnabled(true);
    return;
  }

/************************* read logs **********************************************/

  if(edfplus)
  {
    strncpy(logfilepath, path, MAX_PATH_LENGTH);
    remove_extension_from_filename(logfilepath);
    strcat(logfilepath, ".LOG");
    logfile = fopeno(logfilepath, "rb");
    if(logfile==NULL)
    {
      remove_extension_from_filename(logfilepath);
      strcat(logfilepath, ".log");
      logfile = fopeno(logfilepath, "rb");
      if(logfile==NULL)
      {
        snprintf(txt_string, 2048, "Can not open file %s for reading,\n"
                            "if there is no .log file you can try to create an EDF file instead of EDF+.\n",
                            logfilepath);
        textEdit1->append(QString::fromLocal8Bit(txt_string));
        fclose(inputfile);
        pushButton1->setEnabled(true);
        return;
      }
    }

    rewind(logfile);
    if(fread(scratchpad, 16, 1, logfile)!=1)
    {
      textEdit1->append("error reading .log file.\n");
      fclose(logfile);
      fclose(inputfile);
      pushButton1->setEnabled(true);
      return;
    }
    scratchpad[16] = 0;
    if(check_device(scratchpad))
    {
      snprintf(txt_string, 2048, "error, .log file has unknown signature: \"%s\"\n", scratchpad);
      textEdit1->append(QString::fromLocal8Bit(txt_string));
      fclose(logfile);
      fclose(inputfile);
      pushButton1->setEnabled(true);
      return;
    }

    fseeko(logfile, 0x0091LL, SEEK_SET);
    n_logblocks = fgetc(logfile);
    log_buf = (char *)calloc(1, n_logblocks * 11521);
    if(log_buf==NULL)
    {
      textEdit1->append("malloc error\n");
      fclose(logfile);
      fclose(inputfile);
      pushButton1->setEnabled(true);
      return;
    }
    sublog_buf = (char *)calloc(1, n_logblocks * 11521);
    if(sublog_buf==NULL)
    {
      textEdit1->append("malloc error\n");
      fclose(logfile);
      fclose(inputfile);
      free(log_buf);
      pushButton1->setEnabled(true);
      return;
    }

    read_subevents = 1;

    total_logs = 0;

    for(i=0; i<n_logblocks; i++)
    {
      fseeko(logfile, (long long)(0x0092 + (i * 20)), SEEK_SET);
      if(fread((char *)(&logblock_address), 4, 1, logfile)!=1)
      {
        textEdit1->append("error reading .log file.\n");
        fclose(inputfile);
        fclose(logfile);
        free(log_buf);
        free(sublog_buf);
        pushButton1->setEnabled(true);
        return;
      }
      fseeko(logfile, (long long)(logblock_address + 0x0012), SEEK_SET);
      n_logs = fgetc(logfile);
      fseeko(logfile, (long long)(logblock_address + 0x0014), SEEK_SET);
      if(fread(log_buf + (total_logs * 45), n_logs * 45, 1, logfile)!=1)
      {
        textEdit1->append("error reading .log file.\n");
        fclose(inputfile);
        fclose(logfile);
        free(log_buf);
        free(sublog_buf);
        pushButton1->setEnabled(true);
        return;
      }

      if(read_subevents)
      {
        if(fseeko(logfile, 0x0092LL + ((i + 22) * 20) , SEEK_SET))
        {
          read_subevents = 0;
        }
        else
        {
          if(fread((char *)(&logblock_address), 4, 1, logfile)!=1)
          {
            read_subevents = 0;
          }
          else
          {
            if(fseeko(logfile, logblock_address + 0x0012LL, SEEK_SET))
            {
              read_subevents = 0;
            }
            else
            {
              n_sublogs = fgetc(logfile);
              if(n_sublogs != n_logs)
              {
                read_subevents = 0;
              }
              else
              {
                if(fseeko(logfile, logblock_address + 0x0014LL, SEEK_SET))
                {
                  read_subevents = 0;
                }
                else
                {
                  if(fread(sublog_buf + (total_logs * 45), n_sublogs * 45, 1, logfile)!=1)
                  {
                    read_subevents = 0;
                  }
                }
              }
            }
          }
        }
      }

      total_logs += n_logs;
    }

    for(i=0; i<total_logs; i++)
    {
      for(j=0; j<20; j++)
      {
        if(((unsigned char *)log_buf)[(i * 45) + j]<32)  log_buf[(i * 45) + j] = ' ';
      }

      latin1_to_utf8(log_buf + (i * 45), 20);

      if(read_subevents)
      {
        strncpy(log_buf + (i * 45) + 26, sublog_buf + (i * 45) + 24, 6);
      }
    }

/************************* check pntfile **********************************************/

    strncpy(pntfilepath, path, MAX_PATH_LENGTH);
    remove_extension_from_filename(logfilepath);
    strcat(logfilepath, ".PNT");
    pntfile = fopeno(pntfilepath, "rb");
    if(pntfile==NULL)
    {
      remove_extension_from_filename(logfilepath);
      strcat(logfilepath, ".pnt");
      pntfile = fopeno(pntfilepath, "rb");
      if(pntfile==NULL)
      {
        snprintf(txt_string, 2048, "Can not open file %s for reading,\n"
                            "if there is no .pnt file you can try to create an EDF file instead of EDF+.\n",
                            pntfilepath);
        textEdit1->append(QString::fromLocal8Bit(txt_string));
        fclose(logfile);
        fclose(inputfile);
        free(log_buf);
        free(sublog_buf);
        pushButton1->setEnabled(true);
        return;
      }
    }

    rewind(pntfile);
    if(fread(scratchpad, 16, 1, pntfile)!=1)
    {
      textEdit1->append("error reading .pnt file.\n");
      fclose(pntfile);
      fclose(logfile);
      fclose(inputfile);
      free(log_buf);
      free(sublog_buf);
      pushButton1->setEnabled(true);
      return;
    }
    scratchpad[16] = 0;
    if(check_device(scratchpad))
    {
      snprintf(txt_string, 2048, "error, .pnt file has unknown signature: \"%s\"\n", scratchpad);
      textEdit1->append(QString::fromLocal8Bit(txt_string));
      fclose(pntfile);
      fclose(logfile);
      fclose(inputfile);
      free(log_buf);
      free(sublog_buf);
      pushButton1->setEnabled(true);
      return;
    }
  }

/***************** initialize labels **************************************/

  for(i=0; i<256; i++)
  {
    strcpy(labels[i], "-               ");
  }

  strcpy(labels[0],   "EEG FP1         ");
  strcpy(labels[1],   "EEG FP2         ");
  strcpy(labels[2],   "EEG F3          ");
  strcpy(labels[3],   "EEG F4          ");
  strcpy(labels[4],   "EEG C3          ");
  strcpy(labels[5],   "EEG C4          ");
  strcpy(labels[6],   "EEG P3          ");
  strcpy(labels[7],   "EEG P4          ");
  strcpy(labels[8],   "EEG O1          ");
  strcpy(labels[9],   "EEG O2          ");
  strcpy(labels[10],  "EEG F7          ");
  strcpy(labels[11],  "EEG F8          ");
  strcpy(labels[12],  "EEG T3          ");
  strcpy(labels[13],  "EEG T4          ");
  strcpy(labels[14],  "EEG T5          ");
  strcpy(labels[15],  "EEG T6          ");
  strcpy(labels[16],  "EEG FZ          ");
  strcpy(labels[17],  "EEG CZ          ");
  strcpy(labels[18],  "EEG PZ          ");
  strcpy(labels[19],  "EEG E           ");
  strcpy(labels[20],  "EEG PG1         ");
  strcpy(labels[21],  "EEG PG2         ");
  strcpy(labels[22],  "EEG A1          ");
  strcpy(labels[23],  "EEG A2          ");
  strcpy(labels[24],  "EEG T1          ");
  strcpy(labels[25],  "EEG T2          ");
  for(i=26; i<35; i++)
  {
    sprintf(labels[i], "EEG X%i          ", i - 25);
  }
  strcpy(labels[35],  "EEG X10         ");
  strcpy(labels[36],  "EEG X11         ");
  for(i=42; i<74; i++)
  {
    sprintf(labels[i], "DC%02i            ", i - 41);
  }
  strcpy(labels[74],  "EEG BN1         ");
  strcpy(labels[75],  "EEG BN2         ");
  strcpy(labels[76],  "EEG Mark1       ");
  strcpy(labels[77],  "EEG Mark2       ");
  strcpy(labels[100], "EEG X12/BP1     ");
  strcpy(labels[101], "EEG X13/BP2     ");
  strcpy(labels[102], "EEG X14/BP3     ");
  strcpy(labels[103], "EEG X15/BP4     ");
  for(i=104; i<188; i++)
  {
    sprintf(labels[i], "EEG X%i         ", i - 88);
  }
  for(i=188; i<254; i++)
  {
    sprintf(labels[i], "EEG X%i        ", i - 88);
  }
  strcpy(labels[255], "Z               ");

  if(read_21e_file(path))
  {
    textEdit1->append("Can not open *.21e file, converter will use default electrode names.");
  }

/***************** start conversion **************************************/

  total_blocks = 0;

  fseeko(inputfile, 0x0091LL, SEEK_SET);
  ctl_block_cnt = fgetc(inputfile);
  if(ctl_block_cnt==EOF)
  {
    textEdit1->append("error reading inputfile.\n");
    pushButton1->setEnabled(true);
    fclose(inputfile);
    if(edfplus)
    {
      fclose(logfile);
      free(log_buf);
      free(sublog_buf);
      fclose(pntfile);
    }
    return;
  }

  for(i=0; i<ctl_block_cnt; i++)
  {
    fseeko(inputfile, (long long)(0x0092 + (i * 20)), SEEK_SET);
    if(fread((char *)(&ctlblock_address), 4, 1, inputfile)!=1)
    {
      textEdit1->append("error reading inputfile.\n");
      pushButton1->setEnabled(true);
      fclose(inputfile);
      if(edfplus)
      {
        fclose(logfile);
        free(log_buf);
        free(sublog_buf);
        fclose(pntfile);
      }
      return;
    }
    fseeko(inputfile, (long long)(ctlblock_address + 17), SEEK_SET);
    datablock_cnt = fgetc(inputfile);
    if(datablock_cnt==EOF)
    {
      textEdit1->append("error reading inputfile.\n");
      pushButton1->setEnabled(true);
      fclose(inputfile);
      if(edfplus)
      {
        fclose(logfile);
        free(log_buf);
        free(sublog_buf);
        fclose(pntfile);
      }
      return;
    }

    for(j=0; j<datablock_cnt; j++)
    {
      fseeko(inputfile, (long long)(ctlblock_address + (j * 20) + 18), SEEK_SET);
      if(fread((char *)(&wfmblock_address), 4, 1, inputfile)!=1)
      {
        textEdit1->append("error reading inputfile.\n");
        pushButton1->setEnabled(true);
        fclose(inputfile);
        if(edfplus)
        {
          fclose(logfile);
          free(log_buf);
          free(sublog_buf);
          fclose(pntfile);
        }
        return;
      }

   /********************************************************************/

      strcpy(outputpath, path);
      if(edfplus)  sprintf(outputpath + strlen(path) - 4, "_%u-%u+.edf", i + 1, j + 1);
      else  sprintf(outputpath + strlen(path) - 4, "_%u-%u.edf", i + 1, j + 1);

      outputfile = fopeno(outputpath, "wb");
      if(outputfile==NULL)
      {
        snprintf(txt_string, 2048, "can not open file %s for writing.\n", outputpath);
        textEdit1->append(QString::fromLocal8Bit(txt_string));
        pushButton1->setEnabled(true);
        fclose(inputfile);
        if(edfplus)
        {
          fclose(logfile);
          free(log_buf);
          free(sublog_buf);
          fclose(pntfile);
        }
        return;
      }

      textEdit1->append("Converting a waveform datablock...");

      for(k=0; k<10; k++)  qApp->processEvents();

      error = convert_nk2edf(inputfile, outputfile, pntfile, wfmblock_address, edfplus, total_logs, log_buf, read_subevents);
      if(error==0)
      {
        snprintf(txt_string, 2048, "to %s", outputpath);
        textEdit1->append(txt_string);
      }
      if(error==1)  textEdit1->append("malloc error.\n");
      if(error==2)  textEdit1->append("read error during conversion.\n");
      if(error==3)  textEdit1->append("write error during conversion.\n");
      if(error==4)  textEdit1->append("format error.\n");

      if(fclose(outputfile))
      {
        textEdit1->append("error closing outputfile.\n");
        pushButton1->setEnabled(true);
        fclose(inputfile);
        if(edfplus)
        {
          fclose(logfile);
          fclose(pntfile);
          free(log_buf);
          free(sublog_buf);
        }
        return;
      }

      if(error)
      {
        if(edfplus)
        {
          fclose(logfile);
          fclose(pntfile);
          free(log_buf);
          free(sublog_buf);
        }
        pushButton1->setEnabled(true);
        return;
      }

      total_blocks++;

      /**************************************************************/
    }
  }

  if(fclose(inputfile))  textEdit1->append("error closing inputfile.\n");
  if(edfplus)
  {
    if(fclose(logfile))  textEdit1->append("error closing .log file.\n");
    if(fclose(pntfile))  textEdit1->append("error closing .pnt file.\n");
    free(log_buf);
    free(sublog_buf);
  }

  if(edfplus)  snprintf(txt_string, 2048, "Converted %u waveformblock(s) successfully to EDF+.\n", total_blocks);
  else  snprintf(txt_string, 2048, "Converted %u waveformblock(s) successfully to EDF.\n", total_blocks);
  textEdit1->append(txt_string);

  pushButton1->setEnabled(true);
}
int main(int argc, char* argv[]) {
	int opt = 0;
	int optindex = 0;
	char* ipsw = NULL;
	char* uuid = NULL;
	int tss_enabled = 0;
	int shsh_only = 0;
	char* shsh_dir = NULL;
	use_apple_server=1;

	// create an instance of our context
	struct idevicerestore_client_t* client = (struct idevicerestore_client_t*) malloc(sizeof(struct idevicerestore_client_t));
	if (client == NULL) {
		error("ERROR: Out of memory\n");
		return -1;
	}
	memset(client, '\0', sizeof(struct idevicerestore_client_t));

	while ((opt = getopt_long(argc, argv, "dhcesxtpi:u:", longopts, &optindex)) > 0) {
		switch (opt) {
		case 'h':
			usage(argc, argv);
			return 0;

		case 'd':
			client->flags |= FLAG_DEBUG;
			idevicerestore_debug = 1;
			break;

		case 'e':
			client->flags |= FLAG_ERASE;
			break;

		case 'c':
			client->flags |= FLAG_CUSTOM;
			break;

		case 's':
			use_apple_server=0;
			break;

		case 'x':
			client->flags |= FLAG_EXCLUDE;
			break;

		case 'i':
			if (optarg) {
				char* tail = NULL;
				client->ecid = strtoull(optarg, &tail, 16);
				if (tail && (tail[0] != '\0')) {
					client->ecid = 0;
				}
				if (client->ecid == 0) {
					error("ERROR: Could not parse ECID from '%s'\n", optarg);
					return -1;
				}
			}
			break;

		case 'u':
			uuid = optarg;
			break;

		case 't':
			shsh_only = 1;
			break;

		case 'p':
			client->flags |= FLAG_PWN;
			break;

		default:
			usage(argc, argv);
			return -1;
		}
	}

	if (((argc-optind) == 1) || (client->flags & FLAG_PWN)) {
		argc -= optind;
		argv += optind;

		ipsw = argv[0];
	} else {
		usage(argc, argv);
		return -1;
	}

	if (client->flags & FLAG_DEBUG) {
		idevice_set_debug_level(1);
		irecv_set_debug_level(1);
	}

	client->uuid = uuid;
	client->ipsw = ipsw;

	// update version data (from cache, or apple if too old)
	load_version_data(client);

	// check which mode the device is currently in so we know where to start
	if (check_mode(client) < 0 || client->mode->index == MODE_UNKNOWN) {
		error("ERROR: Unable to discover device mode. Please make sure a device is attached.\n");
		return -1;
	}
	info("Found device in %s mode\n", client->mode->string);

	if (client->mode->index == MODE_WTF) {
		int cpid = 0;

		if (dfu_client_new(client) != 0) {
			error("ERROR: Could not open device in WTF mode\n");
			return -1;
		}
		if ((dfu_get_cpid(client, &cpid) < 0) || (cpid == 0)) { 
			error("ERROR: Could not get CPID for WTF mode device\n");
			dfu_client_free(client);
			return -1;
		}

		char* s_wtfurl = NULL;
		plist_t wtfurl = plist_access_path(client->version_data, 7, "MobileDeviceSoftwareVersionsByVersion", "5", "RecoverySoftwareVersions", "WTF", "304218112", "5", "FirmwareURL");
		if (wtfurl && (plist_get_node_type(wtfurl) == PLIST_STRING)) {
			plist_get_string_val(wtfurl, &s_wtfurl);
		}
		if (!s_wtfurl) {
			info("Using hardcoded x12220000_5_Recovery.ipsw URL\n");
			s_wtfurl = strdup("http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPhone/061-6618.20090617.Xse7Y/x12220000_5_Recovery.ipsw");
		}

		// make a local file name
		char* fnpart = strrchr(s_wtfurl, '/');
		if (!fnpart) {
			fnpart = "x12220000_5_Recovery.ipsw";
		} else {
			fnpart++;
		}
		struct stat fst;
		char wtfipsw[256];
		sprintf(wtfipsw, "cache/%s", fnpart);
		if (stat(wtfipsw, &fst) != 0) {
			__mkdir("cache", 0755);
			download_to_file(s_wtfurl, wtfipsw);
		}

		char wtfname[256];
		sprintf(wtfname, "Firmware/dfu/WTF.s5l%04xxall.RELEASE.dfu", cpid);
		char* wtftmp = NULL;
		uint32_t wtfsize = 0;
		ipsw_extract_to_memory(wtfipsw, wtfname, &wtftmp, &wtfsize);
		if (!wtftmp) {
			error("ERROR: Could not extract WTF\n");
		} else {
			if (dfu_send_buffer(client, wtftmp, wtfsize) != 0) {
				error("ERROR: Could not send WTF...\n");
			}
		}
		dfu_client_free(client);

		sleep(1);

		free(wtftmp);
		client->mode = &idevicerestore_modes[MODE_DFU];
	}

	// discover the device type
	if (check_device(client) < 0 || client->device->index == DEVICE_UNKNOWN) {
		error("ERROR: Unable to discover device type\n");
		return -1;
	}
	info("Identified device as %s\n", client->device->product);

	if ((client->flags & FLAG_PWN) && (client->mode->index != MODE_DFU)) {
		error("ERROR: you need to put your device into DFU mode to pwn it.\n");
		return -1;
	}

	if (client->flags & FLAG_PWN) {
		recovery_client_free(client);

		info("connecting to DFU\n");
		if (dfu_client_new(client) < 0) {
			return -1;
		}
		info("exploiting with limera1n...\n");
		// TODO: check for non-limera1n device and fail
		if (limera1n_exploit(client->device, client->dfu->client) != 0) {
			error("ERROR: limera1n exploit failed\n");
			dfu_client_free(client);
			return -1;
		}
		dfu_client_free(client);
		info("Device should be in pwned DFU state now.\n");

		return 0;
	}

	if (client->mode->index == MODE_RESTORE) {
		if (restore_reboot(client) < 0) {
			error("ERROR: Unable to exit restore mode\n");
			return -1;
		}
	}

	// extract buildmanifest
	plist_t buildmanifest = NULL;
	if (client->flags & FLAG_CUSTOM) {
		info("Extracting Restore.plist from IPSW\n");
		if (ipsw_extract_restore_plist(ipsw, &buildmanifest) < 0) {
			error("ERROR: Unable to extract Restore.plist from %s\n", ipsw);
			return -1;
		}
	} else {
		info("Extracting BuildManifest from IPSW\n");
		if (ipsw_extract_build_manifest(ipsw, &buildmanifest, &tss_enabled) < 0) {
			error("ERROR: Unable to extract BuildManifest from %s\n", ipsw);
			return -1;
		}
	}

	/* check if device type is supported by the given build manifest */
	if (build_manifest_check_compatibility(buildmanifest, client->device->product) < 0) {
		error("ERROR: could not make sure this firmware is suitable for the current device. refusing to continue.\n");
		return -1;
	}

	/* print iOS information from the manifest */
	build_manifest_get_version_information(buildmanifest, &client->version, &client->build);

	info("Product Version: %s\n", client->version);
	info("Product Build: %s\n", client->build);

	if (client->flags & FLAG_CUSTOM) {
		/* prevent signing custom firmware */
		tss_enabled = 0;
		info("Custom firmware requested. Disabled TSS request.\n");
	}

	// choose whether this is an upgrade or a restore (default to upgrade)
	client->tss = NULL;
	plist_t build_identity = NULL;
	if (client->flags & FLAG_CUSTOM) {
		build_identity = plist_new_dict();
		{
			plist_t node;
			plist_t comp;
			plist_t info;
			plist_t manifest;

			info = plist_new_dict();
			plist_dict_insert_item(info, "RestoreBehavior", plist_new_string((client->flags & FLAG_ERASE) ? "Erase" : "Update"));
			plist_dict_insert_item(info, "Variant", plist_new_string((client->flags & FLAG_ERASE) ? "Customer Erase Install (IPSW)" : "Customer Upgrade Install (IPSW)"));
			plist_dict_insert_item(build_identity, "Info", info);

			manifest = plist_new_dict();

			char tmpstr[256];
			char p_all_flash[128];
			char lcmodel[8];
			strcpy(lcmodel, client->device->model);
			int x = 0;
			while (lcmodel[x]) {
				lcmodel[x] = tolower(lcmodel[x]);
				x++;
			}

			sprintf(p_all_flash, "Firmware/all_flash/all_flash.%s.%s", lcmodel, "production");
			strcpy(tmpstr, p_all_flash);
			strcat(tmpstr, "/manifest");

			// get all_flash file manifest
			char *files[16];
			char *fmanifest = NULL;
			uint32_t msize = 0;
			if (ipsw_extract_to_memory(ipsw, tmpstr, &fmanifest, &msize) < 0) {
				error("ERROR: could not extract %s from IPSW\n", tmpstr);
				return -1;
			}

			char *tok = strtok(fmanifest, "\r\n");
			int fc = 0;
			while (tok) {
				files[fc++] = strdup(tok);
				if (fc >= 16) {
					break;
				}
				tok = strtok(NULL, "\r\n");
			}
			free(fmanifest);

			for (x = 0; x < fc; x++) {
				info = plist_new_dict();
				strcpy(tmpstr, p_all_flash);
				strcat(tmpstr, "/");
				strcat(tmpstr, files[x]);
				plist_dict_insert_item(info, "Path", plist_new_string(tmpstr));
				comp = plist_new_dict();
				plist_dict_insert_item(comp, "Info", info);
				const char* compname = get_component_name(files[x]);
				if (compname) {
					plist_dict_insert_item(manifest, compname, comp);
					if (!strncmp(files[x], "DeviceTree", 10)) {
						plist_dict_insert_item(manifest, "RestoreDeviceTree", plist_copy(comp));
					}
				} else {
					error("WARNING: unhandled component %s\n", files[x]);
					plist_free(comp);
				}
				free(files[x]);
				files[x] = NULL;
			}

			// add iBSS
			sprintf(tmpstr, "Firmware/dfu/iBSS.%s.%s.dfu", lcmodel, "RELEASE");
			info = plist_new_dict();
			plist_dict_insert_item(info, "Path", plist_new_string(tmpstr));
			comp = plist_new_dict();
			plist_dict_insert_item(comp, "Info", info);
			plist_dict_insert_item(manifest, "iBSS", comp);

			// add iBEC
			sprintf(tmpstr, "Firmware/dfu/iBEC.%s.%s.dfu", lcmodel, "RELEASE");
			info = plist_new_dict();
			plist_dict_insert_item(info, "Path", plist_new_string(tmpstr));
			comp = plist_new_dict();
			plist_dict_insert_item(comp, "Info", info);
			plist_dict_insert_item(manifest, "iBEC", comp);

			// add kernel cache
			node = plist_dict_get_item(buildmanifest, "KernelCachesByTarget");
			if (node && (plist_get_node_type(node) == PLIST_DICT)) {
				char tt[4];
				strncpy(tt, lcmodel, 3);
				tt[3] = 0;
				plist_t kdict = plist_dict_get_item(node, tt);
				if (kdict && (plist_get_node_type(kdict) == PLIST_DICT)) {
					plist_t kc = plist_dict_get_item(kdict, "Release");
					if (kc && (plist_get_node_type(kc) == PLIST_STRING)) {
						info = plist_new_dict();
						plist_dict_insert_item(info, "Path", plist_copy(kc));
						comp = plist_new_dict();
						plist_dict_insert_item(comp, "Info", info);
						plist_dict_insert_item(manifest, "KernelCache", comp);
						plist_dict_insert_item(manifest, "RestoreKernelCache", plist_copy(comp));

					}
				}
			}

			// add ramdisk
			node = plist_dict_get_item(buildmanifest, "RestoreRamDisks");
			if (node && (plist_get_node_type(node) == PLIST_DICT)) {
				plist_t rd = plist_dict_get_item(node, (client->flags & FLAG_ERASE) ? "User" : "Update");
				if (rd && (plist_get_node_type(rd) == PLIST_STRING)) {
					info = plist_new_dict();
					plist_dict_insert_item(info, "Path", plist_copy(rd));
					comp = plist_new_dict();
					plist_dict_insert_item(comp, "Info", info);
					plist_dict_insert_item(manifest, "RestoreRamDisk", comp);
				}
			}

			// add OS filesystem
			node = plist_dict_get_item(buildmanifest, "SystemRestoreImages");
			if (!node) {
				error("ERROR: missing SystemRestoreImages in Restore.plist\n");
			}
			plist_t os = plist_dict_get_item(node, "User");
			if (!os) {
				error("ERROR: missing filesystem in Restore.plist\n");
			} else {
				info = plist_new_dict();
				plist_dict_insert_item(info, "Path", plist_copy(os));
				comp = plist_new_dict();
				plist_dict_insert_item(comp, "Info", info);
				plist_dict_insert_item(manifest, "OS", comp);
			}

			// finally add manifest
			plist_dict_insert_item(build_identity, "Manifest", manifest);
		}
	} else if (client->flags & FLAG_ERASE) {
		build_identity = build_manifest_get_build_identity(buildmanifest, 0);
		if (build_identity == NULL) {
			error("ERROR: Unable to find any build identities\n");
			plist_free(buildmanifest);
			return -1;
		}
	} else {
		// loop through all build identities in the build manifest
		// and list the valid ones
		int i = 0;
		int valid_builds = 0;
		int build_count = build_manifest_get_identity_count(buildmanifest);
		for (i = 0; i < build_count; i++) {
			build_identity = build_manifest_get_build_identity(buildmanifest, i);
			valid_builds++;
		}
	}

	/* print information about current build identity */
	build_identity_print_information(build_identity);

	/* retrieve shsh blobs if required */
	if (tss_enabled) {
		debug("Getting device's ECID for TSS request\n");
		/* fetch the device's ECID for the TSS request */
		if (get_ecid(client, &client->ecid) < 0) {
			error("ERROR: Unable to find device ECID\n");
			return -1;
		}
		info("Found ECID " FMT_qu "\n", (long long unsigned int)client->ecid);

		if (get_shsh_blobs(client, client->ecid, NULL, 0, build_identity, &client->tss) < 0) {
			error("ERROR: Unable to get SHSH blobs for this device\n");
			return -1;
		}
	}

	if (shsh_only) {
		if (!tss_enabled) {
			info("This device does not require a TSS record");
			return 0;
		}
		if (!client->tss) {
			error("ERROR: could not fetch TSS record");
			plist_free(buildmanifest);
			return -1;
		} else {
			char *bin = NULL;
			uint32_t blen = 0;
			plist_to_bin(client->tss, &bin, &blen);
			if (bin) {
				char zfn[512];
				sprintf(zfn, "shsh/" FMT_qu "-%s-%s.shsh", (long long int)client->ecid, client->device->product, client->version);
				__mkdir("shsh", 0755);
				struct stat fst;
				if (stat(zfn, &fst) != 0) {
					gzFile zf = gzopen(zfn, "wb");
					gzwrite(zf, bin, blen);
					gzclose(zf);
					info("SHSH saved to '%s'\n", zfn);
				} else {
					info("SHSH '%s' already present.\n", zfn);
				}
				free(bin);
			} else {
				error("ERROR: could not get TSS record data\n");
			}
			plist_free(client->tss);
			plist_free(buildmanifest);
			return 0;
		}
	}

	/* verify if we have tss records if required */
	if ((tss_enabled) && (client->tss == NULL)) {
		error("ERROR: Unable to proceed without a TSS record.\n");
		plist_free(buildmanifest);
		return -1;
	}

	if ((tss_enabled) && client->tss) {
		/* fix empty dicts */
		fixup_tss(client->tss);
	}

	// Extract filesystem from IPSW and return its name
	char* filesystem = NULL;
	if (ipsw_extract_filesystem(client->ipsw, build_identity, &filesystem) < 0) {
		error("ERROR: Unable to extract filesystem from IPSW\n");
		if (client->tss)
			plist_free(client->tss);
		plist_free(buildmanifest);
		return -1;
	}

	// if the device is in normal mode, place device into recovery mode
	if (client->mode->index == MODE_NORMAL) {
		info("Entering recovery mode...\n");
		if (normal_enter_recovery(client) < 0) {
			error("ERROR: Unable to place device into recovery mode\n");
			if (client->tss)
				plist_free(client->tss);
			plist_free(buildmanifest);
			return -1;
		}
	}

	// if the device is in DFU mode, place device into recovery mode
	if (client->mode->index == MODE_DFU) {
		recovery_client_free(client);
		if (client->flags & FLAG_CUSTOM) {
			info("connecting to DFU\n");
			if (dfu_client_new(client) < 0) {
				return -1;
			}
			info("exploiting with limera1n\n");
			// TODO: check for non-limera1n device and fail
			if (limera1n_exploit(client->device, client->dfu->client) != 0) {
				error("ERROR: limera1n exploit failed\n");
				dfu_client_free(client);
				return -1;
			}
			dfu_client_free(client);
			info("exploited\n");
		}
		if (dfu_enter_recovery(client, build_identity) < 0) {
			error("ERROR: Unable to place device into recovery mode\n");
			plist_free(buildmanifest);
			if (client->tss)
				plist_free(client->tss);
			return -1;
		}
	}

	if (client->mode->index == MODE_DFU) {
		client->mode = &idevicerestore_modes[MODE_RECOVERY];
	} else {
		/* now we load the iBEC */
		if (recovery_send_ibec(client, build_identity) < 0) {
			error("ERROR: Unable to send iBEC\n");
			return -1;
		}
		recovery_client_free(client);
	
		/* this must be long enough to allow the device to run the iBEC */
		/* FIXME: Probably better to detect if the device is back then */
		sleep(7);
	}

	if (client->build[0] > '8') {
		// we need another tss request with nonce.
		unsigned char* nonce = NULL;
		int nonce_size = 0;
		int nonce_changed = 0;
		if (get_nonce(client, &nonce, &nonce_size) < 0) {
			error("ERROR: Unable to get nonce from device!\n");
			recovery_send_reset(client);
			return -1;
		}

		if (!client->nonce || (nonce_size != client->nonce_size) || (memcmp(nonce, client->nonce, nonce_size) != 0)) {
			nonce_changed = 1;
			if (client->nonce) {
				free(client->nonce);
			}
			client->nonce = nonce;
			client->nonce_size = nonce_size;
		} else {
			free(nonce);
		}

		info("Nonce: ");
		int i;
		for (i = 0; i < client->nonce_size; i++) {
			info("%02x ", client->nonce[i]);
		}
		info("\n");

		if (nonce_changed && !(client->flags & FLAG_CUSTOM)) {
			// Welcome iOS5. We have to re-request the TSS with our nonce.
			plist_free(client->tss);
			if (get_shsh_blobs(client, client->ecid, client->nonce, client->nonce_size, build_identity, &client->tss) < 0) {
				error("ERROR: Unable to get SHSH blobs for this device\n");
				return -1;
			}
			if (!client->tss) {
				error("ERROR: can't continue without TSS\n");
				return -1;
			}
			fixup_tss(client->tss);
		}
	}

	// now finally do the magic to put the device into restore mode
	if (client->mode->index == MODE_RECOVERY) {
		if (client->srnm == NULL) {
			error("ERROR: could not retrieve device serial number. Can't continue.\n");
			return -1;
		}
		if (recovery_enter_restore(client, build_identity) < 0) {
			error("ERROR: Unable to place device into restore mode\n");
			plist_free(buildmanifest);
			if (client->tss)
				plist_free(client->tss);
			return -1;
		}
	}

	// device is finally in restore mode, let's do this
	if (client->mode->index == MODE_RESTORE) {
		info("About to restore device... \n");
		if (restore_device(client, build_identity, filesystem) < 0) {
			error("ERROR: Unable to restore device\n");
			return -1;
		}
	}

	info("Cleaning up...\n");
	if (filesystem)
		unlink(filesystem);

	info("DONE\n");
	return 0;
}