1#include <stdio.h>
2#include <string.h>
3#include <sys/types.h>
4#include <unistd.h>
5#include <stdlib.h>
6#include <time.h>
7
8#include "main.h"
9#include "bftpdutmp.h"
10#include "mypaths.h"
11#include "logging.h"
12#include "options.h"
13
14FILE *bftpdutmp = NULL;
15long bftpdutmp_offset = 0xFFFFFFFF;
16
17void bftpdutmp_init()
18{
19	char *filename = strdup(config_getoption("PATH_BFTPDUTMP"));
20
21        if (! filename)
22            return;
23
24	if ((!strcasecmp(filename, "none")) || (!filename[0]))
25		return;
26    /* First we have to create the file if it doesn't exist */
27
28    bftpdutmp = fopen(filename, "a");
29    if (bftpdutmp)
30        fclose(bftpdutmp);
31    /* Then we can open it for reading and writing */
32    if (!(bftpdutmp = fopen(filename, "r+"))) {
33        control_printf(SL_FAILURE, "421-Could not open %s\r\n"
34                 "421 Server disabled for security reasons.", filename);
35        exit(1);
36    }
37    rewind(bftpdutmp);
38    // clean up memory
39    free(filename);
40}
41
42void bftpdutmp_end()
43{
44    if (bftpdutmp) {
45        if (bftpdutmp_offset != -1)
46            bftpdutmp_log(0);
47        fclose(bftpdutmp);
48        bftpdutmp = NULL;
49    }
50}
51
52void bftpdutmp_log(char type)
53{
54    struct bftpdutmp ut, tmp;
55    long i;
56    if (!bftpdutmp)
57        return;
58    memset((void *) &ut, 0, sizeof(ut));
59    ut.bu_pid = getpid();
60    if (type) {
61        ut.bu_type = 1;
62        strncpy(ut.bu_name, user, sizeof(ut.bu_name));
63        strncpy(ut.bu_host, remotehostname, sizeof(ut.bu_host));
64       /* Determine offset of first user marked dead */
65        rewind(bftpdutmp);
66        i = 0;
67        while (fread((void *) &tmp, sizeof(tmp), 1, bftpdutmp)) {
68            if (!tmp.bu_type)
69                break;
70            i++;
71        }
72        bftpdutmp_offset = i * sizeof(tmp);
73    }
74
75    else
76        ut.bu_type = 0;
77
78    time(&(ut.bu_time));
79    fseek(bftpdutmp, bftpdutmp_offset, SEEK_SET);
80    fwrite((void *) &ut, sizeof(ut), 1, bftpdutmp);
81    fflush(bftpdutmp);
82}
83
84char bftpdutmp_pidexists(pid_t pid)
85{
86    struct bftpdutmp tmp;
87	if (!bftpdutmp)
88		return 0;
89    rewind(bftpdutmp);
90    while (fread((void *) &tmp, sizeof(tmp), 1, bftpdutmp)) {
91        if ((tmp.bu_pid == pid) && (tmp.bu_type))
92            return 1;
93    }
94    return 0;
95}
96
97int bftpdutmp_usercount(char *username)
98{
99    struct bftpdutmp tmp;
100	int count = 0;
101	if (!bftpdutmp)
102		return 0;
103    rewind(bftpdutmp);
104    while ( fread((void *) &tmp, sizeof(tmp), 1, bftpdutmp) ) {
105		/*
106                 Took this out. It seems to just be taking up log space. -- Jesse
107                 bftpd_log("bu_name=%s; username=%s, bu_type=%i\n", tmp.bu_name, username, tmp.bu_type);
108                */
109        if (tmp.bu_type && ( !strcmp(tmp.bu_name, username) || !strcmp(username, "*")))
110			count++;
111    }
112    return count;
113}
114
115int bftpdutmp_dup_ip_count(char *ip_address)
116{
117   struct bftpdutmp tmp;
118   int count = 0;
119
120   if (! bftpdutmp)
121      return 0;
122
123   rewind(bftpdutmp);
124   while ( fread( (void *) &tmp, sizeof(tmp), 1, bftpdutmp) )
125   {
126      if (tmp.bu_type && (! strcmp(tmp.bu_host, ip_address) ) )
127         count++;
128   }
129
130   return count;
131}
132
133
134
135/*
136This function removes a log entry of
137a dead client. This is called
138when the bftpd parent catches a
139signal indicating the child/client died.
140This makes it look like the child
141logged out properly.
142-- Jesse
143*/
144void bftpdutmp_remove_pid(int pid)
145{
146    struct bftpdutmp current;
147    int index = 0;
148
149    if (! bftpdutmp)
150       return;
151
152    rewind(bftpdutmp);
153    /* search for a matching pid */
154    while ( fread( (void *) &current, sizeof(current), 1, bftpdutmp) )
155    {
156       /* over-write the pid */
157       if ( current.bu_pid == pid )
158       {
159           fseek(bftpdutmp, index * sizeof(current), SEEK_SET);
160           memset(&current, 0, sizeof(current));
161           fwrite( (void *) &current, sizeof(current), 1, bftpdutmp);
162       }
163       index++;
164    }
165}
166
167
168