Statistics
| Branch: | Tag: | Revision:

dvbd / clientconnection.cpp @ a7dee730

History | View | Annotate | Download (5.38 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
    control_.write("CONTROL\n");
48
    std::string key;
49
    if (!control_.readLine(key)) {
50
      good_ = false;
51
      return;
52
    }
53
    key = stripTrailingWS(key);
54
    data_.write("DATA " + key + "\n");
55
    std::string welcome;
56
    if (!control_.readLine(welcome)) {
57
      good_ = false;
58
      return;
59
    }
60
  }
61
}
62

    
63
ClientConnection::operator bool () const
64
{
65
  return good_ && control_ && data_;
66
}
67

    
68
std::string ClientConnection::getError() const
69
{
70
  return error_;
71
}
72

    
73
bool ClientConnection::getChannels(const std::string &type, int priority, StringList &channels)
74
{
75
  SetBlocking blocking(control_, true);
76

    
77
  // Check if the command is to list the channels
78
  control_.write("LIST " + type + " " + toString(priority) + "\n");
79

    
80
  do {
81
    std::string reply;
82
    if (!control_.readLine(reply)) {
83
      error_ = "failed to read channel from control socket";
84
      return false;
85
    }
86

    
87
    if (reply.substr(0, 5) == "ERROR") {
88
      return false;
89
    }
90
    else if (reply == "OK\n") 
91
      return true;
92
    else 
93
      channels.push_back( stripTrailingWS(reply.substr(1)) );
94

    
95
  } while (true);
96

    
97
}
98

    
99
UnixClientSocket& ClientConnection::control()
100
{
101
  return control_;
102
}
103

    
104
UnixClientSocket& ClientConnection::data()
105
{
106
  return data_;
107
}
108

    
109
int ClientConnection::schedule(const std::string &type, const std::string &channel,
110
                               time_t when, unsigned duration, int priority,
111
                               const std::string &outputFile)
112
{
113
  SetBlocking saveBlocking(control_, true);
114
  // Convert the time to the right format
115
  char data[256];
116
  strftime(data, sizeof(data), "%Y-%m-%d %H:%M:%S", localtime(&when));
117
  std::string dateTime = data;
118

    
119
  std::string command = 
120
    "SCHEDULE " + dateTime + " " + type + " " + escapeWS(channel) + " " + 
121
    toString(priority) + " " + toString(duration * 60) + " " + outputFile + "\n";
122
  std::cerr << command;
123

    
124
  control_.write(command);
125
    
126
  std::string reply;
127
  control_.readLine(reply);
128
  
129
  if (reply.substr(0, 3) == "JOB") {
130
    int job = toInt(reply.substr(4));
131
    control_.readLine(reply);        // Ok
132
    return job;
133
  }
134
  error_ = stripTrailingWS(reply);
135
  return -1;
136
}
137

    
138
void ClientConnection::checkSchedule(StringList &messages)
139
{
140
  SetBlocking saveBlocking(control_, true);
141
  control_.write("CHECK\n");
142
  do {
143
    std::string reply;
144
    control_.readLine(reply);
145
    if (reply == "OK\n")
146
      break;
147
    messages.push_back(stripTrailingWS(reply));
148
  } while (true);
149
}
150

    
151
bool ClientConnection::listSchedule(StringList &s)
152
{
153
  SetBlocking saveBlocking(control_, true);
154
  control_.write("LISTSCHEDULE\n");
155
  do {
156
    std::string reply;
157
    control_.readLine(reply);
158
    if (reply == "OK\n")
159
      break;
160
    s.push_back(stripTrailingWS(reply));
161
  } while (true);
162
  return true;
163
}
164

    
165
bool ClientConnection::removeJob(int job)
166
{
167
  SetBlocking saveBlocking(control_, true);
168
  control_.write("REMOVEJOB " + toString(job) + "\n");
169
  std::string reply;
170
  control_.readLine(reply);
171
  if (reply == "OK\n")
172
    return true;
173
  error_ = stripTrailingWS(reply);
174
  return false;
175
}
176

    
177
bool ClientConnection::tune(const std::string &type, const std::string &channel, int priority)
178
{
179
  SetBlocking saveBlocking(control_, true);
180
  control_.write("TUNE " + type + " " + escapeWS(channel) + " " + toString(priority) + "\n");
181
  std::string reply;
182
  control_.readLine(reply);
183
  if (reply == "OK\n")
184
    return true;
185
  error_ = stripTrailingWS(reply);
186
  return false;
187
}
188

    
189
bool ClientConnection::getNextJobTime(time_t &nextJobTime)
190
{
191
  SetBlocking saveBlocking(control_, true);
192
  control_.write("NEXTJOBTIME\n");
193

    
194
  std::string reply;
195
  control_.readLine(reply);
196
  if (reply.substr(0, 5) == "ERROR") {
197
    error_ = stripTrailingWS(reply);
198
    return false;
199
  }
200
  struct tm tm;
201
  if (strptime(reply.c_str(), "%Y-%m-%d %H:%M:%S", &tm) == NULL) {
202
    error_ = "Invalid date/time: " + stripTrailingWS(reply);
203
    return false;
204
  }
205
  nextJobTime = mktime(&tm);
206
  return true;
207
}
208

    
209
bool ClientConnection::listConnections(StringList &s)
210
{
211
  SetBlocking saveBlocking(control_, true);
212
  control_.write("LISTCONNECTIONS\n");
213
  do {
214
    std::string reply;
215
    control_.readLine(reply);
216
    if (reply == "OK\n")
217
      break;
218
    s.push_back(stripTrailingWS(reply));
219
  } while (true);
220
  return true;
221
}
222