trema 0.2.5 → 0.2.6

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 (292) hide show
  1. data/.gitignore +1 -1
  2. data/Doxyfile +1 -1
  3. data/Gemfile +18 -6
  4. data/README.md +112 -5
  5. data/Rakefile +3 -1
  6. data/Rantfile +88 -1
  7. data/bin/trema +248 -0
  8. data/bin/trema-config +59 -0
  9. data/cruise.rb +1 -1
  10. data/features/example.dumper.feature +45 -65
  11. data/features/example.hello_trema.feature +21 -0
  12. data/features/example.learning_switch.feature +26 -28
  13. data/features/example.list_switches.feature +19 -33
  14. data/features/example.message.echo_reply.feature +10 -10
  15. data/features/example.message.echo_request.feature +2 -2
  16. data/features/example.message.features_request.feature +6 -5
  17. data/features/example.message.hello.feature +47 -13
  18. data/features/example.message.set_config.feature +4 -4
  19. data/features/example.message.vendor-action.feature +23 -0
  20. data/features/example.multi_learning_switch.feature +14 -42
  21. data/features/example.packet_in.feature +31 -0
  22. data/features/example.packetin_filter_config.feature +11 -7
  23. data/features/example.patch_panel.feature +29 -0
  24. data/features/example.repeater_hub.feature +43 -40
  25. data/features/example.switch_info.feature +51 -0
  26. data/features/example.switch_monitor.feature +24 -42
  27. data/features/packetin_filter.feature +28 -22
  28. data/features/step_definitions/misc_steps.rb +19 -8
  29. data/features/step_definitions/send_packets_steps.rb +1 -10
  30. data/features/step_definitions/stats_steps.rb +4 -4
  31. data/features/support/env.rb +2 -1
  32. data/features/support/hooks.rb +35 -2
  33. data/features/switch_manager.feature +18 -12
  34. data/features/trema-config.feature +26 -39
  35. data/features/trema.dump_flows.feature +26 -12
  36. data/features/trema.help.feature +26 -0
  37. data/features/trema.kill.feature +39 -41
  38. data/features/trema.killall.feature +23 -23
  39. data/features/trema.reset_stats.feature +50 -10
  40. data/features/trema.run.feature +28 -39
  41. data/features/trema.send_packets.feature +29 -40
  42. data/features/trema.show_stats.feature +30 -33
  43. data/features/trema.up.feature +33 -0
  44. data/features/trema.version.feature +9 -0
  45. data/ruby/extconf.rb +7 -0
  46. data/ruby/trema/aggregate-stats-reply.rb +3 -3
  47. data/ruby/trema/app.rb +5 -1
  48. data/ruby/trema/barrier-request.c +55 -30
  49. data/ruby/trema/cli.rb +8 -8
  50. data/ruby/trema/command.rb +1 -3
  51. data/ruby/trema/command/dump_flows.rb +5 -24
  52. data/ruby/trema/command/kill.rb +31 -36
  53. data/ruby/trema/command/killall.rb +1 -19
  54. data/{features/step_definitions/kill_steps.rb → ruby/trema/command/netns.rb} +13 -5
  55. data/ruby/trema/command/reset_stats.rb +3 -23
  56. data/ruby/trema/command/ruby.rb +2 -19
  57. data/ruby/trema/command/run.rb +6 -27
  58. data/ruby/trema/command/send_packets.rb +6 -90
  59. data/ruby/trema/command/show_stats.rb +21 -40
  60. data/ruby/trema/command/up.rb +5 -26
  61. data/ruby/trema/command/version.rb +1 -5
  62. data/ruby/trema/controller.c +14 -16
  63. data/ruby/trema/custom-switch.rb +56 -0
  64. data/ruby/trema/desc-stats-reply.rb +5 -5
  65. data/ruby/trema/dsl/configuration.rb +4 -0
  66. data/{features/step_definitions/up_steps.rb → ruby/trema/dsl/custom-switch.rb} +18 -4
  67. data/ruby/trema/dsl/netns.rb +78 -0
  68. data/ruby/trema/dsl/parser.rb +2 -0
  69. data/ruby/trema/dsl/runner.rb +8 -0
  70. data/ruby/trema/dsl/syntax.rb +18 -0
  71. data/ruby/trema/echo-reply.h +2 -2
  72. data/ruby/trema/echo-request.c +3 -5
  73. data/ruby/trema/enqueue.rb +2 -2
  74. data/ruby/trema/error.c +3 -3
  75. data/ruby/trema/executables.rb +26 -2
  76. data/ruby/trema/features-request.c +3 -5
  77. data/ruby/trema/flow-removed.c +6 -6
  78. data/ruby/trema/flow-stats-reply.rb +6 -8
  79. data/ruby/trema/flow.rb +12 -1
  80. data/ruby/trema/get-config-request.c +55 -28
  81. data/ruby/trema/hello.c +3 -5
  82. data/ruby/trema/host.rb +8 -0
  83. data/ruby/trema/list-switches-reply.c +1 -1
  84. data/ruby/trema/mac.rb +1 -1
  85. data/ruby/trema/match.c +15 -14
  86. data/ruby/trema/monkey-patch/module/deprecation.rb +0 -2
  87. data/ruby/trema/netns.rb +127 -0
  88. data/ruby/trema/ordered-hash.rb +5 -4
  89. data/ruby/trema/packet-in.c +136 -113
  90. data/ruby/trema/packet-queue.rb +9 -9
  91. data/ruby/trema/packetin-filter.rb +1 -1
  92. data/ruby/trema/phost.rb +16 -7
  93. data/ruby/trema/port-mod.c +6 -5
  94. data/ruby/trema/port-stats-reply.rb +2 -2
  95. data/ruby/trema/process.rb +29 -0
  96. data/ruby/trema/queue-stats-reply.rb +2 -4
  97. data/ruby/trema/send-out-port.rb +5 -3
  98. data/ruby/trema/set-eth-addr.rb +4 -0
  99. data/ruby/trema/set-ip-addr.rb +4 -2
  100. data/ruby/trema/set-ip-dst-addr.rb +2 -1
  101. data/ruby/trema/set-ip-src-addr.rb +2 -1
  102. data/ruby/trema/set-ip-tos.rb +3 -2
  103. data/ruby/trema/set-transport-port.rb +3 -2
  104. data/ruby/trema/set-vlan-priority.rb +3 -2
  105. data/ruby/trema/set-vlan-vid.rb +5 -4
  106. data/ruby/trema/shell/reset_stats.rb +2 -1
  107. data/ruby/trema/shell/run.rb +1 -1
  108. data/ruby/trema/shell/send_packets.rb +1 -1
  109. data/ruby/trema/shell/show_stats.rb +1 -1
  110. data/ruby/trema/stats-helper.rb +3 -3
  111. data/ruby/trema/stats-reply.c +26 -17
  112. data/ruby/trema/stats-request.c +39 -41
  113. data/ruby/trema/switch-daemon.rb +36 -31
  114. data/ruby/trema/switch.c +1 -1
  115. data/ruby/trema/table-stats-reply.rb +1 -1
  116. data/ruby/trema/timers.rb +13 -13
  117. data/ruby/trema/trema.c +3 -3
  118. data/ruby/trema/tremashark.rb +9 -2
  119. data/ruby/trema/util.rb +39 -15
  120. data/ruby/trema/vendor-action.rb +8 -3
  121. data/ruby/trema/vendor-stats-reply.rb +4 -6
  122. data/ruby/trema/vendor.c +1 -1
  123. data/ruby/trema/version.rb +1 -1
  124. data/spec/trema/barrier-request_spec.rb +47 -37
  125. data/spec/trema/controller_spec.rb +1 -0
  126. data/spec/trema/dsl/runner_spec.rb +8 -3
  127. data/spec/trema/dsl/vhost_spec.rb +8 -8
  128. data/spec/trema/echo-request_spec.rb +1 -0
  129. data/spec/trema/features-request_spec.rb +1 -0
  130. data/spec/trema/flow-removed_spec.rb +9 -9
  131. data/spec/trema/get-config-request_spec.rb +51 -39
  132. data/spec/trema/match_spec.rb +1 -1
  133. data/spec/trema/openflow-error_spec.rb +11 -11
  134. data/spec/trema/packet-out_spec.rb +5 -5
  135. data/spec/trema/queue-get-config-reply_spec.rb +1 -1
  136. data/spec/trema/queue-get-config-request_spec.rb +1 -1
  137. data/spec/trema/set-eth-dst-addr_spec.rb +1 -1
  138. data/spec/trema/set-eth-src-addr_spec.rb +1 -1
  139. data/spec/trema/set-ip-dst-addr_spec.rb +1 -0
  140. data/spec/trema/set-ip-src-addr_spec.rb +1 -0
  141. data/spec/trema/set-ip-tos_spec.rb +1 -0
  142. data/spec/trema/set-transport-dst-port_spec.rb +1 -0
  143. data/spec/trema/set-transport-src-port_spec.rb +1 -0
  144. data/spec/trema/set-vlan-priority_spec.rb +1 -0
  145. data/spec/trema/set-vlan-vid_spec.rb +2 -1
  146. data/spec/trema/stats-reply_spec.rb +38 -36
  147. data/spec/trema/stats-request_spec.rb +6 -6
  148. data/spec/trema/strip-vlan-header_spec.rb +1 -0
  149. data/spec/trema/util_spec.rb +3 -2
  150. data/spec/trema/vendor-action_spec.rb +9 -8
  151. data/src/examples/dumper/dumper.c +8 -6
  152. data/src/examples/dumper/dumper.rb +1 -1
  153. data/{features/step_definitions/killall_steps.rb → src/examples/hello_trema/hello-trema.rb} +6 -5
  154. data/src/examples/hello_trema/hello_trema.c +4 -4
  155. data/src/examples/learning_switch/learning_switch.c +1 -1
  156. data/src/examples/list_switches/list_switches.c +2 -2
  157. data/src/examples/match_compare/match-compare.rb +2 -2
  158. data/src/examples/multi_learning_switch/multi-learning-switch.rb +1 -1
  159. data/src/examples/multi_learning_switch/multi_learning_switch.c +3 -3
  160. data/src/examples/openflow_message/README +1 -1
  161. data/src/examples/openflow_message/echo-request.rb +1 -1
  162. data/src/examples/openflow_message/features_request.c +21 -21
  163. data/src/examples/openflow_message/hello.c +1 -3
  164. data/src/examples/openflow_message/hello.rb +9 -24
  165. data/src/examples/{hello_trema/hello_trema.rb → openflow_message/vendor-action.rb} +17 -7
  166. data/src/examples/openflow_message/vendor_action.c +105 -0
  167. data/src/examples/openflow_switch/hello_switch.c +81 -0
  168. data/src/examples/packet_in/packet-in.rb +9 -13
  169. data/src/examples/packetin_filter_config/packetin_filter_config.c +2 -2
  170. data/src/examples/patch_panel/network.conf +14 -0
  171. data/src/examples/patch_panel/patch-panel.conf +1 -0
  172. data/{features/step_definitions/show_stats_steps.rb → src/examples/patch_panel/patch-panel.rb} +29 -13
  173. data/src/examples/switch_info/{switch_info.rb → switch-info.rb} +2 -2
  174. data/src/examples/switch_info/switch_info.c +4 -4
  175. data/src/examples/switch_monitor/switch_monitor.c +3 -3
  176. data/src/examples/traffic_monitor/counter.c +9 -9
  177. data/src/examples/traffic_monitor/fdb.c +9 -9
  178. data/src/lib/arp.h +1 -1
  179. data/src/lib/buffer.c +4 -3
  180. data/src/lib/byteorder.c +31 -5
  181. data/src/lib/byteorder.h +2 -2
  182. data/src/lib/chibach.c +8 -6
  183. data/src/lib/daemon.c +29 -3
  184. data/src/lib/doubly_linked_list.c +6 -1
  185. data/src/lib/ether.c +1 -1
  186. data/src/lib/ether.h +1 -1
  187. data/src/lib/event_handler.c +3 -3
  188. data/src/lib/hash_table.c +1 -1
  189. data/src/lib/linked_list.c +50 -2
  190. data/src/lib/linked_list.h +2 -2
  191. data/src/lib/log.c +122 -22
  192. data/src/lib/log.h +13 -9
  193. data/src/lib/management_interface.c +361 -0
  194. data/src/lib/management_interface.h +42 -0
  195. data/src/lib/management_service_interface.c +104 -0
  196. data/src/lib/management_service_interface.h +136 -0
  197. data/src/lib/match_table.c +5 -5
  198. data/src/lib/message_queue.c +5 -3
  199. data/src/lib/message_queue.h +1 -1
  200. data/src/lib/messenger.c +73 -39
  201. data/src/lib/messenger.h +3 -2
  202. data/src/lib/openflow_application_interface.c +17 -17
  203. data/src/lib/openflow_message.c +175 -23
  204. data/src/lib/openflow_message.h +2 -1
  205. data/src/lib/openflow_switch_interface.c +12 -12
  206. data/src/lib/packet_parser.c +11 -32
  207. data/src/lib/packetin_filter_interface.c +5 -5
  208. data/src/lib/persistent_storage.c +7 -7
  209. data/src/lib/secure_channel.c +6 -6
  210. data/src/lib/secure_channel.h +1 -1
  211. data/src/lib/stat.c +54 -17
  212. data/src/lib/stat.h +9 -0
  213. data/src/lib/timer.c +11 -10
  214. data/src/lib/trema.c +38 -9
  215. data/src/lib/trema.h +1 -0
  216. data/src/lib/trema_private.h +6 -0
  217. data/src/lib/trema_wrapper.c +4 -4
  218. data/src/lib/trema_wrapper.h +10 -10
  219. data/src/lib/utility.c +6 -6
  220. data/src/management/application.c +224 -0
  221. data/src/management/echo.c +185 -0
  222. data/src/management/set_logging_level.c +153 -0
  223. data/src/management/show_stats.c +150 -0
  224. data/src/management/trema_manager +184 -0
  225. data/src/packetin_filter/packetin_filter.c +31 -29
  226. data/src/switch_manager/cookie_table.c +7 -7
  227. data/src/switch_manager/dpid_table.c +3 -3
  228. data/src/switch_manager/dpid_table.h +0 -1
  229. data/src/switch_manager/management_interface.h +0 -1
  230. data/src/switch_manager/ofpmsg_recv.c +3 -3
  231. data/src/switch_manager/ofpmsg_recv.h +0 -1
  232. data/src/switch_manager/ofpmsg_send.c +2 -2
  233. data/src/switch_manager/ofpmsg_send.h +0 -1
  234. data/src/switch_manager/secure_channel_listener.c +2 -2
  235. data/src/switch_manager/secure_channel_receiver.c +2 -2
  236. data/src/switch_manager/secure_channel_receiver.h +0 -1
  237. data/src/switch_manager/secure_channel_sender.c +8 -1
  238. data/src/switch_manager/service_interface.c +5 -4
  239. data/src/switch_manager/switch.c +79 -53
  240. data/src/switch_manager/switch_manager.c +24 -22
  241. data/src/switch_manager/xid_table.c +6 -6
  242. data/src/switch_manager/xid_table.h +0 -1
  243. data/src/tremashark/README +4 -3
  244. data/src/tremashark/packet_capture.c +11 -9
  245. data/src/tremashark/pcap_queue.c +2 -2
  246. data/src/tremashark/pcap_queue.h +2 -2
  247. data/src/tremashark/plugin/packet-trema/Makefile +1 -1
  248. data/src/tremashark/plugin/packet-trema/Makefile.common +1 -1
  249. data/src/tremashark/plugin/packet-trema/packet-trema.c +50 -37
  250. data/src/tremashark/queue.c +5 -4
  251. data/src/tremashark/queue.h +1 -1
  252. data/src/tremashark/stdin_relay.c +10 -8
  253. data/src/tremashark/syslog_relay.c +14 -12
  254. data/src/tremashark/tremashark.c +15 -18
  255. data/trema +2 -96
  256. data/trema-config +2 -52
  257. data/trema.gemspec +12 -1
  258. data/unittests/cmockery_trema.h +14 -13
  259. data/unittests/lib/buffer_test.c +1 -1
  260. data/unittests/lib/byteorder_test.c +108 -25
  261. data/unittests/lib/daemon_test.c +141 -5
  262. data/unittests/lib/doubly_linked_list_test.c +5 -1
  263. data/unittests/lib/ether_test.c +4 -4
  264. data/unittests/lib/hash_table_test.c +5 -3
  265. data/unittests/lib/linked_list_test.c +82 -4
  266. data/unittests/lib/log_test.c +96 -5
  267. data/unittests/lib/management_interface_test.c +240 -0
  268. data/unittests/lib/management_service_interface_test.c +319 -0
  269. data/unittests/lib/message_queue_test.c +6 -2
  270. data/unittests/lib/messenger_test.c +167 -2
  271. data/unittests/lib/openflow_application_interface_test.c +16 -22
  272. data/unittests/lib/openflow_message_test.c +721 -24
  273. data/unittests/lib/packet_info_test.c +2 -2
  274. data/unittests/lib/packet_parser_test.c +15 -16
  275. data/unittests/lib/packetin_filter_interface_test.c +6 -6
  276. data/unittests/lib/persistent_storage_test.c +11 -11
  277. data/unittests/lib/stat_test.c +151 -7
  278. data/unittests/lib/timer_test.c +1 -1
  279. data/unittests/lib/trema_private_test.c +2 -2
  280. data/unittests/lib/trema_test.c +40 -12
  281. data/unittests/lib/utility_test.c +3 -3
  282. data/unittests/lib/wrapper_test.c +3 -3
  283. data/unittests/packetin_filter/packetin_filter_test.c +12 -11
  284. data/unittests/switch_manager/switch_manager_test.c +29 -22
  285. metadata +99 -20
  286. data/features/step_definitions/log_steps.rb +0 -90
  287. data/features/step_definitions/run_steps.rb +0 -91
  288. data/features/trema.feature +0 -27
  289. data/features/tutorial.hello_trema.feature +0 -27
  290. data/features/tutorial.packet_in.feature +0 -47
  291. data/features/tutorial.switch_info.feature +0 -55
  292. data/ruby/trema/command/usage.rb +0 -63
@@ -194,13 +194,18 @@ find_element( dlist_element *element, const void *data ) {
194
194
  pthread_mutex_lock( ( ( private_dlist_element * ) element )->mutex );
195
195
 
196
196
  dlist_element *e = NULL;
197
-
198
197
  for ( e = element; e; e = e->next ) {
199
198
  if ( e->data == data ) {
200
199
  pthread_mutex_unlock( ( ( private_dlist_element * ) element )->mutex );
201
200
  return e;
202
201
  }
203
202
  }
203
+ for ( e = element->prev; e; e = e->prev ) {
204
+ if ( e->data == data ) {
205
+ pthread_mutex_unlock( ( ( private_dlist_element * ) element )->mutex );
206
+ return e;
207
+ }
208
+ }
204
209
 
205
210
  pthread_mutex_unlock( ( ( private_dlist_element * ) element )->mutex );
206
211
 
data/src/lib/ether.c CHANGED
@@ -32,7 +32,7 @@ fill_ether_padding( buffer *buf ) {
32
32
 
33
33
  if ( buf->length + ETH_FCS_LENGTH < ETH_MINIMUM_LENGTH ) {
34
34
  padding_length = ETH_MINIMUM_LENGTH - buf->length - ETH_FCS_LENGTH;
35
- debug( "Adding %u octets padding ( original frame length = %u ).",
35
+ debug( "Adding %zu octets padding ( original frame length = %zu ).",
36
36
  buf->length, padding_length );
37
37
  void *padding = append_back_buffer( buf, padding_length );
38
38
  memset( padding, 0, padding_length );
data/src/lib/ether.h CHANGED
@@ -77,7 +77,7 @@ typedef struct snap_header {
77
77
  #define TCI_CREATE( _prio, _cfi, _vid ) \
78
78
  ( uint16_t )( ( ( ( _prio ) & 7 ) << 13 ) | \
79
79
  ( ( ( _cfi ) & 1 ) << 12 ) | \
80
- ( ( _vid ) & 0x0FFF ) )
80
+ ( ( _vid ) & 0x0FFF ) )
81
81
 
82
82
  uint16_t fill_ether_padding( buffer *buf );
83
83
 
@@ -116,7 +116,7 @@ void ( *init_event_handler )() = _init_event_handler;
116
116
  static void
117
117
  _finalize_event_handler() {
118
118
  if ( event_last != event_list ) {
119
- warn( "Event Handler finalized with %i fd event handlers still active. (%i, ...)",
119
+ warn( "Event Handler finalized with %ti fd event handlers still active. (%i, ...)",
120
120
  ( event_last - event_list ), ( event_last > event_list ? event_list->fd : -1 ) );
121
121
  return;
122
122
  }
@@ -176,7 +176,7 @@ _run_event_handler_once( int timeout_usec ) {
176
176
  event_itr = event_itr + 1;
177
177
  }
178
178
  else {
179
- debug( "run_event_handler_once: event fd is changed ( current = %d, new = %d )", current_event.fd, event_itr->fd ) ;
179
+ debug( "run_event_handler_once: event fd is changed ( current = %d, new = %d )", current_event.fd, event_itr->fd );
180
180
  }
181
181
  }
182
182
 
@@ -260,7 +260,7 @@ static void
260
260
  _delete_fd_handler( int fd ) {
261
261
  debug( "Deleting event handler for fd %i.", fd );
262
262
 
263
- event_fd* event = event_list;
263
+ event_fd *event = event_list;
264
264
 
265
265
  while ( event != event_last && event->fd != fd ) {
266
266
  event++;
data/src/lib/hash_table.c CHANGED
@@ -351,7 +351,7 @@ iterate_hash_next( hash_iterator *iterator ) {
351
351
  }
352
352
 
353
353
  dlist_element *e = iterator->element;
354
- if ( e == NULL ) {
354
+ if ( e == NULL ) {
355
355
  if ( iterator->next_bucket_index != NULL ) {
356
356
  iterator->bucket_index = iterator->next_bucket_index;
357
357
  iterator->next_bucket_index = iterator->next_bucket_index->next;
@@ -1,6 +1,4 @@
1
1
  /*
2
- * Author: Yasuhito Takamiya <yasuhito@gmail.com>
3
- *
4
2
  * Copyright (C) 2008-2012 NEC Corporation
5
3
  *
6
4
  * This program is free software; you can redistribute it and/or modify
@@ -138,6 +136,56 @@ list_length_of( const list_element *head ) {
138
136
  }
139
137
 
140
138
 
139
+ /**
140
+ * Calls a function for each element of a list.
141
+ *
142
+ * @param head the head of the list.
143
+ * @param function the function to call with each element's data.
144
+ * @param user_data user-data to pass to the function.
145
+ */
146
+ void
147
+ iterate_list( list_element *head, void function( void *data, void *user_data ), void *user_data ) {
148
+ if ( head == NULL ) {
149
+ die( "head must not be NULL" );
150
+ }
151
+ if ( function != NULL ) {
152
+ for ( list_element *e = head; e != NULL; e = e->next ) {
153
+ function( e->data, user_data );
154
+ }
155
+ }
156
+ }
157
+
158
+
159
+ /**
160
+ * Finds an element in a list, using a supplied function to find the
161
+ * desired element. It iterates over the list, calling the given
162
+ * function which should return true when the desired element is found.
163
+ *
164
+ * @param head the head of the list.
165
+ * @param function the function to call for each element. It should return true when the desired element is found.
166
+ * @param user_data user-data passed to the function.
167
+ * @return the found list element, or NULL if it is not found.
168
+ */
169
+ void *
170
+ find_list_custom( list_element *head, bool function( void *data, void *user_data ), void *user_data ) {
171
+ if ( head == NULL ) {
172
+ die( "head must not be NULL" );
173
+ }
174
+ if ( function == NULL ) {
175
+ die( "function must not be NULL" );
176
+ }
177
+
178
+ void *data_found = NULL;
179
+ for ( list_element *e = head; e != NULL; e = e->next ) {
180
+ if ( function( e->data, user_data ) ) {
181
+ data_found = e->data;
182
+ break;
183
+ }
184
+ }
185
+ return data_found;
186
+ }
187
+
188
+
141
189
  /**
142
190
  * Removes an element from a list. If two elements contain the same
143
191
  * data, only the first is removed. If none of the elements contain
@@ -1,6 +1,4 @@
1
1
  /*
2
- * Author: Yasuhito Takamiya <yasuhito@gmail.com>
3
- *
4
2
  * Copyright (C) 2008-2012 NEC Corporation
5
3
  *
6
4
  * This program is free software; you can redistribute it and/or modify
@@ -69,6 +67,8 @@ bool insert_in_front( list_element **head, void *data );
69
67
  bool insert_before( list_element **head, const void *sibling, void *data );
70
68
  bool append_to_tail( list_element **head, void *data );
71
69
  unsigned int list_length_of( const list_element *head );
70
+ void iterate_list( list_element *head, void function( void *data, void *user_data ), void *user_data );
71
+ void *find_list_custom( list_element *head, bool function( void *data, void *user_data ), void *user_data );
72
72
  bool delete_element( list_element **head, const void *data );
73
73
  bool delete_list( list_element *head );
74
74
 
data/src/lib/log.c CHANGED
@@ -1,6 +1,4 @@
1
1
  /*
2
- * Author: Yasuhito Takamiya <yasuhito@gmail.com>
3
- *
4
2
  * Copyright (C) 2008-2012 NEC Corporation
5
3
  *
6
4
  * This program is free software; you can redistribute it and/or modify
@@ -38,10 +36,13 @@ typedef struct {
38
36
  const int value;
39
37
  } priority;
40
38
 
39
+ typedef priority facility;
40
+
41
41
 
42
42
  static bool initialized = false;
43
43
  static FILE *fd = NULL;
44
44
  static int level = -1;
45
+ static int facility_value = -1;
45
46
  static char ident_string[ PATH_MAX ];
46
47
  static char log_directory[ PATH_MAX ];
47
48
  static logging_type output = LOGGING_TYPE_FILE;
@@ -85,9 +86,40 @@ static priority priorities[][ 3 ] = {
85
86
  },
86
87
  };
87
88
 
89
+ static facility facilities[] = {
90
+ { .name = "kern", .value = LOG_KERN },
91
+ { .name = "user", .value = LOG_USER },
92
+ { .name = "mail", .value = LOG_MAIL },
93
+ { .name = "daemon", .value = LOG_DAEMON },
94
+ { .name = "auth", .value = LOG_AUTH },
95
+ { .name = "syslog", .value = LOG_SYSLOG },
96
+ { .name = "lpr", .value = LOG_LPR },
97
+ { .name = "news", .value = LOG_NEWS },
98
+ { .name = "uucp", .value = LOG_UUCP },
99
+ { .name = "cron", .value = LOG_CRON },
100
+ { .name = "authpriv", .value = LOG_AUTHPRIV },
101
+ { .name = "ftp", .value = LOG_FTP },
102
+ { .name = "local0", .value = LOG_LOCAL0 },
103
+ { .name = "local1", .value = LOG_LOCAL1 },
104
+ { .name = "local2", .value = LOG_LOCAL2 },
105
+ { .name = "local3", .value = LOG_LOCAL3 },
106
+ { .name = "local4", .value = LOG_LOCAL4 },
107
+ { .name = "local5", .value = LOG_LOCAL5 },
108
+ { .name = "local6", .value = LOG_LOCAL6 },
109
+ { .name = "local7", .value = LOG_LOCAL7 },
110
+ { .name = NULL },
111
+ };
112
+
113
+
114
+ static bool
115
+ started() {
116
+ return initialized;
117
+ }
118
+
88
119
 
89
120
  static const char *
90
121
  priority_name_from( int level ) {
122
+ assert( level >= LOG_CRIT && level <= LOG_DEBUG );
91
123
  const char *name = priorities[ level - LOG_CRIT ][ 0 ].name;
92
124
  assert( name != NULL );
93
125
  return name;
@@ -109,6 +141,7 @@ log_file( int priority, const char *format, va_list ap ) {
109
141
  va_list new_ap;
110
142
  va_copy( new_ap, ap );
111
143
  vsnprintf( message, max_message_length, format, new_ap );
144
+ va_end( new_ap );
112
145
 
113
146
  trema_fprintf( fd, "%s [%s] %s\n", now, priority_name, message );
114
147
  fflush( fd );
@@ -122,13 +155,17 @@ log_stdout( const char *format, va_list ap ) {
122
155
  va_list new_ap;
123
156
  va_copy( new_ap, ap );
124
157
  trema_vprintf( format_newline, new_ap );
158
+ va_end( new_ap );
125
159
  fflush( stdout );
126
160
  }
127
161
 
128
162
 
129
163
  static void
130
164
  log_syslog( int priority, const char *format, va_list ap ) {
131
- trema_vsyslog( priority, format, ap );
165
+ va_list new_ap;
166
+ va_copy( new_ap, ap );
167
+ trema_vsyslog( priority, format, new_ap );
168
+ va_end( new_ap );
132
169
  }
133
170
 
134
171
 
@@ -174,7 +211,7 @@ get_log_directory() {
174
211
  }
175
212
 
176
213
 
177
- static FILE*
214
+ static FILE *
178
215
  open_log_file( bool append ) {
179
216
  assert( strlen( get_log_directory() ) > 0 );
180
217
  assert( strlen( get_ident_string() ) > 0 );
@@ -197,8 +234,53 @@ open_log_file( bool append ) {
197
234
  static void
198
235
  open_log_syslog() {
199
236
  assert( strlen( get_ident_string() ) > 0 );
237
+ assert( ( facility_value & ~LOG_FACMASK ) == 0 );
238
+ trema_openlog( get_ident_string(), LOG_NDELAY, facility_value );
239
+ }
240
+
241
+
242
+ static int
243
+ facility_value_from( const char *name ) {
244
+ assert( name != NULL );
245
+
246
+ int value = -1;
247
+
248
+ for ( int i = 0; facilities[ i ].name != NULL; i++ ) {
249
+ if ( strcasecmp( facilities[ i ].name, name ) == 0 ) {
250
+ value = facilities[ i ].value;
251
+ break;
252
+ }
253
+ }
254
+
255
+ return value;
256
+ }
257
+
258
+
259
+ /**
260
+ * Sets syslog facility.
261
+ *
262
+ * @param name name of the syslog facility to be set.
263
+ * @return true on success; false otherwise.
264
+ */
265
+ bool
266
+ set_syslog_facility( const char *name ) {
267
+ assert( name != NULL );
268
+
269
+ int new_facility_value = facility_value_from( name );
270
+ if ( new_facility_value == -1 ) {
271
+ fprintf( stderr, "Invalid syslog facility: %s\n", name );
272
+ trema_abort();
273
+ }
274
+
275
+ pthread_mutex_lock( &mutex );
276
+ facility_value = new_facility_value;
277
+ if ( ( output & LOGGING_TYPE_SYSLOG ) != 0 && started() ) {
278
+ trema_closelog();
279
+ open_log_syslog();
280
+ }
281
+ pthread_mutex_unlock( &mutex );
200
282
 
201
- trema_openlog( get_ident_string(), LOG_NDELAY, LOG_USER );
283
+ return true;
202
284
  }
203
285
 
204
286
 
@@ -228,6 +310,16 @@ init_log( const char *ident, const char *directory, logging_type type ) {
228
310
  set_logging_level( level_string );
229
311
  }
230
312
 
313
+ // set_syslog_facility() may be called before init_log().
314
+ // facility_value = -1 indicates that facility value is not set yet.
315
+ if ( ( facility_value & ~LOG_FACMASK ) != 0 ) {
316
+ facility_value = LOG_USER;
317
+ }
318
+ char *facility_string = getenv( "LOGGING_FACILITY" );
319
+ if ( facility_string != NULL ) {
320
+ set_syslog_facility( facility_string );
321
+ }
322
+
231
323
  set_ident_string( ident );
232
324
  set_log_directory( directory );
233
325
  output = type;
@@ -273,6 +365,8 @@ void
273
365
  rename_log( const char *new_ident ) {
274
366
  assert( new_ident != NULL );
275
367
 
368
+ pthread_mutex_lock( &mutex );
369
+
276
370
  if ( output & LOGGING_TYPE_FILE ) {
277
371
  char old_path[ PATH_MAX ];
278
372
  snprintf( old_path, PATH_MAX, "%s/%s.log", get_log_directory(), get_ident_string() );
@@ -293,6 +387,8 @@ rename_log( const char *new_ident ) {
293
387
  set_ident_string( new_ident );
294
388
  open_log_syslog();
295
389
  }
390
+
391
+ pthread_mutex_unlock( &mutex );
296
392
  }
297
393
 
298
394
 
@@ -306,6 +402,7 @@ finalize_log() {
306
402
  pthread_mutex_lock( &mutex );
307
403
 
308
404
  level = -1;
405
+ facility_value = -1;
309
406
 
310
407
  if ( output & LOGGING_TYPE_FILE ) {
311
408
  if ( fd != NULL ) {
@@ -328,39 +425,41 @@ finalize_log() {
328
425
  }
329
426
 
330
427
 
331
- static char *
332
- lower( const char *string ) {
333
- char *new_string = xstrdup( string );
334
- for ( int i = 0; new_string[ i ] != '\0'; ++i ) {
335
- new_string[ i ] = ( char ) tolower( new_string[ i ] );
336
- }
337
- return new_string;
338
- }
339
-
340
-
341
428
  static int
342
429
  priority_value_from( const char *name ) {
343
430
  assert( name != NULL );
344
431
 
345
432
  int level_value = -1;
346
- char *name_lower = lower( name );
347
433
 
434
+ assert( ( LOG_DEBUG - LOG_CRIT + 1 ) == ( sizeof( priorities )/sizeof( priorities[ 0 ] ) ) );
348
435
  for ( int i = 0; i <= ( LOG_DEBUG - LOG_CRIT ); i++ ) {
349
436
  for ( priority *p = priorities[ i ]; p->name != NULL; p++ ) {
350
- if ( strncmp( p->name, name_lower, 20 ) == 0 ) {
437
+ if ( strcasecmp( p->name, name ) == 0 ) {
351
438
  level_value = p->value;
352
439
  break;
353
440
  }
354
441
  }
355
442
  }
356
- xfree( name_lower );
357
443
  return level_value;
358
444
  }
359
445
 
360
446
 
361
- static bool
362
- started() {
363
- return initialized;
447
+ /**
448
+ * Check if a provided logging level is valid or not.
449
+ *
450
+ * @param name name of the logging level to be checked.
451
+ * @return true if valid; false otherwise.
452
+ */
453
+ bool
454
+ valid_logging_level( const char *name ) {
455
+ assert( name != NULL );
456
+
457
+ int level_value = priority_value_from( name );
458
+ if ( level_value < 0 ) {
459
+ return false;
460
+ }
461
+
462
+ return true;
364
463
  }
365
464
 
366
465
 
@@ -422,7 +521,8 @@ do_log( int priority, const char *format, va_list ap ) {
422
521
  va_end( _args ); \
423
522
  pthread_mutex_unlock( &mutex ); \
424
523
  } \
425
- } while ( 0 )
524
+ } \
525
+ while ( 0 )
426
526
 
427
527
 
428
528
  static void
data/src/lib/log.h CHANGED
@@ -4,8 +4,6 @@
4
4
  * Some good logging guidelines can be found here:
5
5
  * http://watchitlater.com/blog/2009/12/logging-guidelines/
6
6
  *
7
- * Author: Yasuhito Takamiya <yasuhito@gmail.com>
8
- *
9
7
  * Copyright (C) 2008-2012 NEC Corporation
10
8
  *
11
9
  * This program is free software; you can redistribute it and/or modify
@@ -35,8 +33,11 @@
35
33
  #define LOG_H
36
34
 
37
35
 
38
- #include "bool.h"
39
36
  #include <syslog.h>
37
+ #include "bool.h"
38
+
39
+
40
+ #define LOGGING_LEVEL_STR_LENGTH 12
40
41
 
41
42
 
42
43
  typedef enum {
@@ -52,14 +53,17 @@ void rename_log( const char *new_ident );
52
53
  bool finalize_log( void );
53
54
 
54
55
  bool set_logging_level( const char *level );
56
+ bool valid_logging_level( const char *level );
57
+ bool set_syslog_facility( const char *facility );
58
+
55
59
  extern int ( *get_logging_level )( void );
56
60
 
57
- extern void ( *critical )( const char *format, ... );
58
- extern void ( *error )( const char *format, ... );
59
- extern void ( *warn )( const char *format, ... );
60
- extern void ( *notice )( const char *format, ... );
61
- extern void ( *info )( const char *format, ... );
62
- extern void ( *debug )( const char *format, ... );
61
+ extern void ( *critical )( const char *format, ... ) __attribute__( ( format( printf, 1, 2 ) ) );
62
+ extern void ( *error )( const char *format, ... ) __attribute__( ( format( printf, 1, 2 ) ) );
63
+ extern void ( *warn )( const char *format, ... ) __attribute__( ( format( printf, 1, 2 ) ) );
64
+ extern void ( *notice )( const char *format, ... ) __attribute__( ( format( printf, 1, 2 ) ) );
65
+ extern void ( *info )( const char *format, ... ) __attribute__( ( format( printf, 1, 2 ) ) );
66
+ extern void ( *debug )( const char *format, ... ) __attribute__( ( format( printf, 1, 2 ) ) );
63
67
 
64
68
 
65
69
  #endif // LOG_H