/[projects]/smsdaemon/Spooler.cpp
ViewVC logotype

Annotation of /smsdaemon/Spooler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 158 - (hide annotations) (download)
Mon Dec 8 21:49:49 2008 UTC (15 years, 5 months ago) by torben
File size: 2558 byte(s)
rename:
	util.* -> Util.*
	common.* -> Common.*

1 torben 132 #include "Spooler.h"
2     #include <iostream>
3     #include <string>
4     #include <stdexcept>
5     #include <cstring>
6     #include <fstream>
7     #include <sstream>
8     #include <iomanip>
9     #include <errno.h>
10    
11     #include <sys/types.h>
12     #include <sys/stat.h>
13     #include <sys/file.h>
14     #include <dirent.h>
15     #include <fcntl.h>
16     #include <stdlib.h>
17    
18 torben 158 #include "Util.h"
19 torben 132
20     #include "Exceptions.h"
21    
22     const std::string spooldir = "/var/spool/smsdaemon/";
23    
24     using namespace std;
25    
26    
27     void errnoException(std::string msg = "")
28     {
29     if (msg != "")
30     msg += ": ";
31     msg += std::string(strerror(errno));
32     throw std::runtime_error(msg);
33     }
34    
35    
36    
37     void Spooler::enqueue(std::string recipient, std::string message)
38     {
39     bool error = false;
40     lock();
41 torben 134 std::string file = findSpoolFilename();
42 torben 132 std::ofstream out(file.c_str());
43     if (out) {
44     out << recipient << "\n" << message;
45     out.close();
46     } else {
47     error = true;
48     }
49     unlock();
50    
51     if (error)
52     throw std::runtime_error("Could not create spoolfile");
53 torben 134 this->filename = file;
54 torben 132 }
55    
56     std::string Spooler::dequeue()
57     {
58     lock();
59    
60     DIR* dir = opendir( spooldir.c_str() );
61     if (dir == 0)
62     errnoException();
63    
64     string file;
65     string message;
66     dirent* entry;
67     while ( (entry = readdir(dir)) != 0)
68     {
69     if (entry->d_name[0] == '.' )
70     {
71     continue;
72     }
73     else
74     {
75     file = spooldir + string(entry->d_name);
76     break;
77     }
78    
79     }
80    
81     closedir(dir);
82    
83     if (file != "") {
84     message = Util::readfile(file);
85     ::unlink(file.c_str());
86     }
87    
88     unlock();
89    
90 torben 134 this->filename = file;
91    
92 torben 132 if (file != "")
93     return message;
94     else
95     throw filenotfoundexception();
96     }
97    
98 torben 134 std::string Spooler::findSpoolFilename()
99 torben 132 {
100     std::string file;
101     std::stringstream ss;
102    
103     int retrycount = 0;
104    
105     while(1) {
106     ss.str(std::string()); //clear
107     ss << std::setw(8) << std::setfill('0') << std::uppercase << std::hex << rand();
108    
109     string file = spooldir;
110     file += ss.str().c_str();
111    
112     int fd = ::open(file.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP| S_IROTH);
113     retrycount ++;
114    
115     if (fd != -1) {
116     ::close(fd);
117     return file;
118     }
119 torben 155 int err = errno;
120     ::close(fd);
121 torben 132
122 torben 155 if (err == EEXIST) {
123 torben 132 continue;
124 torben 155 }
125 torben 132
126     if (retrycount > 20)
127     throw std::runtime_error("to many retry attempt at creating spool file");
128    
129     throw std::runtime_error("no access to spool directory");
130    
131     }
132     }
133    
134     void Spooler::lock()
135     {
136 torben 155 lockfd = open(spooldir.c_str() , O_RDONLY);
137 torben 132
138 torben 155 if (lockfd == -1) {
139 torben 132 errnoException("Couldn open lockfile");
140     }
141    
142 torben 155 int status = flock(lockfd, LOCK_EX);
143 torben 132
144     if (status == -1) {
145     errnoException();
146     }
147     }
148    
149     void Spooler::unlock()
150     {
151 torben 155 flock(lockfd, LOCK_UN);
152     close(lockfd);
153 torben 132 }
154 torben 134
155     string Spooler::getFilename()
156     {
157     return filename;
158     }

  ViewVC Help
Powered by ViewVC 1.1.20