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

Contents of /smsdaemon/Spooler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 158 - (show 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 #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 #include "Util.h"
19
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 std::string file = findSpoolFilename();
42 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 this->filename = file;
54 }
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 this->filename = file;
91
92 if (file != "")
93 return message;
94 else
95 throw filenotfoundexception();
96 }
97
98 std::string Spooler::findSpoolFilename()
99 {
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 int err = errno;
120 ::close(fd);
121
122 if (err == EEXIST) {
123 continue;
124 }
125
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 lockfd = open(spooldir.c_str() , O_RDONLY);
137
138 if (lockfd == -1) {
139 errnoException("Couldn open lockfile");
140 }
141
142 int status = flock(lockfd, LOCK_EX);
143
144 if (status == -1) {
145 errnoException();
146 }
147 }
148
149 void Spooler::unlock()
150 {
151 flock(lockfd, LOCK_UN);
152 close(lockfd);
153 }
154
155 string Spooler::getFilename()
156 {
157 return filename;
158 }

  ViewVC Help
Powered by ViewVC 1.1.20