~ubuntu-branches/ubuntu/trusty/postfix/trusty-proposed

« back to all changes in this revision

Viewing changes to src/util/dir_forest.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
/*      dir_forest 3
 
4
/* SUMMARY
 
5
/*      file name to directory forest
 
6
/* SYNOPSIS
 
7
/*      #include <dir_forest.h>
 
8
/*
 
9
/*      char    *dir_forest(buf, path, depth)
 
10
/*      VSTRING *buf;
 
11
/*      const char *path;
 
12
/*      int     depth;
 
13
/* DESCRIPTION
 
14
/*      This module implements support for directory forests: a file
 
15
/*      organization that introduces one or more levels of intermediate
 
16
/*      subdirectories in order to reduce the number of files per directory.
 
17
/*
 
18
/*      dir_forest() maps a file basename to a directory forest and
 
19
/*      returns the resulting string: file name "abcd" becomes "a/b/"
 
20
/*      and so on. The number of subdirectory levels is adjustable.
 
21
/*
 
22
/*      Arguments:
 
23
/* .IP buf
 
24
/*      A buffer that is overwritten with the result. The result
 
25
/*      ends in "/" and is null terminated. If a null pointer is
 
26
/*      specified, the result is written to a private buffer that
 
27
/*      is overwritten upon each call.
 
28
/* .IP path
 
29
/*      A null-terminated string of printable characters. Characters
 
30
/*      special to the file system are not permitted.
 
31
/*      The first subdirectory is named after the first character
 
32
/*      in \fIpath\fR, and so on. When the path is shorter than the
 
33
/*      desired number of subdirectory levels, directory names
 
34
/*      of '_' (underscore) are used as replacement.
 
35
/* .IP depth
 
36
/*      The desired number of subdirectory levels.
 
37
/* DIAGNOSTICS
 
38
/*      Panic: interface violations. Fatal error: out of memory.
 
39
/* LICENSE
 
40
/* .ad
 
41
/* .fi
 
42
/*      The Secure Mailer license must be distributed with this software.
 
43
/* AUTHOR(S)
 
44
/*      Wietse Venema
 
45
/*      IBM T.J. Watson Research
 
46
/*      P.O. Box 704
 
47
/*      Yorktown Heights, NY 10598, USA
 
48
/*--*/
 
49
 
 
50
/* System library. */
 
51
 
 
52
#include <sys_defs.h>
 
53
#include <ctype.h>
 
54
 
 
55
/* Utility library. */
 
56
 
 
57
#include "msg.h"
 
58
#include "dir_forest.h"
 
59
 
 
60
/* dir_forest - translate base name to directory forest */
 
61
 
 
62
char   *dir_forest(VSTRING *buf, const char *path, int depth)
 
63
{
 
64
    char   *myname = "dir_forest";
 
65
    static VSTRING *private_buf = 0;
 
66
    int     n;
 
67
    const char *cp;
 
68
    int     ch;
 
69
 
 
70
    /*
 
71
     * Sanity checks.
 
72
     */
 
73
    if (*path == 0)
 
74
        msg_panic("%s: empty path", myname);
 
75
    if (depth < 1)
 
76
        msg_panic("%s: depth %d", myname, depth);
 
77
 
 
78
    /*
 
79
     * Your buffer or mine?
 
80
     */
 
81
    if (buf == 0) {
 
82
        if (private_buf == 0)
 
83
            private_buf = vstring_alloc(1);
 
84
        buf = private_buf;
 
85
    }
 
86
 
 
87
    /*
 
88
     * Generate one or more subdirectory levels, depending on the pathname
 
89
     * contents. When the pathname is short, use underscores instead.
 
90
     * Disallow non-printable characters or characters that are special to
 
91
     * the file system.
 
92
     */
 
93
    VSTRING_RESET(buf);
 
94
    for (cp = path, n = 0; n < depth; n++) {
 
95
        if ((ch = *cp) == 0) {
 
96
            ch = '_';
 
97
        } else {
 
98
            if (!ISPRINT(ch) || ch == '.' || ch == '/')
 
99
                msg_panic("%s: invalid pathname: %s", myname, path);
 
100
            cp++;
 
101
        }
 
102
        VSTRING_ADDCH(buf, ch);
 
103
        VSTRING_ADDCH(buf, '/');
 
104
    }
 
105
    VSTRING_TERMINATE(buf);
 
106
 
 
107
    if (msg_verbose > 1)
 
108
        msg_info("%s: %s -> %s", myname, path, vstring_str(buf));
 
109
    return (vstring_str(buf));
 
110
}