Statistics
| Branch: | Tag: | Revision:

dvbd / src / utils.cpp @ 900cea42

History | View | Annotate | Download (3.31 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 "config.h"
20
#include "utils.h"
21
#include <fcntl.h>
22
#include <sys/types.h>
23
#include <sys/socket.h>
24
#include <sys/stat.h>
25
#include <unistd.h>
26
#include <iostream>
27
#include <cctype>
28
#include <cerrno>
29

    
30
void setNonBlocking(int fd)
31
{
32
  long flags = fcntl(fd, F_GETFL, 0); 
33
  flags |= O_NONBLOCK;
34
  fcntl(fd, F_SETFL, flags);
35
}
36

    
37
int readLineStripTrailingWS(int fd, std::string &line)
38
{
39
  char data[1024];
40
  int bytesread = read(fd, data, 1023);
41

    
42
  if (bytesread <= 0)
43
    return bytesread;
44

    
45
  data[bytesread] = '\x0';
46

    
47
  // Strip trailing whitespace;
48
  for (int j = bytesread - 1; j >= 0 && isspace(data[j]); j--)
49
    data[j] = '\x0';
50

    
51
  line = data;
52
  return bytesread;
53
}
54

    
55
void writeString(int fd, const std::string &line)
56
{
57
  write(fd, line.data(), line.size());
58
}
59

    
60
std::string escapeWS(const std::string &channel)
61
{
62
  std::string result;
63

    
64
  for (unsigned i = 0; i < channel.size(); i++) {
65
    switch (channel[i]) {
66
    case '\\':
67
      result += "\\\\";
68
      break;
69
    case ' ':
70
      result += "\\_";
71
      break;
72
    default:
73
      result += channel[i];
74
    }
75
  }
76

    
77
  return result;
78
}
79

    
80
std::string unescapeWS(const std::string &channel)
81
{
82
  std::string result;
83
  bool escaped = false;
84

    
85
  for (unsigned i = 0; i < channel.size(); i++) {
86
    if (channel[i] == '\\')
87
      escaped = true;
88
    else {
89
      char ch = channel[i];
90

    
91
      if (escaped && ch == '_') {
92
        ch = ' ';
93
        escaped = false;
94
      }
95

    
96
      result += ch;
97
    }
98
  }
99
  return result;
100
}
101

    
102
bool readCredentials(int fd, pid_t &pid, uid_t &uid, gid_t &gid)
103
{
104
  int value = 1;
105
  if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &value, sizeof(value)) < 0) 
106
    std::cerr << "Failed to set SOL_SOCKET SO_PASSCRED: " << strerror(errno) << "\n";
107

    
108
  struct ucred ucred;
109
  socklen_t size = sizeof(ucred);
110
  if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &size) < 0) {
111
    std::cerr << "Failed to get credentials from UNIX socket: " 
112
              << strerror(errno) << "\n";
113
    return false;  
114
  }
115

    
116
  pid = ucred.pid;
117
  uid = ucred.uid;
118
  gid = ucred.gid;
119
  return true;
120
}
121

    
122
bool accessOk(const std::string &path, uid_t uid)
123
{
124
  std::string::size_type lastSlash = path.find_last_of('/');
125
  if (lastSlash == std::string::npos) 
126
    return false;
127

    
128
  std::string dirPart = path.substr(0, lastSlash);
129
  std::string filePart = path.substr(lastSlash + 1);
130

    
131
  // Client must own directory
132
  struct stat info;
133
  if (stat(dirPart.c_str(), &info) != 0)
134
    return false;
135
  
136
  if (info.st_uid != uid)
137
    return false;
138

    
139
  // But must still be writable by this process
140
  if (access(path.c_str(), F_OK) == 0)
141
    return access(path.c_str(), W_OK) == 0;
142
  else 
143
    return access(dirPart.c_str(), W_OK) == 0;
144
}
145