~ubuntu-branches/ubuntu/maverick/openldap/maverick-proposed

« back to all changes in this revision

Viewing changes to libraries/liblutil/meter.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug, Steve Langasek, Mathias Gug
  • Date: 2009-02-18 18:44:00 UTC
  • mfrom: (1.1.2 upstream) (0.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20090218184400-zw4mjse9eywt5566
Tags: 2.4.14-0ubuntu1
[ Steve Langasek ]
* New upstream version
  - Fixes a bug with the pcache overlay not returning cached entries
    (closes: #497697)
  - Update evolution-ntlm patch to apply to current Makefiles.
  - (tentatively) drop gnutls-ciphers, since this bug was reported to be
    fixed upstream in 2.4.8.  The fix applied in 2.4.8 didn't match the
    patch from the bug report, so this should be watched for regressions.
* Build against db4.7 instead of db4.2 at last!  Closes: #421946.
* Build with --disable-ndb, to avoid a misbuild when libmysqlclient is
  installed in the build environment.
* New patch, no-crlcheck-for-gnutls, to fix a build failure when using
  --with-tls=gnutls.

[ Mathias Gug ]
* Merge from debian unstable, remaining changes:
  - debian/apparmor-profile: add AppArmor profile
  - debian/slapd.postinst: Reload AA profile on configuration
  - updated debian/slapd.README.Debian for note on AppArmor
  - debian/control: Recommends apparmor >= 2.1+1075-0ubuntu6
  - debian/control: Conflicts with apparmor-profiles << 2.1+1075-0ubuntu4
    to make sure that if earlier version of apparmour-profiles gets
    installed it won't overwrite our profile.
  - Modify Maintainer value to match the DebianMaintainerField
    speficication.
  - follow ApparmorProfileMigration and force apparmor compalin mode on 
    some upgrades (LP: #203529)
  - debian/slapd.dirs: add etc/apparmor.d/force-complain
  - debian/slapd.preinst: create symlink for force-complain on pre-feisty
    upgrades, upgrades where apparmor-profiles profile is unchanged (ie
    non-enforcing) and upgrades where apparmor profile does not exist.
  - debian/slapd.postrm: remove symlink in force-complain/ on purge
  - debian/patches/fix-ucred-libc due to changes how newer glibc handle
    the ucred struct now.
  - debian/control:
    - Build-depend on libltdl7-dev rather then libltdl3-dev.
  - debian/patches/autogen.sh:
    - Call libtoolize with the --install option to install config.{guess,sub}
      files.
  - Don't use local statement in config script as it fails if /bin/sh
    points to bash (LP: #286063).
  - Disable the testsuite on hppa. Allows building of packages on this
    architecture again, once this package is in the archive.
    LP: #288908.
  - debian/slapd.postinst, debian/slapd.script-common: set correct ownership
    and permissions on /var/lib/ldap, /etc/ldap/slapd.d (group readable) and
    /var/run/slapd (world readable). (LP: #257667).
  - debian/patches/nssov-build, debian/rules: 
    Build and package the nss overlay.
    debian/schema/misc.ldif: add ldif file for the misc schema, which defines
    rfc822MailMember (required by the nss overlay).
  - debian/{control,rules}: enable PIE hardening
  - Use cn=config as the default configuration backend instead of 
    slapd.conf. Migrate slapd.conf  file to /etc/ldap/slapd.d/ on upgrade
    asking the end user to enter a new password to control the access to the
    cn=config tree.
* debian/patches/corrupt-contextCSN: The contextCSN can get corrupted at
  times. (ITS: #5947)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* meter.c - lutil_meter meters */
 
2
/* $OpenLDAP: pkg/ldap/libraries/liblutil/meter.c,v 1.2.2.1 2009/02/05 20:10:59 quanah Exp $ */
 
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 
4
 *
 
5
 * Copyright (c) 2009 by Matthew Backes, Symas Corp.
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted only as authorized by the OpenLDAP
 
10
 * Public License.
 
11
 *
 
12
 * A copy of this license is available in the file LICENSE in the
 
13
 * top-level directory of the distribution or, alternatively, at
 
14
 * <http://www.OpenLDAP.org/license.html>.
 
15
 */
 
16
/* ACKNOWLEDGEMENTS:
 
17
 * This work was initially developed by Matthew Backes for inclusion
 
18
 * in OpenLDAP software.
 
19
 */
 
20
 
 
21
#include "portable.h"
 
22
#include "lutil_meter.h"
 
23
 
 
24
#include <ac/assert.h>
 
25
#include <ac/string.h>
 
26
 
 
27
int
 
28
lutil_time_string (
 
29
        char *dest,
 
30
        int duration,
 
31
        int max_terms)
 
32
{
 
33
        static const int time_div[] = {31556952,
 
34
                                       604800,
 
35
                                       86400,
 
36
                                       3600,
 
37
                                       60,
 
38
                                       1,
 
39
                                       0};
 
40
        const int * time_divp = time_div;
 
41
        static const char * time_name_ch = "ywdhms";
 
42
        const char * time_name_chp = time_name_ch;
 
43
        int term_count = 0;
 
44
        char *buf = dest;
 
45
        int time_quot;
 
46
        
 
47
        assert ( max_terms >= 2 ); /* room for "none" message */
 
48
 
 
49
        if ( duration < 0 ) {
 
50
                *dest = '\0';
 
51
                return 1;
 
52
        }
 
53
        if ( duration == 0 ) {
 
54
                strcpy( dest, "none" );
 
55
                return 0;
 
56
        }
 
57
        while ( term_count < max_terms && duration > 0 ) {
 
58
                if (duration > *time_divp) {
 
59
                        time_quot = duration / *time_divp;
 
60
                        duration %= *time_divp;
 
61
                        if (time_quot > 99) {
 
62
                                return 1;
 
63
                        } else {
 
64
                                *(buf++) = time_quot / 10 + '0';
 
65
                                *(buf++) = time_quot % 10 + '0';
 
66
                                *(buf++) = *time_name_chp;
 
67
                                ++term_count;
 
68
                        }
 
69
                }
 
70
                if ( *(++time_divp) == 0) duration = 0;
 
71
                ++time_name_chp;
 
72
        }
 
73
        *buf = '\0';
 
74
        return 0;
 
75
}
 
76
 
 
77
int
 
78
lutil_get_now (double *now)
 
79
{
 
80
#ifdef HAVE_GETTIMEOFDAY
 
81
        struct timeval tv;
 
82
 
 
83
        assert( now );
 
84
        gettimeofday( &tv, NULL );
 
85
        *now = ((double) tv.tv_sec) + (((double) tv.tv_usec) / 1000000.0);
 
86
        return 0;
 
87
#else
 
88
        time_t tm;
 
89
 
 
90
        assert( now );
 
91
        time( &tm );
 
92
        now = (double) tm;
 
93
        return 0;
 
94
#endif
 
95
}
 
96
 
 
97
int
 
98
lutil_meter_open (
 
99
        lutil_meter_t *meter,
 
100
        const lutil_meter_display_t *display, 
 
101
        const lutil_meter_estimator_t *estimator,
 
102
        unsigned long goal_value)
 
103
{
 
104
        int rc;
 
105
 
 
106
        assert( meter != NULL );
 
107
        assert( display != NULL );
 
108
        assert( estimator != NULL );
 
109
 
 
110
        if (goal_value < 1) return -1;
 
111
 
 
112
        memset( (void*) meter, 0, sizeof( lutil_meter_t ));
 
113
        meter->display = display;
 
114
        meter->estimator = estimator;
 
115
        lutil_get_now( &meter->start_time );
 
116
        meter->last_update = meter->start_time;
 
117
        meter->goal_value = goal_value;
 
118
        meter->last_position = 0;
 
119
 
 
120
        rc = meter->display->display_open( &meter->display_data );
 
121
        if( rc != 0 ) return rc;
 
122
        
 
123
        rc = meter->estimator->estimator_open( &meter->estimator_data );
 
124
        if( rc != 0 ) {
 
125
                meter->display->display_close( &meter->display_data );
 
126
                return rc;
 
127
        }
 
128
        
 
129
        return 0;
 
130
}
 
131
 
 
132
int
 
133
lutil_meter_update (
 
134
        lutil_meter_t *meter,
 
135
        unsigned long position,
 
136
        int force)
 
137
{
 
138
        static const double display_rate = 0.5;
 
139
        double frac, cycle_length, speed, now;
 
140
        time_t remaining_time, elapsed;
 
141
        int rc;
 
142
 
 
143
        assert( meter != NULL );
 
144
        assert( position >= 0 );
 
145
 
 
146
        lutil_get_now( &now );
 
147
 
 
148
        if ( !force && now - meter->last_update < display_rate ) return 0;
 
149
 
 
150
        frac = ((double)position) / ((double) meter->goal_value);
 
151
        elapsed = now - meter->start_time;
 
152
        if (frac <= 0.0) return 0;
 
153
        if (frac >= 1.0) {
 
154
                rc = meter->display->display_update(
 
155
                        &meter->display_data,
 
156
                        1.0,
 
157
                        0,
 
158
                        (time_t) elapsed,
 
159
                        ((double)position) / elapsed);
 
160
        } else {
 
161
                rc = meter->estimator->estimator_update( 
 
162
                        &meter->estimator_data, 
 
163
                        meter->start_time,
 
164
                        frac,
 
165
                        &remaining_time );
 
166
                if ( rc == 0 ) {
 
167
                        cycle_length = now - meter->last_update;
 
168
                        speed = cycle_length > 0.0 ?
 
169
                                ((double)(position - meter->last_position)) 
 
170
                                / cycle_length :
 
171
                                0.0;
 
172
                        rc = meter->display->display_update(
 
173
                                &meter->display_data,
 
174
                                frac,
 
175
                                remaining_time,
 
176
                                (time_t) elapsed,
 
177
                                speed);
 
178
                        if ( rc == 0 ) {
 
179
                                meter->last_update = now;
 
180
                                meter->last_position = position;
 
181
                        }
 
182
                }
 
183
        }
 
184
 
 
185
        return rc;
 
186
}
 
187
 
 
188
int
 
189
lutil_meter_close (lutil_meter_t *meter)
 
190
{
 
191
        meter->estimator->estimator_close( &meter->estimator_data );
 
192
        meter->display->display_close( &meter->display_data );
 
193
 
 
194
        return 0;
 
195
}
 
196
 
 
197
/* Default display and estimator */
 
198
typedef struct {
 
199
        int buffer_length;
 
200
        char * buffer;
 
201
        int need_eol;
 
202
        int phase;
 
203
        FILE *output;
 
204
} text_display_state_t;
 
205
 
 
206
static int
 
207
text_open (void ** display_datap)
 
208
{
 
209
        static const int default_buffer_length = 81;
 
210
        text_display_state_t *data;
 
211
 
 
212
        assert( display_datap != NULL );
 
213
        data = calloc( 1, sizeof( text_display_state_t ));
 
214
        assert( data != NULL );
 
215
        data->buffer_length = default_buffer_length;
 
216
        data->buffer = calloc( 1, default_buffer_length );
 
217
        assert( data->buffer != NULL );
 
218
        data->output = stderr;
 
219
        *display_datap = data;
 
220
        return 0;
 
221
}
 
222
 
 
223
static int
 
224
text_update ( 
 
225
        void **display_datap,
 
226
        double frac,
 
227
        time_t remaining_time,
 
228
        time_t elapsed,
 
229
        double byte_rate)
 
230
{
 
231
        text_display_state_t *data;
 
232
        char *buf, *buf_end;
 
233
 
 
234
        assert( display_datap != NULL );
 
235
        assert( *display_datap != NULL );
 
236
        data = (text_display_state_t*) *display_datap;
 
237
 
 
238
        if ( data->output == NULL ) return 1;
 
239
 
 
240
        buf = data->buffer;
 
241
        buf_end = buf + data->buffer_length - 1;
 
242
 
 
243
/* |#################### 100.00% eta  1d19h elapsed 23w 7d23h15m12s spd nnnn.n M/s */
 
244
 
 
245
        {
 
246
                /* spinner */
 
247
                static const int phase_mod = 8;
 
248
                static const char phase_char[] = "_.-*\"*-.";
 
249
                *buf++ = phase_char[data->phase % phase_mod];
 
250
                data->phase++;
 
251
        }
 
252
 
 
253
        {
 
254
                /* bar */
 
255
                static const int bar_length = 20;
 
256
                static const double bar_lengthd = 20.0;
 
257
                static const char fill_char = '#';
 
258
                static const char blank_char = ' ';
 
259
                char *bar_end = buf + bar_length;
 
260
                char *bar_pos = frac < 0.0 ? 
 
261
                        buf :
 
262
                        frac < 1.0 ?
 
263
                        buf + (int) (bar_lengthd * frac) :
 
264
                        bar_end;
 
265
 
 
266
                assert( (buf_end - buf) > bar_length );
 
267
                while ( buf < bar_end ) {
 
268
                        *buf = buf < bar_pos ?
 
269
                                fill_char : blank_char;
 
270
                        ++buf;
 
271
                }
 
272
        }
 
273
 
 
274
        {
 
275
                /* percent */
 
276
                (void) snprintf( buf, buf_end-buf, "%7.2f%%", 100.0*frac );
 
277
                buf += 8;
 
278
        }
 
279
 
 
280
        {
 
281
                /* eta and elapsed */
 
282
                char time_buffer[19];
 
283
                int rc;
 
284
                rc = lutil_time_string( time_buffer, remaining_time, 2);
 
285
                if (rc == 0)
 
286
                        snprintf( buf, buf_end-buf, " eta %6s", time_buffer );
 
287
                buf += 5+6;
 
288
                rc = lutil_time_string( time_buffer, elapsed, 5);
 
289
                if (rc == 0)
 
290
                        snprintf( buf, buf_end-buf, " elapsed %15s", 
 
291
                                  time_buffer );
 
292
                buf += 9+15;
 
293
        }
 
294
 
 
295
        {
 
296
                /* speed */
 
297
                static const char prefixes[] = " kMGTPEZY";
 
298
                const char *prefix_chp = prefixes;
 
299
 
 
300
                while (*prefix_chp && byte_rate >= 1024.0) {
 
301
                        byte_rate /= 1024.0;
 
302
                        ++prefix_chp;
 
303
                }
 
304
                if ( byte_rate >= 1024.0 ) {
 
305
                        snprintf( buf, buf_end-buf, " fast!" );
 
306
                        buf += 6;
 
307
                } else {
 
308
                        snprintf( buf, buf_end-buf, " spd %5.1f %c/s",
 
309
                                  byte_rate,
 
310
                                  *prefix_chp);
 
311
                        buf += 5+6+4;
 
312
                }
 
313
        }
 
314
 
 
315
        (void) fprintf( data->output,
 
316
                        "\r%-79s", 
 
317
                        data->buffer );
 
318
        data->need_eol = 1;
 
319
        return 0;
 
320
}
 
321
 
 
322
static int
 
323
text_close (void ** display_datap)
 
324
{
 
325
        text_display_state_t *data;
 
326
 
 
327
        if (display_datap) {
 
328
                if (*display_datap) {
 
329
                        data = (text_display_state_t*) *display_datap;
 
330
                        if (data->output && data->need_eol) 
 
331
                                fputs ("\n", data->output);
 
332
                        if (data->buffer)
 
333
                                free( data->buffer );
 
334
                        free( data );
 
335
                }
 
336
                *display_datap = NULL;
 
337
        }
 
338
        return 0;
 
339
}
 
340
 
 
341
static int
 
342
null_open_close (void **datap)
 
343
{
 
344
        assert( datap );
 
345
        *datap = NULL;
 
346
        return 0;
 
347
}
 
348
 
 
349
static int
 
350
linear_update (
 
351
        void **estimator_datap, 
 
352
        double start, 
 
353
        double frac, 
 
354
        time_t *remaining)
 
355
{
 
356
        double now;
 
357
        double elapsed;
 
358
        
 
359
        assert( estimator_datap != NULL );
 
360
        assert( *estimator_datap == NULL );
 
361
        assert( start > 0.0 );
 
362
        assert( frac >= 0.0 );
 
363
        assert( frac <= 1.0 );
 
364
        assert( remaining != NULL );
 
365
        lutil_get_now( &now );
 
366
 
 
367
        elapsed = now-start;
 
368
        assert( elapsed >= 0.0 );
 
369
 
 
370
        if ( frac == 0.0 ) {
 
371
                return 1;
 
372
        } else if ( frac >= 1.0 ) {
 
373
                *remaining = 0;
 
374
                return 0;
 
375
        } else {
 
376
                *remaining = (time_t) (elapsed/frac-elapsed+0.5);
 
377
                return 0;
 
378
        }
 
379
}
 
380
 
 
381
const lutil_meter_display_t lutil_meter_text_display = {
 
382
        text_open, text_update, text_close
 
383
};
 
384
 
 
385
const lutil_meter_estimator_t lutil_meter_linear_estimator = {
 
386
        null_open_close, linear_update, null_open_close
 
387
};