Beispiel #1
0
static void
decode_and_get_info(Camera *camera, const char *folder, struct tf_packet *p, const char *fn,
		CameraFileInfo *info, GPContext *context)
{
	unsigned short count = (get_u16(&p->length) - PACKET_HEAD_SIZE) / sizeof(struct typefile);
	struct typefile *entries = (struct typefile *) p->data;
	int i;
	char *name;

	for(i = 0; i < count; i++) {
		switch (entries[i].filetype) {
		case 1: break;/*dir*/
		case 2:	/* file */
			name = _convert_and_logname (camera, (char*)entries[i].name);
			if (!strcmp (name, fn)) { /* the wanted current one */
				memset (info, 0, sizeof (*info));
				info->file.fields = GP_FILE_INFO_SIZE|GP_FILE_INFO_MTIME;
				if (strstr (name, ".rec")) {
					info->file.fields |= GP_FILE_INFO_TYPE;
					strcpy (info->file.type, GP_MIME_MPEG);
				}
				info->file.size = get_u64(&entries[i].size);
				info->file.mtime = tfdt_to_time(&entries[i].stamp);
			} else { /* cache the others to avoid further turnarounds */
				CameraFileInfo	xinfo;

				memset (&xinfo, 0, sizeof (xinfo));
				xinfo.file.fields = GP_FILE_INFO_TYPE|GP_FILE_INFO_SIZE|GP_FILE_INFO_MTIME;
				strcpy (xinfo.file.type, GP_MIME_MPEG);
				xinfo.file.size = get_u64(&entries[i].size);
				xinfo.file.mtime = tfdt_to_time(&entries[i].stamp);
				gp_filesystem_append (camera->fs, folder, name, context); /* FIXME: might fail if exist? */
				gp_filesystem_set_info_noop (camera->fs, folder, name, xinfo, context);
			}
			break;
		default:
			break;
	}
#if 0
        /* This makes the assumption that the timezone of the Toppy and the system
         * that puppy runs on are the same. Given the limitations on the length of
         * USB cables, this condition is likely to be satisfied. */
        timestamp = tfdt_to_time(&entries[i].stamp);
        printf("%c %20llu %24.24s %s\n", type, get_u64(&entries[i].size),
               ctime(&timestamp), entries[i].name);
#endif
    }
}
Beispiel #2
0
void decode_dir(struct tf_packet *p)
{
    __u16 count =
        (get_u16(&p->length) - PACKET_HEAD_SIZE) / sizeof(struct typefile);
    struct typefile *entries = (struct typefile *) p->data;
    int i;
    time_t timestamp;
    if (xml) {
      printf("<?xml version=\"1.0\" encoding=\"ISO-8859-15\"?>\r\n\r\n");
      printf("<contents>\n");
    }
    for(i = 0; (i < count); i++)
    {
        /* This makes the assumption that the timezone of the Toppy and the system
         * that puppy runs on are the same. Given the limitations on the length of
         * USB cables, this condition is likely to be satisfied. */
      struct tm tm;
        timestamp = tfdt_to_time(&entries[i].stamp);
        tm = *localtime(&timestamp);
        if (xml) {
          int ft = entries[i].filetype;
          printf("<file type=\"%s\" size=\"%llu\" time=\"%04d-%02d-%02d %d:%02d:%02d\" name=\"%W\"/>\n",
                 ft == 1 ? "dir" :
                 ft == 2 ? "file" :
                           "unknown",
                 get_u64(&entries[i].size),
                 tm.tm_year + 1900,
                 tm.tm_mon + 1,
                 tm.tm_mday,
                 tm.tm_hour,
                 tm.tm_min,
                 tm.tm_sec,
                 entries[i].name);
        } else {
          char type;

          switch (entries[i].filetype)
          {
          case 1:
            type = 'd';
            break;

          case 2:
            type = 'f';
            break;

          default:
            type = '?';
          }

          printf("%c %20llu %24.24s %s\n", type, get_u64(&entries[i].size),
                 ctime(&timestamp), entries[i].name);
        }
    }
    if (xml) {
      printf("</contents>\n");
    }
}
Beispiel #3
0
static void
decode_dir(Camera *camera, struct tf_packet *p, int listdirs, CameraList *list)
{
	unsigned short count = (get_u16(&p->length) - PACKET_HEAD_SIZE) / sizeof(struct typefile);
	struct typefile *entries = (struct typefile *) p->data;
	int i;
	char *name;

	for(i = 0; i < count; i++) {
		switch (entries[i].filetype) {
		case 1:
			if (listdirs) {
				if (!strcmp ((char*)entries[i].name, ".."))
					continue;
				gp_list_append (list, (char*)entries[i].name, NULL);
			}
			break;
		case 2:
			if (!listdirs) {
				name = _convert_and_logname (camera, (char*)entries[i].name);
				gp_list_append (list, name, NULL);
			}
			break;
		default:
			break;
	}

#if 0
        /* This makes the assumption that the timezone of the Toppy and the system
         * that puppy runs on are the same. Given the limitations on the length of
         * USB cables, this condition is likely to be satisfied. */
        timestamp = tfdt_to_time(&entries[i].stamp);
        printf("%c %20llu %24.24s %s\n", type, get_u64(&entries[i].size),
               ctime(&timestamp), entries[i].name);
#endif
    }
}
Beispiel #4
0
static int
get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
	       CameraFileType type, CameraFile *file, void *data,
	       GPContext *context)
{
	Camera *camera = data;
	int result = GP_ERROR_IO;
	enum {
		START,
		DATA,
		ABORT
	} state;
	int r, pid = 0, update = 0;
	uint64_t byteCount = 0;
	struct utimbuf mod_utime_buf = { 0, 0 };
	char *path;
	struct tf_packet reply;

	if (type != GP_FILE_TYPE_NORMAL)
		return GP_ERROR_NOT_SUPPORTED;

	do_cmd_turbo (camera, "ON", context);

	path = get_path(camera, folder, filename);
	r = send_cmd_hdd_file_send(camera, GET, path, context);
	free (path);
	if(r < 0)
		goto out;

	state = START;
	while(0 < (r = get_tf_packet(camera, &reply, context)))
	{
		update = (update + 1) % 4;
		switch (get_u32(&reply.cmd)) {
		case DATA_HDD_FILE_START:
			if(state == START) {
				struct typefile *tf = (struct typefile *) reply.data;

				byteCount = get_u64(&tf->size);
				pid = gp_context_progress_start (context, byteCount, _("Downloading %s..."), filename);
				mod_utime_buf.actime = mod_utime_buf.modtime =
				tfdt_to_time(&tf->stamp);

				send_success(camera,context);
				state = DATA;
			} else {
				gp_log (GP_LOG_ERROR, "topfield", "ERROR: Unexpected DATA_HDD_FILE_START packet in state %d\n", state);
				send_cancel(camera,context);
				state = ABORT;
			}
			break;

		case DATA_HDD_FILE_DATA:
			if(state == DATA) {
				uint64_t offset = get_u64(reply.data);
				uint16_t dataLen = get_u16(&reply.length) - (PACKET_HEAD_SIZE + 8);
				int w;

				if (!update) { /* avoid doing it too often */
					gp_context_progress_update (context, pid, offset + dataLen);
					if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
						send_cancel(camera,context);
						state = ABORT;
					}
				}

				if(r < get_u16(&reply.length)) {
					gp_log (GP_LOG_ERROR, "topfield", "ERROR: Short packet %d instead of %d\n", r, get_u16(&reply.length));
					/* TODO: Fetch the rest of the packet */
				}

				w = gp_file_append (file, (char*)&reply.data[8], dataLen);

				if(w < GP_OK) {
					/* Can't write data - abort transfer */
					gp_log (GP_LOG_ERROR, "topfield", "ERROR: Can not write data: %d\n", w);
					send_cancel(camera,context);
					state = ABORT;
				}
			} else {
				gp_log (GP_LOG_ERROR, "topfield", "ERROR: Unexpected DATA_HDD_FILE_DATA packet in state %d\n", state);
				send_cancel(camera,context);
				state = ABORT;
			}
			break;

		case DATA_HDD_FILE_END:
			send_success(camera,context);
			result = GP_OK;
			goto out;
			break;

		case FAIL:
			gp_log (GP_LOG_ERROR, "topfield", "ERROR: Device reports %s\n", decode_error(&reply));
			send_cancel(camera,context);
			state = ABORT;
			break;

		case SUCCESS:
			goto out;
			break;

		default:
			gp_log (GP_LOG_ERROR, "topfield", "ERROR: Unhandled packet (cmd 0x%x)\n", get_u32(&reply.cmd));
			break;
		}
	}
	if (pid) gp_context_progress_stop (context, pid);
out:
	do_cmd_turbo (camera, "OFF", context);
	return result;
}
Beispiel #5
0
int do_hdd_file_get(int fd, char *srcPath, char *dstPath)
{
    int result = -EPROTO;
    time_t startTime = time(NULL);
    enum
    {
        START,
        DATA,
        ABORT
    } state;
    int dst = -1;
    int r;
    int update = 0;
    __u64 byteCount = 0;
    struct utimbuf mod_utime_buf = { 0, 0 };

    dst = open64(dstPath, O_WRONLY | O_CREAT | O_TRUNC,
                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    if(dst < 0)
    {
        fprintf(stderr, "ERROR: Can not open destination file: %s\n",
                strerror(errno));
        return errno;
    }

    r = send_cmd_hdd_file_send(fd, GET, srcPath);
    if(r < 0)
    {
        goto out;
    }

    state = START;
    while(0 < (r = get_tf_packet(fd, &reply)))
    {
        update = (update + 1) % 16;
        switch (get_u32(&reply.cmd))
        {
            case DATA_HDD_FILE_START:
                if(state == START)
                {
                    struct typefile *tf = (struct typefile *) reply.data;

                    byteCount = get_u64(&tf->size);
                    mod_utime_buf.actime = mod_utime_buf.modtime =
                        tfdt_to_time(&tf->stamp);

                    send_success(fd);
                    state = DATA;
                }
                else
                {
                    fprintf(stderr,
                            "ERROR: Unexpected DATA_HDD_FILE_START packet in state %d\n",
                            state);
                    send_cancel(fd);
                    state = ABORT;
                }
                break;

            case DATA_HDD_FILE_DATA:
                if(state == DATA)
                {
                    __u64 offset = get_u64(reply.data);
                    __u16 dataLen =
                        get_u16(&reply.length) - (PACKET_HEAD_SIZE + 8);
                    ssize_t w;

                    if(!update && !quiet)
                    {
                        progressStats(byteCount, offset + dataLen, startTime);
                    }

                    if(r < get_u16(&reply.length))
                    {
                        fprintf(stderr,
                                "ERROR: Short packet %d instead of %d\n", r,
                                get_u16(&reply.length));
                        /* TODO: Fetch the rest of the packet */
                    }

                    w = write(dst, &reply.data[8], dataLen);
                    if(w < dataLen)
                    {
                        /* Can't write data - abort transfer */
                        fprintf(stderr, "ERROR: Can not write data: %s\n",
                                strerror(errno));
                        send_cancel(fd);
                        state = ABORT;
                    }
                }
                else
                {
                    fprintf(stderr,
                            "ERROR: Unexpected DATA_HDD_FILE_DATA packet in state %d\n",
                            state);
                    send_cancel(fd);
                    state = ABORT;
                }
                break;

            case DATA_HDD_FILE_END:
                send_success(fd);
                result = 0;
                goto out;
                break;

            case FAIL:
                fprintf(stderr, "ERROR: Device reports %s\n",
                        decode_error(&reply));
                send_cancel(fd);
                state = ABORT;
                break;

            case SUCCESS:
                goto out;
                break;

            default:
                fprintf(stderr, "ERROR: Unhandled packet (cmd 0x%x)\n",
                        get_u32(&reply.cmd));
        }
    }
    utime(dstPath, &mod_utime_buf);
    finalStats(byteCount, startTime);

  out:
    close(dst);
    return result;
}