Implement upload and download commands.
[libguestfs.git] / daemon / tune2fs.c
1 /* libguestfs - the guestfsd daemon
2  * Copyright (C) 2009 Red Hat Inc. 
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <config.h>
20
21 #define _GNU_SOURCE // for strchrnul
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <ctype.h>
27
28 #include "../src/guestfs_protocol.h"
29 #include "daemon.h"
30 #include "actions.h"
31
32 char **
33 do_tune2fs_l (const char *device)
34 {
35   int r;
36   char *out, *err;
37   char *p, *pend, *colon;
38   char **ret = NULL;
39   int size = 0, alloc = 0;
40
41   IS_DEVICE (device, NULL);
42
43   r = command (&out, &err, "/sbin/tune2fs", "-l", device, NULL);
44   if (r == -1) {
45     reply_with_error ("tune2fs: %s", err);
46     free (err);
47     free (out);
48     return NULL;
49   }
50   free (err);
51
52   p = out;
53
54   /* Discard the first line if it contains "tune2fs ...". */
55   if (strncmp (p, "tune2fs ", 8) == 0) {
56     p = strchr (p, '\n');
57     if (p) p++;
58     else {
59       reply_with_error ("tune2fs: truncated output");
60       free (out);
61       return NULL;
62     }
63   }
64
65   /* Read the lines and split into "key: value". */
66   while (*p) {
67     pend = strchrnul (p, '\n');
68     if (*pend == '\n') {
69       *pend = '\0';
70       pend++;
71     }
72
73     if (!*p) continue;
74
75     colon = strchr (p, ':');
76     if (colon) {
77       *colon = '\0';
78
79       do { colon++; } while (*colon && isspace (*colon));
80
81       if (add_string (&ret, &size, &alloc, p) == -1) {
82         free (out);
83         return NULL;
84       }
85       if (strcmp (colon, "<none>") == 0 ||
86           strcmp (colon, "<not available>") == 0 ||
87           strcmp (colon, "(none)") == 0) {
88         if (add_string (&ret, &size, &alloc, "") == -1) {
89           free (out);
90           return NULL;
91         }
92       } else {
93         if (add_string (&ret, &size, &alloc, colon) == -1) {
94           free (out);
95           return NULL;
96         }
97       }
98     }
99     else {
100       if (add_string (&ret, &size, &alloc, p) == -1) {
101         free (out);
102         return NULL;
103       }
104       if (add_string (&ret, &size, &alloc, "") == -1) {
105         free (out);
106         return NULL;
107       }
108     }
109
110     p = pend;
111   }
112
113   free (out);
114
115   if (add_string (&ret, &size, &alloc, NULL) == -1)
116     return NULL;
117
118   return ret;
119 }