tizen: kdbus: make i explicitly positive in make_single_header_vector
[platform/upstream/glib.git] / gio / gio-tool-set.c
1 /*
2  * Copyright 2015 Red Hat, Inc.
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  *
19  * Author: Matthias Clasen <mclasen@redhat.com>
20  */
21
22 #include "config.h"
23
24 #include <gio/gio.h>
25 #include <gi18n.h>
26 #include <stdlib.h>
27
28 #include "gio-tool.h"
29
30
31 static char *attr_type = "string";
32 static gboolean nofollow_symlinks = FALSE;
33 static gboolean delete = FALSE;
34
35 static const GOptionEntry entries[] = {
36   { "type", 't', 0, G_OPTION_ARG_STRING, &attr_type, N_("Type of the attribute"), N_("TYPE") },
37   { "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don’t follow symbolic links"), NULL },
38   { "delete", 'd', 0, G_OPTION_ARG_NONE, &delete, N_("Unset given attribute"), NULL },
39   G_OPTION_ENTRY_NULL
40 };
41
42 static char *
43 hex_unescape (const char *str)
44 {
45   int i;
46   char *unescaped_str, *p;
47   unsigned char c;
48   int len;
49
50   len = strlen (str);
51   unescaped_str = g_malloc (len + 1);
52
53   p = unescaped_str;
54   for (i = 0; i < len; i++)
55     {
56       if (str[i] == '\\' &&
57           str[i+1] == 'x' &&
58           len - i >= 4)
59         {
60           c =
61             (g_ascii_xdigit_value (str[i+2]) << 4) |
62             g_ascii_xdigit_value (str[i+3]);
63           *p++ = c;
64           i += 3;
65         }
66       else
67         *p++ = str[i];
68     }
69   *p++ = 0;
70
71   return unescaped_str;
72 }
73
74 int
75 handle_set (int argc, char *argv[], gboolean do_help)
76 {
77   GOptionContext *context;
78   GError *error = NULL;
79   GFile *file;
80   const char *attribute;
81   GFileAttributeType type;
82   gpointer value;
83   gpointer value_allocated = NULL;
84   gboolean b;
85   guint32 uint32;
86   gint32 int32;
87   guint64 uint64;
88   gint64 int64;
89   gchar *param;
90   int retval = 0;
91
92   g_set_prgname ("gio set");
93
94   /* Translators: commandline placeholder */
95   param = g_strdup_printf ("%s %s %s…", _("LOCATION"), _("ATTRIBUTE"), _("VALUE"));
96   context = g_option_context_new (param);
97   g_free (param);
98   g_option_context_set_help_enabled (context, FALSE);
99   g_option_context_set_summary (context, _("Set a file attribute of LOCATION."));
100   g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
101
102   if (do_help)
103     {
104       show_help (context, NULL);
105       g_option_context_free (context);
106       return 0;
107     }
108
109   if (!g_option_context_parse (context, &argc, &argv, &error))
110     {
111       show_help (context, error->message);
112       g_error_free (error);
113       g_option_context_free (context);
114       return 1;
115     }
116
117   if (argc < 2)
118     {
119       show_help (context, _("Location not specified"));
120       g_option_context_free (context);
121       return 1;
122     }
123
124   if (argc < 3)
125     {
126       show_help (context, _("Attribute not specified"));
127       g_option_context_free (context);
128       return 1;
129     }
130
131   attribute = argv[2];
132   if (delete)
133     {
134       type = G_FILE_ATTRIBUTE_TYPE_INVALID;
135     }
136   else
137     {
138       type = attribute_type_from_string (attr_type);
139     }
140
141   if ((argc < 4) && (type != G_FILE_ATTRIBUTE_TYPE_INVALID))
142     {
143       show_help (context, _("Value not specified"));
144       g_option_context_free (context);
145       return 1;
146     }
147
148   if ((argc > 4) && (type != G_FILE_ATTRIBUTE_TYPE_STRINGV))
149     {
150       show_help (context, _("Too many arguments"));
151       g_option_context_free (context);
152       return 1;
153     }
154
155   g_option_context_free (context);
156
157   switch (type)
158     {
159     case G_FILE_ATTRIBUTE_TYPE_STRING:
160       value = argv[3];
161       break;
162     case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
163       value = value_allocated = hex_unescape (argv[3]);
164       break;
165     case G_FILE_ATTRIBUTE_TYPE_BOOLEAN:
166       b = g_ascii_strcasecmp (argv[3], "true") == 0;
167       value = &b;
168       break;
169     case G_FILE_ATTRIBUTE_TYPE_UINT32:
170       uint32 = atol (argv[3]);
171       value = &uint32;
172       break;
173     case G_FILE_ATTRIBUTE_TYPE_INT32:
174       int32 = atol (argv[3]);
175       value = &int32;
176       break;
177     case G_FILE_ATTRIBUTE_TYPE_UINT64:
178       uint64 = g_ascii_strtoull (argv[3], NULL, 10);
179       value = &uint64;
180       break;
181     case G_FILE_ATTRIBUTE_TYPE_INT64:
182       int64 = g_ascii_strtoll (argv[3], NULL, 10);
183       value = &int64;
184       break;
185     case G_FILE_ATTRIBUTE_TYPE_STRINGV:
186       value = &argv[3];
187       break;
188     case G_FILE_ATTRIBUTE_TYPE_INVALID:
189       value = NULL;
190       break;
191     case G_FILE_ATTRIBUTE_TYPE_OBJECT:
192     default:
193       print_error (_("Invalid attribute type “%s”"), attr_type);
194       return 1;
195     }
196
197   file = g_file_new_for_commandline_arg (argv[1]);
198
199   if (!g_file_set_attribute (file,
200                              attribute,
201                              type,
202                              value,
203                              nofollow_symlinks ?
204                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS :
205                                G_FILE_QUERY_INFO_NONE,
206                              NULL, &error))
207     {
208       print_error ("%s", error->message);
209       g_error_free (error);
210       retval = 1;
211     }
212
213   g_clear_pointer (&value_allocated, g_free);
214   g_object_unref (file);
215
216   return retval;
217 }