1 /*
2  *  Copyright (C) 2004-2008 Christos Tsantilas
3  *
4  *  This program is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Lesser General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2.1 of the License, or (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  *  MA  02110-1301  USA.
18  */
19 
20 #include "common.h"
21 #include "c-icap.h"
22 #include "array.h"
23 #include "service.h"
24 #include "debug.h"
25 
ci_service_data_read_lock(ci_service_xdata_t * srv_xdata)26 void ci_service_data_read_lock(ci_service_xdata_t * srv_xdata)
27 {
28     ci_thread_rwlock_rdlock(&srv_xdata->lock);
29 }
30 
ci_service_data_read_unlock(ci_service_xdata_t * srv_xdata)31 void ci_service_data_read_unlock(ci_service_xdata_t * srv_xdata)
32 {
33     ci_thread_rwlock_unlock(&srv_xdata->lock);
34 }
35 
ci_service_set_istag(ci_service_xdata_t * srv_xdata,const char * istag)36 void ci_service_set_istag(ci_service_xdata_t * srv_xdata, const char *istag)
37 {
38     ci_thread_rwlock_wrlock(&srv_xdata->lock);
39     snprintf(srv_xdata->ISTag, sizeof(srv_xdata->ISTag), "ISTag: \"%s%.*s\"", ISTAG, CI_SERVICE_ISTAG_SIZE, istag);
40     ci_thread_rwlock_unlock(&srv_xdata->lock);
41 }
42 
ci_service_set_transfer_preview(ci_service_xdata_t * srv_xdata,const char * preview)43 void ci_service_set_transfer_preview(ci_service_xdata_t * srv_xdata,
44                                      const char *preview)
45 {
46     ci_thread_rwlock_wrlock(&srv_xdata->lock);
47     strcpy(srv_xdata->TransferPreview, "Transfer-Preview: ");
48     strncat(srv_xdata->TransferPreview, preview,
49             MAX_HEADER_SIZE - sizeof("Transfer-Preview: "));
50     ci_thread_rwlock_unlock(&srv_xdata->lock);
51 }
52 
ci_service_set_transfer_ignore(ci_service_xdata_t * srv_xdata,const char * ignore)53 void ci_service_set_transfer_ignore(ci_service_xdata_t * srv_xdata,
54                                     const char *ignore)
55 {
56     ci_thread_rwlock_wrlock(&srv_xdata->lock);
57     strcpy(srv_xdata->TransferIgnore, "Transfer-Ignore: ");
58     strncat(srv_xdata->TransferIgnore, ignore,
59             MAX_HEADER_SIZE - sizeof("Transfer-Ignore: "));
60     ci_thread_rwlock_unlock(&srv_xdata->lock);
61 }
62 
ci_service_set_transfer_complete(ci_service_xdata_t * srv_xdata,const char * complete)63 void ci_service_set_transfer_complete(ci_service_xdata_t * srv_xdata,
64                                       const char *complete)
65 {
66     ci_thread_rwlock_wrlock(&srv_xdata->lock);
67     strcpy(srv_xdata->TransferComplete, "Transfer-Complete: ");
68     strncat(srv_xdata->TransferComplete, complete,
69             MAX_HEADER_SIZE - sizeof("Transfer-Complete: "));
70     ci_thread_rwlock_unlock(&srv_xdata->lock);
71 }
72 
73 
ci_service_set_preview(ci_service_xdata_t * srv_xdata,int preview)74 void ci_service_set_preview(ci_service_xdata_t * srv_xdata, int preview)
75 {
76     ci_thread_rwlock_wrlock(&srv_xdata->lock);
77     srv_xdata->preview_size = preview;
78     ci_thread_rwlock_unlock(&srv_xdata->lock);
79 }
80 
ci_service_enable_204(ci_service_xdata_t * srv_xdata)81 void ci_service_enable_204(ci_service_xdata_t * srv_xdata)
82 {
83     ci_thread_rwlock_wrlock(&srv_xdata->lock);
84     srv_xdata->allow_204 = 1;
85     ci_thread_rwlock_unlock(&srv_xdata->lock);
86 }
87 
ci_service_enable_206(ci_service_xdata_t * srv_xdata)88 void ci_service_enable_206(ci_service_xdata_t * srv_xdata)
89 {
90     ci_thread_rwlock_wrlock(&srv_xdata->lock);
91     if (!srv_xdata->disable_206)
92         srv_xdata->allow_206 = 1;
93     ci_thread_rwlock_unlock(&srv_xdata->lock);
94 }
95 
ci_service_set_max_connections(ci_service_xdata_t * srv_xdata,int max_connections)96 void ci_service_set_max_connections(ci_service_xdata_t *srv_xdata, int max_connections)
97 {
98     ci_thread_rwlock_wrlock(&srv_xdata->lock);
99     srv_xdata->max_connections = max_connections;
100     ci_thread_rwlock_unlock(&srv_xdata->lock);
101 }
102 
ci_service_set_options_ttl(ci_service_xdata_t * srv_xdata,int ttl)103 void ci_service_set_options_ttl(ci_service_xdata_t *srv_xdata, int ttl)
104 {
105     ci_thread_rwlock_wrlock(&srv_xdata->lock);
106     srv_xdata->options_ttl = ttl;
107     ci_thread_rwlock_unlock(&srv_xdata->lock);
108 }
109 
ci_service_set_xopts(ci_service_xdata_t * srv_xdata,uint64_t xopts)110 void ci_service_set_xopts(ci_service_xdata_t * srv_xdata, uint64_t xopts)
111 {
112     ci_thread_rwlock_wrlock(&srv_xdata->lock);
113     srv_xdata->xopts = xopts;
114     ci_thread_rwlock_unlock(&srv_xdata->lock);
115 }
116 
ci_service_add_xopts(ci_service_xdata_t * srv_xdata,uint64_t xopts)117 void ci_service_add_xopts(ci_service_xdata_t * srv_xdata, uint64_t xopts)
118 {
119     ci_thread_rwlock_wrlock(&srv_xdata->lock);
120     srv_xdata->xopts |= xopts;
121     ci_thread_rwlock_unlock(&srv_xdata->lock);
122 }
123 
ci_service_add_xincludes(ci_service_xdata_t * srv_xdata,char ** xincludes)124 void ci_service_add_xincludes(ci_service_xdata_t * srv_xdata,
125                               char **xincludes)
126 {
127     int len, i;
128     len = 0;
129     i = 0;
130     if (!xincludes)
131         return;
132     ci_thread_rwlock_wrlock(&srv_xdata->lock);
133     while (XINCLUDES_SIZE - len - 2 > 0 && xincludes[i]) {
134         if (len) {
135             strcat(srv_xdata->xincludes, ", ");
136             len += 2;
137         }
138         strncat(srv_xdata->xincludes, xincludes[i], XINCLUDES_SIZE - len);
139         len += strlen(xincludes[i]);
140         i++;
141     }
142     ci_thread_rwlock_unlock(&srv_xdata->lock);
143 }
144 
ci_service_add_option_handler(ci_service_xdata_t * srv_xdata,const char * name,int (* handler)(struct ci_request *))145 void ci_service_add_option_handler(ci_service_xdata_t *srv_xdata, const char *name, int (*handler)(struct ci_request *))
146 {
147     if (!handler)
148         return;
149     ci_thread_rwlock_wrlock(&srv_xdata->lock);
150     if (!srv_xdata->option_handlers)
151         srv_xdata->option_handlers = ci_list_create(1024, sizeof(struct ci_option_handler));
152     struct ci_option_handler oh;
153     strncpy(oh.name, name, sizeof(oh.name) - 1);
154     oh.name[sizeof(oh.name) - 1] = '\0';
155     oh.handler = handler;
156     ci_list_push_back(srv_xdata->option_handlers, &oh);
157     ci_thread_rwlock_unlock(&srv_xdata->lock);
158 }
159