File: diraliases.c

package info (click to toggle)
pure-ftpd 1.0.49-4.1
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye, sid
  • size: 3,324 kB
  • sloc: ansic: 29,998; sh: 1,643; makefile: 544; perl: 283
file content (159 lines) | stat: -rw-r--r-- 3,572 bytes parent folder | download
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
/*

0) alias file format.
 alternating lines of alias and dir
 (this enables embedded whitespace in dir and alias without quoting rules)
 optional blank lines
 optional lines beginning with '#' as comments
 (no you can't put a '#' just anywhere)

1) data structure for alias list nodes.
typedef struct DirAlias_ {
       char *alias;
       char *dir;
       struct DirAlias *next;
} DirAlias;

2) init routine
 A) open alias file
 B) while not EOF do
      read line
      parse line
        dir must begin with "/"
      allocate DirAlias and members
      if tail is NULL then head and tail (global DirAlias_t pointers)
       are set to member
      else tail->next is set to member and then tail is set to member

3) lookup routine
  A) given potential alias return dir or NULL
     (walk list starting with head looking for match)

4) FTP CWD command mods
  A) if chdir() fails try alias (use lookup routine)

5) FTP SITE ALIAS command
  A) list aliases

*/

#include <config.h>

#ifdef WITH_DIRALIASES

#include "ftpd.h"
#include "messages.h"
#include "diraliases.h"

#ifdef WITH_DMALLOC
# include <dmalloc.h>
#endif

static DirAlias *head, *tail;
static signed char aliases_up;

/* returns: 0 on success, -1 on failure */

int init_aliases(void)
{
    FILE *fp;
    char alias[MAXALIASLEN + 1U];
    char dir[PATH_MAX + 1U];

    if ((fp = fopen(ALIASES_FILE, "r")) == NULL) {
        return 0;
    }
    while (fgets(alias, sizeof alias, fp) != NULL) {
        if (*alias == '#' || *alias == '\n' || *alias == 0) {
            continue;
        }
        {
            char * const z = alias + strlen(alias) - 1U;

            if (*z != '\n') {
                goto bad;
            }
            *z = 0;
        }
        do {
            if (fgets(dir, sizeof dir, fp) == NULL || *dir == 0) {
                goto bad;
            }
            {
                char * const z = dir + strlen(dir) - 1U;

                if (*z == '\n') {
                    *z = 0;
                }
            }
        } while (*dir == '#' || *dir == 0);
        if (head == NULL) {
            if ((head = tail = malloc(sizeof *head)) == NULL ||
                (tail->alias = strdup(alias)) == NULL ||
                (tail->dir = strdup(dir)) == NULL) {
                die_mem();
            }
        } else {
            DirAlias *curr;

            if ((curr = malloc(sizeof *curr)) == NULL ||
                (curr->alias = strdup(alias)) == NULL ||
                (curr->dir = strdup(dir)) == NULL) {
                die_mem();
            }
            tail->next = curr;
            tail = curr;
        }
        tail->next = NULL;
    }
    fclose(fp);
    aliases_up++;

    return 0;

    bad:
    fclose(fp);
    logfile(LOG_ERR, MSG_ALIASES_BROKEN_FILE " [" ALIASES_FILE "]");

    return -1;
}


char *lookup_alias(const char *alias)
{
    const DirAlias *curr = head;

    if (aliases_up == 0) {
        return NULL;
    }
    while (curr != NULL) {
        if (strcmp(curr->alias, alias) == 0) {
            return curr->dir;
        }
        curr = curr->next;
    }
    return NULL;
}


void print_aliases(void)
{
    const DirAlias *curr = head;

    if (aliases_up == 0) {
        addreply_noformat(502, MSG_CONF_ERR);

        return;
    }
    addreply_noformat(214, MSG_ALIASES_LIST);
    while (curr != NULL) {
        char line[MAXALIASLEN + PATH_MAX + 3U];

        snprintf(line, sizeof line, " %s %s", curr->alias, curr->dir);
        addreply_noformat(0, line);
        curr = curr->next;
    }
    addreply_noformat(214, " ");
}

#endif