libexplain
1.4.D001
|
00001 /* 00002 * libexplain - a library of system-call-specific strerror replacements 00003 * Copyright (C) 2012, 2013 Peter Miller 00004 * Written by Peter Miller <pmiller@opensource.org.au> 00005 * 00006 * This program is free software; you can redistribute it and/or modify it 00007 * under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 3 of the License, or (at your 00009 * option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, but WITHOUT 00012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00014 * License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include <libexplain/ac/grp.h> 00021 #include <libexplain/ac/stdlib.h> 00022 #include <libexplain/ac/string.h> 00023 00024 #include <libexplain/fstrcmp.h> 00025 #include <libexplain/output.h> 00026 #include <libexplain/string_to_thing.h> 00027 00028 00029 gid_t 00030 explain_parse_gid_t_or_die(const char *text) 00031 { 00032 /* see if it is a group name */ 00033 { 00034 struct group *gr; 00035 00036 setgrent(); 00037 gr = getgrnam(text); 00038 if (gr) 00039 return gr->gr_gid; 00040 } 00041 00042 /* see if it is a number */ 00043 { 00044 char *ep; 00045 long result; 00046 00047 result = strtol(text, &ep, 0); 00048 if (ep != text && *ep == '\0') 00049 return result; 00050 } 00051 00052 /* fuzzy name match for nicer error messages */ 00053 { 00054 double best_weight = 0.6; 00055 int best_gid = -1; 00056 char best_name[100]; 00057 00058 setgrent(); 00059 for (;;) 00060 { 00061 double w; 00062 struct group *gr; 00063 00064 gr = getgrent(); 00065 if (!gr) 00066 break; 00067 w = explain_fstrcmp(text, gr->gr_name); 00068 if (w > best_weight) 00069 { 00070 best_weight = w; 00071 explain_strendcpy 00072 ( 00073 best_name, 00074 gr->gr_name, 00075 best_name + sizeof(best_name) 00076 ); 00077 best_gid = gr->gr_gid; 00078 } 00079 } 00080 if (best_gid > 0) 00081 { 00082 explain_output_error_and_die 00083 ( 00084 /* FIXME: i18n */ 00085 "unable to interpret \"%s\" as a group name, " 00086 "did you mean the \"%s\" group instead?", 00087 text, 00088 best_name 00089 ); 00090 } 00091 else 00092 { 00093 explain_output_error_and_die 00094 ( 00095 /* FIXME: i18n */ 00096 "unable to interpret \"%s\" as a group name", 00097 text 00098 ); 00099 } 00100 } 00101 00102 /* I give up */ 00103 return -1; 00104 } 00105 00106 00107 /* vim: set ts=8 sw=4 et : */