tools: Add O_CLOEXEC to open()
[framework/connectivity/connman.git] / tools / alg-test.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <sys/stat.h>
31 #include <sys/sendfile.h>
32 #include <sys/socket.h>
33 #include <linux/if_alg.h>
34
35 static void build_hash(int sk, int fd, size_t size, const char *pathname)
36 {
37         unsigned char hash[20];
38         ssize_t written, length;
39         int i;
40
41         written = sendfile(sk, fd, NULL, size);
42         if (written < 0)
43                 perror("Failed to write data");
44
45         printf("send %zd bytes\n", written);
46
47         length = recv(sk, hash, sizeof(hash), 0);
48         if (length < 0)
49                 perror("Failed to read data");
50
51         printf("recv %zd bytes\n", length);
52
53         for (i = 0; i < length; i++)
54                 printf("%02x", hash[i]);
55         printf("  %s\n", pathname);
56 }
57
58 static int create_hash(int sk, const char *pathname)
59 {
60         struct stat st;
61         int fd;
62
63         fd = open(pathname, O_RDONLY | O_CLOEXEC);
64         if (fd < 0)
65                 return -1;
66
67         if (fstat(fd, &st) < 0) {
68                 close(fd);
69                 return -1;
70         }
71
72         build_hash(sk, fd, st.st_size, pathname);
73
74         close(fd);
75
76         return 0;
77 }
78
79 static int create_socket(void)
80 {
81         struct sockaddr_alg salg = {
82                 .salg_family = AF_ALG,
83                 .salg_type = "hash",
84                 .salg_name = "sha1",
85         };
86         int sk, nsk;
87
88         sk = socket(PF_ALG, SOCK_SEQPACKET, 0);
89         if (sk < 0) {
90                 perror("Failed to create socket");
91                 return -1;
92         }
93
94         if (bind(sk, (struct sockaddr *) &salg, sizeof(salg)) < 0) {
95                 perror("Failed to bind socket");
96                 close(sk);
97                 return -1;
98         }
99
100         nsk = accept(sk, NULL, 0);
101         if (nsk < 0) {
102                 perror("Failed to accept socket");
103                 close(sk);
104                 return -1;
105         }
106
107         close(sk);
108
109         return nsk;
110 }
111
112 int main(int argc, char *argv[])
113 {
114         int sk;
115
116         if (argc < 2) {
117                 fprintf(stderr, "Missing argument\n");
118                 return 1;
119         }
120
121         sk = create_socket();
122         if (sk < 0)
123                 return 1;
124
125         create_hash(sk, argv[1]);
126
127         close(sk);
128
129         return 0;
130 }