3 * Copyright 2014, Michal Orynicz for Tieto Corporation
4 * Copyright 2014, Michal Labedzki for Tieto Corporation
6 * SPDX-License-Identifier: GPL-2.0-or-later
10 #include "logcat_text.h"
15 #include "file_wrappers.h"
23 static int logcat_text_brief_file_type_subtype
= -1;
24 static int logcat_text_process_file_type_subtype
= -1;
25 static int logcat_text_tag_file_type_subtype
= -1;
26 static int logcat_text_thread_file_type_subtype
= -1;
27 static int logcat_text_time_file_type_subtype
= -1;
28 static int logcat_text_threadtime_file_type_subtype
= -1;
29 static int logcat_text_long_file_type_subtype
= -1;
31 void register_logcat_text(void);
33 /* Returns '?' for invalid priorities */
34 static char get_priority(const uint8_t priority
) {
35 static char priorities
[] = "??VDIWEFS";
37 if (priority
>= (uint8_t) sizeof(priorities
))
40 return priorities
[priority
];
43 static int buffered_detect_version(const uint8_t *pd
)
45 const struct logger_entry
*log_entry
;
46 const struct logger_entry_v2
*log_entry_v2
;
48 const uint8_t *msg_payload
= NULL
;
53 log_entry
= (const struct logger_entry
*)(const void *) pd
;
54 log_entry_v2
= (const struct logger_entry_v2
*)(const void *) pd
;
56 /* must contain at least priority and two nulls as separator */
57 if (log_entry
->len
< 3)
60 /* payload length may not exceed the maximum payload size */
61 if (log_entry
->len
> LOGGER_ENTRY_MAX_PAYLOAD
)
64 /* cannot rely on __pad being 0 for v1, use heuristics to find out what
65 * version is in use. First assume the smallest msg. */
66 for (version
= 1; version
<= 2; ++version
) {
68 msg_payload
= (const uint8_t *) (log_entry
+ 1);
69 } else if (version
== 2) {
70 /* v2 is 4 bytes longer */
71 msg_payload
= (const uint8_t *) (log_entry_v2
+ 1);
72 if (log_entry_v2
->hdr_size
!= sizeof(*log_entry_v2
))
76 /* A v2 msg has a 32-bit userid instead of v1 priority */
77 if (get_priority(msg_payload
[0]) == '?')
80 /* Is there a terminating '\0' for the tag? */
81 msg_part
= (uint8_t *) memchr(msg_payload
, '\0', log_entry
->len
- 1);
85 /* if msg is '\0'-terminated, is it equal to the payload len? */
87 msg_len
= (uint16_t)(log_entry
->len
- (msg_part
- msg_payload
));
88 msg_end
= (uint8_t *) memchr(msg_part
, '\0', msg_len
);
89 /* is the end of the buffer (-1) equal to the end of msg? */
90 if (msg_end
&& (msg_payload
+ log_entry
->len
- 1 != msg_end
))
99 static char *logcat_log(const struct dumper_t
*dumper
, uint32_t seconds
,
100 int milliseconds
, int pid
, int tid
, char priority
, const char *tag
,
103 char time_buffer
[15];
107 datetime
= (time_t) seconds
;
109 switch (dumper
->type
) {
110 case WTAP_ENCAP_LOGCAT_BRIEF
:
111 return ws_strdup_printf("%c/%-8s(%5i): %s\n",
112 priority
, tag
, pid
, log
);
113 case WTAP_ENCAP_LOGCAT_PROCESS
:
114 /* NOTE: Last parameter should be "process name", not tag;
115 Unfortunately, we do not have process name */
116 return ws_strdup_printf("%c(%5i) %s (%s)\n",
117 priority
, pid
, log
, "");
118 case WTAP_ENCAP_LOGCAT_TAG
:
119 return ws_strdup_printf("%c/%-8s: %s\n",
121 case WTAP_ENCAP_LOGCAT_THREAD
:
122 return ws_strdup_printf("%c(%5i:%5i) %s\n",
123 priority
, pid
, tid
, log
);
124 case WTAP_ENCAP_LOGCAT_TIME
:
125 tm
= gmtime(&datetime
);
127 strftime(time_buffer
, sizeof(time_buffer
), "%m-%d %H:%M:%S",
129 return ws_strdup_printf("%s.%03i %c/%-8s(%5i): %s\n",
130 time_buffer
, milliseconds
, priority
, tag
, pid
, log
);
132 return ws_strdup_printf("Not representable %c/%-8s(%5i): %s\n",
133 priority
, tag
, pid
, log
);
135 case WTAP_ENCAP_LOGCAT_THREADTIME
:
136 tm
= gmtime(&datetime
);
138 strftime(time_buffer
, sizeof(time_buffer
), "%m-%d %H:%M:%S",
140 return ws_strdup_printf("%s.%03i %5i %5i %c %-8s: %s\n",
141 time_buffer
, milliseconds
, pid
, tid
, priority
, tag
, log
);
143 return ws_strdup_printf("Not representable %5i %5i %c %-8s: %s\n",
144 pid
, tid
, priority
, tag
, log
);
146 case WTAP_ENCAP_LOGCAT_LONG
:
147 tm
= gmtime(&datetime
);
149 strftime(time_buffer
, sizeof(time_buffer
), "%m-%d %H:%M:%S",
151 return ws_strdup_printf("[ %s.%03i %5i:%5i %c/%-8s ]\n%s\n\n",
152 time_buffer
, milliseconds
, pid
, tid
, priority
, tag
, log
);
154 return ws_strdup_printf("[ Not representable %5i:%5i %c/%-8s ]\n%s\n\n",
155 pid
, tid
, priority
, tag
, log
);
163 static void get_time(char *string
, wtap_rec
*rec
) {
168 if (6 == sscanf(string
, "%d-%d %d:%d:%d.%d", &date
.tm_mon
, &date
.tm_mday
, &date
.tm_hour
,
169 &date
.tm_min
, &date
.tm_sec
, &ms
)) {
173 seconds
= mktime(&date
);
174 rec
->ts
.secs
= seconds
;
175 rec
->ts
.nsecs
= (int) (ms
* 1e6
);
176 rec
->presence_flags
= WTAP_HAS_TS
;
178 rec
->presence_flags
= 0;
179 rec
->ts
.secs
= (time_t) 0;
184 static bool logcat_text_read_packet(FILE_T fh
, wtap_rec
*rec
,
185 Buffer
*buf
, int file_type
) {
190 cbuff
= (char*)g_malloc(WTAP_MAX_PACKET_SIZE_STANDARD
);
192 ret
= file_gets(cbuff
, WTAP_MAX_PACKET_SIZE_STANDARD
, fh
);
193 } while (NULL
!= ret
&& 3 > strlen(cbuff
) && !file_eof(fh
));
195 if (NULL
== ret
|| 3 > strlen(cbuff
)) {
200 if (logcat_text_long_file_type_subtype
== file_type
&&
201 !g_regex_match_simple(SPECIAL_STRING
, cbuff
, (GRegexCompileFlags
)(G_REGEX_ANCHORED
| G_REGEX_RAW
), G_REGEX_MATCH_NOTEMPTY
)) {
202 int64_t file_off
= 0;
207 lbuff
= (char*)g_malloc(WTAP_MAX_PACKET_SIZE_STANDARD
);
208 file_off
= file_tell(fh
);
209 ret2
= file_gets(lbuff
,WTAP_MAX_PACKET_SIZE_STANDARD
, fh
);
210 while (NULL
!= ret2
&& 2 < strlen(lbuff
) && !file_eof(fh
)) {
211 (void) g_strlcat(cbuff
,lbuff
,WTAP_MAX_PACKET_SIZE_STANDARD
);
212 file_off
= file_tell(fh
);
213 ret2
= file_gets(lbuff
,WTAP_MAX_PACKET_SIZE_STANDARD
, fh
);
216 if(NULL
== ret2
|| 2 < strlen(lbuff
)) {
222 file_seek(fh
,file_off
,SEEK_SET
,&err
);
226 rec
->rec_type
= REC_TYPE_PACKET
;
227 rec
->block
= wtap_block_create(WTAP_BLOCK_PACKET
);
228 rec
->rec_header
.packet_header
.caplen
= (uint32_t)strlen(cbuff
);
229 rec
->rec_header
.packet_header
.len
= rec
->rec_header
.packet_header
.caplen
;
231 ws_buffer_assure_space(buf
, rec
->rec_header
.packet_header
.caplen
+ 1);
232 pd
= ws_buffer_start_ptr(buf
);
233 if ((logcat_text_time_file_type_subtype
== file_type
234 || logcat_text_threadtime_file_type_subtype
== file_type
235 || logcat_text_long_file_type_subtype
== file_type
)
236 && '-' != cbuff
[0]) { /* the last part filters out the -- beginning of... lines */
237 if (logcat_text_long_file_type_subtype
== file_type
) {
238 get_time(cbuff
+2, rec
);
240 get_time(cbuff
, rec
);
243 rec
->presence_flags
= 0;
244 rec
->ts
.secs
= (time_t) 0;
247 memcpy(pd
, cbuff
, rec
->rec_header
.packet_header
.caplen
+ 1);
252 static bool logcat_text_read(wtap
*wth
, wtap_rec
*rec
,
253 Buffer
*buf
, int *err _U_
, char **err_info _U_
, int64_t *data_offset
) {
254 *data_offset
= file_tell(wth
->fh
);
256 return logcat_text_read_packet(wth
->fh
, rec
, buf
, wth
->file_type_subtype
);
259 static bool logcat_text_seek_read(wtap
*wth
, int64_t seek_off
,
260 wtap_rec
*rec
, Buffer
*buf
, int *err
, char **err_info _U_
) {
261 if (file_seek(wth
->random_fh
, seek_off
, SEEK_SET
, err
) == -1)
264 if (!logcat_text_read_packet(wth
->random_fh
, rec
, buf
,
265 wth
->file_type_subtype
)) {
267 *err
= WTAP_ERR_SHORT_READ
;
273 wtap_open_return_val
logcat_text_open(wtap
*wth
, int *err
, char **err_info _U_
) {
277 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1)
278 return WTAP_OPEN_ERROR
;
280 cbuff
= (char*)g_malloc(WTAP_MAX_PACKET_SIZE_STANDARD
);
282 ret
= file_gets(cbuff
, WTAP_MAX_PACKET_SIZE_STANDARD
, wth
->fh
);
283 } while (NULL
!= ret
&& !file_eof(wth
->fh
)
284 && ((3 > strlen(cbuff
))
285 || g_regex_match_simple(SPECIAL_STRING
, cbuff
, (GRegexCompileFlags
)(G_REGEX_ANCHORED
| G_REGEX_RAW
),
286 G_REGEX_MATCH_NOTEMPTY
)));
288 if (g_regex_match_simple(BRIEF_STRING
, cbuff
, (GRegexCompileFlags
)(G_REGEX_ANCHORED
| G_REGEX_RAW
),
289 G_REGEX_MATCH_NOTEMPTY
)) {
290 wth
->file_type_subtype
= logcat_text_brief_file_type_subtype
;
291 wth
->file_encap
= WTAP_ENCAP_LOGCAT_BRIEF
;
292 } else if (g_regex_match_simple(TAG_STRING
, cbuff
, (GRegexCompileFlags
)(G_REGEX_ANCHORED
| G_REGEX_RAW
),
293 G_REGEX_MATCH_NOTEMPTY
)) {
294 wth
->file_type_subtype
= logcat_text_tag_file_type_subtype
;
295 wth
->file_encap
= WTAP_ENCAP_LOGCAT_TAG
;
296 } else if (g_regex_match_simple(PROCESS_STRING
, cbuff
, (GRegexCompileFlags
)(G_REGEX_ANCHORED
| G_REGEX_RAW
),
297 G_REGEX_MATCH_NOTEMPTY
)) {
298 wth
->file_type_subtype
= logcat_text_process_file_type_subtype
;
299 wth
->file_encap
= WTAP_ENCAP_LOGCAT_PROCESS
;
300 } else if (g_regex_match_simple(TIME_STRING
, cbuff
, (GRegexCompileFlags
)(G_REGEX_ANCHORED
| G_REGEX_RAW
),
301 G_REGEX_MATCH_NOTEMPTY
)) {
302 wth
->file_type_subtype
= logcat_text_time_file_type_subtype
;
303 wth
->file_encap
= WTAP_ENCAP_LOGCAT_TIME
;
304 } else if (g_regex_match_simple(THREAD_STRING
, cbuff
, (GRegexCompileFlags
)(G_REGEX_ANCHORED
| G_REGEX_RAW
),
305 G_REGEX_MATCH_NOTEMPTY
)) {
306 wth
->file_type_subtype
= logcat_text_thread_file_type_subtype
;
307 wth
->file_encap
= WTAP_ENCAP_LOGCAT_THREAD
;
308 } else if (g_regex_match_simple(THREADTIME_STRING
, cbuff
, (GRegexCompileFlags
)(G_REGEX_ANCHORED
| G_REGEX_RAW
),
309 G_REGEX_MATCH_NOTEMPTY
)) {
310 wth
->file_type_subtype
= logcat_text_threadtime_file_type_subtype
;
311 wth
->file_encap
= WTAP_ENCAP_LOGCAT_THREADTIME
;
312 } else if (g_regex_match_simple(LONG_STRING
, cbuff
, (GRegexCompileFlags
)(G_REGEX_ANCHORED
| G_REGEX_RAW
),
313 G_REGEX_MATCH_NOTEMPTY
)) {
314 wth
->file_type_subtype
= logcat_text_long_file_type_subtype
;
315 wth
->file_encap
= WTAP_ENCAP_LOGCAT_LONG
;
318 return WTAP_OPEN_NOT_MINE
;
321 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1) {
323 return WTAP_OPEN_ERROR
;
325 wth
->snapshot_length
= 0;
327 wth
->subtype_read
= logcat_text_read
;
328 wth
->subtype_seek_read
= logcat_text_seek_read
;
329 wth
->file_tsprec
= WTAP_TSPREC_USEC
;
331 return WTAP_OPEN_MINE
;
334 static int logcat_text_brief_dump_can_write_encap(int encap
) {
335 if (encap
== WTAP_ENCAP_PER_PACKET
)
336 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED
;
339 case WTAP_ENCAP_LOGCAT
:
340 case WTAP_ENCAP_LOGCAT_BRIEF
:
341 case WTAP_ENCAP_WIRESHARK_UPPER_PDU
:
344 return WTAP_ERR_UNWRITABLE_ENCAP
;
348 static int logcat_text_process_dump_can_write_encap(int encap
) {
349 if (encap
== WTAP_ENCAP_PER_PACKET
)
350 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED
;
353 case WTAP_ENCAP_LOGCAT
:
354 case WTAP_ENCAP_LOGCAT_PROCESS
:
355 case WTAP_ENCAP_WIRESHARK_UPPER_PDU
:
358 return WTAP_ERR_UNWRITABLE_ENCAP
;
362 static int logcat_text_tag_dump_can_write_encap(int encap
) {
363 if (encap
== WTAP_ENCAP_PER_PACKET
)
364 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED
;
367 case WTAP_ENCAP_LOGCAT
:
368 case WTAP_ENCAP_LOGCAT_TAG
:
369 case WTAP_ENCAP_WIRESHARK_UPPER_PDU
:
372 return WTAP_ERR_UNWRITABLE_ENCAP
;
376 static int logcat_text_time_dump_can_write_encap(int encap
) {
377 if (encap
== WTAP_ENCAP_PER_PACKET
)
378 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED
;
381 case WTAP_ENCAP_LOGCAT
:
382 case WTAP_ENCAP_LOGCAT_TIME
:
383 case WTAP_ENCAP_WIRESHARK_UPPER_PDU
:
386 return WTAP_ERR_UNWRITABLE_ENCAP
;
390 static int logcat_text_thread_dump_can_write_encap(int encap
) {
391 if (encap
== WTAP_ENCAP_PER_PACKET
)
392 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED
;
395 case WTAP_ENCAP_LOGCAT
:
396 case WTAP_ENCAP_LOGCAT_THREAD
:
397 case WTAP_ENCAP_WIRESHARK_UPPER_PDU
:
400 return WTAP_ERR_UNWRITABLE_ENCAP
;
404 static int logcat_text_threadtime_dump_can_write_encap(int encap
) {
405 if (encap
== WTAP_ENCAP_PER_PACKET
)
406 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED
;
409 case WTAP_ENCAP_LOGCAT
:
410 case WTAP_ENCAP_LOGCAT_THREADTIME
:
411 case WTAP_ENCAP_WIRESHARK_UPPER_PDU
:
414 return WTAP_ERR_UNWRITABLE_ENCAP
;
418 static int logcat_text_long_dump_can_write_encap(int encap
) {
419 if (encap
== WTAP_ENCAP_PER_PACKET
)
420 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED
;
423 case WTAP_ENCAP_LOGCAT
:
424 case WTAP_ENCAP_LOGCAT_LONG
:
425 case WTAP_ENCAP_WIRESHARK_UPPER_PDU
:
428 return WTAP_ERR_UNWRITABLE_ENCAP
;
432 static bool logcat_text_dump_text(wtap_dumper
*wdh
,
434 const uint8_t *pd
, int *err
, char **err_info
)
439 const struct logger_entry
*log_entry
;
440 const struct logger_entry_v2
*log_entry_v2
;
446 int32_t milliseconds
;
447 const uint8_t *msg_payload
= NULL
;
448 const char *msg_begin
;
454 const struct dumper_t
*dumper
= (const struct dumper_t
*) wdh
->priv
;
456 /* We can only write packet records. */
457 if (rec
->rec_type
!= REC_TYPE_PACKET
) {
458 *err
= WTAP_ERR_UNWRITABLE_REC_TYPE
;
463 * Make sure this packet doesn't have a link-layer type that
464 * differs from the one for the file.
466 if (wdh
->file_encap
!= rec
->rec_header
.packet_header
.pkt_encap
) {
467 *err
= WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED
;
471 switch (wdh
->file_encap
) {
472 case WTAP_ENCAP_WIRESHARK_UPPER_PDU
:
476 skipped_length
= logcat_exported_pdu_length(pd
);
477 pd
+= skipped_length
;
479 if (!wtap_dump_file_write(wdh
, (const char*) pd
, rec
->rec_header
.packet_header
.caplen
- skipped_length
, err
)) {
484 case WTAP_ENCAP_LOGCAT
:
485 /* Skip EXPORTED_PDU*/
486 if (wdh
->file_encap
== WTAP_ENCAP_WIRESHARK_UPPER_PDU
) {
489 skipped_length
= logcat_exported_pdu_length(pd
);
490 pd
+= skipped_length
;
492 logcat_version
= buffered_detect_version(pd
);
494 const union wtap_pseudo_header
*pseudo_header
= &rec
->rec_header
.packet_header
.pseudo_header
;
496 logcat_version
= pseudo_header
->logcat
.version
;
499 log_entry
= (const struct logger_entry
*)(const void *) pd
;
500 log_entry_v2
= (const struct logger_entry_v2
*)(const void *) pd
;
502 payload_length
= GINT32_FROM_LE(log_entry
->len
);
503 pid
= GINT32_FROM_LE(log_entry
->pid
);
504 tid
= GINT32_FROM_LE(log_entry
->tid
);
505 seconds
= GINT32_FROM_LE(log_entry
->sec
);
506 milliseconds
= GINT32_FROM_LE(log_entry
->nsec
) / 1000000;
508 /* msg: <prio:1><tag:N>\0<msg:N>\0 with N >= 0, last \0 can be missing */
509 if (logcat_version
== 1) {
510 msg_payload
= (const uint8_t *) (log_entry
+ 1);
512 priority
= get_priority(msg_payload
[0]);
513 tag
= msg_payload
+ 1;
514 msg_pre_skip
= 1 + (int) strlen(tag
) + 1;
515 msg_begin
= msg_payload
+ msg_pre_skip
;
516 } else if (logcat_version
== 2) {
517 msg_payload
= (const uint8_t *) (log_entry_v2
+ 1);
519 priority
= get_priority(msg_payload
[0]);
520 tag
= msg_payload
+ 1;
521 msg_pre_skip
= 1 + (int) strlen(tag
) + 1;
522 msg_begin
= msg_payload
+ msg_pre_skip
;
524 *err
= WTAP_ERR_UNWRITABLE_REC_DATA
;
525 *err_info
= ws_strdup_printf("logcat: version %d isn't supported",
530 /* copy the message part. If a nul byte was missing, it will be added. */
531 log
= g_strndup(msg_begin
, payload_length
- msg_pre_skip
);
533 /* long format: display one header followed by the whole message (which may
534 * contain new lines). Other formats: include tag, etc. with each line */
538 if (dumper
->type
== WTAP_ENCAP_LOGCAT_LONG
) {
539 /* read until end, there is no next string */
542 /* read until next newline */
543 log_next
= strchr(log_part
, '\n');
544 if (log_next
!= NULL
) {
547 /* ignore trailing newline */
548 if (*log_next
== '\0') {
554 buf
= logcat_log(dumper
, seconds
, milliseconds
, pid
, tid
, priority
, tag
, log_part
);
559 length
= (uint32_t) strlen(buf
);
561 if (!wtap_dump_file_write(wdh
, buf
, length
, err
)) {
565 } while (log_next
!= NULL
);
570 case WTAP_ENCAP_LOGCAT_BRIEF
:
571 case WTAP_ENCAP_LOGCAT_TAG
:
572 case WTAP_ENCAP_LOGCAT_PROCESS
:
573 case WTAP_ENCAP_LOGCAT_TIME
:
574 case WTAP_ENCAP_LOGCAT_THREAD
:
575 case WTAP_ENCAP_LOGCAT_THREADTIME
:
576 case WTAP_ENCAP_LOGCAT_LONG
:
577 if (dumper
->type
== wdh
->file_encap
) {
578 if (!wtap_dump_file_write(wdh
, (const char*) pd
, rec
->rec_header
.packet_header
.caplen
, err
)) {
582 *err
= WTAP_ERR_UNWRITABLE_FILE_TYPE
;
590 static bool logcat_text_dump_open(wtap_dumper
*wdh
, unsigned dump_type
) {
591 struct dumper_t
*dumper
;
593 dumper
= g_new(struct dumper_t
, 1);
594 dumper
->type
= dump_type
;
597 wdh
->subtype_write
= logcat_text_dump_text
;
602 static bool logcat_text_brief_dump_open(wtap_dumper
*wdh
, int *err _U_
, char **err_info _U_
) {
603 return logcat_text_dump_open(wdh
, WTAP_ENCAP_LOGCAT_BRIEF
);
606 static bool logcat_text_process_dump_open(wtap_dumper
*wdh
, int *err _U_
, char **err_info _U_
) {
607 return logcat_text_dump_open(wdh
, WTAP_ENCAP_LOGCAT_PROCESS
);
610 static bool logcat_text_tag_dump_open(wtap_dumper
*wdh
, int *err _U_
, char **err_info _U_
) {
611 return logcat_text_dump_open(wdh
, WTAP_ENCAP_LOGCAT_TAG
);
614 static bool logcat_text_time_dump_open(wtap_dumper
*wdh
, int *err _U_
, char **err_info _U_
) {
615 return logcat_text_dump_open(wdh
, WTAP_ENCAP_LOGCAT_TIME
);
618 static bool logcat_text_thread_dump_open(wtap_dumper
*wdh
, int *err _U_
, char **err_info _U_
) {
619 return logcat_text_dump_open(wdh
, WTAP_ENCAP_LOGCAT_THREAD
);
622 static bool logcat_text_threadtime_dump_open(wtap_dumper
*wdh
, int *err _U_
, char **err_info _U_
) {
623 return logcat_text_dump_open(wdh
, WTAP_ENCAP_LOGCAT_THREADTIME
);
626 static bool logcat_text_long_dump_open(wtap_dumper
*wdh
, int *err _U_
, char **err_info _U_
) {
627 return logcat_text_dump_open(wdh
, WTAP_ENCAP_LOGCAT_LONG
);
630 static const struct supported_block_type logcat_text_brief_blocks_supported
[] = {
632 * We support packet blocks, with no comments or other options.
634 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
637 static const struct file_type_subtype_info logcat_text_brief_info
= {
638 "Android Logcat Brief text format", "logcat-brief", NULL
, NULL
,
639 false, BLOCKS_SUPPORTED(logcat_text_brief_blocks_supported
),
640 logcat_text_brief_dump_can_write_encap
, logcat_text_brief_dump_open
, NULL
643 static const struct supported_block_type logcat_text_process_blocks_supported
[] = {
645 * We support packet blocks, with no comments or other options.
647 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
650 static const struct file_type_subtype_info logcat_text_process_info
= {
651 "Android Logcat Process text format", "logcat-process", NULL
, NULL
,
652 false, BLOCKS_SUPPORTED(logcat_text_process_blocks_supported
),
653 logcat_text_process_dump_can_write_encap
, logcat_text_process_dump_open
, NULL
656 static const struct supported_block_type logcat_text_tag_blocks_supported
[] = {
658 * We support packet blocks, with no comments or other options.
660 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
663 static const struct file_type_subtype_info logcat_text_tag_info
= {
664 "Android Logcat Tag text format", "logcat-tag", NULL
, NULL
,
665 false, BLOCKS_SUPPORTED(logcat_text_tag_blocks_supported
),
666 logcat_text_tag_dump_can_write_encap
, logcat_text_tag_dump_open
, NULL
669 static const struct supported_block_type logcat_text_thread_blocks_supported
[] = {
671 * We support packet blocks, with no comments or other options.
673 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
676 static const struct file_type_subtype_info logcat_text_thread_info
= {
677 "Android Logcat Thread text format", "logcat-thread", NULL
, NULL
,
678 false, BLOCKS_SUPPORTED(logcat_text_thread_blocks_supported
),
679 logcat_text_thread_dump_can_write_encap
, logcat_text_thread_dump_open
, NULL
682 static const struct supported_block_type logcat_text_time_blocks_supported
[] = {
684 * We support packet blocks, with no comments or other options.
686 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
689 static const struct file_type_subtype_info logcat_text_time_info
= {
690 "Android Logcat Time text format", "logcat-time", NULL
, NULL
,
691 false, BLOCKS_SUPPORTED(logcat_text_time_blocks_supported
),
692 logcat_text_time_dump_can_write_encap
, logcat_text_time_dump_open
, NULL
695 static const struct supported_block_type logcat_text_threadtime_blocks_supported
[] = {
697 * We support packet blocks, with no comments or other options.
699 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
702 static const struct file_type_subtype_info logcat_text_threadtime_info
= {
703 "Android Logcat Threadtime text format", "logcat-threadtime", NULL
, NULL
,
704 false, BLOCKS_SUPPORTED(logcat_text_threadtime_blocks_supported
),
705 logcat_text_threadtime_dump_can_write_encap
, logcat_text_threadtime_dump_open
, NULL
708 static const struct supported_block_type logcat_text_long_blocks_supported
[] = {
710 * We support packet blocks, with no comments or other options.
712 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
715 static const struct file_type_subtype_info logcat_text_long_info
= {
716 "Android Logcat Long text format", "logcat-long", NULL
, NULL
,
717 false, BLOCKS_SUPPORTED(logcat_text_long_blocks_supported
),
718 logcat_text_long_dump_can_write_encap
, logcat_text_long_dump_open
, NULL
721 void register_logcat_text(void)
723 logcat_text_brief_file_type_subtype
= wtap_register_file_type_subtype(&logcat_text_brief_info
);
724 logcat_text_process_file_type_subtype
= wtap_register_file_type_subtype(&logcat_text_process_info
);
725 logcat_text_tag_file_type_subtype
= wtap_register_file_type_subtype(&logcat_text_tag_info
);
726 logcat_text_thread_file_type_subtype
= wtap_register_file_type_subtype(&logcat_text_thread_info
);
727 logcat_text_time_file_type_subtype
= wtap_register_file_type_subtype(&logcat_text_time_info
);
728 logcat_text_threadtime_file_type_subtype
= wtap_register_file_type_subtype(&logcat_text_threadtime_info
);
729 logcat_text_long_file_type_subtype
= wtap_register_file_type_subtype(&logcat_text_long_info
);
732 * Register names for backwards compatibility with the
733 * wtap_filetypes table in Lua.
735 wtap_register_backwards_compatibility_lua_name("LOGCAT_BRIEF",
736 logcat_text_brief_file_type_subtype
);
737 wtap_register_backwards_compatibility_lua_name("LOGCAT_PROCESS",
738 logcat_text_process_file_type_subtype
);
739 wtap_register_backwards_compatibility_lua_name("LOGCAT_TAG",
740 logcat_text_tag_file_type_subtype
);
741 wtap_register_backwards_compatibility_lua_name("LOGCAT_THREAD",
742 logcat_text_thread_file_type_subtype
);
743 wtap_register_backwards_compatibility_lua_name("LOGCAT_TIME",
744 logcat_text_time_file_type_subtype
);
745 wtap_register_backwards_compatibility_lua_name("LOGCAT_THREADTIME",
746 logcat_text_threadtime_file_type_subtype
);
747 wtap_register_backwards_compatibility_lua_name("LOGCAT_LONG",
748 logcat_text_long_file_type_subtype
);
752 * Editor modelines - https://www.wireshark.org/tools/modelines.html
757 * indent-tabs-mode: nil
760 * vi: set shiftwidth=4 tabstop=8 expandtab:
761 * :indentSize=4:tabSize=8:noTabs=true: