/*
 * Copyright (c) 2003, 2004 Nokia
 * Author: tsavola@movial.fi
 *
 * This program is licensed under GPL (see COPYING for details)
 */

#ifndef PROTOCOL_H
#define PROTOCOL_H

#include "common.h"
#include "mount.h"

#include <stdint.h>
#include <pty.h>

#define PROTOCOL_VERSION     7

#define INTERNAL_ERROR_CODE  32767

typedef struct {
	uint32_t len;
	uint16_t *vec;
} uint16v_t;

uint16v_t *uint16v_alloc(uint32_t len);
void uint16v_free(uint16v_t *);

ssize_t write_ni(int fd, void *buf, size_t len);
ssize_t read_ni(int fd, void *buf, size_t len);

int write_buf(int fd, void *buf, size_t len);
int read_buf(int fd, void *buf, size_t len);

int write_uint16(int fd, uint16_t);
int read_uint16(int fd, uint16_t *);

int write_uint32(int fd, uint32_t);
int read_uint32(int fd, uint32_t *);

int write_uint64(int fd, uint64_t);
int read_uint64(int fd, uint64_t *);

int write_uint16v(int fd, uint16v_t *);
uint16v_t *read_uint16v(int fd);

int write_str(int fd, const char *);
char *read_str(int fd);

int write_strv(int fd, char **);
char **read_strv(int fd);

int write_mount(int fd, const mount_info_t *);
mount_info_t *read_mount(int fd);

int write_mountv(int fd, mount_info_t **);
mount_info_t **read_mountv(int fd);

int write_winsize(int fd, const struct winsize *);
struct winsize *read_winsize(int fd);

typedef enum {
	PTYPE_VERSION   = 0x0b,

	PTYPE_MESSAGE   = 0x10,  /* Daemon */
	PTYPE_ERROR     = 0x11,  /* Daemon */

	PTYPE_USER      = 0x22,  /* Client */
	PTYPE_AUTH      = 0x23,  /* Daemon */
	PTYPE_RC        = 0x24,  /* Daemon */

	PTYPE_COMMAND   = 0x30,  /* Client */
	PTYPE_MOUNT     = 0x31,  /* Client */
	PTYPE_UMOUNT    = 0x32,  /* Client */

	PTYPE_TARGET    = 0x41,  /* Client */
	PTYPE_MOUNTS    = 0x42,  /* Client */

	PTYPE_ARGS      = 0x50,  /* Client */
	PTYPE_CWD       = 0x51,  /* Client */
	PTYPE_ENVIRON   = 0x52,  /* Client */
	PTYPE_IDS       = 0x53,  /* Client */
	PTYPE_UMASK     = 0x54,  /* Client */
	PTYPE_WINSIZE   = 0x55,  /* Client */

	PTYPE_IN_REQ    = 0x60,  /* Daemon */
	PTYPE_IN_DATA   = 0x61,  /* Client */
	PTYPE_OUT_REQ   = 0x62,  /* Client */
	PTYPE_OUT_DATA  = 0x63,  /* Daemon */
	PTYPE_ERR_REQ   = 0x64,  /* Client */
	PTYPE_ERR_DATA  = 0x65,  /* Daemon */
} ptype_t;

int write_enum(int fd, int);
int read_enum(int fd);

int write_buf_packet(int fd, ptype_t, size_t size, void *);
int write_str_packet(int fd, ptype_t, const char *);
int write_uint16_packet(int fd, ptype_t, uint16_t);

int send_version(int fd);
int get_version(int fd);

#endif
