mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-26 23:13:13 +02:00
setting_helpers.cpp: fix set timezone if build with uclibc
This commit is contained in:
@@ -607,6 +607,9 @@ case "$BOXTYPE" in
|
||||
esac
|
||||
AM_CONDITIONAL(HAVE_LIBSTB_HAL, test "$libstb_hal" = "yes")
|
||||
|
||||
# uclibc
|
||||
AM_CONDITIONAL(HAVE_UCLIBC, test "$targetlibdir/ld-uClibc.so.0")
|
||||
|
||||
# generic
|
||||
if test "$BOXMODEL" = "generic"; then
|
||||
AC_DEFINE(BOXMODEL_GENERIC, 1, [generic pc])
|
||||
|
@@ -46,3 +46,8 @@ libneutrino_system_a_SOURCES = \
|
||||
ytparser.cpp \
|
||||
setting_helpers.cpp
|
||||
# safe_system.c
|
||||
|
||||
if HAVE_UCLIBC
|
||||
libneutrino_system_a_SOURCES += \
|
||||
tzif-display.cpp
|
||||
endif
|
||||
|
@@ -31,6 +31,9 @@
|
||||
|
||||
#include <system/setting_helpers.h>
|
||||
#include "configure_network.h"
|
||||
#ifdef __UCLIBC__
|
||||
#include "tzif-display.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -622,7 +625,20 @@ bool CTZChangeNotifier::changeNotify(const neutrino_locale_t, void *Data)
|
||||
fprintf(f, "%s\n", zone.c_str());
|
||||
fclose(f);
|
||||
}
|
||||
#ifdef __UCLIBC__
|
||||
const char *tzif_rule = get_tzif_rule(cmd.c_str());
|
||||
if (tzif_rule == NULL)
|
||||
return false;
|
||||
f = fopen("/etc/TZ", "w");
|
||||
if (f)
|
||||
{
|
||||
fprintf(f, "%s\n", tzif_rule);
|
||||
fclose(f);
|
||||
}
|
||||
cmd = tzif_rule;
|
||||
#else
|
||||
cmd = ":" + zone;
|
||||
#endif
|
||||
setenv("TZ", cmd.c_str(), 1);
|
||||
tzset();
|
||||
}
|
||||
|
258
src/system/tzif-display.cpp
Normal file
258
src/system/tzif-display.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/** tzif-display.c http://libhdate.sourceforge.net
|
||||
* display contents of tzif file (in support of hcal and hdate)
|
||||
* hcal.c Hebrew calendar (part of package libhdate)
|
||||
* hdate.c Hebrew date/times information(part of package libhdate)
|
||||
*
|
||||
* compile:
|
||||
* gcc -c -Wall -Werror -g tzif-display.c
|
||||
* build:
|
||||
* gcc -Wall tzif-display.c -o tzif-display
|
||||
* run:
|
||||
* ./tzif-display full-pathname-to-tzif-file
|
||||
*
|
||||
* Copyright: 2012 (c) Boruch Baum <zdump@gmx.com>
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tzif-display.h"
|
||||
|
||||
/***************************************************
|
||||
* parse a tzfile "long format" value
|
||||
***************************************************/
|
||||
long parse_tz_long( const char *sourceptr, const int field_size)
|
||||
{
|
||||
long retval = 0;
|
||||
char *long_ptr;
|
||||
|
||||
// if (sizeof(long) < field_size)
|
||||
// printf("warning: field truncated because it is larger than a 'long' integer\n\n");
|
||||
|
||||
int i,j;
|
||||
long_ptr = (char*) &retval;
|
||||
if ((field_size < (int)sizeof(long)) && (sourceptr[0] >> 8))
|
||||
{
|
||||
for (i=sizeof(long)-1; (i>=field_size); i--) long_ptr[i] = 255;
|
||||
}
|
||||
j = 0;
|
||||
for (i=field_size-1; (i>=0) && (j<(int)sizeof(long)); i--)
|
||||
{
|
||||
long_ptr[j] = sourceptr[i];
|
||||
j++;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* read a tzheader file
|
||||
***************************************************/
|
||||
int read_tz_header( timezonefileheader *header, const char *temp_buffer)
|
||||
{
|
||||
const int field_size = 4;
|
||||
|
||||
memcpy( header->magicnumber, &temp_buffer[0], 5 );
|
||||
header->magicnumber[5] = '\0';
|
||||
|
||||
header->ttisgmtcnt = parse_tz_long(&temp_buffer[20], field_size);
|
||||
header->ttisstdcnt = parse_tz_long(&temp_buffer[24], field_size);
|
||||
header->leapcnt = parse_tz_long(&temp_buffer[28], field_size);
|
||||
header->timecnt = parse_tz_long(&temp_buffer[32], field_size);
|
||||
header->typecnt = parse_tz_long(&temp_buffer[36], field_size);
|
||||
header->charcnt = parse_tz_long(&temp_buffer[40], field_size);
|
||||
#if 0
|
||||
printf("Header format ID: %s\n",header->magicnumber);
|
||||
printf("number of UTC/local indicators stored in the file = %ld\n", header->ttisgmtcnt);
|
||||
printf("number of standard/wall indicators stored in the file = %ld\n",header->ttisstdcnt);
|
||||
printf("number of leap seconds for which data is stored in the file = %ld\n",header->leapcnt);
|
||||
printf("number of \"transition times\" for which data is stored in the file = %ld\n",header->timecnt);
|
||||
printf("number of \"local time types\" for which data is stored in the file (must not be zero) = %ld\n",header->typecnt);
|
||||
printf("number of characters of \"timezone abbreviation strings\" stored in the file = %ld\n\n",header->charcnt);
|
||||
#endif
|
||||
if (header->typecnt == 0)
|
||||
{
|
||||
printf("Error in file format. Zero local time types suggested.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header->timecnt == 0)
|
||||
{
|
||||
printf("No transition times recorded in this file\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* tzif2_handle
|
||||
***********************************************************************/
|
||||
char* tzif2_handle( timezonefileheader *tzh, const char *tzfile_buffer_ptr, size_t buffer_size )
|
||||
{
|
||||
char *start_ptr;
|
||||
char magicnumber[6] = "TZif2";
|
||||
|
||||
printf("tzif handle format 2\n");
|
||||
|
||||
start_ptr = (char*)memmem( tzfile_buffer_ptr, buffer_size, &magicnumber, sizeof(magicnumber) );
|
||||
if (start_ptr == NULL)
|
||||
{
|
||||
printf("error finding tzif2 header\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("tzif2 header found at position %d\n", start_ptr - tzfile_buffer_ptr);
|
||||
if ( read_tz_header( tzh, (char*) start_ptr ) == false )
|
||||
{
|
||||
printf("Error reading header file version 2\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return start_ptr + HEADER_LEN;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* Display contents of a timezone file
|
||||
***************************************************/
|
||||
char *display_tzfile_data( const timezonefileheader tzh,
|
||||
const char* tzfile_buffer_ptr,
|
||||
const int field_size /// 4bytes for tzif1, 8bytes for tzif2
|
||||
)
|
||||
{
|
||||
char *local_time_type_ptr;
|
||||
|
||||
typedef struct {
|
||||
long gmtoff; // seconds to add to UTC
|
||||
char is_dst; // whether tm_isdst should be set by localtime(3)
|
||||
char abbrind; // index into the array of timezone abbreviation characters
|
||||
} ttinfo_struct;
|
||||
|
||||
ttinfo_struct *ttinfo_data_ptr;
|
||||
char *ttinfo_read_ptr;
|
||||
char* tz_abbrev_ptr;
|
||||
char *leapinfo_ptr;
|
||||
char *wall_indicator_ptr;
|
||||
char *local_indicator_ptr;
|
||||
char *general_rule = NULL;
|
||||
|
||||
local_time_type_ptr = (char*) tzfile_buffer_ptr + tzh.timecnt*field_size;
|
||||
ttinfo_read_ptr = local_time_type_ptr + tzh.timecnt;
|
||||
|
||||
ttinfo_data_ptr = (ttinfo_struct*)malloc( sizeof(ttinfo_struct) * tzh.typecnt);
|
||||
if (ttinfo_data_ptr == NULL)
|
||||
{
|
||||
printf("memory allocation error - ttinfo_data\ntzname = ");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// timezone abbreviation list
|
||||
tz_abbrev_ptr = ttinfo_read_ptr + (tzh.typecnt * 6);
|
||||
|
||||
leapinfo_ptr = tz_abbrev_ptr + (tzh.charcnt);
|
||||
|
||||
wall_indicator_ptr = leapinfo_ptr + (tzh.leapcnt*field_size*2);
|
||||
|
||||
local_indicator_ptr = wall_indicator_ptr + tzh.ttisstdcnt;
|
||||
|
||||
if (field_size == TZIF2_FIELD_SIZE)
|
||||
{
|
||||
/// parse 'general rule' at end of file
|
||||
/// format should be per man(3) tzset
|
||||
char *start_line_ptr;
|
||||
start_line_ptr = strchr( local_indicator_ptr + tzh.ttisgmtcnt, 10 );
|
||||
if (start_line_ptr == NULL)
|
||||
printf("\nno \'general rule\' information found at end of file\n");
|
||||
else
|
||||
{
|
||||
char *end_line_ptr;
|
||||
end_line_ptr = strchr( start_line_ptr+1, 10 );
|
||||
if (end_line_ptr == NULL)
|
||||
printf("\nerror finding \'general rule\' info terminator symbol\n");
|
||||
else
|
||||
{
|
||||
*end_line_ptr = '\0';
|
||||
printf("general rule: %s\n", start_line_ptr+1 );
|
||||
general_rule = start_line_ptr+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(ttinfo_data_ptr);
|
||||
return general_rule;
|
||||
}
|
||||
|
||||
const char *get_tzif_rule(const char *filename)
|
||||
{
|
||||
FILE *tz_file;
|
||||
char *tzif_buffer_ptr;
|
||||
char *start_ptr;
|
||||
int field_size;
|
||||
const char *rule = NULL;
|
||||
struct stat file_status;
|
||||
timezonefileheader tzh;
|
||||
|
||||
tz_file = fopen(filename, "rb");
|
||||
|
||||
if (tz_file == NULL)
|
||||
{
|
||||
error(errno,0,"tz file %s not found\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fstat( fileno( tz_file), &file_status) != 0)
|
||||
{
|
||||
printf("error retreiving file status\n");
|
||||
fclose(tz_file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tzif_buffer_ptr = (char *) malloc( file_status.st_size );
|
||||
if (tzif_buffer_ptr == NULL)
|
||||
{
|
||||
printf("memory allocation error - tzif buffer\n");
|
||||
fclose(tz_file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( fread( tzif_buffer_ptr, file_status.st_size, 1, tz_file) != 1 )
|
||||
{
|
||||
printf("error reading into tzif buffer\n");
|
||||
free(tzif_buffer_ptr);
|
||||
return NULL;
|
||||
}
|
||||
fclose(tz_file);
|
||||
|
||||
|
||||
if ( read_tz_header( &tzh, tzif_buffer_ptr ) == false )
|
||||
{
|
||||
printf("Error reading header file version 1\n");
|
||||
free(tzif_buffer_ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tzh.magicnumber[4] == 50 )
|
||||
{
|
||||
start_ptr = tzif2_handle( &tzh, &tzif_buffer_ptr[HEADER_LEN], file_status.st_size - HEADER_LEN);
|
||||
field_size = TZIF2_FIELD_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
start_ptr = &tzif_buffer_ptr[HEADER_LEN];
|
||||
field_size = TZIF1_FIELD_SIZE;
|
||||
}
|
||||
if (start_ptr != NULL)
|
||||
rule = display_tzfile_data( tzh, start_ptr, field_size );
|
||||
|
||||
free(tzif_buffer_ptr);
|
||||
return rule;
|
||||
}
|
57
src/system/tzif-display.h
Normal file
57
src/system/tzif-display.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/** tzif-display.h http://libhdate.sourceforge.net
|
||||
*
|
||||
* Copyright: 2012 (c) Boruch Baum <zdump@gmx.com>
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TZIF_DISPLAY_H_
|
||||
#define _TZIF_DISPLAY_H_
|
||||
|
||||
#include <stdio.h> /// For printf, fopen, fclose, FILE
|
||||
#include <stdlib.h> /// For malloc, free
|
||||
#include <error.h> /// For error
|
||||
#include <errno.h> /// For errno
|
||||
#include <string.h> /// for memset, memcpy, memmem
|
||||
#include <sys/stat.h> /// for stat
|
||||
#include <locale.h> /// for setlocale
|
||||
#include <time.h> /// for ctime_r, tzset
|
||||
|
||||
/***************************************************
|
||||
* definition of a tzfile header
|
||||
***************************************************/
|
||||
#define HEADER_LEN 44
|
||||
typedef struct {
|
||||
char magicnumber[6]; // = TZif2 or TZif\0
|
||||
// char reserved[15]; // nulls
|
||||
long unsigned ttisgmtcnt; // number of UTC/local indicators stored in the file.
|
||||
long unsigned ttisstdcnt; // number of standard/wall indicators stored in the file.
|
||||
long unsigned leapcnt; // number of leap seconds for which data is stored in the file.
|
||||
long unsigned timecnt; // number of "transition times" for which data is stored in the file.
|
||||
long unsigned typecnt; // number of "local time types" for which data is stored in the file (must not be zero).
|
||||
long unsigned charcnt; // number of characters of "timezone abbreviation strings" stored in the file.
|
||||
} timezonefileheader;
|
||||
#define TZIF1_FIELD_SIZE 4
|
||||
#define TZIF2_FIELD_SIZE 8
|
||||
|
||||
long parse_tz_long( const char *sourceptr, const int field_size);
|
||||
int read_tz_header( timezonefileheader *header, const char *temp_buffer);
|
||||
char *tzif2_handle( timezonefileheader *tzh, const char *tzfile_buffer_ptr, size_t buffer_size );
|
||||
char *display_tzfile_data( const timezonefileheader tzh,
|
||||
const char* tzfile_buffer_ptr,
|
||||
const int field_size /// 4bytes for tzif1, 8bytes for tzif2
|
||||
);
|
||||
const char *get_tzif_rule(const char *filename);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user