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; }
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); }
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); }
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); }
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); }