~ubuntu-branches/debian/stretch/sflphone/stretch

« back to all changes in this revision

Viewing changes to daemon/src/fileutils.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2013-06-23 11:40:53 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20130623114053-31kveg263f17i9e7
Tags: 1.2.3-1
* New upstream release
* Add Build-Depends: intltool, yelp-tools, gnome-common

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  Copyright (C) 2011-2012 Savoir-Faire Linux Inc.
 
3
 *  Copyright (C) 2010 Michael Kerrisk
 
4
 *  Copyright (C) 2007-2009 Rémi Denis-Courmont
 
5
 *
3
6
 *  Author: Rafaël Carré <rafael.carre@savoirfairelinux.com>
4
7
 *
5
8
 *  This program is free software; you can redistribute it and/or modify
28
31
 *  as that of the covered work.
29
32
 */
30
33
 
 
34
#ifdef HAVE_CONFIG_H
 
35
#include "config.h"
 
36
#endif
 
37
 
31
38
#include <sys/types.h>
32
39
#include <unistd.h>
33
40
#include <libgen.h>
40
47
#include <sstream>
41
48
#include <iostream>
42
49
#include <unistd.h>
 
50
#include <cstring>
 
51
#include <fcntl.h>
 
52
#include <pwd.h>
 
53
#include <cerrno>
43
54
#include "fileutils.h"
 
55
#include "logger.h"
44
56
 
45
57
namespace fileutils {
46
58
// returns true if directory exists
71
83
    return program_dir;
72
84
}
73
85
 
74
 
//TODO it is faking this, implement proper system 
75
 
const char *get_data_dir()
76
 
{
77
 
    std::string path = std::string(get_program_dir()) + "/../../share/sflphone/ringtones/";
78
 
    return path.c_str();
79
 
}
80
 
 
81
 
bool create_pidfile()
82
 
{
83
 
    std::string xdg_env(XDG_CACHE_HOME);
84
 
    std::string path = (not xdg_env.empty()) ? xdg_env : std::string(HOMEDIR) + DIR_SEPARATOR_STR ".cache/";
85
 
 
86
 
    if (!check_dir(path.c_str()))
87
 
        return false;
88
 
 
89
 
    path += "sflphone";
90
 
 
91
 
    if (!check_dir(path.c_str()))
92
 
        return false;
93
 
 
94
 
    std::string pidfile = path + "/" PIDFILE;
95
 
    std::ifstream is(pidfile.c_str());
96
 
 
97
 
    if (is) {
98
 
        // PID file exists. Check if the former process is still alive or
99
 
        // not. If alive, give user a hint.
100
 
        int oldPid;
101
 
        is >> oldPid;
102
 
 
103
 
        if (kill(oldPid, 0) == 0) {
104
 
            // Use cerr because logging has not been initialized
105
 
            std::cerr << "There is already a sflphoned daemon running in " <<
106
 
                "the system. Starting Failed." << std::endl;
107
 
            return false;
108
 
        }
109
 
    }
110
 
 
111
 
    // write pid file
112
 
    std::ofstream os(pidfile.c_str());
113
 
 
114
 
    if (!os) {
115
 
        perror(pidfile.c_str());
116
 
        return false;
117
 
    } else {
118
 
        os << getpid();
119
 
    }
120
 
 
121
 
    return true;
 
86
// FIXME: This should use our real DATADIR
 
87
std::string
 
88
get_data_dir()
 
89
{
 
90
    return std::string(get_program_dir()) + "/../../share/sflphone/ringtones/";
 
91
}
 
92
 
 
93
namespace {
 
94
 
 
95
/* Lock a file region */
 
96
int
 
97
lockReg(int fd, int cmd, int type, int whence, int start, off_t len)
 
98
{
 
99
    struct flock fl;
 
100
 
 
101
    fl.l_type = type;
 
102
    fl.l_whence = whence;
 
103
    fl.l_start = start;
 
104
    fl.l_len = len;
 
105
 
 
106
    return fcntl(fd, cmd, &fl);
 
107
}
 
108
 
 
109
int /* Lock a file region using nonblocking F_SETLK */
 
110
lockRegion(int fd, int type, int whence, int start, int len)
 
111
{
 
112
    return lockReg(fd, F_SETLK, type, whence, start, len);
 
113
}
 
114
}
 
115
 
 
116
FileHandle
 
117
create_pidfile()
 
118
{
 
119
    const std::string name(get_home_dir() + DIR_SEPARATOR_STR PIDFILE);
 
120
    FileHandle f(name);
 
121
    char buf[100];
 
122
    f.fd = open(f.name.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
 
123
    if (f.fd == -1) {
 
124
        ERROR("Could not open PID file %s", f.name.c_str());
 
125
        return f;
 
126
    }
 
127
 
 
128
    if (lockRegion(f.fd, F_WRLCK, SEEK_SET, 0, 0) == -1) {
 
129
        if (errno  == EAGAIN or errno == EACCES)
 
130
            ERROR("PID file '%s' is locked; probably "
 
131
                    "'%s' is already running", f.name.c_str(), PACKAGE_NAME);
 
132
        else
 
133
            ERROR("Unable to lock PID file '%s'", f.name.c_str());
 
134
        close(f.fd);
 
135
        f.fd = -1;
 
136
        return f;
 
137
    }
 
138
 
 
139
    if (ftruncate(f.fd, 0) == -1) {
 
140
        ERROR("Could not truncate PID file '%s'", f.name.c_str());
 
141
        close(f.fd);
 
142
        f.fd = -1;
 
143
        return f;
 
144
    }
 
145
 
 
146
    snprintf(buf, sizeof(buf), "%ld\n", (long) getpid());
 
147
 
 
148
    const int buf_strlen = strlen(buf);
 
149
    if (write(f.fd, buf, buf_strlen) != buf_strlen) {
 
150
        ERROR("Problem writing to PID file '%s'", f.name.c_str());
 
151
        close(f.fd);
 
152
        f.fd = -1;
 
153
        return f;
 
154
    }
 
155
 
 
156
    return f;
122
157
}
123
158
 
124
159
bool isDirectoryWritable(const std::string &directory)
125
160
{
126
161
    return access(directory.c_str(), W_OK) == 0;
127
162
}
 
163
 
 
164
FileHandle::FileHandle(const std::string &n) : fd(-1), name(n)
 
165
{}
 
166
 
 
167
FileHandle::~FileHandle()
 
168
{
 
169
    // we will only delete the file if it was created by this process
 
170
    if (fd != -1) {
 
171
        close(fd);
 
172
        if (unlink(name.c_str()) == -1)
 
173
            ERROR("%s", strerror(errno));
 
174
    }
 
175
}
 
176
 
 
177
std::string
 
178
get_home_dir()
 
179
{
 
180
    // 1) try getting user's home directory from the environment
 
181
    const std::string home(PROTECTED_GETENV("HOME"));
 
182
    if (not home.empty())
 
183
        return home;
 
184
 
 
185
    // 2) try getting it from getpwuid_r (i.e. /etc/passwd)
 
186
    const long max = sysconf(_SC_GETPW_R_SIZE_MAX);
 
187
    if (max != -1) {
 
188
        char buf[max];
 
189
        struct passwd pwbuf, *pw;
 
190
        if (getpwuid_r(getuid(), &pwbuf, buf, sizeof(buf), &pw) == 0 and pw != NULL)
 
191
            return pw->pw_dir;
 
192
    }
 
193
 
 
194
    return "";
 
195
}
128
196
}