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

Annotation of /smsdaemon/Spooler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 132 - (hide annotations) (download)
Sun Dec 7 00:59:05 2008 UTC (15 years, 5 months ago) by torben
File size: 2384 byte(s)
Added spooling (queing) function, with a standalone application(smsqueue) to put new messages 
into the spool dir.

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     #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 = getSpoolFilename();
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     }
54    
55     std::string Spooler::dequeue()
56     {
57     lock();
58    
59     DIR* dir = opendir( spooldir.c_str() );
60     if (dir == 0)
61     errnoException();
62    
63     string file;
64     string message;
65     dirent* entry;
66     while ( (entry = readdir(dir)) != 0)
67     {
68     if (entry->d_name[0] == '.' )
69     {
70     continue;
71     }
72     else
73     {
74     file = spooldir + string(entry->d_name);
75     break;
76     }
77    
78     }
79    
80     closedir(dir);
81    
82     if (file != "") {
83     message = Util::readfile(file);
84     ::unlink(file.c_str());
85     }
86    
87     unlock();
88    
89     if (file != "")
90     return message;
91     else
92     throw filenotfoundexception();
93     }
94    
95     std::string Spooler::getSpoolFilename()
96     {
97     std::string file;
98     std::stringstream ss;
99    
100     int retrycount = 0;
101    
102     while(1) {
103     ss.str(std::string()); //clear
104     ss << std::setw(8) << std::setfill('0') << std::uppercase << std::hex << rand();
105    
106     string file = spooldir;
107     file += ss.str().c_str();
108    
109     int fd = ::open(file.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP| S_IROTH);
110     retrycount ++;
111    
112     if (fd != -1) {
113     ::close(fd);
114     return file;
115     }
116    
117     if (errno == EEXIST)
118     continue;
119    
120     if (retrycount > 20)
121     throw std::runtime_error("to many retry attempt at creating spool file");
122    
123     throw std::runtime_error("no access to spool directory");
124    
125     }
126     }
127    
128     void Spooler::lock()
129     {
130     fd = open(spooldir.c_str() , O_RDONLY);
131    
132     if (fd == -1) {
133     errnoException("Couldn open lockfile");
134     }
135    
136     int status = flock(fd, LOCK_EX);
137    
138     if (status == -1) {
139     errnoException();
140     }
141     }
142    
143     void Spooler::unlock()
144     {
145     flock(fd, LOCK_UN);
146     }

  ViewVC Help
Powered by ViewVC 1.1.20