2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sbin/hammer/cmd_history.c,v 1.1 2008/02/04 08:34:22 dillon Exp $
39 static void hammer_do_history(const char *path
, off_t off
, int len
);
40 static void dumpat(const char *path
, off_t off
, int len
);
43 * history <file1> ... <fileN>
46 hammer_cmd_history(const char *offset_str
, char **av
, int ac
)
54 if (*offset_str
== '@') {
55 off
= strtoll(offset_str
+ 1, &rptr
, 0);
57 len
= strtol(rptr
+ 1, NULL
, 0);
62 for (i
= 0; i
< ac
; ++i
)
63 hammer_do_history(av
[i
], off
, len
);
67 hammer_do_history(const char *path
, off_t off
, int len
)
69 struct hammer_ioc_history hist
;
75 fd
= open(path
, O_RDONLY
);
77 printf("%s\n", strerror(errno
));
80 bzero(&hist
, sizeof(hist
));
81 hist
.beg_tid
= HAMMER_MIN_TID
;
82 hist
.end_tid
= HAMMER_MAX_TID
;
85 hist
.flags
|= HAMMER_IOC_HISTORY_ATKEY
;
87 hist
.nxt_key
= off
+ 1;
91 if (ioctl(fd
, HAMMERIOC_GETHISTORY
, &hist
) < 0) {
92 printf("%s\n", strerror(errno
));
96 status
= ((hist
.flags
& HAMMER_IOC_HISTORY_UNSYNCED
) ?
98 printf("%016llx %s {\n", hist
.obj_id
, status
);
100 for (i
= 0; i
< hist
.count
; ++i
) {
106 char *hist_path
= NULL
;
108 t
= (int64_t)hist
.tid_ary
[i
] / 1000000000LL;
109 localtime_r(&t
, &tp
);
110 strftime(timebuf1
, sizeof(timebuf1
),
111 "%e-%b-%Y %H:%M:%S", &tp
);
113 asprintf(&hist_path
, "%s@@0x%016llx",
114 path
, hist
.tid_ary
[i
]);
115 if (off
< 0 && stat(hist_path
, &st
) == 0) {
116 localtime_r(&st
.st_mtime
, &tp
);
117 strftime(timebuf2
, sizeof(timebuf2
),
118 "%e-%b-%Y %H:%M:%S %Z", &tp
);
120 snprintf(timebuf2
, sizeof(timebuf2
), "?");
123 printf(" %016llx %s contents-to %s",
127 printf(" %016llx %s",
132 dumpat(hist_path
, off
, len
);
139 if (hist
.flags
& HAMMER_IOC_HISTORY_EOF
)
141 if (hist
.flags
& HAMMER_IOC_HISTORY_NEXT_KEY
)
143 if ((hist
.flags
& HAMMER_IOC_HISTORY_NEXT_TID
) == 0)
145 hist
.beg_tid
= hist
.nxt_tid
;
146 if (ioctl(fd
, HAMMERIOC_GETHISTORY
, &hist
) < 0) {
147 printf(" error: %s\n", strerror(errno
));
156 dumpat(const char *path
, off_t off
, int len
)
163 fd
= open(path
, O_RDONLY
);
168 n
= (len
> (int)sizeof(buf
)) ? (int)sizeof(buf
) : len
;
169 r
= read(fd
, buf
, n
);
173 for (n
= 0; n
< r
; ++n
) {
175 putc(buf
[n
], stdout
);