1 /* 2 * Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved. 3 * Copyright 2004-2007, Haiku Inc. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 //! The mail daemon's settings 9 10 11 #include <MailSettings.h> 12 13 #include <Message.h> 14 #include <FindDirectory.h> 15 #include <Directory.h> 16 #include <File.h> 17 #include <Entry.h> 18 #include <Path.h> 19 #include <String.h> 20 #include <Messenger.h> 21 22 #include <stdio.h> 23 #include <string.h> 24 #include <stdlib.h> 25 26 27 class BMailSettings; 28 29 namespace MailInternal { 30 status_t WriteMessageFile(const BMessage& archive, const BPath& path, 31 const char* name); 32 } 33 34 35 // #pragma mark - Chain methods 36 37 // 38 // To do 39 // 40 BMailChain* 41 NewMailChain() 42 { 43 // attempted solution: use time(NULL) and hope it's unique. Is there a better idea? 44 // note that two chains in two second is quite possible. how to fix this? 45 // maybe we could | in some bigtime_t as well. hrrm... 46 47 // This is to fix a problem with generating the correct id for chains. 48 // Basically if the chains dir does not exist, the first time you create 49 // an account both the inbound and outbound chains will be called 0. 50 create_directory("/boot/home/config/settings/Mail/chains",0777); 51 52 BPath path; 53 find_directory(B_USER_SETTINGS_DIRECTORY, &path); 54 path.Append("Mail/chains"); 55 BDirectory chain_dir(path.Path()); 56 BDirectory outbound_dir(&chain_dir,"outbound"), inbound_dir(&chain_dir,"inbound"); 57 58 // TODO(bga): A better way to do all this anyway is to write the chain 59 // information to the settings message (a new field would be added). 60 61 // Lock Chain directory to avoid concurrent access. 62 chain_dir.Lock(); 63 64 int32 id = -1; //-----When inc'ed, we start with 0---- 65 chain_dir.ReadAttr("last_issued_chain_id",B_INT32_TYPE,0,&id,sizeof(id)); 66 67 BString string_id; 68 69 do { 70 id++; 71 string_id = ""; 72 string_id << id; 73 } while ((outbound_dir.Contains(string_id.String())) 74 || (inbound_dir.Contains(string_id.String()))); 75 76 chain_dir.WriteAttr("last_issued_chain_id",B_INT32_TYPE,0,&id,sizeof(id)); 77 78 return new BMailChain(id); 79 } 80 81 82 BMailChain* 83 GetMailChain(uint32 id) 84 { 85 return new BMailChain(id); 86 } 87 88 89 status_t 90 GetInboundMailChains(BList *list) 91 { 92 BPath path; 93 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); 94 if (status != B_OK) { 95 fprintf(stderr, "Couldn't find user settings directory: %s\n", 96 strerror(status)); 97 return status; 98 } 99 100 path.Append("Mail/chains/inbound"); 101 BDirectory chainDirectory(path.Path()); 102 entry_ref ref; 103 104 while (chainDirectory.GetNextRef(&ref) == B_OK) { 105 char *end; 106 uint32 id = strtoul(ref.name, &end, 10); 107 108 if (!end || *end == '\0') 109 list->AddItem((void*)new BMailChain(id)); 110 } 111 112 return B_OK; 113 } 114 115 116 status_t 117 GetOutboundMailChains(BList *list) 118 { 119 BPath path; 120 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); 121 if (status != B_OK) { 122 fprintf(stderr, "Couldn't find user settings directory: %s\n", 123 strerror(status)); 124 return status; 125 } 126 127 path.Append("Mail/chains/outbound"); 128 BDirectory chainDirectory(path.Path()); 129 entry_ref ref; 130 131 while (chainDirectory.GetNextRef(&ref) == B_OK) { 132 char *end; 133 uint32 id = strtoul(ref.name, &end, 10); 134 if (!end || *end == '\0') 135 list->AddItem((void*)new BMailChain(id)); 136 } 137 138 return B_OK; 139 } 140 141 142 // #pragma mark - BMailSettings 143 144 145 BMailSettings::BMailSettings() 146 { 147 Reload(); 148 } 149 150 151 BMailSettings::~BMailSettings() 152 { 153 } 154 155 156 status_t 157 BMailSettings::InitCheck() const 158 { 159 return B_OK; 160 } 161 162 163 status_t 164 BMailSettings::Save(bigtime_t /*timeout*/) 165 { 166 status_t ret; 167 // 168 // Find chain-saving directory 169 // 170 171 BPath path; 172 ret = find_directory(B_USER_SETTINGS_DIRECTORY, &path); 173 if (ret != B_OK) { 174 fprintf(stderr, "Couldn't find user settings directory: %s\n", 175 strerror(ret)); 176 return ret; 177 } 178 179 path.Append("Mail"); 180 181 status_t result = MailInternal::WriteMessageFile(data,path,"new_mail_daemon"); 182 if (result < B_OK) 183 return result; 184 185 BMessenger("application/x-vnd.Be-POST").SendMessage('mrrs'); 186 187 return B_OK; 188 } 189 190 191 status_t 192 BMailSettings::Reload() 193 { 194 status_t ret; 195 196 BPath path; 197 ret = find_directory(B_USER_SETTINGS_DIRECTORY, &path); 198 if (ret != B_OK) { 199 fprintf(stderr, "Couldn't find user settings directory: %s\n", 200 strerror(ret)); 201 return ret; 202 } 203 204 path.Append("Mail/new_mail_daemon"); 205 206 // open 207 BFile settings(path.Path(),B_READ_ONLY); 208 ret = settings.InitCheck(); 209 if (ret != B_OK) { 210 fprintf(stderr, "Couldn't open settings file '%s': %s\n", 211 path.Path(), strerror(ret)); 212 return ret; 213 } 214 215 // read settings 216 BMessage tmp; 217 ret = tmp.Unflatten(&settings); 218 if (ret != B_OK) { 219 fprintf(stderr, "Couldn't read settings from '%s': %s\n", 220 path.Path(), strerror(ret)); 221 return ret; 222 } 223 224 // clobber old settings 225 data = tmp; 226 return B_OK; 227 } 228 229 230 // # pragma mark - Global settings 231 232 233 int32 234 BMailSettings::WindowFollowsCorner() 235 { 236 return data.FindInt32("WindowFollowsCorner"); 237 } 238 239 240 void 241 BMailSettings::SetWindowFollowsCorner(int32 which_corner) 242 { 243 if (data.ReplaceInt32("WindowFollowsCorner",which_corner)) 244 data.AddInt32("WindowFollowsCorner",which_corner); 245 } 246 247 248 uint32 249 BMailSettings::ShowStatusWindow() 250 { 251 return data.FindInt32("ShowStatusWindow"); 252 } 253 254 255 void 256 BMailSettings::SetShowStatusWindow(uint32 mode) 257 { 258 if (data.ReplaceInt32("ShowStatusWindow",mode)) 259 data.AddInt32("ShowStatusWindow",mode); 260 } 261 262 263 bool 264 BMailSettings::DaemonAutoStarts() 265 { 266 return data.FindBool("DaemonAutoStarts"); 267 } 268 269 270 void 271 BMailSettings::SetDaemonAutoStarts(bool does_it) 272 { 273 if (data.ReplaceBool("DaemonAutoStarts",does_it)) 274 data.AddBool("DaemonAutoStarts",does_it); 275 } 276 277 278 BRect 279 BMailSettings::ConfigWindowFrame() 280 { 281 return data.FindRect("ConfigWindowFrame"); 282 } 283 284 285 void 286 BMailSettings::SetConfigWindowFrame(BRect frame) 287 { 288 if (data.ReplaceRect("ConfigWindowFrame",frame)) 289 data.AddRect("ConfigWindowFrame",frame); 290 } 291 292 293 BRect 294 BMailSettings::StatusWindowFrame() 295 { 296 BRect frame; 297 if (data.FindRect("StatusWindowFrame", &frame) != B_OK) 298 return BRect(100, 100, 200, 120); 299 300 return frame; 301 } 302 303 304 void 305 BMailSettings::SetStatusWindowFrame(BRect frame) 306 { 307 if (data.ReplaceRect("StatusWindowFrame",frame)) 308 data.AddRect("StatusWindowFrame",frame); 309 } 310 311 312 int32 313 BMailSettings::StatusWindowWorkspaces() 314 { 315 return data.FindInt32("StatusWindowWorkSpace"); 316 } 317 318 319 void 320 BMailSettings::SetStatusWindowWorkspaces(int32 workspace) 321 { 322 if (data.ReplaceInt32("StatusWindowWorkSpace",workspace)) 323 data.AddInt32("StatusWindowWorkSpace",workspace); 324 325 BMessage msg('wsch'); 326 msg.AddInt32("StatusWindowWorkSpace",workspace); 327 BMessenger("application/x-vnd.Be-POST").SendMessage(&msg); 328 } 329 330 331 int32 332 BMailSettings::StatusWindowLook() 333 { 334 return data.FindInt32("StatusWindowLook"); 335 } 336 337 338 void 339 BMailSettings::SetStatusWindowLook(int32 look) 340 { 341 if (data.ReplaceInt32("StatusWindowLook",look)) 342 data.AddInt32("StatusWindowLook",look); 343 344 BMessage msg('lkch'); 345 msg.AddInt32("StatusWindowLook",look); 346 BMessenger("application/x-vnd.Be-POST").SendMessage(&msg); 347 } 348 349 350 bigtime_t 351 BMailSettings::AutoCheckInterval() 352 { 353 bigtime_t value = B_INFINITE_TIMEOUT; 354 data.FindInt64("AutoCheckInterval",&value); 355 return value; 356 } 357 358 359 void 360 BMailSettings::SetAutoCheckInterval(bigtime_t interval) 361 { 362 if (data.ReplaceInt64("AutoCheckInterval",interval)) 363 data.AddInt64("AutoCheckInterval",interval); 364 } 365 366 367 bool 368 BMailSettings::CheckOnlyIfPPPUp() 369 { 370 return data.FindBool("CheckOnlyIfPPPUp"); 371 } 372 373 374 void 375 BMailSettings::SetCheckOnlyIfPPPUp(bool yes) 376 { 377 if (data.ReplaceBool("CheckOnlyIfPPPUp",yes)) 378 data.AddBool("CheckOnlyIfPPPUp",yes); 379 } 380 381 382 bool 383 BMailSettings::SendOnlyIfPPPUp() 384 { 385 return data.FindBool("SendOnlyIfPPPUp"); 386 } 387 388 389 void 390 BMailSettings::SetSendOnlyIfPPPUp(bool yes) 391 { 392 if (data.ReplaceBool("SendOnlyIfPPPUp",yes)) 393 data.AddBool("SendOnlyIfPPPUp",yes); 394 } 395 396 397 uint32 398 BMailSettings::DefaultOutboundChainID() 399 { 400 return data.FindInt32("DefaultOutboundChainID"); 401 } 402 403 404 void 405 BMailSettings::SetDefaultOutboundChainID(uint32 to) 406 { 407 if (data.ReplaceInt32("DefaultOutboundChainID",to)) 408 data.AddInt32("DefaultOutboundChainID",to); 409 } 410