jabberd2
2.2.17
Main Page
Data Structures
Files
File List
Globals
c2s
pbx.c
Go to the documentation of this file.
1
/* vim: set noet ts=4 sw=4: */
2
/*
3
* jabberd - Jabber Open Source Server
4
* Copyright (c) 2009 Tomasz Sterna
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19
*/
20
28
#include "
c2s.h
"
29
30
#define COMMANDLINE_LENGTH_MAX 2048
31
static
void
_pbx_close_pipe
(
c2s_t
c2s);
32
static
void
_pbx_open_pipe
(
c2s_t
c2s,
int
mode);
33
static
void
_pbx_read_pipe
(
c2s_t
c2s);
34
static
void
_pbx_write_pipe
(
c2s_t
c2s);
35
int
_pbx_process_command
(
c2s_t
c2s,
char
*cmd);
36
37
static
void
_pbx_read_command
(
c2s_t
c2s) {
38
char
buf[
COMMANDLINE_LENGTH_MAX
];
39
char
*bufp;
40
41
bufp = (
char
*)&buf;
42
while
(read(c2s->
pbx_pipe_fd
, bufp, 1) > 0)
43
if
(bufp - ((
char
*)&buf) <
COMMANDLINE_LENGTH_MAX
-1) bufp++;
44
*bufp =
'\0'
;
45
46
log_debug
(
ZONE
,
"command read: %s"
, buf);
47
48
_pbx_close_pipe
(c2s);
49
50
if
(
_pbx_process_command
(c2s, buf) == 0)
51
_pbx_write_pipe
(c2s);
52
53
_pbx_read_pipe
(c2s);
54
}
55
56
static
int
_pbx_mio_callback
(
mio_t
m,
mio_action_t
a,
mio_fd_t
fd,
void
*data,
void
*arg) {
57
c2s_t
c2s = (
c2s_t
) arg;
58
59
log_debug
(
ZONE
,
"action %s on PBX pipe"
, a==0?
"action_ACCEPT"
:a==1?
"action_READ"
:a==2?
"action_WRITE"
:a==3?
"action_CLOSE"
:
"-unknown-"
);
60
61
switch
(a) {
62
case
action_READ
:
63
log_debug
(
ZONE
,
"read action on fd %d"
, fd->
fd
);
64
_pbx_read_command
(c2s);
65
return
1;
/* want to read again */
66
67
case
action_WRITE
:
68
/* write buffered lines from jqueue */
69
_pbx_close_pipe
(c2s);
70
return
0;
71
72
case
action_CLOSE
:
73
c2s->
pbx_pipe_mio_fd
= 0;
74
c2s->
pbx_pipe_fd
= -1;
75
return
0;
76
77
default
:
78
break
;
79
}
80
81
return
0;
82
}
83
84
static
void
_pbx_close_pipe
(
c2s_t
c2s) {
85
log_debug
(
ZONE
,
"### close_pipe"
);
86
if
(c2s->
pbx_pipe_mio_fd
)
87
mio_close
(c2s->
mio
, c2s->
pbx_pipe_mio_fd
);
88
}
89
90
static
void
_pbx_open_pipe
(
c2s_t
c2s,
int
mode) {
91
#ifdef WIN32
92
log_debug
(
ZONE
,
"PBX is not supported under Windows"
);
93
log_write
(c2s->
log
, LOG_ERR,
"PBX for Windows is not supported yet"
);
94
exit(EXIT_FAILURE);
95
#else
96
log_debug
(
ZONE
,
"### open_pipe"
);
97
c2s->
pbx_pipe_fd
= open(c2s->
pbx_pipe
, mode | O_NONBLOCK);
98
if
(c2s->
pbx_pipe_fd
== -1) {
99
c2s->
pbx_pipe_mio_fd
= 0;
100
log_debug
(
ZONE
,
"error opening pipe: %d %s"
, errno, strerror(errno));
101
log_write
(c2s->
log
, LOG_ERR,
"failed to open PBX named pipe %s for %s"
, c2s->
pbx_pipe
, mode==O_RDONLY?
"reading"
:
"writing"
);
102
exit(EXIT_FAILURE);
103
}
else
104
c2s->
pbx_pipe_mio_fd
=
mio_register
(c2s->
mio
, c2s->
pbx_pipe_fd
,
_pbx_mio_callback
, (
void
*) c2s);
105
#endif
106
}
107
/* open pipe for reading */
108
static
void
_pbx_read_pipe
(
c2s_t
c2s) {
109
log_debug
(
ZONE
,
"### read_pipe"
);
110
_pbx_open_pipe
(c2s, O_RDONLY);
111
mio_read
(c2s->
mio
, c2s->
pbx_pipe_mio_fd
);
112
}
113
/* trigger buffer write */
114
static
void
_pbx_write_pipe
(
c2s_t
c2s) {
115
log_debug
(
ZONE
,
"### write_pipe"
);
116
_pbx_open_pipe
(c2s, O_RDWR);
117
mio_write
(c2s->
mio
, c2s->
pbx_pipe_mio_fd
);
118
}
119
120
void
c2s_pbx_init
(
c2s_t
c2s) {
121
#ifdef WIN32
122
log_debug
(
ZONE
,
"PBX is not supported under Windows"
);
123
log_write
(c2s->
log
, LOG_ERR,
"PBX for Windows is not supported yet"
);
124
exit(EXIT_FAILURE);
125
#else
126
struct
stat sb;
127
128
/* create the FIFO */
129
if
(stat(c2s->
pbx_pipe
, &sb) == -1) {
130
if
(mkfifo(c2s->
pbx_pipe
, S_IRUSR | S_IWUSR | S_IRGRP) == -1) {
131
log_write
(c2s->
log
, LOG_ERR,
"failed to create PBX named pipe: %s"
, c2s->
pbx_pipe
);
132
exit(EXIT_FAILURE);
133
}
134
}
else
{
135
if
(!S_ISFIFO(sb.st_mode)) {
136
log_write
(c2s->
log
, LOG_ERR,
"file %s exists but is not a named pipe"
, c2s->
pbx_pipe
);
137
exit(EXIT_FAILURE);
138
}
139
}
140
141
_pbx_read_pipe
(c2s);
142
#endif
143
}
Generated by
1.8.1.1