sock->sk = NULL;
p2pkp_destroy_udp_sock(ps->net_sock);
+ if (ps->file) {
+ p2pkp_close_file(ps->file);
+ ps->file = 0;
+ }
sock_put(sk);
DEBUG("Released the socket");
}
static int p2pkp_bind(struct socket *sock, struct sockaddr *myaddr,
- int sockaddr_len){return 0;}
+ int sockaddr_len)
+{
+ struct sock *sk = sock->sk;
+ struct p2pkp_sock *ps = sock2p2pkp(sk);
+ struct sockaddr_in *sin = (struct sockaddr_in *)myaddr;
+ int err = 0;
+
+ if (!sock || !myaddr || sockaddr_len != sizeof(struct sockaddr_in) ||
+ sin->sin_family != AF_INET) {
+ ERROR("invalid parameters for bind");
+ return -EINVAL;
+ }
+
+ lock_sock(sk);
+ err = ps->net_sock->ops->bind(ps->net_sock, myaddr, sockaddr_len);
+ if (err < 0) {
+ ERROR("can't bind socket");
+ }
+ release_sock(sk);
+ return err;
+}
static int p2pkp_connect(struct socket *sock, struct sockaddr *vaddr,
int sockaddr_len, int flags)
static int p2pkp_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len)
{
- int err = -ENXIO;
- int f_index, bytes_read;
+ int err = 0;
+ int f_index, bytes_read, files_no = 0;
struct sock *sk = sock->sk;
struct p2pkp_sock *ps = sock2p2pkp(sk);
struct sockaddr_in *sin = (struct sockaddr_in *)m->msg_name;
lock_sock(sk);
if (!(sock->state & SS_CONNECTED)) {
ERROR("unconnected socket");
- err = -ECONNREFUSED;
- goto release;
+ release_sock(sk);
+ return -ECONNREFUSED;
}
release_sock(sk);
/* check if the file exists */
for (f_index = 0; f_index < m->msg_iovlen; f_index++) {
+ err = 0;
file_name = (char *)m->msg_iov[f_index].iov_base;
file = p2pkp_open_file_read(file_name);
if (!file) {
ERROR("cannot open file %s\n", file_name);
+ err = -ENOENT;
continue;
}
+ ps->file = file;
DEBUG("opened file %s", file_name);
for (;;) {
bytes_read = p2pkp_read_from_file(file, ps->buffer, ps->buffer_len);
DEBUG("read %d bytes from file", bytes_read);
if (bytes_read < 0) {
ERROR("cannot read from file");
+ err = bytes_read;
goto out_close;
}
if (bytes_read == 0)
list_for_each(pos, &ps->conn_list) {
conn = list_entry(pos, struct p2pkp_conn_info, list);
- err = p2pkp_msgsend(ps->net_sock,
- &conn->sin, ps->buffer, ps->buffer_len);
+ err = p2pkp_msgsend(ps->net_sock, &conn->sin,
+ ps->buffer, bytes_read);
if (err < 0) {
ERROR("can't send first message");
goto out_conn;
}
}
+ files_no++;
out_conn:
release_sock(sk);
}
out_close:
p2pkp_close_file(file);
+ ps->file = 0;
}
-
DEBUG("Sending completed successfully");
- err = 0;
-release:
- release_sock(sk);
- return err;
+ return err ? err : files_no;
}
static int p2pkp_recvmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *m, size_t total_len, int flags){return 0;}
+ struct msghdr *m, size_t total_len, int flags)
+{
+ int err = -ENXIO;
+ int bytes_read, bytes_written = 0;
+ struct sock *sk = sock->sk;
+ struct p2pkp_sock *ps = sock2p2pkp(sk);
+ struct sockaddr_in *sin = (struct sockaddr_in *)m->msg_name;
+ struct file * file;
+ char *file_name = (char *)m->msg_iov[0].iov_base;
+ mode_t mode = P2PKP_DEFAULT_MODE;
+
+ /* first try to get some files */
+ if (!sock || !m || !file_name) {
+ ERROR("invalid socket parameters");
+ return -EINVAL;
+ }
+
+ file = p2pkp_open_file_write(file_name, mode);
+ if (!file) {
+ ERROR("cannot open file %s\n", file_name);
+ return -ENOENT;
+ }
+ ps->file = file;
+
+ lock_sock(sk);
+ /* TODO keep connections */
+ do {
+ bytes_read = p2pkp_msgrecv(ps->net_sock, sin, ps->buffer, ps->buffer_len);
+ if (bytes_read > 0) {
+ bytes_written += p2pkp_write_in_file(file, ps->buffer, bytes_read);
+ err = 0;
+ } else if (bytes_read != -ERESTARTSYS) {
+ ERROR("cannot read data: %d", bytes_read);
+ err = -ENXIO;
+ }
+ DEBUG("wrote %d", bytes_written);
+ } while (bytes_read < ps->buffer_len);
+
+ release_sock(sk);
+ p2pkp_close_file(file);
+ ps->file = 0;
+
+ return err ? err : bytes_written;
+}
static int p2pkp_create(struct net *net, struct socket *sock, int protocol,
sock_put(sk);
return err;
}
-
-