~ubuntu-branches/ubuntu/dapper/postfix/dapper-security

« back to all changes in this revision

Viewing changes to src/global/off_cvt.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2005-02-27 09:33:07 UTC
  • Revision ID: james.westby@ubuntu.com-20050227093307-cn789t27ibnlh6tf
Tags: upstream-2.1.5
ImportĀ upstreamĀ versionĀ 2.1.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*++
 
2
/* NAME
 
3
/*      off_cvt 3
 
4
/* SUMMARY
 
5
/*      off_t conversions
 
6
/* SYNOPSIS
 
7
/*      #include <off_cvt.h>
 
8
/*
 
9
/*      off_t   off_cvt_string(string)
 
10
/*      const char *string;
 
11
/*
 
12
/*      VSTRING *off_cvt_number(result, offset)
 
13
/*      VSTRING *result;
 
14
/*      off_t   offset;
 
15
/* DESCRIPTION
 
16
/*      This module provides conversions between \fIoff_t\fR and string.
 
17
/*
 
18
/*      off_cvt_string() converts a string, containing a non-negative
 
19
/*      offset, to numerical form. The result is -1 in case of problems.
 
20
/*
 
21
/*      off_cvt_number() converts a non-negative offset to string form.
 
22
/*
 
23
/*      Arguments:
 
24
/* .IP string
 
25
/*      String with non-negative number to be converted to off_t.
 
26
/* .IP result
 
27
/*      Buffer for storage of the result of conversion to string.
 
28
/* .IP offset
 
29
/*      Non-negative off_t value to be converted to string.
 
30
/* DIAGNOSTICS
 
31
/*      Panic: negative offset
 
32
/* LICENSE
 
33
/* .ad
 
34
/* .fi
 
35
/*      The Secure Mailer license must be distributed with this software.
 
36
/* AUTHOR(S)
 
37
/*      Wietse Venema
 
38
/*      IBM T.J. Watson Research
 
39
/*      P.O. Box 704
 
40
/*      Yorktown Heights, NY 10598, USA
 
41
/*--*/
 
42
 
 
43
/* System library. */
 
44
 
 
45
#include <sys_defs.h>
 
46
#include <ctype.h>
 
47
 
 
48
/* Utility library. */
 
49
 
 
50
#include <msg.h>
 
51
#include <vstring.h>
 
52
 
 
53
/* Global library. */
 
54
 
 
55
#include "off_cvt.h"
 
56
 
 
57
/* Application-specific. */
 
58
 
 
59
#define STR     vstring_str
 
60
#define END     vstring_end
 
61
#define SWAP(type, a, b) { type temp; temp = a; a = b; b = temp; }
 
62
 
 
63
/* off_cvt_string - string to number */
 
64
 
 
65
off_t   off_cvt_string(const char *str)
 
66
{
 
67
    int     ch;
 
68
    off_t   result;
 
69
    off_t   res2;
 
70
    off_t   res4;
 
71
    off_t   res8;
 
72
    off_t   res10;
 
73
 
 
74
    /*
 
75
     * Multiplication by numbers > 2 can overflow without producing a smaller
 
76
     * result mod 2^N (where N is the number of bits in the result type).
 
77
     * (Victor Duchovni, Morgan Stanley).
 
78
     */
 
79
    for (result = 0; (ch = *(unsigned char *) str) != 0; str++) {
 
80
        if (!ISDIGIT(ch))
 
81
            return (-1);
 
82
        if ((res2 = result + result) < result)
 
83
            return (-1);
 
84
        if ((res4 = res2 + res2) < res2)
 
85
            return (-1);
 
86
        if ((res8 = res4 + res4) < res4)
 
87
            return (-1);
 
88
        if ((res10 = res8 + res2) < res8)
 
89
            return (-1);
 
90
        if ((result = res10 + ch - '0') < res10)
 
91
            return (-1);
 
92
    }
 
93
    return (result);
 
94
}
 
95
 
 
96
/* off_cvt_number - number to string */
 
97
 
 
98
VSTRING *off_cvt_number(VSTRING *buf, off_t offset)
 
99
{
 
100
    static char digs[] = "0123456789";
 
101
    char   *start;
 
102
    char   *last;
 
103
    int     i;
 
104
 
 
105
    /*
 
106
     * Sanity checks
 
107
     */
 
108
    if (offset < 0)
 
109
        msg_panic("off_cvt_number: negative offset -%s",
 
110
                  STR(off_cvt_number(buf, -offset)));
 
111
 
 
112
    /*
 
113
     * First accumulate the result, backwards.
 
114
     */
 
115
    VSTRING_RESET(buf);
 
116
    while (offset != 0) {
 
117
        VSTRING_ADDCH(buf, digs[offset % 10]);
 
118
        offset /= 10;
 
119
    }
 
120
    VSTRING_TERMINATE(buf);
 
121
 
 
122
    /*
 
123
     * Then, reverse the result.
 
124
     */
 
125
    start = STR(buf);
 
126
    last = END(buf) - 1;
 
127
    for (i = 0; i < VSTRING_LEN(buf) / 2; i++)
 
128
        SWAP(int, start[i], last[-i]);
 
129
    return (buf);
 
130
}
 
131
 
 
132
#ifdef TEST
 
133
 
 
134
 /*
 
135
  * Proof-of-concept test program. Read a number from stdin, convert to
 
136
  * off_t, back to string, and print the result.
 
137
  */
 
138
#include <vstream.h>
 
139
#include <vstring_vstream.h>
 
140
 
 
141
int     main(int unused_argc, char **unused_argv)
 
142
{
 
143
    VSTRING *buf = vstring_alloc(100);
 
144
    off_t   offset;
 
145
 
 
146
    while (vstring_fgets_nonl(buf, VSTREAM_IN)) {
 
147
        if ((offset = off_cvt_string(STR(buf))) < 0) {
 
148
            msg_warn("bad input %s", STR(buf));
 
149
        } else {
 
150
            vstream_printf("%s\n", STR(off_cvt_number(buf, offset)));
 
151
        }
 
152
        vstream_fflush(VSTREAM_OUT);
 
153
    }
 
154
    vstring_free(buf);
 
155
}
 
156
 
 
157
#endif