File: libsdate.c

package info (click to toggle)
sdate 0.4
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,036 kB
  • ctags: 64
  • sloc: sh: 3,008; ansic: 149; makefile: 65; perl: 18
file content (213 lines) | stat: -rw-r--r-- 5,483 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
  Copyright (C) 1993 Christoph Berg <cb@df7cb.de>
  This program is free software, see COPYING for copyright terms.
  sdate is based on fakeroot:

  Copyright: GPL. 
  Author: joost witteveen  (joostje@debian.org)
*/
/* #define _POSIX_C_SOURCE 199309L whatever that may mean...*/ 
/* #define _BSD_SOURCE             I use strdup, S_IFDIR, etc */ 

/* Roderich Schupp writes (bug #79100):
   /usr/include/dlfcn.h from libc6 2.2-5 defines RTLD_NEXT only
   when compiled with _GNU_SOURCE defined. Hence libfakeroot.c doesn't pick
   it
   up and does a dlopen("/lib/libc.so.6",...) in get_libc().
   This works most of the time, but explodes if you have an arch-optimized
   libc installed: the program now has two versions of libc.so
   (/lib/libc.so.6 and, say, /lib/i586/libc.so.6) mapped. Again for
   some programs you might get away with this, but running bash under
   fakeroot
   always bombs. Simple fix:
*/
#define _GNU_SOURCE 

#include "config.h"
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <unistd.h> 
#include <dirent.h>
#include <errno.h>

/* sdate */
#include <time.h>


/* 
   Where are those shared libraries? 
   If I knew of a configure/libtool way to find that out, I'd use it. Or
   any other way other than the method I'm using below. Does anybody know
   how I can get that location? (BTW, symply linking a programme, and running
   `ldd' on it isn't the option, as Digital Unix doesn't have ldd)
*/


/* 
   Note that LIBCPATH isn't actually used on Linux or Solaris, as RTLD_NEXT
   is defined and we use that to get the `next_*' functions

   Linux:
*/

/* OSF1 :*/
/*#define LIBCPATH "/usr/shlib/libc.so"*/

/*
// next_wrap_st:
// this structure is used in next_wrap, which is defined in
// wrapstruct.h, included below
*/
 
struct next_wrap_st{
  void **doit;
  char *name;
};

void *get_libc(){
 
#ifndef RTLD_NEXT
 void *lib=0;
 if(!lib){ 
   lib= dlopen(LIBCPATH,RTLD_LAZY);
 }
 if (NULL==lib) {
   fprintf(stderr, "Couldn't find libc at: %s\n", LIBCPATH);
   abort();
 }
 return lib;
#else
  return RTLD_NEXT;
#endif
}
void load_library_symbols(void);

#include "wrapped.h"
#include "wraptmpf.h"
#include "wrapdef.h"
#include "wrapstruct.h"


void load_library_symbols(void){
  /* this function loads all original functions from the C library.
     I ran into problems when  each function individually
     loaded it's original counterpart, as RTLD_NEXT seems to have
     a different meaning in files with different names than libtricks.c
     (I.E, dlsym(RTLD_NEXT, ...) called in vsearch.c returned funtions
     defined in libtricks */
  /* The calling of this function itself is somewhat tricky:
     the awk script wrapawk generates several .h files. In wraptmpf.h
     there are temporary definitions for tmp_*, that do the call
     to this function. The other generated .h files do even more tricky
     things :) */

  static int done=0;
  int i;
  char* msg;
  
  if(!done){
    for(i=0; next_wrap[i].doit; i++){
      *(next_wrap[i].doit)=dlsym(get_libc(), next_wrap[i].name);
      if ( (msg = dlerror()) != NULL){
	fprintf (stderr, "dlsym(%s): %s\n", next_wrap[i].name, msg);
/*	abort ();*/
      }
    }
  }
}

/* sdate */

static inline int epoch_days(int y, int m) /* days past 1970-01-01 */
{
                           /* 1  2   3   4   5    6    7    8    9    10   11   12 */
  static int mon_offset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  return 365 * (y - 70)
	+ (int)((y - 69) / 4)         /* leap days in previous years */
	+ ((y % 4 == 0) && (m >= 2))  /* this year's leap day */
	+ mon_offset[m];
}

static struct tm *septemberfy(struct tm *t)
{
  static int sep_offset = -1;
  static int sep_y = 93;
  static int sep_m = 8;

  if (sep_offset == -1) {
    char *e;
    if ((e = getenv("SDATE_EPOCH"))) {
      sscanf(e, "%d-%d", &sep_y, &sep_m);
      sep_m--;
    }

    if (sep_y < 70)
      sep_y += 100;
    if (sep_y > 1900)
      sep_y -= 1900;
    if (sep_y < 1 || sep_y > 199) /* range where our leap year stuff works */
      sep_y = 93;
    if (sep_m < 0 || sep_m > 11)
      sep_m = 8;

    sep_offset = epoch_days(sep_y, sep_m);
  }

  if((t->tm_year == sep_y && t->tm_mon > sep_m) || t->tm_year > sep_y) {
#ifdef DEBUG
    fprintf(stderr, "septemberfy: %d-%d-%d\n", t->tm_year, t->tm_mon, t->tm_mday);
#endif
    if(t->tm_mon >= 0 && t->tm_mon < 12)
      t->tm_mday += epoch_days(t->tm_year, t->tm_mon) - sep_offset;
    t->tm_mon = sep_m;
    t->tm_year = sep_y;
  }
  return t;
}

struct tm *gmtime(const time_t *timep) {
  struct tm *result = next_gmtime(timep);
#ifdef DEBUG
  fputs("gmtime wrapped\n", stderr);
#endif
  return septemberfy(result);
}

struct tm *gmtime_r(const time_t *timep, struct tm *result) {
#ifdef DEBUG
  fputs("gmtime_r wrapped\n", stderr);
#endif
  result = next_gmtime_r(timep, result);
  return septemberfy(result);
}

struct tm *localtime(const time_t *timep) {
  struct tm *result = next_localtime(timep);
#ifdef DEBUG
  fputs("localtime wrapped\n", stderr);
#endif
  return septemberfy(result);
}

struct tm *localtime_r(const time_t *timep, struct tm *result) {
#ifdef DEBUG
  fputs("localtime_r wrapped\n", stderr);
#endif
  result = next_localtime_r(timep, result);
  return septemberfy(result);
}

/*
time_t mktime(struct tm *tm) {
#ifdef DEBUG
  fputs("mktime wrapped\n", stderr);
#endif
  return next_mktime(tm);
}
*/