1235537Sgber/*-
2235537Sgber * Copyright (c) 2012 The FreeBSD Foundation
3235537Sgber * All rights reserved.
4235537Sgber *
5235537Sgber * This software was developed by Semihalf under sponsorship
6235537Sgber * from the FreeBSD Foundation.
7235537Sgber *
8235537Sgber * Redistribution and use in source and binary forms, with or without
9235537Sgber * modification, are permitted provided that the following conditions
10235537Sgber * are met:
11235537Sgber *
12235537Sgber * 1. Redistributions of source code must retain the above copyright
13235537Sgber *    notice, this list of conditions and the following disclaimer.
14235537Sgber * 2. Redistributions in binary form must reproduce the above copyright
15235537Sgber *    notice, this list of conditions and the following disclaimer in the
16235537Sgber *    documentation and/or other materials provided with the distribution.
17235537Sgber *
18235537Sgber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19235537Sgber * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20235537Sgber * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21235537Sgber * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22235537Sgber * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23235537Sgber * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24235537Sgber * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25235537Sgber * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26235537Sgber * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27235537Sgber * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28235537Sgber * SUCH DAMAGE.
29235537Sgber */
30235537Sgber
31235537Sgber#include <sys/cdefs.h>
32235537Sgber__FBSDID("$FreeBSD$");
33235537Sgber#include <sys/types.h>
34235537Sgber
35235537Sgber#include <stdio.h>
36235537Sgber#include <stdlib.h>
37235537Sgber#include <sysexits.h>
38235537Sgber#include <time.h>
39235537Sgber
40235537Sgber#include <fs/nandfs/nandfs_fs.h>
41235537Sgber#include <libnandfs.h>
42235537Sgber
43235537Sgber#include "nandfs.h"
44235537Sgber
45235537Sgber#define NCPINFO	512
46235537Sgber
47235537Sgberstatic void
48235537Sgberlssnap_usage(void)
49235537Sgber{
50235537Sgber
51235537Sgber	fprintf(stderr, "usage:\n");
52235537Sgber	fprintf(stderr, "\tlssnap node\n");
53235537Sgber}
54235537Sgber
55235537Sgberstatic void
56235537Sgberprint_cpinfo(struct nandfs_cpinfo *cpinfo)
57235537Sgber{
58235537Sgber	struct tm tm;
59235537Sgber	time_t t;
60235537Sgber	char timebuf[128];
61235537Sgber
62235537Sgber	t = (time_t)cpinfo->nci_create;
63235537Sgber	localtime_r(&t, &tm);
64235537Sgber	strftime(timebuf, sizeof(timebuf), "%F %T", &tm);
65235537Sgber
66235537Sgber	printf("%20llu  %s\n", (unsigned long long)cpinfo->nci_cno, timebuf);
67235537Sgber}
68235537Sgber
69235537Sgberint
70235537Sgbernandfs_lssnap(int argc, char **argv)
71235537Sgber{
72235537Sgber	struct nandfs_cpinfo *cpinfos;
73235537Sgber	struct nandfs fs;
74235537Sgber	uint64_t next;
75235537Sgber	int error, nsnap, i;
76235537Sgber
77235537Sgber	if (argc != 1) {
78235537Sgber		lssnap_usage();
79235537Sgber		return (EX_USAGE);
80235537Sgber	}
81235537Sgber
82235537Sgber	cpinfos = malloc(sizeof(*cpinfos) * NCPINFO);
83235537Sgber	if (cpinfos == NULL) {
84235537Sgber		fprintf(stderr, "cannot allocate memory\n");
85235537Sgber		return (-1);
86235537Sgber	}
87235537Sgber
88235537Sgber	nandfs_init(&fs, argv[0]);
89235537Sgber	error = nandfs_open(&fs);
90235537Sgber	if (error == -1) {
91235537Sgber		fprintf(stderr, "nandfs_open: %s\n", nandfs_errmsg(&fs));
92235537Sgber		goto out;
93235537Sgber	}
94235537Sgber
95235537Sgber	for (next = 1; next != 0; next = cpinfos[nsnap - 1].nci_next) {
96235537Sgber		nsnap = nandfs_get_snap(&fs, next, cpinfos, NCPINFO);
97235537Sgber		if (nsnap < 1)
98235537Sgber			break;
99235537Sgber
100235537Sgber		for (i = 0; i < nsnap; i++)
101235537Sgber			print_cpinfo(&cpinfos[i]);
102235537Sgber	}
103235537Sgber
104235537Sgber	if (nsnap == -1)
105235537Sgber		fprintf(stderr, "nandfs_get_snap: %s\n", nandfs_errmsg(&fs));
106235537Sgber
107235537Sgberout:
108235537Sgber	nandfs_close(&fs);
109235537Sgber	nandfs_destroy(&fs);
110235537Sgber	free(cpinfos);
111235537Sgber	return (error);
112235537Sgber}
113