nutcracker 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }