Пример #1
0
spc_mach_message_t* spc_serialize(spc_message_t* msg)
{
    spc_mach_message_t* mach_msg;

    size_t actual_size, content_size, initial_size = msg->content->num_items * 32;      // heuristic

    writer_t writer;
    writer.start = malloc(initial_size);
    writer.end = writer.start + initial_size;
    writer.ptr = writer.start;
    writer.ports = NULL;
    writer.num_ports = 0;

    spc_write(&writer, last_header, 8);
    spc_write_uint32(&writer, SPC_TYPE_DICT);
    spc_write_dict(&writer, msg->content);

    content_size = writer.ptr - writer.start;
    char* ptr;

    if (writer.num_ports != 0) {
        // Must create a complex messge
        actual_size = sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t) + writer.num_ports * sizeof(mach_msg_port_descriptor_t) + content_size;
        mach_msg = malloc(actual_size);
        mach_msg->header.msgh_bits = MACH_MSGH_BITS_COMPLEX;

        ptr = (char*)mach_msg + sizeof(mach_msg_header_t);
        mach_msg_body_t* body = (mach_msg_body_t*)ptr;
        body->msgh_descriptor_count = writer.num_ports;
        ptr += sizeof(mach_msg_body_t);

        for (size_t i = 0; i < writer.num_ports; i++) {
            mach_msg_port_descriptor_t* descriptor = (mach_msg_port_descriptor_t*)ptr;
            descriptor->type = MACH_MSG_PORT_DESCRIPTOR;
            descriptor->name = writer.ports[i].name;
            descriptor->disposition = writer.ports[i].type;
            ptr += sizeof(mach_msg_port_descriptor_t);
        }
    } else {
        actual_size = sizeof(mach_msg_header_t) + content_size;
        mach_msg = malloc(actual_size);
        mach_msg->header.msgh_bits = 0;
        ptr = (char*)mach_msg->buf;
    }

    // Fill in the mach message
    mach_msg->header.msgh_remote_port = msg->remote_port.name;
    mach_msg->header.msgh_local_port  = msg->local_port.name;
    mach_msg->header.msgh_id          = msg->id;
    mach_msg->header.msgh_size        = actual_size;
    mach_msg->header.msgh_bits       |= MACH_MSGH_BITS(msg->remote_port.type, msg->local_port.type);
    memcpy(ptr, writer.start, content_size);

    free(writer.start);

    return mach_msg;
}
Пример #2
0
size_t spc_serialize_value(writer_t* writer, spc_value_t value)
{
    size_t bytes_written = 0;
    bytes_written += spc_write_uint32(writer, value.type);
    switch (value.type) {
        case SPC_TYPE_NULL:
            break;
        case SPC_TYPE_BOOL:
            bytes_written += spc_write_uint32(writer, value.value.u64);
            break;
        case SPC_TYPE_UINT64:
            bytes_written += spc_write_uint64(writer, value.value.u64);
            break;
        case SPC_TYPE_INT64:
            bytes_written += spc_write_int64(writer, value.value.i64);
            break;
        case SPC_TYPE_DOUBLE:
            bytes_written += spc_write_double(writer, value.value.dbl);
            break;
        case SPC_TYPE_STRING:
            bytes_written += spc_write_uint32(writer, strlen(value.value.str) + 1);
            bytes_written += spc_write_str(writer, value.value.str);
            break;
        case SPC_TYPE_ARRAY:
            bytes_written += spc_write_array(writer, value.value.array);
            break;
        case SPC_TYPE_DICT:
            bytes_written += spc_write_dict(writer, value.value.dict);
            break;
        case SPC_TYPE_FD:
        case SPC_TYPE_SEND_PORT:
        case SPC_TYPE_RECV_PORT:
            spc_write_port(writer, value.value.port);
            break;
        case SPC_TYPE_UUID:
            bytes_written += spc_write(writer, value.value.ptr, 0x10);
            break;
        case SPC_TYPE_DATA:
            bytes_written += spc_write_uint32(writer, value.value.data.size);
            bytes_written += spc_write_padded(writer, value.value.data.ptr, value.value.data.size);
            break;
        default:
            printf("Unsupported value type: 0x%x\n", value.type);
    }

    return bytes_written;
}
Пример #3
0
int
main(int argc, char **argv)
{
	int i, n, off;
	int c;
	char *addr;
	char *path;
	Spuser *user;
	Spcfsys *fs;
	Spcfid *fid;
	char buf[512];

	user = sp_unix_users->uid2user(sp_unix_users, geteuid());
	while ((c = getopt(argc, argv, "dp:")) != -1) {
		switch (c) {
		case 'd':
			spc_chatty = 1;
			break;

		case 'u':
			user = sp_unix_users->uname2user(sp_unix_users, optarg);
			break;

		default:
			usage();
		}
	}
	
	if (!user) {
		fprintf(stderr, "cannot retrieve user %d\n", geteuid());
		exit(1);
	}

	if (argc - optind < 2)
		usage();

	addr = argv[optind];
	path = argv[optind+1];

	fs = spc_netmount(addr, user, 564, NULL, NULL);
	fid = spc_open(fs, path, Owrite);
	if (!fid) {
		fid = spc_create(fs, path, 0666, Owrite);
		if (!fid) {
			fprintf(stderr, "error creating\n");
			exit(1);
		}
	}

	off = 0;
	while ((n = read(0, buf, sizeof(buf))) > 0) {
		i = spc_write(fid, (u8*) buf, n, off);
		if (i != n) {
			fprintf(stderr, "error writing\n");
			exit(1);
		}

		off += n;
	}
			
	spc_close(fid);
	spc_umount(fs);

	exit(0);
}