1 /*
2     tools.c -- common tools for the all progs.
3     Copyright (C) 2001, 2002 Yury Umanets <torque@ukrpost.net>, see COPYING for
4     licensing and copyright details.
5 */
6 
7 #ifdef HAVE_CONFIG_H
8 #  include <config.h>
9 #endif
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdarg.h>
15 #include <errno.h>
16 #include <sys/stat.h>
17 
18 #include <reiserfs/exception.h>
19 #include <reiserfs/debug.h>
20 #include <reiserfs/libprogs_tools.h>
21 
22 #if ENABLE_NLS
23 #  include <locale.h>
24 #  include <libintl.h>
25 #  define _(String) dgettext (PACKAGE, String)
26 #else
27 #  define _(String) (String)
28 #endif
29 
30 #define KB 1024
31 #define MB (1024 * KB)
32 #define GB (1024 * MB)
33 
progs_strtol(const char * str,int * error)34 long progs_strtol(const char *str, int *error) {
35     char *err;
36     long result = 0;
37 
38     if (error)
39 	*error = 0;
40 
41     if (!str) {
42 	if (error) *error = 1;
43 	return 0;
44     }
45 
46     result = strtol(str, &err, 10);
47 
48     if (errno == ERANGE || *err) {
49 	if (error) *error = 1;
50 	return 0;
51     }
52 
53     return result;
54 }
55 
56 /* Choose functions */
progs_choose_check(const char * chooses,int choose)57 int progs_choose_check(const char *chooses, int choose) {
58     unsigned i;
59 
60     if (!chooses) return 0;
61 
62     for (i = 0; i < strlen(chooses); i++)
63 	if (chooses[i] == choose) return 1;
64 
65     return 0;
66 }
67 
progs_choose(const char * chooses,const char * error,const char * format,...)68 int progs_choose(const char *chooses, const char *error, const char *format, ...) {
69     va_list args;
70     int choose, prompts = 0;
71     char mess[4096], buf[255];
72 
73     if (!chooses || !format || !error)
74 	return 0;
75 
76     memset(mess, 0, 4096);
77 
78     va_start(args, format);
79     vsprintf(mess, format, args);
80     va_end(args);
81 
82     fprintf(stderr, mess);
83     fflush(stderr);
84 
85     do {
86 	memset(buf, 0, 255);
87 
88 	fgets(buf, 255, stdin);
89 	choose = buf[0];
90 
91 	if (progs_choose_check(chooses, choose))
92 	    break;
93 
94 	if (prompts < 2) {
95 	    fprintf(stderr, error);
96 	    fflush(stderr);
97 	}
98     } while (prompts++ < 2);
99 
100     if (!progs_choose_check(chooses, choose))
101 	choose = 0;
102 
103     return choose;
104 }
105 
106 /* Device functions */
progs_dev_check(const char * dev)107 int progs_dev_check(const char *dev) {
108     struct stat st;
109 
110     if (!dev)
111 	return 0;
112 
113     if (stat(dev, &st) == -1)
114 	return 0;
115 
116     if (!S_ISBLK(st.st_mode)) {
117 	libreiserfs_exception_throw(EXCEPTION_WARNING, EXCEPTION_IGNORE,
118 	    _("Device %s isn't a block device."), dev);
119     }
120 
121     return 1;
122 }
123 
124 /* Parsing functions */
progs_digit_check(const char * str)125 int progs_digit_check(const char *str) {
126     int error = 0;
127 
128     progs_digit_parse(str, 4096, &error);
129     return !error;
130 }
131 
progs_digit_parse(const char * str,size_t blocksize,int * error)132 long progs_digit_parse(const char *str, size_t blocksize, int *error) {
133     long long size;
134     char number[255], label = 0;
135 
136     if (error)
137 	*error = 0;
138 
139     if (!str || strlen(str) == 0 || !blocksize) {
140 	if (error) *error = 1;
141 	return 0;
142     }
143 
144     memset(number, 0, 255);
145     strncpy(number, str, strlen(str));
146     label = number[strlen(number) - 1];
147 
148     if (label == 'K' || label == 'M' || label == 'G')
149 	number[strlen(number) - 1] = '\0';
150     else
151 	label = 0;
152 
153     if ((size = progs_strtol(number, error)) == 0 && *error)
154 	return 0;
155 
156     if (label == 0 || label == 'M')
157 	size = size * MB;
158     else if (label == 'K')
159 	size = size * KB;
160     else if (label == 'G')
161 	size = size * GB;
162 
163     return size / blocksize;
164 }
165 
166