File: nws_timeout.c

package info (click to toggle)
nws 2.11-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,700 kB
  • ctags: 2,820
  • sloc: ansic: 28,849; sh: 3,289; java: 1,205; makefile: 697; perl: 12
file content (156 lines) | stat: -rw-r--r-- 4,551 bytes parent folder | download | duplicates (3)
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
/* $Id: nws_timeout.c,v 1.4 2003/01/29 05:31:39 graziano Exp $ */

#include "config_nws.h"
#include <stdio.h>
#include <time.h>

#ifdef WITH_LDAP
#include <ldap.h>

#define TWODIGIT_TO_INT(str,pos) ((str[pos]-'0')*10+(str[pos+1]-'0'))
#define FOURDIGIT_TO_INT(str,pos) ((str[pos]-'0')*1000+(str[pos+1]-'0')*100+(str[pos+2]-'0')*10+(str[pos+3]-'0'))

/*
** Simple program that runs once and times out (deletes) any records whose
** expiration is non-zero and whose modifyTimestamp+expiration < time()
** Not terribly well-written, but at least it works
*/


/*
** Same as mktime(3), except that it assumes that timeptr is in UTC, not local
** time.
*/
time_t
mktime_utc(struct tm *timeptr) {
  time_t result;
  int days;

  result = ((timeptr->tm_year-70) * 365 * 24 * 3600); /* Normal years */
  result += ((timeptr->tm_year-72)/4 * 24 * 3600);    /* Handle leap years */
  if (((timeptr->tm_year + 1900) % 4) && (timeptr->tm_mon >= 2))
    result += 24 * 3600;                       /* Handle if this is leap year */
  days = 0;                                    /* Handle months; kludge */
  switch (timeptr->tm_mon) {
    case 11: days += 30;
    case 10: days += 31;
    case 9:  days += 30;
    case 8:  days += 31;
    case 7:  days += 31;
    case 6:  days += 30;
    case 5:  days += 31;
    case 4:  days += 30;
    case 3:  days += 31;
    case 2:  days += 28;
    case 1:  days += 31;
  }
  result += days * 24 * 3600;
  result += ((timeptr->tm_mday-1) * 24 * 3600) +
            (timeptr->tm_hour * 3600) +
            (timeptr->tm_min * 60) +
            (timeptr->tm_sec);
  return result;
}


/*
** Converts an LDAP timestamp (which follows the syntax of
** 1.3.6.1.4.1.1466.115.121.1.24, generalized time, a string of format
** YYYYMMDDhhmmssZ) to a Unix time value (time_t, seconds since the epoch).
** This function is incomplete: the last character of an LDAP timestamp gives
** the time zone, which we just assume to be Z (UTC).
*/
time_t
ConvertTimeFromLdap(char *ldapTime) {
  struct tm t;

  /* Convert time to a struct tm */
  t.tm_year = FOURDIGIT_TO_INT(ldapTime, 0) - 1900;
  t.tm_mon  = TWODIGIT_TO_INT (ldapTime, 4) - 1;
  t.tm_mday = TWODIGIT_TO_INT (ldapTime, 6);
  t.tm_hour = TWODIGIT_TO_INT (ldapTime, 8);
  t.tm_min  = TWODIGIT_TO_INT (ldapTime, 10);
  t.tm_sec  = TWODIGIT_TO_INT (ldapTime, 12);

  return mktime_utc(&t);
}

int
main (int argc, char **argv) {
  int port, result;
  LDAP *ld;
  LDAPMessage *res, *entry;
  const char *attrs[] = {"expiration", "modifyTimestamp", NULL};
  char *dn, **rawTimestamp, **rawExpiration;
  time_t timestamp, now;
  int expiration;

  /* Check arguments; get port */
  if ((argc != 3) || (sscanf(argv[2], "%i", &port) == 0)) {
    printf("Usage: %s ldap_host ldap_port\n", argv[0]);
    return 1;
  }

  /* Initialize LDAP struct */
  ld = ldap_init(argv[1], port);
  if (ld == NULL) {
    perror(argv[0]);
    return 1;
  }

  /* Bind to server */
  result = ldap_simple_bind_s(ld, NULL, NULL);
  if (result != LDAP_SUCCESS) {
    fprintf(stderr, "%s: %s\n", argv[0], ldap_err2string(result));
    return 1;
  }

  /* Get all records that might need deleting */
  result = ldap_search_s(ld,
                         "o=NWS, c=US",
                         LDAP_SCOPE_SUBTREE,
                         "(&(expiration=*)(!(expiration=0)))",
                         (char**) attrs,
                         0,
                         &res);
  if (result != LDAP_SUCCESS) {
    fprintf(stderr, "%s: %s\n", argv[0], ldap_err2string(result));
    return 1;
  }
  entry = ldap_first_entry(ld, res);
  now = time(NULL);
  while (entry) {
    dn = ldap_get_dn(ld, entry);
    rawTimestamp  = ldap_get_values(ld, entry, "modifyTimestamp");
    rawExpiration = ldap_get_values(ld, entry, "expiration");

    printf("DN: %s\n", dn);
    /*printf("  Timestamp:  %s\n", rawTimestamp[0]);*/
    /*printf("  Expiration: %s\n", rawExpiration[0]);*/

    timestamp = ConvertTimeFromLdap(rawTimestamp[0]);
    sscanf(rawExpiration[0], "%i", &expiration);

    printf("  Touched: %s", ctime(&timestamp));
    timestamp += expiration;
    printf("  Expires: %s", asctime(localtime(&timestamp)));

    if (timestamp < now) {
      result = ldap_delete_s(ld, dn);
      if (result != LDAP_SUCCESS) {
        fprintf(stderr, "%s: %s\n", argv[0], ldap_err2string(result));
        return 1;
      }
      printf("  DELETED\n");
    }

    ldap_value_free(rawTimestamp);
    ldap_value_free(rawExpiration);
    ldap_memfree(dn);
    entry = ldap_next_entry(ld, entry);
  }

  return 0;
}

#endif