public
Created

sendfile

  • Download Gist
client.c
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sendfile.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
 
#ifndef _MAX_SIZE_
#define _MAX_SIZE_ 80
#endif /* _MAX_SIZE_ */
 
#ifndef _SERVER_PORT_
#define _SERVER_PORT_ 9734
#endif /* _SERVER_PORT_ */
 
int err_num = 0;
/* destination address */
struct sockaddr_in dest_addr;
 
void send_usrname_credentials(char *usrname, int sock_fd);
 
void send_password_credentials(char *password, int sock_fd);
 
/* send file to the server */
void deliver_mail(const char *filename, int sock_fd);
 
/* sendfile */
ssize_t do_sendfile(int sock_fd, int input_fd, off_t offset, size_t count);
 
int main(int argc, char **argv)
{
if (argc != 2)
{
(void)fprintf(stderr, "Usage: %s <username>\n", argv[0]);
exit(EXIT_FAILURE);
}
 
/* username */
char *username = argv[1];
/* password */
char *password = NULL;
 
int err_num;
 
/* socket fd */
int socket_fd;
int length;
int string_len;
int result;
/* create the socket for the client */
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
/* checking for "socket" errors */
if (socket_fd < 0)
{
err_num = errno;
(void)fprintf(stdout, "\"socket\" error: %s\n", strerror(err_num));
exit(EXIT_FAILURE);
}
/* Initialize the socket address structure */
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
dest_addr.sin_port = htons(_SERVER_PORT_);
length = sizeof(dest_addr);
/* connect the socket to the server's socket */
result = connect(socket_fd, (struct sockaddr *)&dest_addr, length);
/* checking for "connect" errors */
if (result < 0)
{
err_num = errno;
(void)fprintf(stderr, "\"connect\" error: %s\n", strerror(err_num));
close(socket_fd);
exit(EXIT_FAILURE);
}
(void)fprintf(stdout, "Connect completed\n");
deliver_mail("mail", socket_fd);
/* send the username to the server
send_usrname_credentials(username, socket_fd);
(void)fprintf(stdout, "Utente: %s\n", username);
*/
return 0;
}
 
/* send the username to the server */
void send_usrname_credentials(char *usrname, int sock_fd)
{
struct msghdr username_cred;
struct iovec iov;
 
username_cred.msg_name = &dest_addr;
username_cred.msg_namelen = sizeof(dest_addr);
username_cred.msg_iov = &iov;
username_cred.msg_iovlen = 1;
username_cred.msg_iov->iov_base = usrname;
username_cred.msg_iov->iov_len = (strlen(usrname) + 1);
username_cred.msg_control = 0;
username_cred.msg_controllen = 0;
username_cred.msg_flags = 0;
sendmsg(sock_fd, &username_cred, 0);
}
 
/* send the password to the server */
void send_password_credentials(char *password, int sock_fd)
{
struct msghdr password_cred;
struct iovec iov;
 
password_cred.msg_name = &dest_addr;
password_cred.msg_namelen = sizeof(dest_addr);
password_cred.msg_iov = &iov;
password_cred.msg_iovlen = 1;
password_cred.msg_iov->iov_base = password;
password_cred.msg_iov->iov_len = (strlen(password) + 1);
password_cred.msg_control = 0;
password_cred.msg_controllen = 0;
password_cred.msg_flags = 0;
sendmsg(sock_fd, &password_cred, 0);
}
 
/* send file to the server */
void deliver_mail(const char *filename, int sock_fd)
{
/* file descriptor for file to send */
int file_descriptor;
/* argument to fstat */
struct stat stat_buf;
/* file offset */
off_t offset = 0;
int ret_val;
size_t total_bytes_sent = 0;
/* open the file to be sent */
file_descriptor = open(filename, O_RDONLY);
/* checking for "open" errors */
if (file_descriptor < 0)
{ exit(EXIT_FAILURE); }
/* get the size of the file to be sent */
fstat(file_descriptor, &stat_buf);
offset = 0;
/* sendfile */
total_bytes_sent = do_sendfile(sock_fd, file_descriptor, offset, stat_buf.st_size);
(void)fprintf(stdout, "Total bytes sent: %d\n", total_bytes_sent);
 
close(file_descriptor);
}
 
/* sendfile */
ssize_t do_sendfile(int sock_fd, int input_fd, off_t offset, size_t count)
{
ssize_t bytes_sent;
size_t total_bytes_sent = 0;
while (total_bytes_sent < count)
{
if ((bytes_sent = sendfile(sock_fd, input_fd, &offset, (count - total_bytes_sent))) <= 0)
{
if (errno == EINTR || errno == EAGAIN)
{ continue; }
err_num = errno;
(void)fprintf(stderr, "\"sendfile\" error:%s\n", strerror(err_num));
return (-1);
}
total_bytes_sent += bytes_sent;
}
return (total_bytes_sent);
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.