예제 #1
0
static int ohci_hcd_brcm_probe(struct platform_device *pdev)
{
	struct resource *res = NULL;
	struct usb_hcd *hcd = NULL;
	int irq = -1;
	int ret;

	if (usb_disabled())
		return -ENODEV;

	/* clear this to enable Port Power management */
	distrust_firmware = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		err("platform_get_resource error.");
		return -ENODEV;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		err("platform_get_irq error.");
		return -ENODEV;
	}

#ifndef CONFIG_USB_EHCI_HCD
	// Init common registers for board and HC specific issues
	brcm_usb_init();
#endif

	/* initialize hcd */
	hcd = usb_create_hcd(&ohci_brcm_hc_driver, &pdev->dev, (char *)hcd_name);
	if (!hcd) {
		err("Failed to create hcd");
		return -ENOMEM;
	}

	hcd->regs = ioremap(res->start, res->end - res->start);
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_len(res);
	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
	if (ret != 0) {
		err("Failed to add hcd");
		usb_put_hcd(hcd);
		iounmap(hcd->regs);
		return ret;
	}

	return ret;
}
예제 #2
0
파일: files.c 프로젝트: Schala/mhxd
static void
hxd_scandir (struct htlc_conn *htlc, const char *path)
{
	DIR *dir;
	struct dirent *de;
	struct hl_filelist_hdr **fhdrs = 0;
	u_int16_t count = 0, maxcount = 0;
	struct stat sb;
	int is_link;
	char pathbuf[MAXPATHLEN];
	u_int16_t nlen;
#if defined(CONFIG_ICONV)
	char *out_p;
	size_t out_len;
#endif
	if (!(dir = opendir(path))) {
		snd_strerror(htlc, errno);
		return;
	}
	while ((de = readdir(dir))) {
		if (skip_match(de->d_name))
			continue;
		if (count >= maxcount) {
			maxcount += 16;
			fhdrs = xrealloc(fhdrs, sizeof(struct hl_filelist_hdr *) * maxcount);
		}
		nlen = (u_int16_t)strlen(de->d_name);
		snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path, de->d_name);
		fhdrs[count] = xmalloc(SIZEOF_HL_FILELIST_HDR + nlen);
		fhdrs[count]->type = HTLS_DATA_FILE_LIST;
		fhdrs[count]->len = (SIZEOF_HL_FILELIST_HDR - 4) + nlen;
		fhdrs[count]->unknown = 0;
		fhdrs[count]->encoding = 0;
		fhdrs[count]->fnlen = htons(nlen);
#if defined(CONFIG_ICONV)
		if (hxd_cfg.text.client_encoding[0] && hxd_cfg.text.server_encoding[0]) {
			out_len = convbuf(hxd_cfg.text.client_encoding,
					  hxd_cfg.text.server_encoding,
					  de->d_name, (size_t)nlen, &out_p);
			if (out_len) {
				if (out_len > (size_t)nlen)
					out_len = (size_t)nlen;
				memcpy(fhdrs[count]->fname, out_p, out_len);
				xfree(out_p);
			} else {
				memcpy(fhdrs[count]->fname, de->d_name, nlen);
			}
		} else
#endif
			memcpy(fhdrs[count]->fname, de->d_name, nlen);
#ifdef HAVE_CORESERVICES
		resolve_alias_path(pathbuf, pathbuf);
#endif
		if (SYS_lstat(pathbuf, &sb)) {
broken_alias:
			fhdrs[count]->fsize = 0;
			fhdrs[count]->ftype = htonl(0x616c6973);	/* 'alis' */
			fhdrs[count]->fcreator = 0;
			count++;
			continue;
		}
#ifdef HAVE_CORESERVICES
		if (is_alias(pathbuf, &is_link))
			goto broken_alias;
#else
		if (S_ISLNK(sb.st_mode)) {
			is_link = 1;
			if (stat(pathbuf, &sb))
				goto broken_alias;
		} else {
			is_link = 0;
		}
#endif
		if (S_ISDIR(sb.st_mode)) {
			u_int32_t ndirs = 0;
			DIR *subdir;
			struct dirent *subde;
			if ((subdir = opendir(pathbuf))) {
				while ((subde = readdir(subdir)))
					if (!skip_match(subde->d_name))
						ndirs++;
				closedir(subdir);
			}
			fhdrs[count]->fsize = htonl(ndirs);
			fhdrs[count]->ftype = htonl(0x666c6472);	/* 'fldr' */
			fhdrs[count]->fcreator = 0;
		} else {
			u_int32_t size = sb.st_size;
#if defined(CONFIG_HFS)
			if (hxd_cfg.operation.hfs) {
				size += resource_len(pathbuf);
				type_creator((u_int8_t *)&fhdrs[count]->ftype, pathbuf);
			} else {
				fhdrs[count]->ftype = 0;
				fhdrs[count]->fcreator = 0;
			}
#else
			fhdrs[count]->ftype = 0;
			fhdrs[count]->fcreator = 0;
#endif
			fhdrs[count]->fsize = htonl(size);
		}
		count++;
	}
	closedir(dir);
	if (fhdrs)
		fh_sort(fhdrs, count);
	hlwrite_dhdrs(htlc, count, (struct hl_data_hdr **)fhdrs);
	while (count) {
		count--;
		xfree(fhdrs[count]);
	}
	if (fhdrs)
		xfree(fhdrs);
}
예제 #3
0
파일: files.c 프로젝트: Schala/mhxd
void
rcv_folder_get (struct htlc_conn *htlc)
{
	u_int16_t fnlen = 0, preview = 0;
	char path[MAXPATHLEN], dir[MAXPATHLEN], filename[NAME_MAX], pathbuf[MAXPATHLEN];
	char abuf[HOSTLEN+1], buf[128];
	struct stat sb;
	u_int32_t size = 0, data_size = 0, rsrc_size = 0, ref, 
		  data_pos = 0, rsrc_pos = 0, nfiles = 0;
	int err, siz, len;
	struct SOCKADDR_IN lsaddr;
	struct htxf_conn *htxf;
	u_int16_t i;
	DIR *dirp;
	struct dirent *de;

	dir[0] = 0;

	if (htlc->nr_gets >= htlc->get_limit) {
		len = snprintf(buf, sizeof(buf), "%u at a time", htlc->get_limit);
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, len, buf);
		return;
	}
	if (nr_gets >= hxd_cfg.limits.total_downloads) {
		len = snprintf(buf, sizeof(buf), "maximum number of total downloads reached (%u >= %d)",
			       nr_gets, hxd_cfg.limits.total_downloads);
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, len, buf);
		return;
	}
	for (i = 0; i < HTXF_GET_MAX; i++)
		if (!htlc->htxf_out[i])
			break;
	if (i == HTXF_GET_MAX) {
		snd_strerror(htlc, EAGAIN);
		return;
	}

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
			case HTLC_DATA_RFLT:
				if (dh_len >= 50)
					L32NTOH(data_pos, &dh_data[46]);
				if (dh_len >= 66)
					L32NTOH(rsrc_pos, &dh_data[62]);
				break;
			case HTLC_DATA_FILE_PREVIEW:
				dh_getint(preview);
				break;
		}
	dh_end()

	if (!fnlen && !dir[0]) {
		/* No file name given */
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}

	if (dir[0]) {
		if (fnlen)
			snprintf(path, sizeof(path), "%s/%s", dir, filename);
		else
			strcpy(path, dir);
	} else {
		snprintf(path, sizeof(path), "%s/%s", ROOTDIR, filename);
	}
#ifdef HAVE_CORESERVICES
	resolve_alias_path(path, path);
#endif
	if (check_dropbox(htlc, path)) {
		snd_strerror(htlc, EPERM);
		return;
	}

	if (stat(path, &sb)) {
		snd_strerror(htlc, errno);
		return;
	}

	if (!S_ISDIR(sb.st_mode)) {
		snd_strerror(htlc, ENOTDIR);
		return;
	}

	if (!(dirp = opendir(path))) {
		snd_strerror(htlc, errno);
		return;
	}
	while ((de = readdir(dirp))) {
		if (de->d_name[0] == '.')
			continue;
		nfiles++;
		snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path, de->d_name);
		if (stat(pathbuf, &sb))
			continue;
		if (S_ISDIR(sb.st_mode))
			continue;
		data_size = sb.st_size;
		rsrc_size = resource_len(pathbuf);
		size += (data_size - data_pos) + (preview ? 0 : (rsrc_size - rsrc_pos));
		size += 133 + ((rsrc_size - rsrc_pos) ? 16 : 0) + comment_len(pathbuf);
	}
	closedir(dirp);

	if (!nfiles) {
		hlwrite(htlc, HTLS_HDR_TASK, 0, 2,
			HTLC_DATA_HTXF_SIZE, sizeof(size), &size,
			HTLC_DATA_FILE_NFILES, sizeof(nfiles), &nfiles);
		return;
	}

	ref = htxf_ref_new(htlc);
	ref = htonl(ref);

	siz = sizeof(struct SOCKADDR_IN);
	if (getsockname(htlc->fd, (struct sockaddr *)&lsaddr, &siz)) {
		hxd_log("rcv_file_get: getsockname: %s", strerror(errno));
		snd_strerror(htlc, errno);
		return;
	}
	htxf = htxf_new(htlc, 0);
	htxf->type = HTXF_TYPE_FOLDER;
	htxf->total_size = size;
	htxf->ref = ref;
	htxf->preview = preview;
	htxf->sockaddr = htlc->sockaddr;
	htxf->listen_sockaddr = lsaddr;
	htxf->listen_sockaddr.SIN_PORT = htons(ntohs(htxf->listen_sockaddr.SIN_PORT) + 1);
	strcpy(htxf->path, path);

	htlc->nr_gets++;
	nr_gets++;
	if (log_download) {
		inaddr2str(abuf, &htlc->sockaddr);
		hxd_log("%s@%s:%u - %s:%u:%u:%s - download %s:%08x", htlc->userid, abuf, ntohs(htlc->sockaddr.SIN_PORT),
			htlc->name, htlc->icon, htlc->uid, htlc->login, htxf->path, htxf->ref);
	}
	size = htonl(size);
	nfiles = htonl(nfiles);
	hlwrite(htlc, HTLS_HDR_TASK, 0, 3,
		HTLS_DATA_HTXF_SIZE, sizeof(size), &size,
		HTLS_DATA_FILE_NFILES, sizeof(nfiles), &nfiles,
		HTLS_DATA_HTXF_REF, sizeof(ref), &ref);
}
예제 #4
0
파일: files.c 프로젝트: Schala/mhxd
void
rcv_file_get (struct htlc_conn *htlc)
{
	u_int16_t fnlen = 0, preview = 0;
	char path[MAXPATHLEN], dir[MAXPATHLEN], filename[NAME_MAX];
	char abuf[HOSTLEN+1], buf[128];
	struct stat sb;
	u_int32_t size = 0, data_size = 0, rsrc_size = 0, ref, 
		  data_pos = 0, rsrc_pos = 0;
	int err, siz, len;
	struct SOCKADDR_IN lsaddr;
	struct htxf_conn *htxf;
	u_int16_t i;
#if defined(CONFIG_HTXF_QUEUE)
	u_int16_t queue_pos;
#endif

	dir[0] = 0;

	if (htlc->nr_gets >= htlc->get_limit) {
		for (i = 0; i < HTXF_GET_MAX; i++) {
			htxf = htlc->htxf_out[i];
			if (!htxf)
				continue;
			if ((htxf->total_pos == htxf->total_size)
			    || htxf->gone)
				goto ok;
		}
		len = snprintf(buf, sizeof(buf), "%u at a time", htlc->get_limit);
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, len, buf);
		return;
	}
ok:
#if defined(CONFIG_HTXF_QUEUE)
	if (!htlc->access_extra.ignore_queue && nr_queued >= hxd_cfg.limits.queue_size) {
#else
	if (nr_gets >= hxd_cfg.limits.total_downloads) {
#endif
#if defined(CONFIG_HTXF_QUEUE)
		len = snprintf(buf, sizeof(buf),
			       "queue is full (%u >= %d) please try again later",
			       nr_gets, hxd_cfg.limits.queue_size);
#else
		len = snprintf(buf, sizeof(buf),
			       "maximum number of total downloads reached (%u >= %d)",
			       nr_gets, hxd_cfg.limits.total_downloads);
#endif
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, len, buf);
		return;
	}
	for (i = 0; i < HTXF_GET_MAX; i++)
		if (!htlc->htxf_out[i])
			break;
	if (i == HTXF_GET_MAX) {
		snd_strerror(htlc, EAGAIN);
		return;
	}

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
			case HTLC_DATA_RFLT:
				if (dh_len >= 50)
					L32NTOH(data_pos, &dh_data[46]);
				if (dh_len >= 66)
					L32NTOH(rsrc_pos, &dh_data[62]);
				break;
			case HTLC_DATA_FILE_PREVIEW:
				dh_getint(preview);
				break;
		}
	dh_end()

	if (!fnlen && !dir[0]) {
		/* No file name given */
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}

	if (dir[0]) {
		if (fnlen)
			snprintf(path, sizeof(path), "%s/%s", dir, filename);
		else
			strcpy(path, dir);
	} else {
		snprintf(path, sizeof(path), "%s/%s", ROOTDIR, filename);
	}
#ifdef HAVE_CORESERVICES
	resolve_alias_path(path, path);
#endif
	if (check_dropbox(htlc, path)) {
		snd_strerror(htlc, EPERM);
		return;
	}

#ifdef CONFIG_HTXF_PREVIEW
	if (preview) {
		Image *img, *mimg;
		ImageInfo ii;
		ExceptionInfo ei;
		char previewpath[MAXPATHLEN];
		static int magick_inited = 0;

		if (!magick_inited) {
			InitializeMagick("hxd");
			magick_inited = 1;
		}

#if MaxTextExtent < MAXPATHLEN
		if (strlen(path) >= sizeof(ii.filename)) {
			hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR,
				13, "path too long");
			return;
		}
#endif
		memset(&ii, 0, sizeof(ii));
		memset(&ei, 0, sizeof(ei));
		GetImageInfo(&ii);
		GetExceptionInfo(&ei);

		err = preview_path(previewpath, path, &sb);
		if (!err) {
			/* Preview file already exists */
			strcpy(ii.filename, previewpath);
			mimg = ReadImage(&ii, &ei);
		} else {
			/* Create preview file */
			strcpy(ii.filename, path);
			img = ReadImage(&ii, &ei);
			if (!img)
				goto text_preview;
			mimg = MinifyImage(img, &ei);
			DestroyImage(img);
		}
		if (!mimg) {
			hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR,
				18, "MinifyImage failed");
			return;
		}
		if (err) {
			err = preview_path(previewpath, path, 0);
			if (err) {
				snd_strerror(htlc, err);
				DestroyImage(mimg);
				return;
			}
			strcpy(mimg->filename, previewpath);
			data_pos = 0;
			rsrc_pos = 0;
			WriteImage(&ii, mimg);
			DestroyImage(mimg);
		} else {
			DestroyImage(mimg);
		}
		strcpy(path, previewpath);
	}

text_preview:
#endif
	if (stat(path, &sb)) {
		snd_strerror(htlc, errno);
		return;
	}

	if (S_ISDIR(sb.st_mode)) {
		snd_strerror(htlc, EISDIR);
		return;
	}

	data_size = sb.st_size;
	size = (data_size - data_pos) + (preview ? 0 : 133);
#if defined(CONFIG_HFS)
	if (hxd_cfg.operation.hfs) {
		rsrc_size = resource_len(path);
		size += preview ? 0 : (rsrc_size - rsrc_pos);
		if (!preview)
			size += ((rsrc_size - rsrc_pos) ? 16 : 0) + comment_len(path);
	}
#endif

	ref = htxf_ref_new(htlc);
	ref = htonl(ref);

	siz = sizeof(struct SOCKADDR_IN);
	if (getsockname(htlc->fd, (struct sockaddr *)&lsaddr, &siz)) {
		hxd_log("rcv_file_get: getsockname: %s", strerror(errno));
		snd_strerror(htlc, errno);
		return;
	}
	htxf = htxf_new(htlc, 0);
	htxf->type = HTXF_TYPE_FILE;
	htxf->data_size = data_size;
	htxf->rsrc_size = rsrc_size;
	htxf->data_pos = data_pos;
	htxf->rsrc_pos = rsrc_pos;
	htxf->total_size = size;
	htxf->ref = ref;
	htxf->limit_out_Bps = htlc->nr_puts > 0 ?
		(htlc->limit_uploader_out_Bps ? htlc->limit_uploader_out_Bps : htlc->limit_out_Bps) :
		  htlc->limit_out_Bps;
	hxd_log("conf: %u!%u", htxf->limit_out_Bps, htlc->limit_out_Bps);
	htxf->preview = preview;
	htxf->sockaddr = htlc->sockaddr;
	htxf->listen_sockaddr = lsaddr;
	htxf->listen_sockaddr.SIN_PORT = htons(ntohs(htxf->listen_sockaddr.SIN_PORT) + 1);
	strcpy(htxf->path, path);

	htlc->nr_gets++;
	nr_gets++;
#if defined(CONFIG_HTXF_QUEUE)
	if (htlc->access_extra.ignore_queue)
		htxf->queue_pos = queue_pos = 0;
	else
		htxf->queue_pos = queue_pos = insert_into_queue(htlc);
#endif

	if (log_download) {
		inaddr2str(abuf, &htlc->sockaddr);
		hxd_log("%s@%s:%u - %s:%u:%u:%s - download %s:%08x", htlc->userid, abuf, ntohs(htlc->sockaddr.SIN_PORT),
			htlc->name, htlc->icon, htlc->uid, htlc->login, htxf->path, htxf->ref);
#if defined(CONFIG_SQL)
		sql_download(htlc->name, abuf, htlc->login, path);
#endif
	}
	size = htonl(size);
#if defined(CONFIG_HTXF_QUEUE)
	queue_pos = htons(queue_pos);
	hlwrite(htlc, HTLS_HDR_TASK, 0, 3,
		HTLS_DATA_HTXF_REF, sizeof(ref), &ref,
		HTLS_DATA_HTXF_SIZE, sizeof(size), &size,
		HTLS_DATA_QUEUE_POSITION, sizeof(queue_pos), &queue_pos);
#else
	hlwrite(htlc, HTLS_HDR_TASK, 0, 2,
		HTLS_DATA_HTXF_REF, sizeof(ref), &ref,
		HTLS_DATA_HTXF_SIZE, sizeof(size), &size);
#endif
}

void
rcv_file_put (struct htlc_conn *htlc)
{
	u_int16_t fnlen = 0, resume = 0;
	char path[MAXPATHLEN], dir[MAXPATHLEN], filename[NAME_MAX];
	char abuf[HOSTLEN+1], buf[128];
	struct stat sb;
	int err, siz, len;
	u_int32_t ref, data_pos = 0, rsrc_pos = 0, totalsize = 0;
	u_int8_t rflt[74];
	struct SOCKADDR_IN lsaddr;
	struct htxf_conn *htxf;
	u_int16_t i;

	dir[0] = 0;

	if (htlc->nr_puts >= htlc->put_limit) {
		len = snprintf(buf, sizeof(buf), "%u at a time", htlc->put_limit);
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, len, buf);
		return;
	}
	if (nr_puts >= hxd_cfg.limits.total_uploads) {
		len = snprintf(buf, sizeof(buf), "maximum number of total uploads reached (%u >= %d)",
			       nr_gets, hxd_cfg.limits.total_uploads);
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, len, buf);
		return;
	}
	for (i = 0; i < HTXF_PUT_MAX; i++)
		if (!htlc->htxf_in[i])
			break;
	if (i == HTXF_PUT_MAX) {
		snd_strerror(htlc, EAGAIN);
		return;
	}

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
			case HTLC_DATA_FILE_PREVIEW:
				dh_getint(resume);
				break;
			case HTLC_DATA_HTXF_SIZE:
				dh_getint(totalsize);
				break;
		}
	dh_end()

	if (!htlc->access.upload_anywhere && (!dir[0] || (!strcasestr(dir, "UPLOAD") && !strcasestr(dir, "DROP BOX")))) {
		snd_strerror(htlc, EPERM);
		return;
	}
	if (!fnlen && !dir[0]) {
		/* No file name given */
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}

	if (dir[0]) {
		if (fnlen)
			snprintf(path, sizeof(path), "%s/%s", dir, filename);
		else
			strcpy(path, dir);
	} else {
		snprintf(path, sizeof(path), "%s/%s", ROOTDIR, filename);
	}
#ifdef HAVE_CORESERVICES
	resolve_alias_path(path, path);
#endif
	if (!resume) {
		if (!stat(path, &sb)) {
			snd_strerror(htlc, EEXIST);
			return;
		}
		if (errno != ENOENT) {
			snd_strerror(htlc, errno);
			return;
		}
	} else {
		if (stat(path, &sb)) {
			snd_strerror(htlc, errno);
			return;
		}
		data_pos = sb.st_size;
#if defined(CONFIG_HFS)
		if (hxd_cfg.operation.hfs)
			rsrc_pos = resource_len(path);
#endif
		memcpy(rflt, "RFLT\0\1\
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
\0\0\0\2DATA\0\0\0\0\0\0\0\0\0\0\0\0MACR\0\0\0\0\0\0\0\0\0\0\0\0", 74);
		S32HTON(data_pos, &rflt[46]);
		S32HTON(rsrc_pos, &rflt[62]);
	}

	ref = htxf_ref_new(htlc);
	ref = htonl(ref);

	siz = sizeof(struct SOCKADDR_IN);
	if (getsockname(htlc->fd, (struct sockaddr *)&lsaddr, &siz)) {
		hxd_log("rcv_file_get: getsockname: %s", strerror(errno));
		snd_strerror(htlc, errno);
		return;
	}
	htxf = htxf_new(htlc, 1);
	htxf->type = HTXF_TYPE_FILE;
	htxf->data_pos = data_pos;
	htxf->rsrc_pos = rsrc_pos;
	htxf->total_size = totalsize;
	htxf->ref = ref;
	htxf->sockaddr = htlc->sockaddr;
	htxf->listen_sockaddr = lsaddr;
	htxf->listen_sockaddr.SIN_PORT = htons(ntohs(htxf->listen_sockaddr.SIN_PORT) + 1);
	strcpy(htxf->path, path);

	htlc->nr_puts++;
	nr_puts++;
	if (log_upload) {
		inaddr2str(abuf, &htlc->sockaddr);
		hxd_log("%s@%s:%u - %s:%u:%u:%s - upload %s:%08x", htlc->userid, abuf, ntohs(htlc->sockaddr.SIN_PORT),
			htlc->name, htlc->icon, htlc->uid, htlc->login, htxf->path, htxf->ref);
#if defined(CONFIG_SQL)
		sql_upload(htlc->name, abuf, htlc->login, path);
#endif
	}
	if (!resume)
		hlwrite(htlc, HTLS_HDR_TASK, 0, 1,
			HTLS_DATA_HTXF_REF, sizeof(ref), &ref);
	else
		hlwrite(htlc, HTLS_HDR_TASK, 0, 2,
			HTLS_DATA_RFLT, 74, rflt,
			HTLS_DATA_HTXF_REF, sizeof(ref), &ref);
}
예제 #5
0
파일: files.c 프로젝트: Schala/mhxd
void
rcv_file_getinfo (struct htlc_conn *htlc)
{
	u_int32_t size;
	u_int8_t date_create[8], date_modify[8];
	u_int16_t fnlen = 0;
	char dir[MAXPATHLEN], filename[NAME_MAX], path[MAXPATHLEN];
	struct stat sb;
	int is_link;
	int err;
	u_int16_t file_typelen, file_creatorlen;
	u_int8_t file_type[12], file_creator[4];
	u_int32_t mactime;
#if defined(CONFIG_HFS)
	struct hfsinfo fi;
#endif

	dir[0] = 0;

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len > NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
		}
	dh_end()

	if (!fnlen && !dir[0]) {
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}

	if (dir[0]) {
		if (fnlen)
			snprintf(path, sizeof(path), "%s/%s", dir, filename);
		else {
			int i, len = strlen(dir);

			for (i = len - 1; i > 0; i--)
				if (dir[i] == DIRCHAR) {
					fnlen = len - i > NAME_MAX ? NAME_MAX : len - i;
					strcpy(filename, &dir[len - fnlen + 1]);
					break;
				}
			strcpy(path, dir);
		}
	} else {
		snprintf(path, sizeof(path), "%s/%s", ROOTDIR, filename);
	}
#ifdef HAVE_CORESERVICES
	resolve_alias_path(path, path);
#endif
	if (check_dropbox(htlc, path)) {
		snd_strerror(htlc, EPERM);
		return;
	}

	if (log_getinfo)
		hxd_log("%s:%s:%u - getinfo %s", htlc->name, htlc->login, htlc->uid, path);

	if (SYS_lstat(path, &sb)) {
broken_alias:	snd_strerror(htlc, errno);
		return;
	}
	if (S_ISLNK(sb.st_mode)) {
		is_link = 1;
		if (stat(path, &sb))
			goto broken_alias;
	} else {
		is_link = 0;
	}
	size = sb.st_size;
#if defined(CONFIG_HFS)
	if (hxd_cfg.operation.hfs)
		size += resource_len(path);
#endif
	size = htonl(size);
	memset(date_create, 0, 8);
	memset(date_modify, 0, 8);

#if defined(CONFIG_HFS)
	if (!hxd_cfg.operation.hfs)
		goto skiphfs;

	hfsinfo_read(path, &fi);
	mactime = hfs_h_to_mtime(fi.create_time);
	*((u_int16_t *)date_create) = htons(1904);
	*((u_int32_t *)(date_create+4)) = mactime;
	mactime = hfs_h_to_mtime(fi.modify_time);
	*((u_int16_t *)date_modify) = htons(1904);
	*((u_int32_t *)(date_modify+4)) = mactime;
	file_typelen = 4;
	file_creatorlen = 4;
	if (S_ISDIR(sb.st_mode)) {
#if 0
		if (is_link) {
			file_typelen = 12;
			memcpy(file_type, "Folder Alias", file_typelen);
		} else
			memcpy(file_type, "fldr", 4);
#endif
		memcpy(fi.type, "fldr", 4);
		memcpy(file_type, "fldr", 4);
		memcpy(file_creator, "n/a ", 4);
	} else {
		memcpy(file_type, fi.type, 4);
		memcpy(file_creator, fi.creator, 4);
	}

	if (is_link) {
		memcpy(file_type, "\0\0\0\0", 4);
		file_typelen = 4;
	}

	hlwrite(htlc, HTLS_HDR_TASK, 0, 8,
		HTLS_DATA_FILE_ICON, 4, fi.type,
		HTLS_DATA_FILE_TYPE, file_typelen, file_type,
		HTLS_DATA_FILE_CREATOR, file_creatorlen, file_creator,
		HTLS_DATA_FILE_SIZE, sizeof(size), &size,
		HTLS_DATA_FILE_NAME, fnlen, filename,
		HTLS_DATA_FILE_DATE_CREATE, 8, date_create,
		HTLS_DATA_FILE_DATE_MODIFY, 8, date_modify,
		HTLS_DATA_FILE_COMMENT, fi.comlen > 200 ? 200 : fi.comlen, fi.comment);

	return;
skiphfs:
#endif
	mactime = htonl(sb.st_mtime + 2082844800);
	*((u_int16_t *)date_modify) = 1904;
	*((u_int32_t *)(date_modify+4)) = mactime;
	hlwrite(htlc, HTLS_HDR_TASK, 0, 3,
		HTLS_DATA_FILE_SIZE, sizeof(size), &size,
		HTLS_DATA_FILE_NAME, fnlen, filename,
		HTLS_DATA_FILE_DATE_MODIFY, 8, date_modify);
}