1 /*
2 
3   G N O K I I
4 
5   A Linux/Unix toolset and driver for the mobile phones.
6 
7   This file is part of gnokii.
8 
9   Gnokii is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13 
14   Gnokii is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18 
19   You should have received a copy of the GNU General Public License
20   along with gnokii; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 
23   Copyright (C) 1999-2000  Hugh Blemings & Pavel Janik ml.
24   Copyright (C) 1999-2000  Gary Reuter, Reinhold Jordan
25   Copyright (C) 1999-2011  Pawel Kot
26   Copyright (C) 2000-2002  Marcin Wiacek, Chris Kemp, Manfred Jonsson
27   Copyright (C) 2001       Marian Jancar, Bartek Klepacz
28   Copyright (C) 2001-2002  Pavel Machek, Markus Plail
29   Copyright (C) 2002       Ladis Michl, Simon Huggins
30   Copyright (C) 2002-2004  BORBELY Zoltan
31   Copyright (C) 2003       Bertrik Sikken
32   Copyright (C) 2004       Martin Goldhahn
33 
34   Mainline code for gnokii utility. Utils functions.
35 
36 */
37 
38 #include "config.h"
39 #include "misc.h"
40 #include "compat.h"
41 
42 #include <stdio.h>
43 #include <signal.h>
44 #ifdef HAVE_SYS_STAT_H
45 #  include <sys/stat.h>
46 #endif
47 
48 #include "gnokii-app.h"
49 #include "gnokii.h"
50 
askoverwrite(const char * filename,int mode)51 int askoverwrite(const char *filename, int mode)
52 {
53 	int confirm = -1;
54 	char ans[5];
55 	struct stat buf;
56 
57 	/* Ask before overwriting */
58 	if ((mode == 1) && (stat(filename, &buf) == 0)) {
59 		fprintf(stdout, _("File %s exists.\n"), filename);
60 		while (confirm < 0) {
61 			fprintf(stdout, _("Overwrite? (yes/no) "));
62 			gn_line_get(stdin, ans, sizeof(ans) - 1);
63 			if (!strcmp(ans, _("yes")))
64 				confirm = 1;
65 			else if (!strcmp(ans, _("no")))
66 				confirm = 0;
67 		}
68 		if (!confirm)
69 			return -1;
70 	}
71 	return mode;
72 }
73 
74 /* FIXME - this should not ask for confirmation here - I'm not sure what calls it though */
75 /* mode == 0 -> overwrite
76  * mode == 1 -> ask
77  * mode == 2 -> append
78  */
writefile(char * filename,char * text,int mode)79 int writefile(char *filename, char *text, int mode)
80 {
81 	FILE *file;
82 
83 	mode = askoverwrite(filename, mode);
84 
85 	/* append */
86 	if (mode == 2)
87 		file = fopen(filename, "a");
88 	/* overwrite */
89 	else
90 		file = fopen(filename, "w");
91 
92 	if (!file) {
93 		fprintf(stderr, _("Can't open file %s for writing!\n"),  filename);
94 		return -1;
95 	}
96 	fprintf(file, "%s\n", text);
97 	fclose(file);
98 	/* Return value is used as new mode. Set it to append mode */
99 	return 2;
100 }
101 
writebuffer(const char * filename,const char * buffer,size_t nitems,int mode)102 int writebuffer(const char *filename, const char *buffer, size_t nitems, int mode)
103 {
104 	/* Return value is used as new mode. Set it to append mode */
105 	int retval = 2;
106 	FILE *file;
107 
108 	mode = askoverwrite(filename, mode);
109 
110 	/* append */
111 	if (mode == 2)
112 		file = fopen(filename, "a");
113 	/* overwrite */
114 	else
115 		file = fopen(filename, "w");
116 
117 	if (!file) {
118 		fprintf(stderr, _("Can't open file %s for writing!\n"),  filename);
119 		retval = -1;
120 		goto out;
121 	}
122 	if (fwrite(buffer, 1, nitems, file) != nitems)
123 		retval = -1;
124 	fclose(file);
125 out:
126 	return retval;
127 }
128 
readtext(gn_sms_user_data * udata)129 gn_error readtext(gn_sms_user_data *udata)
130 {
131 	/* The maximum length of an uncompressed concatenated short message is
132 	   255 * 153 = 39015 default alphabet characters */
133 	char message_buffer[255 * GN_SMS_MAX_LENGTH];
134 	int chars_read;
135 
136 #ifndef	WIN32
137 	if (isatty(0))
138 #endif
139 		fprintf(stderr, _("Please enter SMS text. End your input with <cr><control-D>:\n"));
140 
141 	/* Get message text from stdin. */
142 	chars_read = fread(message_buffer, 1, sizeof(message_buffer), stdin);
143 
144 	if (chars_read == 0) {
145 		fprintf(stderr, _("Couldn't read from stdin!\n"));
146 		return GN_ERR_INTERNALERROR;
147 	}
148 	if (udata->type != GN_SMS_DATA_iMelody && chars_read > 0 && message_buffer[chars_read - 1] == '\n')
149 		message_buffer[--chars_read] = 0;
150 	if (chars_read > (sizeof(udata->u.text) - 1)) {
151  		fprintf(stderr, _("Input too long! (%d, maximum is %d)\n"), chars_read, (int)(sizeof(udata->u.text) - 1));
152 		return GN_ERR_INTERNALERROR;
153 	}
154 
155 	udata->length = snprintf(udata->u.text, sizeof(udata->u.text), "%s", message_buffer);
156 
157 	return GN_ERR_NONE;
158 }
159 
loadbitmap(gn_bmp * bitmap,char * s,int type,struct gn_statemachine * state)160 gn_error loadbitmap(gn_bmp *bitmap, char *s, int type, struct gn_statemachine *state)
161 {
162 	gn_error error;
163 	bitmap->type = type;
164 	error = gn_bmp_null(bitmap, &state->driver.phone);
165 	if (error != GN_ERR_NONE) {
166 		fprintf(stderr, _("Could not null bitmap: %s\n"), gn_error_print(error));
167 		return error;
168 	}
169 	error = gn_file_bitmap_read(s, bitmap, &state->driver.phone);
170 	if (error != GN_ERR_NONE) {
171 		fprintf(stderr, _("Could not load bitmap from %s: %s\n"), s, gn_error_print(error));
172 		return error;
173 	}
174 	return GN_ERR_NONE;
175 }
176 
177 /*
178  * Does almost the same as atoi().
179  * Returns error in case when the string is not numerical or when strtol returns an error.
180  * Modifies errno variable.
181  */
gnokii_atoi(char * string)182 int gnokii_atoi(char *string)
183 {
184 	char *aux = NULL;
185 	int num;
186 
187 	errno = 0;
188 	num = strtol(string, &aux, 10);
189 	if (*aux)
190 		errno = ERANGE;
191 	return num;
192 }
193 
194 /* Calculates end value from the command line of the form:
195  * gnokii --something [...] start [end]
196  * where end can be either number or 'end' string.
197  * If end is less than start, it is set to start value.
198  */
parse_end_value_option(int argc,char * argv[],int pos,int start_value)199 int parse_end_value_option(int argc, char *argv[], int pos, int start_value)
200 {
201 	int retval = start_value;
202 
203 	if (argc > pos && (argv[pos][0] != '-')) {
204 		if (!strcasecmp(argv[pos], "end"))
205 			retval = INT_MAX;
206 		else
207 			retval = gnokii_atoi(argv[pos]);
208 	}
209 	if (retval < start_value) {
210 		fprintf(stderr, _("Warning: end value (%d) is less than start value (%d). Setting it to the start value (%d)\n"),
211 			retval, start_value, start_value);
212 		retval = start_value;
213 	}
214 
215 	return retval;
216 }
217 
218 volatile bool bshutdown = false;
219 
220 /* SIGINT signal handler. */
interrupted(int sig)221 void interrupted(int sig)
222 {
223 	signal(sig, SIG_IGN);
224 	bshutdown = true;
225 }
226 
console_raw(void)227 void console_raw(void)
228 {
229 #ifndef WIN32
230 	struct termios it;
231 
232 	tcgetattr(fileno(stdin), &it);
233 	it.c_lflag &= ~(ICANON);
234 	//it.c_iflag &= ~(INPCK|ISTRIP|IXON);
235 	it.c_cc[VMIN] = 1;
236 	it.c_cc[VTIME] = 0;
237 
238 	tcsetattr(fileno(stdin), TCSANOW, &it);
239 #endif
240 }
241 
242