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/pwd.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 uid_t 00030 explain_parse_uid_t_or_die(const char *text) 00031 { 00032 /* see if is a user name */ 00033 { 00034 struct passwd *pw; 00035 00036 setpwent(); 00037 pw = getpwnam(text); 00038 if (pw) 00039 return pw->pw_uid; 00040 } 00041 00042 /* see if it is a number */ 00043 { 00044 char *ep; 00045 long result; 00046 00047 ep = 0; 00048 /* 00049 * If endptr is not NULL, strtol() stores the address of the 00050 * first invalid character in *endptr. If there were no digits 00051 * at all, strtol() stores the original value of nptr in *endptr 00052 * (and returns 0). In particular, if *nptr is not '\0' but 00053 * **endptr is '\0' on return, the entire string is valid. 00054 */ 00055 result = strtol(text, &ep, 0); 00056 if (ep != text && *ep == '\0') 00057 return result; 00058 } 00059 00060 /* fuzzy name match for nicer error messages */ 00061 { 00062 double best_weight = 0.6; 00063 int best_gid = -1; 00064 char best_name[100]; 00065 00066 setpwent(); 00067 for (;;) 00068 { 00069 struct passwd *pw; 00070 double w; 00071 00072 pw = getpwent(); 00073 if (!pw) 00074 break; 00075 w = explain_fstrcmp(text, pw->pw_name); 00076 if (w > best_weight) 00077 { 00078 best_weight = w; 00079 explain_strendcpy 00080 ( 00081 best_name, 00082 pw->pw_name, 00083 best_name + sizeof(best_name) 00084 ); 00085 best_gid = pw->pw_gid; 00086 } 00087 } 00088 if (best_gid > 0) 00089 { 00090 explain_output_error_and_die 00091 ( 00092 /* FIXME: i18n */ 00093 "unable to interpret \"%s\" as a user name, " 00094 "did you mean the \"%s\" user instead?", 00095 text, 00096 best_name 00097 ); 00098 } 00099 else 00100 { 00101 explain_output_error_and_die 00102 ( 00103 /* FIXME: i18n */ 00104 "unable to interpret \"%s\" as a user name", 00105 text 00106 ); 00107 } 00108 } 00109 00110 /* I give up */ 00111 return -1; 00112 } 00113 00114 00115 /* vim: set ts=8 sw=4 et : */