Merge branch 'issue-699' into 'master'
[glib.git] / gio / gio-tool-set.c
blobab3ac1544ebeb1047af8a7813fe4de5b333454ee
1 /*
2 * Copyright 2015 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library 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 GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 * Author: Matthias Clasen <mclasen@redhat.com>
20 #include "config.h"
22 #include <gio/gio.h>
23 #include <gi18n.h>
24 #include <stdlib.h>
26 #include "gio-tool.h"
29 static char *attr_type = "string";
30 static gboolean nofollow_symlinks = FALSE;
32 static const GOptionEntry entries[] = {
33 { "type", 't', 0, G_OPTION_ARG_STRING, &attr_type, N_("Type of the attribute"), N_("TYPE") },
34 { "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don’t follow symbolic links"), NULL },
35 { NULL }
38 static char *
39 hex_unescape (const char *str)
41 int i;
42 char *unescaped_str, *p;
43 unsigned char c;
44 int len;
46 len = strlen (str);
47 unescaped_str = g_malloc (len + 1);
49 p = unescaped_str;
50 for (i = 0; i < len; i++)
52 if (str[i] == '\\' &&
53 str[i+1] == 'x' &&
54 len - i >= 4)
56 c =
57 (g_ascii_xdigit_value (str[i+2]) << 4) |
58 g_ascii_xdigit_value (str[i+3]);
59 *p++ = c;
60 i += 3;
62 else
63 *p++ = str[i];
65 *p++ = 0;
67 return unescaped_str;
70 int
71 handle_set (int argc, char *argv[], gboolean do_help)
73 GOptionContext *context;
74 GError *error = NULL;
75 GFile *file;
76 const char *attribute;
77 GFileAttributeType type;
78 gpointer value;
79 gboolean b;
80 guint32 uint32;
81 gint32 int32;
82 guint64 uint64;
83 gint64 int64;
84 gchar *param;
86 g_set_prgname ("gio set");
88 /* Translators: commandline placeholder */
89 param = g_strdup_printf ("%s %s %s…", _("LOCATION"), _("ATTRIBUTE"), _("VALUE"));
90 context = g_option_context_new (param);
91 g_free (param);
92 g_option_context_set_help_enabled (context, FALSE);
93 g_option_context_set_summary (context, _("Set a file attribute of LOCATION."));
94 g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
96 if (do_help)
98 show_help (context, NULL);
99 g_option_context_free (context);
100 return 0;
103 if (!g_option_context_parse (context, &argc, &argv, &error))
105 show_help (context, error->message);
106 g_error_free (error);
107 g_option_context_free (context);
108 return 1;
111 if (argc < 2)
113 show_help (context, _("Location not specified"));
114 g_option_context_free (context);
115 return 1;
118 if (argc < 3)
120 show_help (context, _("Attribute not specified"));
121 g_option_context_free (context);
122 return 1;
125 attribute = argv[2];
127 type = attribute_type_from_string (attr_type);
128 if ((argc < 4) && (type != G_FILE_ATTRIBUTE_TYPE_INVALID))
130 show_help (context, _("Value not specified"));
131 g_option_context_free (context);
132 return 1;
135 if ((argc > 4) && (type != G_FILE_ATTRIBUTE_TYPE_STRINGV))
137 show_help (context, _("Too many arguments"));
138 g_option_context_free (context);
139 return 1;
142 g_option_context_free (context);
144 switch (type)
146 case G_FILE_ATTRIBUTE_TYPE_STRING:
147 value = argv[3];
148 break;
149 case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
150 value = hex_unescape (argv[3]);
151 break;
152 case G_FILE_ATTRIBUTE_TYPE_BOOLEAN:
153 b = g_ascii_strcasecmp (argv[3], "true") == 0;
154 value = &b;
155 break;
156 case G_FILE_ATTRIBUTE_TYPE_UINT32:
157 uint32 = atol (argv[3]);
158 value = &uint32;
159 break;
160 case G_FILE_ATTRIBUTE_TYPE_INT32:
161 int32 = atol (argv[3]);
162 value = &int32;
163 break;
164 case G_FILE_ATTRIBUTE_TYPE_UINT64:
165 uint64 = g_ascii_strtoull (argv[3], NULL, 10);
166 value = &uint64;
167 break;
168 case G_FILE_ATTRIBUTE_TYPE_INT64:
169 int64 = g_ascii_strtoll (argv[3], NULL, 10);
170 value = &int64;
171 break;
172 case G_FILE_ATTRIBUTE_TYPE_STRINGV:
173 value = &argv[3];
174 break;
175 case G_FILE_ATTRIBUTE_TYPE_INVALID:
176 value = NULL;
177 break;
178 case G_FILE_ATTRIBUTE_TYPE_OBJECT:
179 default:
180 print_error (_("Invalid attribute type “%s”"), attr_type);
181 return 1;
184 file = g_file_new_for_commandline_arg (argv[1]);
186 if (!g_file_set_attribute (file,
187 attribute,
188 type,
189 value,
190 nofollow_symlinks ?
191 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS :
192 G_FILE_QUERY_INFO_NONE,
193 NULL, &error))
195 print_error ("%s", error->message);
196 g_error_free (error);
197 g_object_unref (file);
198 return 1;
201 g_object_unref (file);
203 return 0;