1 /* 2 * Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved. 3 * Copyright 2004-2009, 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 <Directory.h> 14 #include <Entry.h> 15 #include <File.h> 16 #include <FindDirectory.h> 17 #include <Message.h> 18 #include <Messenger.h> 19 #include <Path.h> 20 #include <String.h> 21 #include <Window.h> 22 23 #include <stdio.h> 24 #include <string.h> 25 #include <stdlib.h> 26 27 28 class BMailSettings; 29 30 namespace MailInternal { 31 status_t WriteMessageFile(const BMessage& archive, const BPath& path, 32 const char* name); 33 } 34 35 36 // #pragma mark - Chain methods 37 38 39 // TODO! 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 uint32 workspaces; 316 if (data.FindInt32("StatusWindowWorkSpace", (int32*)&workspaces) != B_OK) 317 return B_ALL_WORKSPACES; 318 319 return workspaces; 320 } 321 322 323 void 324 BMailSettings::SetStatusWindowWorkspaces(int32 workspace) 325 { 326 if (data.ReplaceInt32("StatusWindowWorkSpace",workspace)) 327 data.AddInt32("StatusWindowWorkSpace",workspace); 328 329 BMessage msg('wsch'); 330 msg.AddInt32("StatusWindowWorkSpace",workspace); 331 BMessenger("application/x-vnd.Be-POST").SendMessage(&msg); 332 } 333 334 335 int32 336 BMailSettings::StatusWindowLook() 337 { 338 return data.FindInt32("StatusWindowLook"); 339 } 340 341 342 void 343 BMailSettings::SetStatusWindowLook(int32 look) 344 { 345 if (data.ReplaceInt32("StatusWindowLook",look)) 346 data.AddInt32("StatusWindowLook",look); 347 348 BMessage msg('lkch'); 349 msg.AddInt32("StatusWindowLook",look); 350 BMessenger("application/x-vnd.Be-POST").SendMessage(&msg); 351 } 352 353 354 bigtime_t 355 BMailSettings::AutoCheckInterval() 356 { 357 bigtime_t value = B_INFINITE_TIMEOUT; 358 data.FindInt64("AutoCheckInterval",&value); 359 return value; 360 } 361 362 363 void 364 BMailSettings::SetAutoCheckInterval(bigtime_t interval) 365 { 366 if (data.ReplaceInt64("AutoCheckInterval",interval)) 367 data.AddInt64("AutoCheckInterval",interval); 368 } 369 370 371 bool 372 BMailSettings::CheckOnlyIfPPPUp() 373 { 374 return data.FindBool("CheckOnlyIfPPPUp"); 375 } 376 377 378 void 379 BMailSettings::SetCheckOnlyIfPPPUp(bool yes) 380 { 381 if (data.ReplaceBool("CheckOnlyIfPPPUp",yes)) 382 data.AddBool("CheckOnlyIfPPPUp",yes); 383 } 384 385 386 bool 387 BMailSettings::SendOnlyIfPPPUp() 388 { 389 return data.FindBool("SendOnlyIfPPPUp"); 390 } 391 392 393 void 394 BMailSettings::SetSendOnlyIfPPPUp(bool yes) 395 { 396 if (data.ReplaceBool("SendOnlyIfPPPUp",yes)) 397 data.AddBool("SendOnlyIfPPPUp",yes); 398 } 399 400 401 uint32 402 BMailSettings::DefaultOutboundChainID() 403 { 404 return data.FindInt32("DefaultOutboundChainID"); 405 } 406 407 408 void 409 BMailSettings::SetDefaultOutboundChainID(uint32 to) 410 { 411 if (data.ReplaceInt32("DefaultOutboundChainID",to)) 412 data.AddInt32("DefaultOutboundChainID",to); 413 } 414