You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
295 lines
5.6 KiB
295 lines
5.6 KiB
/* Copyright 1996-2002,2005,2007,2009,2011 Alain Knaff.
|
|
* This file is part of mtools.
|
|
*
|
|
* Mtools is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Mtools is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Mtools. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Miscellaneous routines.
|
|
*/
|
|
|
|
#include "sysincludes.h"
|
|
#include "msdos.h"
|
|
#include "stream.h"
|
|
#include "vfat.h"
|
|
#include "mtools.h"
|
|
|
|
|
|
void printOom(void)
|
|
{
|
|
fprintf(stderr, "Out of memory error");
|
|
}
|
|
|
|
char *get_homedir(void)
|
|
{
|
|
#ifndef OS_mingw32msvc
|
|
struct passwd *pw;
|
|
uid_t uid;
|
|
char *homedir;
|
|
char *username;
|
|
|
|
homedir = getenv ("HOME");
|
|
/*
|
|
* first we call getlogin.
|
|
* There might be several accounts sharing one uid
|
|
*/
|
|
if ( homedir )
|
|
return homedir;
|
|
|
|
pw = 0;
|
|
|
|
username = getenv("LOGNAME");
|
|
if ( !username )
|
|
username = getlogin();
|
|
if ( username )
|
|
pw = getpwnam( username);
|
|
|
|
if ( pw == 0 ){
|
|
/* if we can't getlogin, look up the pwent by uid */
|
|
uid = geteuid();
|
|
pw = getpwuid(uid);
|
|
}
|
|
|
|
/* we might still get no entry */
|
|
if ( pw )
|
|
return pw->pw_dir;
|
|
return 0;
|
|
#else
|
|
return getenv("HOME");
|
|
#endif
|
|
}
|
|
|
|
|
|
static void get_mcwd_file_name(char *file)
|
|
{
|
|
char *mcwd_path;
|
|
const char *homedir;
|
|
|
|
mcwd_path = getenv("MCWD");
|
|
if (mcwd_path == NULL || *mcwd_path == '\0'){
|
|
homedir= get_homedir();
|
|
if(!homedir)
|
|
homedir="/tmp";
|
|
strncpy(file, homedir, MAXPATHLEN-6);
|
|
file[MAXPATHLEN-6]='\0';
|
|
strcat( file, "/.mcwd");
|
|
} else {
|
|
strncpy(file, mcwd_path, MAXPATHLEN);
|
|
file[MAXPATHLEN]='\0';
|
|
}
|
|
}
|
|
|
|
void unlink_mcwd(void)
|
|
{
|
|
char file[MAXPATHLEN+1];
|
|
get_mcwd_file_name(file);
|
|
unlink(file);
|
|
}
|
|
|
|
FILE *open_mcwd(const char *mode)
|
|
{
|
|
struct MT_STAT sbuf;
|
|
char file[MAXPATHLEN+1];
|
|
time_t now;
|
|
|
|
get_mcwd_file_name(file);
|
|
if (*mode == 'r'){
|
|
if (MT_STAT(file, &sbuf) < 0)
|
|
return NULL;
|
|
/*
|
|
* Ignore the info, if the file is more than 6 hours old
|
|
*/
|
|
getTimeNow(&now);
|
|
if (now - sbuf.st_mtime > 6 * 60 * 60) {
|
|
fprintf(stderr,
|
|
"Warning: \"%s\" is out of date, removing it\n",
|
|
file);
|
|
unlink(file);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return fopen(file, mode);
|
|
}
|
|
|
|
|
|
|
|
void *safe_malloc(size_t size)
|
|
{
|
|
void *p;
|
|
|
|
p = malloc(size);
|
|
if(!p){
|
|
printOom();
|
|
exit(1);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
void print_sector(const char *message, unsigned char *data, int size)
|
|
{
|
|
int col;
|
|
int row;
|
|
|
|
printf("%s:\n", message);
|
|
|
|
for(row = 0; row * 16 < size; row++){
|
|
printf("%03x ", row * 16);
|
|
for(col = 0; col < 16; col++)
|
|
printf("%02x ", data [row*16+col]);
|
|
for(col = 0; col < 16; col++) {
|
|
if(isprint(data [row*16+col]))
|
|
printf("%c", data [row*16+col]);
|
|
else
|
|
printf(".");
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
#if (SIZEOF_TIME_T > SIZEOF_LONG) && defined (HAVE_STRTOLL)
|
|
# define STRTOTIME strtoll
|
|
#else
|
|
# define STRTOTIME strtol
|
|
#endif
|
|
|
|
time_t getTimeNow(time_t *now)
|
|
{
|
|
static int haveTime = 0;
|
|
static time_t sharedNow;
|
|
|
|
if(!haveTime) {
|
|
const char *source_date_epoch = getenv("SOURCE_DATE_EPOCH");
|
|
if (source_date_epoch) {
|
|
char *endptr;
|
|
time_t epoch =
|
|
STRTOTIME(source_date_epoch, &endptr, 10);
|
|
errno = 0;
|
|
|
|
if (endptr == source_date_epoch)
|
|
fprintf(stderr,
|
|
"SOURCE_DATE_EPOCH \"%s\" invalid\n",
|
|
source_date_epoch);
|
|
else if (errno != 0)
|
|
fprintf(stderr,
|
|
"SOURCE_DATE_EPOCH: strtoll: %s: %s\n",
|
|
strerror(errno), source_date_epoch);
|
|
else if (*endptr != '\0')
|
|
fprintf(stderr,
|
|
"SOURCE_DATE_EPOCH has trailing garbage \"%s\"\n",
|
|
endptr);
|
|
else {
|
|
sharedNow = epoch;
|
|
haveTime = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!haveTime) {
|
|
time(&sharedNow);
|
|
haveTime = 1;
|
|
}
|
|
if(now)
|
|
*now = sharedNow;
|
|
return sharedNow;
|
|
}
|
|
|
|
/* Convert a string to an offset. The string should be a number,
|
|
optionally followed by S (sectors), K (K-Bytes), M (Megabytes), G
|
|
(Gigabytes) */
|
|
off_t str_to_offset(char *str) {
|
|
char s, *endp = NULL;
|
|
off_t ofs;
|
|
|
|
ofs = strtol(str, &endp, 0);
|
|
if (ofs <= 0)
|
|
return 0; /* invalid or missing offset */
|
|
s = *endp++;
|
|
if (s) { /* trailing char, see if it is a size specifier */
|
|
if (s == 's' || s == 'S') /* sector */
|
|
ofs <<= 9;
|
|
else if (s == 'k' || s == 'K') /* kb */
|
|
ofs <<= 10;
|
|
else if (s == 'm' || s == 'M') /* Mb */
|
|
ofs <<= 20;
|
|
else if (s == 'g' || s == 'G') /* Gb */
|
|
ofs <<= 30;
|
|
else
|
|
return 0; /* invalid character */
|
|
if (*endp)
|
|
return 0; /* extra char, invalid */
|
|
}
|
|
return ofs;
|
|
}
|
|
|
|
#if 0
|
|
|
|
#undef free
|
|
#undef malloc
|
|
|
|
static int total=0;
|
|
|
|
void myfree(void *ptr)
|
|
{
|
|
int *size = ((int *) ptr)-1;
|
|
total -= *size;
|
|
fprintf(stderr, "freeing %d bytes at %p total allocated=%d\n",
|
|
*size, ptr, total);
|
|
free(size);
|
|
}
|
|
|
|
void *mymalloc(size_t size)
|
|
{
|
|
int *ptr;
|
|
ptr = (int *)malloc(size+sizeof(int));
|
|
if(!ptr)
|
|
return 0;
|
|
*ptr = size;
|
|
ptr++;
|
|
total += size;
|
|
fprintf(stderr, "allocating %d bytes at %p total allocated=%d\n",
|
|
size, ptr, total);
|
|
return (void *) ptr;
|
|
}
|
|
|
|
void *mycalloc(size_t nmemb, size_t size)
|
|
{
|
|
void *ptr = mymalloc(nmemb * size);
|
|
if(!ptr)
|
|
return 0;
|
|
memset(ptr, 0, size);
|
|
return ptr;
|
|
}
|
|
|
|
void *myrealloc(void *ptr, size_t size)
|
|
{
|
|
int oldsize = ((int *)ptr) [-1];
|
|
void *new = mymalloc(size);
|
|
if(!new)
|
|
return 0;
|
|
memcpy(new, ptr, oldsize);
|
|
myfree(ptr);
|
|
return new;
|
|
}
|
|
|
|
char *mystrdup(char *src)
|
|
{
|
|
char *dest;
|
|
dest = mymalloc(strlen(src)+1);
|
|
if(!dest)
|
|
return 0;
|
|
strcpy(dest, src);
|
|
return dest;
|
|
}
|
|
|
|
#endif
|