nutcracker 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/README.md +22 -0
  2. data/Rakefile +55 -0
  3. data/bin/nutcracker +2 -0
  4. data/ext/nutcracker/ChangeLog +66 -0
  5. data/ext/nutcracker/LICENSE +177 -0
  6. data/ext/nutcracker/Makefile.am +7 -0
  7. data/ext/nutcracker/Makefile.in +726 -0
  8. data/ext/nutcracker/NOTICE +124 -0
  9. data/ext/nutcracker/README.md +240 -0
  10. data/ext/nutcracker/aclocal.m4 +956 -0
  11. data/ext/nutcracker/conf/nutcracker.leaf.yml +10 -0
  12. data/ext/nutcracker/conf/nutcracker.root.yml +8 -0
  13. data/ext/nutcracker/conf/nutcracker.yml +67 -0
  14. data/ext/nutcracker/config.h.in +316 -0
  15. data/ext/nutcracker/config/config.guess +1561 -0
  16. data/ext/nutcracker/config/config.sub +1686 -0
  17. data/ext/nutcracker/config/depcomp +630 -0
  18. data/ext/nutcracker/config/install-sh +520 -0
  19. data/ext/nutcracker/config/ltmain.sh +8413 -0
  20. data/ext/nutcracker/config/missing +376 -0
  21. data/ext/nutcracker/configure +18862 -0
  22. data/ext/nutcracker/configure.ac +155 -0
  23. data/ext/nutcracker/contrib/Makefile.am +3 -0
  24. data/ext/nutcracker/contrib/Makefile.in +560 -0
  25. data/ext/nutcracker/contrib/yaml-0.1.4.tar.gz +0 -0
  26. data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
  27. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
  28. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +736 -0
  29. data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
  30. data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +956 -0
  31. data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +80 -0
  32. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1561 -0
  33. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1686 -0
  34. data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +630 -0
  35. data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +520 -0
  36. data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +8406 -0
  37. data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +376 -0
  38. data/ext/nutcracker/contrib/yaml-0.1.4/configure +13085 -0
  39. data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
  40. data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
  41. data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
  42. data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +7357 -0
  43. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +368 -0
  44. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +123 -0
  45. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
  46. data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +92 -0
  47. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
  48. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +484 -0
  49. data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
  50. data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
  51. data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
  52. data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
  53. data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
  54. data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
  55. data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
  56. data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
  57. data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
  58. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
  59. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +675 -0
  60. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
  61. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
  62. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
  63. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
  64. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
  65. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
  66. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
  67. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
  68. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
  69. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
  70. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
  71. data/ext/nutcracker/extconf.rb +5 -0
  72. data/ext/nutcracker/m4/libtool.m4 +7376 -0
  73. data/ext/nutcracker/m4/ltoptions.m4 +368 -0
  74. data/ext/nutcracker/m4/ltsugar.m4 +123 -0
  75. data/ext/nutcracker/m4/ltversion.m4 +23 -0
  76. data/ext/nutcracker/m4/lt~obsolete.m4 +92 -0
  77. data/ext/nutcracker/notes/c-styleguide.txt +425 -0
  78. data/ext/nutcracker/notes/debug.txt +96 -0
  79. data/ext/nutcracker/notes/memcache.txt +123 -0
  80. data/ext/nutcracker/notes/recommendation.md +118 -0
  81. data/ext/nutcracker/notes/redis.md +415 -0
  82. data/ext/nutcracker/notes/socket.txt +131 -0
  83. data/ext/nutcracker/scripts/multi_get.sh +26 -0
  84. data/ext/nutcracker/scripts/nutcracker.init +73 -0
  85. data/ext/nutcracker/scripts/nutcracker.spec +52 -0
  86. data/ext/nutcracker/scripts/pipelined_read.sh +23 -0
  87. data/ext/nutcracker/scripts/pipelined_write.sh +29 -0
  88. data/ext/nutcracker/scripts/populate_memcached.sh +24 -0
  89. data/ext/nutcracker/scripts/redis-check.py +23 -0
  90. data/ext/nutcracker/scripts/redis-check.sh +564 -0
  91. data/ext/nutcracker/src/Makefile.am +46 -0
  92. data/ext/nutcracker/src/Makefile.in +726 -0
  93. data/ext/nutcracker/src/hashkit/Makefile.am +22 -0
  94. data/ext/nutcracker/src/hashkit/Makefile.in +501 -0
  95. data/ext/nutcracker/src/hashkit/nc_crc32.c +105 -0
  96. data/ext/nutcracker/src/hashkit/nc_fnv.c +82 -0
  97. data/ext/nutcracker/src/hashkit/nc_hashkit.h +74 -0
  98. data/ext/nutcracker/src/hashkit/nc_hsieh.c +93 -0
  99. data/ext/nutcracker/src/hashkit/nc_jenkins.c +230 -0
  100. data/ext/nutcracker/src/hashkit/nc_ketama.c +240 -0
  101. data/ext/nutcracker/src/hashkit/nc_md5.c +379 -0
  102. data/ext/nutcracker/src/hashkit/nc_modula.c +144 -0
  103. data/ext/nutcracker/src/hashkit/nc_murmur.c +99 -0
  104. data/ext/nutcracker/src/hashkit/nc_one_at_a_time.c +51 -0
  105. data/ext/nutcracker/src/hashkit/nc_random.c +146 -0
  106. data/ext/nutcracker/src/nc.c +573 -0
  107. data/ext/nutcracker/src/nc_array.c +204 -0
  108. data/ext/nutcracker/src/nc_array.h +73 -0
  109. data/ext/nutcracker/src/nc_client.c +189 -0
  110. data/ext/nutcracker/src/nc_client.h +28 -0
  111. data/ext/nutcracker/src/nc_conf.c +1766 -0
  112. data/ext/nutcracker/src/nc_conf.h +134 -0
  113. data/ext/nutcracker/src/nc_connection.c +392 -0
  114. data/ext/nutcracker/src/nc_connection.h +99 -0
  115. data/ext/nutcracker/src/nc_core.c +334 -0
  116. data/ext/nutcracker/src/nc_core.h +131 -0
  117. data/ext/nutcracker/src/nc_event.c +214 -0
  118. data/ext/nutcracker/src/nc_event.h +39 -0
  119. data/ext/nutcracker/src/nc_log.c +254 -0
  120. data/ext/nutcracker/src/nc_log.h +120 -0
  121. data/ext/nutcracker/src/nc_mbuf.c +285 -0
  122. data/ext/nutcracker/src/nc_mbuf.h +67 -0
  123. data/ext/nutcracker/src/nc_message.c +828 -0
  124. data/ext/nutcracker/src/nc_message.h +253 -0
  125. data/ext/nutcracker/src/nc_proxy.c +359 -0
  126. data/ext/nutcracker/src/nc_proxy.h +34 -0
  127. data/ext/nutcracker/src/nc_queue.h +788 -0
  128. data/ext/nutcracker/src/nc_rbtree.c +348 -0
  129. data/ext/nutcracker/src/nc_rbtree.h +47 -0
  130. data/ext/nutcracker/src/nc_request.c +588 -0
  131. data/ext/nutcracker/src/nc_response.c +332 -0
  132. data/ext/nutcracker/src/nc_server.c +841 -0
  133. data/ext/nutcracker/src/nc_server.h +143 -0
  134. data/ext/nutcracker/src/nc_signal.c +131 -0
  135. data/ext/nutcracker/src/nc_signal.h +34 -0
  136. data/ext/nutcracker/src/nc_stats.c +1188 -0
  137. data/ext/nutcracker/src/nc_stats.h +206 -0
  138. data/ext/nutcracker/src/nc_string.c +109 -0
  139. data/ext/nutcracker/src/nc_string.h +112 -0
  140. data/ext/nutcracker/src/nc_util.c +619 -0
  141. data/ext/nutcracker/src/nc_util.h +214 -0
  142. data/ext/nutcracker/src/proto/Makefile.am +14 -0
  143. data/ext/nutcracker/src/proto/Makefile.in +482 -0
  144. data/ext/nutcracker/src/proto/nc_memcache.c +1306 -0
  145. data/ext/nutcracker/src/proto/nc_proto.h +155 -0
  146. data/ext/nutcracker/src/proto/nc_redis.c +2102 -0
  147. data/lib/nutcracker.rb +7 -0
  148. data/lib/nutcracker/version.rb +3 -0
  149. metadata +194 -0
@@ -0,0 +1,214 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include <unistd.h>
19
+ #include <sys/epoll.h>
20
+
21
+ #include <nc_core.h>
22
+ #include <nc_event.h>
23
+
24
+ int
25
+ event_init(struct context *ctx, int size)
26
+ {
27
+ int status, ep;
28
+ struct epoll_event *event;
29
+
30
+ ASSERT(ctx->ep < 0);
31
+ ASSERT(ctx->nevent != 0);
32
+ ASSERT(ctx->event == NULL);
33
+
34
+ ep = epoll_create(size);
35
+ if (ep < 0) {
36
+ log_error("epoll create of size %d failed: %s", size, strerror(errno));
37
+ return -1;
38
+ }
39
+
40
+ event = nc_calloc(ctx->nevent, sizeof(*ctx->event));
41
+ if (event == NULL) {
42
+ status = close(ep);
43
+ if (status < 0) {
44
+ log_error("close e %d failed, ignored: %s", ep, strerror(errno));
45
+ }
46
+ return -1;
47
+ }
48
+
49
+ ctx->ep = ep;
50
+ ctx->event = event;
51
+
52
+ log_debug(LOG_INFO, "e %d with nevent %d timeout %d", ctx->ep,
53
+ ctx->nevent, ctx->timeout);
54
+
55
+ return 0;
56
+ }
57
+
58
+ void
59
+ event_deinit(struct context *ctx)
60
+ {
61
+ int status;
62
+
63
+ ASSERT(ctx->ep >= 0);
64
+
65
+ nc_free(ctx->event);
66
+
67
+ status = close(ctx->ep);
68
+ if (status < 0) {
69
+ log_error("close e %d failed, ignored: %s", ctx->ep, strerror(errno));
70
+ }
71
+ ctx->ep = -1;
72
+ }
73
+
74
+ int
75
+ event_add_out(int ep, struct conn *c)
76
+ {
77
+ int status;
78
+ struct epoll_event event;
79
+
80
+ ASSERT(ep > 0);
81
+ ASSERT(c != NULL);
82
+ ASSERT(c->sd > 0);
83
+ ASSERT(c->recv_active);
84
+
85
+ if (c->send_active) {
86
+ return 0;
87
+ }
88
+
89
+ event.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
90
+ event.data.ptr = c;
91
+
92
+ status = epoll_ctl(ep, EPOLL_CTL_MOD, c->sd, &event);
93
+ if (status < 0) {
94
+ log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
95
+ strerror(errno));
96
+ } else {
97
+ c->send_active = 1;
98
+ }
99
+
100
+ return status;
101
+ }
102
+
103
+ int
104
+ event_del_out(int ep, struct conn *c)
105
+ {
106
+ int status;
107
+ struct epoll_event event;
108
+
109
+ ASSERT(ep > 0);
110
+ ASSERT(c != NULL);
111
+ ASSERT(c->sd > 0);
112
+ ASSERT(c->recv_active);
113
+
114
+ if (!c->send_active) {
115
+ return 0;
116
+ }
117
+
118
+ event.events = (uint32_t)(EPOLLIN | EPOLLET);
119
+ event.data.ptr = c;
120
+
121
+ status = epoll_ctl(ep, EPOLL_CTL_MOD, c->sd, &event);
122
+ if (status < 0) {
123
+ log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
124
+ strerror(errno));
125
+ } else {
126
+ c->send_active = 0;
127
+ }
128
+
129
+ return status;
130
+ }
131
+
132
+ int
133
+ event_add_conn(int ep, struct conn *c)
134
+ {
135
+ int status;
136
+ struct epoll_event event;
137
+
138
+ ASSERT(ep > 0);
139
+ ASSERT(c != NULL);
140
+ ASSERT(c->sd > 0);
141
+
142
+ event.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
143
+ event.data.ptr = c;
144
+
145
+ status = epoll_ctl(ep, EPOLL_CTL_ADD, c->sd, &event);
146
+ if (status < 0) {
147
+ log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
148
+ strerror(errno));
149
+ } else {
150
+ c->send_active = 1;
151
+ c->recv_active = 1;
152
+ }
153
+
154
+ return status;
155
+ }
156
+
157
+ int
158
+ event_del_conn(int ep, struct conn *c)
159
+ {
160
+ int status;
161
+
162
+ ASSERT(ep > 0);
163
+ ASSERT(c != NULL);
164
+ ASSERT(c->sd > 0);
165
+
166
+ status = epoll_ctl(ep, EPOLL_CTL_DEL, c->sd, NULL);
167
+ if (status < 0) {
168
+ log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
169
+ strerror(errno));
170
+ } else {
171
+ c->recv_active = 0;
172
+ c->send_active = 0;
173
+ }
174
+
175
+ return status;
176
+ }
177
+
178
+ int
179
+ event_wait(int ep, struct epoll_event *event, int nevent, int timeout)
180
+ {
181
+ int nsd;
182
+
183
+ ASSERT(ep > 0);
184
+ ASSERT(event != NULL);
185
+ ASSERT(nevent > 0);
186
+
187
+ for (;;) {
188
+ nsd = epoll_wait(ep, event, nevent, timeout);
189
+ if (nsd > 0) {
190
+ return nsd;
191
+ }
192
+
193
+ if (nsd == 0) {
194
+ if (timeout == -1) {
195
+ log_error("epoll wait on e %d with %d events and %d timeout "
196
+ "returned no events", ep, nevent, timeout);
197
+ return -1;
198
+ }
199
+
200
+ return 0;
201
+ }
202
+
203
+ if (errno == EINTR) {
204
+ continue;
205
+ }
206
+
207
+ log_error("epoll wait on e %d with %d events failed: %s", ep, nevent,
208
+ strerror(errno));
209
+
210
+ return -1;
211
+ }
212
+
213
+ NOT_REACHED();
214
+ }
@@ -0,0 +1,39 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #ifndef _NC_EVENT_H_
19
+ #define _NC_EVENT_H_
20
+
21
+ #include <nc_core.h>
22
+
23
+ /*
24
+ * A hint to the kernel that is used to size the event backing store
25
+ * of a given epoll instance
26
+ */
27
+ #define EVENT_SIZE_HINT 1024
28
+
29
+ int event_init(struct context *ctx, int size);
30
+ void event_deinit(struct context *ctx);
31
+
32
+ int event_add_out(int ep, struct conn *c);
33
+ int event_del_out(int ep, struct conn *c);
34
+ int event_add_conn(int ep, struct conn *c);
35
+ int event_del_conn(int ep, struct conn *c);
36
+
37
+ int event_wait(int ep, struct epoll_event *event, int nevent, int timeout);
38
+
39
+ #endif
@@ -0,0 +1,254 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include <stdlib.h>
19
+ #include <stdarg.h>
20
+ #include <ctype.h>
21
+ #include <time.h>
22
+ #include <sys/stat.h>
23
+ #include <fcntl.h>
24
+
25
+ #include <nc_core.h>
26
+
27
+ static struct logger logger;
28
+
29
+ int
30
+ log_init(int level, char *name)
31
+ {
32
+ struct logger *l = &logger;
33
+
34
+ l->level = MAX(LOG_EMERG, MIN(level, LOG_PVERB));
35
+ l->name = name;
36
+ if (name == NULL || !strlen(name)) {
37
+ l->fd = STDERR_FILENO;
38
+ } else {
39
+ l->fd = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644);
40
+ if (l->fd < 0) {
41
+ log_stderr("opening log file '%s' failed: %s", name,
42
+ strerror(errno));
43
+ return -1;
44
+ }
45
+ }
46
+
47
+ return 0;
48
+ }
49
+
50
+ void
51
+ log_deinit(void)
52
+ {
53
+ struct logger *l = &logger;
54
+
55
+ if (l->fd < 0 || l->fd == STDERR_FILENO) {
56
+ return;
57
+ }
58
+
59
+ close(l->fd);
60
+ }
61
+
62
+ void
63
+ log_reopen(void)
64
+ {
65
+ struct logger *l = &logger;
66
+
67
+ if (l->fd != STDERR_FILENO) {
68
+ close(l->fd);
69
+ l->fd = open(l->name, O_WRONLY | O_APPEND | O_CREAT, 0644);
70
+ if (l->fd < 0) {
71
+ log_stderr("reopening log file '%s' failed, ignored: %s", l->name,
72
+ strerror(errno));
73
+ }
74
+ }
75
+ }
76
+
77
+ void
78
+ log_level_up(void)
79
+ {
80
+ struct logger *l = &logger;
81
+
82
+ if (l->level < LOG_PVERB) {
83
+ l->level++;
84
+ loga("up log level to %d", l->level);
85
+ }
86
+ }
87
+
88
+ void
89
+ log_level_down(void)
90
+ {
91
+ struct logger *l = &logger;
92
+
93
+ if (l->level > LOG_EMERG) {
94
+ l->level--;
95
+ loga("down log level to %d", l->level);
96
+ }
97
+ }
98
+
99
+ void
100
+ log_level_set(int level)
101
+ {
102
+ struct logger *l = &logger;
103
+
104
+ l->level = MAX(LOG_EMERG, MIN(level, LOG_PVERB));
105
+ loga("set log level to %d", l->level);
106
+ }
107
+
108
+ int
109
+ log_loggable(int level)
110
+ {
111
+ struct logger *l = &logger;
112
+
113
+ if (level > l->level) {
114
+ return 0;
115
+ }
116
+
117
+ return 1;
118
+ }
119
+
120
+ void
121
+ _log(const char *file, int line, int panic, const char *fmt, ...)
122
+ {
123
+ struct logger *l = &logger;
124
+ int len, size, errno_save;
125
+ char buf[LOG_MAX_LEN], *timestr;
126
+ va_list args;
127
+ struct tm *local;
128
+ time_t t;
129
+ ssize_t n;
130
+
131
+ if (l->fd < 0) {
132
+ return;
133
+ }
134
+
135
+ errno_save = errno;
136
+ len = 0; /* length of output buffer */
137
+ size = LOG_MAX_LEN; /* size of output buffer */
138
+
139
+ t = time(NULL);
140
+ local = localtime(&t);
141
+ timestr = asctime(local);
142
+
143
+ len += nc_scnprintf(buf + len, size - len, "[%.*s] %s:%d ",
144
+ strlen(timestr) - 1, timestr, file, line);
145
+
146
+ va_start(args, fmt);
147
+ len += nc_vscnprintf(buf + len, size - len, fmt, args);
148
+ va_end(args);
149
+
150
+ buf[len++] = '\n';
151
+
152
+ n = nc_write(l->fd, buf, len);
153
+ if (n < 0) {
154
+ l->nerror++;
155
+ }
156
+
157
+ errno = errno_save;
158
+
159
+ if (panic) {
160
+ abort();
161
+ }
162
+ }
163
+
164
+ void
165
+ _log_stderr(const char *fmt, ...)
166
+ {
167
+ struct logger *l = &logger;
168
+ int len, size, errno_save;
169
+ char buf[4 * LOG_MAX_LEN];
170
+ va_list args;
171
+ ssize_t n;
172
+
173
+ errno_save = errno;
174
+ len = 0; /* length of output buffer */
175
+ size = 4 * LOG_MAX_LEN; /* size of output buffer */
176
+
177
+ va_start(args, fmt);
178
+ len += nc_vscnprintf(buf, size, fmt, args);
179
+ va_end(args);
180
+
181
+ buf[len++] = '\n';
182
+
183
+ n = nc_write(STDERR_FILENO, buf, len);
184
+ if (n < 0) {
185
+ l->nerror++;
186
+ }
187
+
188
+ errno = errno_save;
189
+ }
190
+
191
+ /*
192
+ * Hexadecimal dump in the canonical hex + ascii display
193
+ * See -C option in man hexdump
194
+ */
195
+ void
196
+ _log_hexdump(const char *file, int line, char *data, int datalen,
197
+ const char *fmt, ...)
198
+ {
199
+ struct logger *l = &logger;
200
+ char buf[8 * LOG_MAX_LEN];
201
+ int i, off, len, size, errno_save;
202
+ ssize_t n;
203
+
204
+ if (l->fd < 0) {
205
+ return;
206
+ }
207
+
208
+ /* log hexdump */
209
+ errno_save = errno;
210
+ off = 0; /* data offset */
211
+ len = 0; /* length of output buffer */
212
+ size = 8 * LOG_MAX_LEN; /* size of output buffer */
213
+
214
+ while (datalen != 0 && (len < size - 1)) {
215
+ char *save, *str;
216
+ unsigned char c;
217
+ int savelen;
218
+
219
+ len += nc_scnprintf(buf + len, size - len, "%08x ", off);
220
+
221
+ save = data;
222
+ savelen = datalen;
223
+
224
+ for (i = 0; datalen != 0 && i < 16; data++, datalen--, i++) {
225
+ c = (unsigned char)(*data);
226
+ str = (i == 7) ? " " : " ";
227
+ len += nc_scnprintf(buf + len, size - len, "%02x%s", c, str);
228
+ }
229
+ for ( ; i < 16; i++) {
230
+ str = (i == 7) ? " " : " ";
231
+ len += nc_scnprintf(buf + len, size - len, " %s", str);
232
+ }
233
+
234
+ data = save;
235
+ datalen = savelen;
236
+
237
+ len += nc_scnprintf(buf + len, size - len, " |");
238
+
239
+ for (i = 0; datalen != 0 && i < 16; data++, datalen--, i++) {
240
+ c = (unsigned char)(isprint(*data) ? *data : '.');
241
+ len += nc_scnprintf(buf + len, size - len, "%c", c);
242
+ }
243
+ len += nc_scnprintf(buf + len, size - len, "|\n");
244
+
245
+ off += 16;
246
+ }
247
+
248
+ n = nc_write(l->fd, buf, len);
249
+ if (n < 0) {
250
+ l->nerror++;
251
+ }
252
+
253
+ errno = errno_save;
254
+ }