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