-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhelpers.c
More file actions
206 lines (171 loc) · 5.56 KB
/
helpers.c
File metadata and controls
206 lines (171 loc) · 5.56 KB
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
/*
* Copyright (c) 2016-2018. Uniquid Inc. or its affiliates. All Rights Reserved.
*
* License is in the "LICENSE" file accompanying this file.
* See the License for the specific language governing permissions and limitations under the License.
*/
/*
* @file helpers.c
*
* @date 27/lug/2016
* @author M. Palumbi
*/
/**
* @file helpers.h
*
* some usefull funtions
*
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <time.h>
#include "helpers.h"
char *program_name;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// error � print a diagnostic and optionally exit
void error( int status, int err, char *fmt, ... )
{
va_list ap;
va_start( ap, fmt );
fprintf( stderr, "%d:%s: ", getpid(), program_name );
vfprintf( stderr, fmt, ap );
va_end( ap );
if ( err )
fprintf( stderr, ": %s (%d)\n", strerror( err ), err );
if ( status )
exit( status );
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Read characters from 'fd' until a newline is encountered. If a newline
// character is not encountered in the first (n - 1) bytes, then the excess
// characters are discarded. The returned string placed in 'buf' is
// null-terminated and includes the newline character if it was read in the
// first (n - 1) bytes. The function return value is the number of bytes
// placed in buffer (which includes the newline character if encountered,
// but excludes the terminating null byte).
ssize_t readLine(int fd, void *buffer, size_t n)
{
ssize_t numRead; /* # of bytes fetched by last read() */
size_t totRead; /* Total bytes read so far */
char *buf;
char ch;
if (n <= 0 || buffer == NULL) {
errno = EINVAL;
return -1;
}
buf = buffer; /* No pointer arithmetic on "void *" */
totRead = 0;
for (;;) {
numRead = read(fd, &ch, 1);
if (numRead == -1) {
if (errno == EINTR) /* Interrupted --> restart read() */
continue;
else
return -1; /* Some other error */
} else if (numRead == 0) { /* EOF */
if (totRead == 0) /* No bytes read; return 0 */
return 0;
else /* Some bytes read; add '\0' */
break;
} else { /* 'numRead' must be 1 if we get here */
if (totRead < n - 1) { /* Discard > (n - 1) bytes */
totRead++;
*buf++ = ch;
}
if (ch == '\n')
break;
}
}
*buf = '\0';
return totRead;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ReadXBytes
// Read x bytes from a socket. Keep reading until
// all the data has been read from the socket.
// This assumes buffer is at least x bytes long,
// and that the socket is blocking.
ssize_t ReadXBytes(int socket, void* buffer, unsigned int x)
{
unsigned int bytesRead = 0;
int result;
while (bytesRead < x)
{
result = read(socket, (char *)buffer + bytesRead, x - bytesRead);
if (result < 1 )
{
if (errno == EINTR) /* Interrupted --> restart read() */
continue;
else
return -1; /* Some other error */
}
bytesRead += result;
}
return bytesRead;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// WriteXBytes
// Write a buffer full of data to a socket. Keep writing until
// all the data has been put into the socket.
// sock I the socket to write
// buffer I the buffer holding the data
// buflen I the length of the buffer in bytes
// Returns: status code indicating success - 0 = success
int WriteXBytes(const int sock, const char *const buffer, const size_t buflen)
{
size_t bytesWritten=0;
ssize_t writeResult;
int done=0;
do {
writeResult=send(sock,buffer+bytesWritten,buflen-bytesWritten,MSG_NOSIGNAL);
if(writeResult==-1) {
if(errno==EINTR)
writeResult=0;
else {
bytesWritten=-1;
done=1;
}
}
else {
bytesWritten+=writeResult;
//if(writeResult==0)
if(bytesWritten == buflen)
done=1;
}
} while(done==0);
return bytesWritten;
}
static uint8_t mac[6];
uint8_t *getSerial( void )
{
// try to read serial.no
int uniq = open("serial.no", O_RDWR|O_CREAT, 0644);
if (read(uniq, mac, sizeof(mac)) != sizeof(mac)) // if we cant read userial.no generate one
{
int rnd = open("/dev/random", O_RDONLY);
if(read(rnd, mac, sizeof(mac)) <= 0) // if we cant read /dev/random use time for seed
*(int32_t *)mac = time(NULL);
close(rnd);
write(uniq, mac, sizeof(mac));
}
close(uniq);
return mac;
}
FILE *logfile = NULL;
void LOG_print( char *fmt, ... )
{
va_list ap;
if (logfile == NULL) logfile = fopen("access.log", "a");
va_start( ap, fmt );
fprintf( logfile, "%ld: ", time(NULL) );
vfprintf( logfile, fmt, ap );
va_end( ap );
fflush(logfile);
}