summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2006-03-22 14:53:18 +0000
committerMarc Kleine-Budde <mkl@pengutronix.de>2006-03-22 14:53:18 +0000
commit4f991f6d46091710a791b80904cabf032845792e (patch)
treee64019dab4e429a30921beea0a9fc29821f00b6e
parentd68cc212b75a459154968ab34bc8d969b7957ba2 (diff)
downloadcanutils-1.0.x.tar.gz
canutils-1.0.x.tar.xz
git-svn-id: https://iocaste.extern.pengutronix.de/svn/canutils/trunks/canutils-1.0-trunk@66 5fd5a299-6ef2-0310-aa18-8b01d7c39d8ccanutils-1.0.x
-rw-r--r--src/candump.c163
1 files changed, 104 insertions, 59 deletions
diff --git a/src/candump.c b/src/candump.c
index bf1514a..844bd58 100644
--- a/src/candump.c
+++ b/src/candump.c
@@ -1,3 +1,4 @@
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -30,14 +31,16 @@ static void print_usage(char *prg)
{
fprintf(stderr, "Usage: %s <can-interface> [Options]\n"
"Options:\n"
- " -f, --family=FAMILY protocol family (default PF_CAN = %d)\n"
- " -t, --type=TYPE socket type, see man 2 socket (default SOCK_RAW = %d)\n"
- " -p, --protocol=PROTO CAN protocol (default CAN_PROTO_RAW = %d)\n"
+ " -f, --family=FAMILY\t" "protocol family (default PF_CAN = %d)\n"
+ " -t, --type=TYPE\t" "socket type, see man 2 socket (default SOCK_RAW = %d)\n"
+ " -p, --protocol=PROTO\t" "CAN protocol (default CAN_PROTO_RAW = %d)\n"
" --filter=id:mask[:id:mask]...\n"
- " apply filter\n"
- " -h, --help this help\n"
- " --version print version information and exit\n",
- prg, PF_CAN, SOCK_RAW, CAN_PROTO_RAW);
+ "\t\t\t" "apply filter\n"
+ " -h, --help\t\t" "this help\n"
+ " -o <filename>\t\t" "output into filename\n"
+ " -d\t\t\t" "daemonize\n"
+ " --version\t\t" "print version information and exit\n",
+ prg, PF_CAN, SOCK_RAW, CAN_PROTO_RAW);
}
static void sigterm(int signo)
@@ -62,19 +65,24 @@ int add_filter(u_int32_t id, u_int32_t mask)
return 0;
}
+#define BUF_SIZ (255)
+
int main(int argc, char **argv)
{
int family = PF_CAN, type = SOCK_RAW, proto = CAN_PROTO_RAW;
- int opt;
+ int opt, optdaemon = 0;
struct sockaddr_can addr;
struct can_frame frame;
int nbytes, i;
struct ifreq ifr;
char *ptr;
+ char *optout = NULL;
u_int32_t id, mask;
+ FILE *out = stdout;
+ char buf[BUF_SIZ];
+ int n = 0, err;
- signal(SIGTERM, sigterm);
- signal(SIGHUP, sigterm);
+ signal(SIGPIPE, SIG_IGN);
struct option long_options[] = {
{ "help", no_argument, 0, 'h' },
@@ -86,60 +94,68 @@ int main(int argc, char **argv)
{ 0, 0, 0, 0},
};
- while ((opt = getopt_long(argc, argv, "f:t:p:", long_options, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "f:t:p:o:d", long_options, NULL)) != -1) {
switch (opt) {
- case 'h':
- print_usage(basename(argv[0]));
- exit(0);
-
- case 'f':
- family = strtoul(optarg, NULL, 0);
- break;
-
- case 't':
- type = strtoul(optarg, NULL, 0);
- break;
-
- case 'p':
- proto = strtoul(optarg, NULL, 0);
- break;
-
- case FILTER_OPTION:
- ptr = optarg;
- while(1) {
- id = strtoul(ptr, NULL, 0);
- ptr = strchr(ptr, ':');
- if(!ptr) {
- fprintf(stderr, "filter must be applied in the form id:mask[:id:mask]...\n");
- exit(1);
- }
- ptr++;
- mask = strtoul(ptr, NULL, 0);
- ptr = strchr(ptr, ':');
- add_filter(id,mask);
- if(!ptr)
- break;
- ptr++;
+ case 'd':
+ optdaemon++;
+ break;
+
+ case 'h':
+ print_usage(basename(argv[0]));
+ exit(0);
+
+ case 'f':
+ family = strtoul(optarg, NULL, 0);
+ break;
+
+ case 't':
+ type = strtoul(optarg, NULL, 0);
+ break;
+
+ case 'p':
+ proto = strtoul(optarg, NULL, 0);
+ break;
+
+ case 'o':
+ optout = optarg;
+ break;
+
+ case FILTER_OPTION:
+ ptr = optarg;
+ while(1) {
+ id = strtoul(ptr, NULL, 0);
+ ptr = strchr(ptr, ':');
+ if(!ptr) {
+ fprintf(stderr, "filter must be applied in the form id:mask[:id:mask]...\n");
+ exit(1);
}
- break;
+ ptr++;
+ mask = strtoul(ptr, NULL, 0);
+ ptr = strchr(ptr, ':');
+ add_filter(id,mask);
+ if(!ptr)
+ break;
+ ptr++;
+ }
+ break;
- case VERSION_OPTION:
- printf("candump %s\n",VERSION);
- exit(0);
+ case VERSION_OPTION:
+ printf("candump %s\n",VERSION);
+ exit(0);
- default:
- fprintf(stderr, "Unknown option %c\n", opt);
- break;
+ default:
+ fprintf(stderr, "Unknown option %c\n", opt);
+ break;
}
}
if (optind == argc) {
print_usage(basename(argv[0]));
- exit(0);
+ exit (EXIT_SUCCESS);
}
- printf("interface = %s, family = %d, type = %d, proto = %d\n",
- argv[optind], family, type, proto);
+ fprintf(out, "interface = %s, family = %d, type = %d, proto = %d\n",
+ argv[optind], family, type, proto);
if ((s = socket(family, type, proto)) < 0) {
perror("socket");
return 1;
@@ -163,23 +179,52 @@ int main(int argc, char **argv)
}
}
+ if (optdaemon)
+ daemon(1, 0);
+ else {
+ signal(SIGTERM, sigterm);
+ signal(SIGHUP, sigterm);
+ }
+
+ if (optout) {
+ out = fopen(optout, "a");
+ if (!out) {
+ perror("fopen");
+ exit (EXIT_FAILURE);
+ }
+ }
+
while (running) {
if ((nbytes = read(s, &frame, sizeof(struct can_frame))) < 0) {
perror("read");
return 1;
} else {
if (frame.can_id & CAN_FLAG_EXTENDED)
- printf("<0x%08x> ", frame.can_id & CAN_ID_EXT_MASK);
+ n = snprintf(buf, BUF_SIZ, "<0x%08x> ", frame.can_id & CAN_ID_EXT_MASK);
else
- printf("<0x%03x> ", frame.can_id & CAN_ID_STD_MASK);
+ n = snprintf(buf, BUF_SIZ, "<0x%03x> ", frame.can_id & CAN_ID_STD_MASK);
- printf("[%d] ", frame.can_dlc);
+ n += snprintf(buf + n, BUF_SIZ - n, "[%d] ", frame.can_dlc);
for (i = 0; i < frame.can_dlc; i++) {
- printf("%02x ", frame.payload.data_u8[i]);
+ n += snprintf(buf + n, BUF_SIZ - n, "%02x ", frame.payload.data_u8[i]);
}
if (frame.can_id & CAN_FLAG_RTR)
- printf("remote request");
- printf("\n");
+ n += snprintf(buf + n, BUF_SIZ - n, "remote request");
+
+ fprintf(out, "%s\n", buf);
+
+ do {
+ err = fflush(out);
+ if (err == -1 && errno == EPIPE) {
+ err = -EPIPE;
+ fclose(out);
+ out = fopen(optout, "a");
+ if (!out)
+ exit (EXIT_FAILURE);
+ }
+ } while (err == -EPIPE);
+
+ n = 0;
}
}