1/*  Copyright 1996-2002,2005,2007,2009 Alain Knaff.
2 *  This file is part of mtools.
3 *
4 *  Mtools is free software: you can redistribute it and/or modify
5 *  it under the terms of the GNU General Public License as published by
6 *  the Free Software Foundation, either version 3 of the License, or
7 *  (at your option) any later version.
8 *
9 *  Mtools is distributed in the hope that it will be useful,
10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 *  GNU General Public License for more details.
13 *
14 *  You should have received a copy of the GNU General Public License
15 *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Miscellaneous routines.
18 */
19
20#include "sysincludes.h"
21#include "msdos.h"
22#include "stream.h"
23#include "vfat.h"
24#include "mtools.h"
25
26
27void printOom(void)
28{
29	fprintf(stderr, "Out of memory error");
30}
31
32char *get_homedir(void)
33{
34#ifndef OS_mingw32msvc
35	struct passwd *pw;
36	uid_t uid;
37	char *homedir;
38	char *username;
39
40	homedir = getenv ("HOME");
41	/*
42	 * first we call getlogin.
43	 * There might be several accounts sharing one uid
44	 */
45	if ( homedir )
46		return homedir;
47
48	pw = 0;
49
50	username = getenv("LOGNAME");
51	if ( !username )
52		username = getlogin();
53	if ( username )
54		pw = getpwnam( username);
55
56	if ( pw == 0 ){
57		/* if we can't getlogin, look up the pwent by uid */
58		uid = geteuid();
59		pw = getpwuid(uid);
60	}
61
62	/* we might still get no entry */
63	if ( pw )
64		return pw->pw_dir;
65	return 0;
66#else
67	return getenv("HOME");
68#endif
69}
70
71
72static void get_mcwd_file_name(char *file)
73{
74	char *mcwd_path;
75	const char *homedir;
76
77	mcwd_path = getenv("MCWD");
78	if (mcwd_path == NULL || *mcwd_path == '\0'){
79		homedir= get_homedir();
80		if(!homedir)
81			homedir="/tmp";
82		strncpy(file, homedir, MAXPATHLEN-6);
83		file[MAXPATHLEN-6]='\0';
84		strcat( file, "/.mcwd");
85	} else {
86		strncpy(file, mcwd_path, MAXPATHLEN);
87		file[MAXPATHLEN]='\0';
88	}
89}
90
91void unlink_mcwd(void)
92{
93	char file[MAXPATHLEN+1];
94	get_mcwd_file_name(file);
95	unlink(file);
96}
97
98FILE *open_mcwd(const char *mode)
99{
100	struct MT_STAT sbuf;
101	char file[MAXPATHLEN+1];
102	time_t now;
103
104	get_mcwd_file_name(file);
105	if (*mode == 'r'){
106		if (MT_STAT(file, &sbuf) < 0)
107			return NULL;
108		/*
109		 * Ignore the info, if the file is more than 6 hours old
110		 */
111		getTimeNow(&now);
112		if (now - sbuf.st_mtime > 6 * 60 * 60) {
113			fprintf(stderr,
114				"Warning: \"%s\" is out of date, removing it\n",
115				file);
116			unlink(file);
117			return NULL;
118		}
119	}
120
121	return  fopen(file, mode);
122}
123
124
125
126void *safe_malloc(size_t size)
127{
128	void *p;
129
130	p = malloc(size);
131	if(!p){
132		printOom();
133		exit(1);
134	}
135	return p;
136}
137
138void print_sector(const char *message, unsigned char *data, int size)
139{
140	int col;
141	int row;
142
143	printf("%s:\n", message);
144
145	for(row = 0; row * 16 < size; row++){
146		printf("%03x  ", row * 16);
147		for(col = 0; col < 16; col++)
148			printf("%02x ", data [row*16+col]);
149		for(col = 0; col < 16; col++) {
150			if(isprint(data [row*16+col]))
151				printf("%c", data [row*16+col]);
152			else
153				printf(".");
154		}
155		printf("\n");
156	}
157}
158
159
160time_t getTimeNow(time_t *now)
161{
162	static int haveTime = 0;
163	static time_t sharedNow;
164
165	if(!haveTime) {
166		time(&sharedNow);
167		haveTime = 1;
168	}
169	if(now)
170		*now = sharedNow;
171	return sharedNow;
172}
173
174#if 0
175
176#undef free
177#undef malloc
178
179static int total=0;
180
181void myfree(void *ptr)
182{
183	int *size = ((int *) ptr)-1;
184	total -= *size;
185	fprintf(stderr, "freeing %d bytes at %p total alloced=%d\n",
186		*size, ptr, total);
187	free(size);
188}
189
190void *mymalloc(size_t size)
191{
192	int *ptr;
193	ptr = (int *)malloc(size+sizeof(int));
194	if(!ptr)
195		return 0;
196	*ptr = size;
197	ptr++;
198	total += size;
199	fprintf(stderr, "allocating %d bytes at %p total allocated=%d\n",
200		size, ptr, total);
201	return (void *) ptr;
202}
203
204void *mycalloc(size_t nmemb, size_t size)
205{
206	void *ptr = mymalloc(nmemb * size);
207	if(!ptr)
208		return 0;
209	memset(ptr, 0, size);
210	return ptr;
211}
212
213void *myrealloc(void *ptr, size_t size)
214{
215	int oldsize = ((int *)ptr) [-1];
216	void *new = mymalloc(size);
217	if(!new)
218		return 0;
219	memcpy(new, ptr, oldsize);
220	myfree(ptr);
221	return new;
222}
223
224char *mystrdup(char *src)
225{
226	char *dest;
227	dest = mymalloc(strlen(src)+1);
228	if(!dest)
229		return 0;
230	strcpy(dest, src);
231	return dest;
232}
233
234
235#endif
236