Statistics
| Branch: | Tag: | Revision:

dvbd / src / clientconnection.cpp @ e34a9e8b

History | View | Annotate | Download (5.64 KB)

1
/*
2
  Copyright 2003 John Knottenbelt
3
  
4
  This program is free software; you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation; either version 2 of the License, or
7
  (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
12
  GNU General Public License for more details.
13
 
14
  You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
*/
18

    
19
#include "clientconnection.h"
20
#include "unixclientsocket.h"
21
#include "stringutil.h"
22
#include "utils.h"
23
#include <iostream>
24

    
25
class SetBlocking {
26
public:
27
  SetBlocking(UnixClientSocket &client, bool desiredState)
28
    : client_(client), savedState_(client.isBlocking())
29
  {
30
    client_.setBlocking(desiredState);
31
  }
32

    
33
  ~SetBlocking()
34
  {
35
    client_.setBlocking(savedState_);
36
  }
37

    
38
private:
39
  UnixClientSocket &client_;
40
  bool savedState_;
41
};
42

    
43
ClientConnection::ClientConnection( const std::string &socketFile )
44
 : control_(socketFile), data_(socketFile), good_(true)
45
{
46
  if (!control_ || !data_) {
47
    good_ = false;
48
    error_ = "Failed to connect to socket " + socketFile;
49
    return;
50
  }
51

    
52
  control_.write("CONTROL\n");
53
  std::string key;
54
  if (!control_.readLine(key)) {
55
    error_ = "Failed to read data key";
56
    good_ = false;
57
    return;
58
  }
59
  key = stripTrailingWS(key);
60
  data_.write("DATA " + key + "\n");
61
  std::string welcome;
62
  if (!control_.readLine(welcome)) {
63
    error_ = "Failed to read welcome message";
64
    good_ = false;
65
    return;
66
  }
67
}
68

    
69
ClientConnection::operator bool () const
70
{
71
  return good_ && control_ && data_;
72
}
73

    
74
std::string ClientConnection::getError() const
75
{
76
  return error_;
77
}
78

    
79
bool ClientConnection::getChannels(const std::string &type, int priority, StringList &channels)
80
{
81
  SetBlocking blocking(control_, true);
82

    
83
  // Check if the command is to list the channels
84
  control_.write("LIST " + type + " " + toString(priority) + "\n");
85

    
86
  do {
87
    std::string reply;
88
    if (!control_.readLine(reply)) {
89
      error_ = "failed to read channel from control socket";
90
      return false;
91
    }
92

    
93
    if (reply.substr(0, 5) == "ERROR") {
94
      return false;
95
    }
96
    else if (reply == "OK\n") 
97
      return true;
98
    else 
99
      channels.push_back( stripTrailingWS(reply.substr(1)) );
100

    
101
  } while (true);
102

    
103
}
104

    
105
UnixClientSocket& ClientConnection::control()
106
{
107
  return control_;
108
}
109

    
110
UnixClientSocket& ClientConnection::data()
111
{
112
  return data_;
113
}
114

    
115
int ClientConnection::schedule(const std::string &type, const std::string &channel,
116
                               bool convertToPS, time_t when, unsigned duration, int priority,
117
                               const std::string &outputFile)
118
{
119
  SetBlocking saveBlocking(control_, true);
120
  // Convert the time to the right format
121
  char data[256];
122
  strftime(data, sizeof(data), "%Y-%m-%d %H:%M:%S", localtime(&when));
123
  std::string dateTime = data;
124

    
125
  std::string command = 
126
    "SCHEDULE " + dateTime + " " + type + " " + escapeWS(channel) + " " + 
127
    toString(convertToPS) + " " + toString(priority) + " " + 
128
    toString(duration * 60) + " " + outputFile + "\n";
129
  std::cerr << command;
130

    
131
  control_.write(command);
132
    
133
  std::string reply;
134
  control_.readLine(reply);
135
  
136
  if (reply.substr(0, 3) == "JOB") {
137
    int job = toInt(reply.substr(4));
138
    control_.readLine(reply);        // Ok
139
    return job;
140
  }
141
  error_ = stripTrailingWS(reply);
142
  return -1;
143
}
144

    
145
void ClientConnection::checkSchedule(StringList &messages)
146
{
147
  SetBlocking saveBlocking(control_, true);
148
  control_.write("CHECK\n");
149
  do {
150
    std::string reply;
151
    control_.readLine(reply);
152
    if (reply == "OK\n")
153
      break;
154
    messages.push_back(stripTrailingWS(reply));
155
  } while (true);
156
}
157

    
158
bool ClientConnection::listSchedule(StringList &s)
159
{
160
  SetBlocking saveBlocking(control_, true);
161
  control_.write("LISTSCHEDULE\n");
162
  do {
163
    std::string reply;
164
    control_.readLine(reply);
165
    if (reply == "OK\n")
166
      break;
167
    s.push_back(stripTrailingWS(reply));
168
  } while (true);
169
  return true;
170
}
171

    
172
bool ClientConnection::removeJob(int job)
173
{
174
  SetBlocking saveBlocking(control_, true);
175
  control_.write("REMOVEJOB " + toString(job) + "\n");
176
  std::string reply;
177
  control_.readLine(reply);
178
  if (reply == "OK\n")
179
    return true;
180
  error_ = stripTrailingWS(reply);
181
  return false;
182
}
183

    
184
bool ClientConnection::tune(const std::string &type, const std::string &channel, 
185
                            bool convertToPS, int priority)
186
{
187
  SetBlocking saveBlocking(control_, true);
188
  control_.write("TUNE " + type + " " + escapeWS(channel) + " " + 
189
                 toString(convertToPS) + " " + toString(priority) + "\n");
190
  std::string reply;
191
  control_.readLine(reply);
192
  if (reply == "OK\n")
193
    return true;
194
  error_ = stripTrailingWS(reply);
195
  return false;
196
}
197

    
198
bool ClientConnection::getNextJobTime(time_t &nextJobTime)
199
{
200
  SetBlocking saveBlocking(control_, true);
201
  control_.write("NEXTJOBTIME\n");
202

    
203
  std::string reply;
204
  control_.readLine(reply);
205
  if (reply.substr(0, 5) == "ERROR") {
206
    error_ = stripTrailingWS(reply);
207
    return false;
208
  }
209
  struct tm tm;
210
  if (strptime(reply.c_str(), "%Y-%m-%d %H:%M:%S", &tm) == NULL) {
211
    error_ = "Invalid date/time: " + stripTrailingWS(reply);
212
    return false;
213
  }
214
  nextJobTime = mktime(&tm);
215
  return true;
216
}
217

    
218
bool ClientConnection::listConnections(StringList &s)
219
{
220
  SetBlocking saveBlocking(control_, true);
221
  control_.write("LISTCONNECTIONS\n");
222
  do {
223
    std::string reply;
224
    control_.readLine(reply);
225
    if (reply == "OK\n")
226
      break;
227
    s.push_back(stripTrailingWS(reply));
228
  } while (true);
229
  return true;
230
}
231