Fossil SCM
New "Normal" mode for viewing email messages in webmail.
Commit
3ddc8817137f74459df37513567c82aeeddf19dddafa8c1e19dc043d3997def9
Parent
485d01fb17d22f6…
2 files changed
+1
-1
+59
-9
+1
-1
| --- src/smtp.c | ||
| +++ src/smtp.c | ||
| @@ -652,11 +652,11 @@ | ||
| 652 | 652 | @ euser TEXT, -- User who received this email |
| 653 | 653 | @ edate INT, -- Date received. Seconds since 1970 |
| 654 | 654 | @ efrom TEXT, -- Who is the email from |
| 655 | 655 | @ emsgid INT, -- Raw email text |
| 656 | 656 | @ ets INT, -- Transcript of the receiving SMTP session |
| 657 | -@ estate INT, -- 0: Unread, 1: read, 2: trash | |
| 657 | +@ estate INT, -- 0: Unread, 1: read, 2: trash 3: sent | |
| 658 | 658 | @ esubject TEXT, -- Subject line for display |
| 659 | 659 | @ etags TEXT -- zero or more tags |
| 660 | 660 | @ ); |
| 661 | 661 | @ |
| 662 | 662 | @ -- Information on how to deliver incoming email. |
| 663 | 663 |
| --- src/smtp.c | |
| +++ src/smtp.c | |
| @@ -652,11 +652,11 @@ | |
| 652 | @ euser TEXT, -- User who received this email |
| 653 | @ edate INT, -- Date received. Seconds since 1970 |
| 654 | @ efrom TEXT, -- Who is the email from |
| 655 | @ emsgid INT, -- Raw email text |
| 656 | @ ets INT, -- Transcript of the receiving SMTP session |
| 657 | @ estate INT, -- 0: Unread, 1: read, 2: trash |
| 658 | @ esubject TEXT, -- Subject line for display |
| 659 | @ etags TEXT -- zero or more tags |
| 660 | @ ); |
| 661 | @ |
| 662 | @ -- Information on how to deliver incoming email. |
| 663 |
| --- src/smtp.c | |
| +++ src/smtp.c | |
| @@ -652,11 +652,11 @@ | |
| 652 | @ euser TEXT, -- User who received this email |
| 653 | @ edate INT, -- Date received. Seconds since 1970 |
| 654 | @ efrom TEXT, -- Who is the email from |
| 655 | @ emsgid INT, -- Raw email text |
| 656 | @ ets INT, -- Transcript of the receiving SMTP session |
| 657 | @ estate INT, -- 0: Unread, 1: read, 2: trash 3: sent |
| 658 | @ esubject TEXT, -- Subject line for display |
| 659 | @ etags TEXT -- zero or more tags |
| 660 | @ ); |
| 661 | @ |
| 662 | @ -- Information on how to deliver incoming email. |
| 663 |
+59
-9
| --- src/webmail.c | ||
| +++ src/webmail.c | ||
| @@ -352,10 +352,38 @@ | ||
| 352 | 352 | } |
| 353 | 353 | } |
| 354 | 354 | emailtoc_free(p); |
| 355 | 355 | blob_reset(&email); |
| 356 | 356 | } |
| 357 | + | |
| 358 | +/* | |
| 359 | +** Add the select/option box to the timeline submenu that shows | |
| 360 | +** the various email message formats. | |
| 361 | +*/ | |
| 362 | +static void webmail_f_submenu(void){ | |
| 363 | + static const char *az[] = { | |
| 364 | + "0", "Normal", | |
| 365 | + "1", "Decoded", | |
| 366 | + "2", "Raw", | |
| 367 | + }; | |
| 368 | + style_submenu_multichoice("f", sizeof(az)/(2*sizeof(az[0])), az, 0); | |
| 369 | +} | |
| 370 | + | |
| 371 | +/* | |
| 372 | +** If the first N characters of z[] are the name of a header field | |
| 373 | +** that should be shown in "Normal" mode, then return 1. | |
| 374 | +*/ | |
| 375 | +static int webmail_normal_header(const char *z, int N){ | |
| 376 | + static const char *az[] = { | |
| 377 | + "To", "Cc", "Bcc", "Date", "From", "Subject", | |
| 378 | + }; | |
| 379 | + int i; | |
| 380 | + for(i=0; i<sizeof(az)/sizeof(az[0]); i++){ | |
| 381 | + if( sqlite3_strnicmp(z, az[i], N)==0 ) return 1; | |
| 382 | + } | |
| 383 | + return 0; | |
| 384 | +} | |
| 357 | 385 | |
| 358 | 386 | /* |
| 359 | 387 | ** Paint a page showing a single email message |
| 360 | 388 | */ |
| 361 | 389 | static void webmail_show_one_message( |
| @@ -366,10 +394,11 @@ | ||
| 366 | 394 | Blob sql; |
| 367 | 395 | Stmt q; |
| 368 | 396 | int eState = -1; |
| 369 | 397 | char zENum[30]; |
| 370 | 398 | style_submenu_element("Index", "%s", url_render(pUrl,"id",0,0,0)); |
| 399 | + webmail_f_submenu(); | |
| 371 | 400 | blob_init(&sql, 0, 0); |
| 372 | 401 | db_begin_transaction(); |
| 373 | 402 | blob_append_sql(&sql, |
| 374 | 403 | "SELECT decompress(etxt), estate" |
| 375 | 404 | " FROM emailblob, emailbox" |
| @@ -382,23 +411,21 @@ | ||
| 382 | 411 | style_header("Message %d",emailid); |
| 383 | 412 | if( db_step(&q)==SQLITE_ROW ){ |
| 384 | 413 | Blob msg = db_column_text_as_blob(&q, 0); |
| 385 | 414 | int eFormat = atoi(PD("f","0")); |
| 386 | 415 | eState = db_column_int(&q, 1); |
| 387 | - url_add_parameter(pUrl, "id", P("id")); | |
| 388 | - if( eFormat==1 ){ | |
| 416 | + if( eFormat==2 ){ | |
| 389 | 417 | @ <pre>%h(db_column_text(&q, 0))</pre> |
| 390 | - style_submenu_element("Decoded", "%s", url_render(pUrl,"f",0,0,0)); | |
| 391 | 418 | }else{ |
| 392 | 419 | EmailToc *p = emailtoc_from_email(&msg); |
| 393 | 420 | int i, j; |
| 394 | - style_submenu_element("Raw", "%s", url_render(pUrl,"f","1",0,0)); | |
| 395 | 421 | @ <p> |
| 396 | 422 | for(i=0; i<p->nHdr; i++){ |
| 397 | 423 | char *z = p->azHdr[i]; |
| 398 | 424 | email_hdr_unfold(z); |
| 399 | 425 | for(j=0; z[j] && z[j]!=':'; j++){} |
| 426 | + if( eFormat==0 && !webmail_normal_header(z, j) ) continue; | |
| 400 | 427 | if( z[j]!=':' ){ |
| 401 | 428 | @ %h(z)<br> |
| 402 | 429 | }else{ |
| 403 | 430 | z[j] = 0; |
| 404 | 431 | @ <b>%h(z):</b> %h(z+j+1)<br> |
| @@ -408,11 +435,16 @@ | ||
| 408 | 435 | @ <hr><b>Messsage Body #%d(i): %h(p->aBody[i].zMimetype) \ |
| 409 | 436 | if( p->aBody[i].zFilename ){ |
| 410 | 437 | @ "%h(p->aBody[i].zFilename)" |
| 411 | 438 | } |
| 412 | 439 | @ </b> |
| 413 | - if( strncmp(p->aBody[i].zMimetype, "text/", 5)!=0 ) continue; | |
| 440 | + if( eFormat==0 ){ | |
| 441 | + if( strncmp(p->aBody[i].zMimetype, "text/plain", 10)!=0 ) continue; | |
| 442 | + if( p->aBody[i].zFilename ) continue; | |
| 443 | + }else{ | |
| 444 | + if( strncmp(p->aBody[i].zMimetype, "text/", 5)!=0 ) continue; | |
| 445 | + } | |
| 414 | 446 | switch( p->aBody[i].encoding ){ |
| 415 | 447 | case EMAILENC_B64: { |
| 416 | 448 | int n = 0; |
| 417 | 449 | decodeBase64(p->aBody[i].zContent, &n, p->aBody[i].zContent); |
| 418 | 450 | break; |
| @@ -452,10 +484,14 @@ | ||
| 452 | 484 | style_submenu_element("Delete", "%s", |
| 453 | 485 | url_render(pUrl,"trash","1",zENum,"1")); |
| 454 | 486 | style_submenu_element("Mark As Unread", "%s", |
| 455 | 487 | url_render(pUrl,"unread","1",zENum,"1")); |
| 456 | 488 | } |
| 489 | + if( eState==3 ){ | |
| 490 | + style_submenu_element("Delete", "%s", | |
| 491 | + url_render(pUrl,"trash","1",zENum,"1")); | |
| 492 | + } | |
| 457 | 493 | |
| 458 | 494 | db_end_transaction(0); |
| 459 | 495 | style_footer(); |
| 460 | 496 | return; |
| 461 | 497 | } |
| @@ -463,21 +499,27 @@ | ||
| 463 | 499 | /* |
| 464 | 500 | ** Scan the query parameters looking for parameters with name of the |
| 465 | 501 | ** form "eN" where N is an integer. For all such integers, change |
| 466 | 502 | ** the state of every emailbox entry with ebid==N to eStateNew provided |
| 467 | 503 | ** that either zUser is NULL or matches. |
| 504 | +** | |
| 505 | +** Or if eNewState==99, then delete the entries. | |
| 468 | 506 | */ |
| 469 | 507 | static void webmail_change_state(int eNewState, const char *zUser){ |
| 470 | 508 | Blob sql; |
| 471 | 509 | int sep = '('; |
| 472 | 510 | int i; |
| 473 | 511 | const char *zName; |
| 474 | 512 | int n; |
| 475 | 513 | if( !cgi_csrf_safe(0) ) return; |
| 476 | 514 | blob_init(&sql, 0, 0); |
| 477 | - blob_append_sql(&sql, "UPDATE emailbox SET estate=%d WHERE ebid IN ", | |
| 478 | - eNewState); | |
| 515 | + if( eNewState==99 ){ | |
| 516 | + blob_append_sql(&sql, "DELETE FROM emailbox WHERE estate==2 AND ebid IN "); | |
| 517 | + }else{ | |
| 518 | + blob_append_sql(&sql, "UPDATE emailbox SET estate=%d WHERE ebid IN ", | |
| 519 | + eNewState); | |
| 520 | + } | |
| 479 | 521 | for(i=0; (zName = cgi_parameter_name(i))!=0; i++){ |
| 480 | 522 | if( zName[0]!='e' ) continue; |
| 481 | 523 | if( !fossil_isdigit(zName[1]) ) continue; |
| 482 | 524 | n = atoi(zName+1); |
| 483 | 525 | blob_append_sql(&sql, "%c%d", sep, n); |
| @@ -502,11 +544,12 @@ | ||
| 502 | 544 | static void webmail_d_submenu(void){ |
| 503 | 545 | static const char *az[] = { |
| 504 | 546 | "0", "InBox", |
| 505 | 547 | "1", "Unread", |
| 506 | 548 | "2", "Trash", |
| 507 | - "3", "Everything", | |
| 549 | + "3", "Sent", | |
| 550 | + "4", "Everything", | |
| 508 | 551 | }; |
| 509 | 552 | style_submenu_multichoice("d", sizeof(az)/(2*sizeof(az[0])), az, 0); |
| 510 | 553 | } |
| 511 | 554 | |
| 512 | 555 | /* |
| @@ -576,10 +619,11 @@ | ||
| 576 | 619 | webmail_d_submenu(); |
| 577 | 620 | db_begin_transaction(); |
| 578 | 621 | if( P("trash")!=0 ) webmail_change_state(2,zUser); |
| 579 | 622 | if( P("unread")!=0 ) webmail_change_state(0,zUser); |
| 580 | 623 | if( P("read")!=0 ) webmail_change_state(1,zUser); |
| 624 | + if( P("purge")!=0 ) webmail_change_state(99,zUser); | |
| 581 | 625 | blob_init(&sql, 0, 0); |
| 582 | 626 | blob_append_sql(&sql, |
| 583 | 627 | "CREATE TEMP TABLE tmbox AS " |
| 584 | 628 | "SELECT ebid," /* 0 */ |
| 585 | 629 | " efrom," /* 1 */ |
| @@ -601,11 +645,15 @@ | ||
| 601 | 645 | } |
| 602 | 646 | case 2: { /* Trashcan only */ |
| 603 | 647 | blob_append_sql(&sql, " WHERE estate=2"); |
| 604 | 648 | break; |
| 605 | 649 | } |
| 606 | - case 3: { /* Everything */ | |
| 650 | + case 3: { /* Outgoing email only */ | |
| 651 | + blob_append_sql(&sql, " WHERE estate=3"); | |
| 652 | + break; | |
| 653 | + } | |
| 654 | + case 4: { /* Everything */ | |
| 607 | 655 | blob_append_sql(&sql, " WHERE 1"); |
| 608 | 656 | break; |
| 609 | 657 | } |
| 610 | 658 | } |
| 611 | 659 | if( showAll ){ |
| @@ -635,17 +683,19 @@ | ||
| 635 | 683 | @ <form action="%R/webmail" method="POST"> |
| 636 | 684 | @ <table border="0" width="100%%"> |
| 637 | 685 | @ <tr><td align="left"> |
| 638 | 686 | if( d==2 ){ |
| 639 | 687 | @ <input type="submit" name="read" value="Undelete"> |
| 688 | + @ <input type="submit" name="purge" value="Delete Permanently"> | |
| 640 | 689 | }else{ |
| 641 | 690 | @ <input type="submit" name="trash", value="Delete"> |
| 642 | 691 | if( d!=1 ){ |
| 643 | 692 | @ <input type="submit" name="unread" value="Mark as unread"> |
| 644 | 693 | } |
| 645 | 694 | @ <input type="submit" name="read" value="Mark as read"> |
| 646 | 695 | } |
| 696 | + @ <a href="%s(url_render(&url,0,0,0,0))">refresh</a> | |
| 647 | 697 | @ </td><td align="right"> |
| 648 | 698 | if( pg>0 ){ |
| 649 | 699 | sqlite3_snprintf(sizeof(zPPg), zPPg, "%d", pg-1); |
| 650 | 700 | @ <a href="%s(url_render(&url,"pg",zPPg,0,0))">< Newer</a> |
| 651 | 701 | } |
| 652 | 702 |
| --- src/webmail.c | |
| +++ src/webmail.c | |
| @@ -352,10 +352,38 @@ | |
| 352 | } |
| 353 | } |
| 354 | emailtoc_free(p); |
| 355 | blob_reset(&email); |
| 356 | } |
| 357 | |
| 358 | /* |
| 359 | ** Paint a page showing a single email message |
| 360 | */ |
| 361 | static void webmail_show_one_message( |
| @@ -366,10 +394,11 @@ | |
| 366 | Blob sql; |
| 367 | Stmt q; |
| 368 | int eState = -1; |
| 369 | char zENum[30]; |
| 370 | style_submenu_element("Index", "%s", url_render(pUrl,"id",0,0,0)); |
| 371 | blob_init(&sql, 0, 0); |
| 372 | db_begin_transaction(); |
| 373 | blob_append_sql(&sql, |
| 374 | "SELECT decompress(etxt), estate" |
| 375 | " FROM emailblob, emailbox" |
| @@ -382,23 +411,21 @@ | |
| 382 | style_header("Message %d",emailid); |
| 383 | if( db_step(&q)==SQLITE_ROW ){ |
| 384 | Blob msg = db_column_text_as_blob(&q, 0); |
| 385 | int eFormat = atoi(PD("f","0")); |
| 386 | eState = db_column_int(&q, 1); |
| 387 | url_add_parameter(pUrl, "id", P("id")); |
| 388 | if( eFormat==1 ){ |
| 389 | @ <pre>%h(db_column_text(&q, 0))</pre> |
| 390 | style_submenu_element("Decoded", "%s", url_render(pUrl,"f",0,0,0)); |
| 391 | }else{ |
| 392 | EmailToc *p = emailtoc_from_email(&msg); |
| 393 | int i, j; |
| 394 | style_submenu_element("Raw", "%s", url_render(pUrl,"f","1",0,0)); |
| 395 | @ <p> |
| 396 | for(i=0; i<p->nHdr; i++){ |
| 397 | char *z = p->azHdr[i]; |
| 398 | email_hdr_unfold(z); |
| 399 | for(j=0; z[j] && z[j]!=':'; j++){} |
| 400 | if( z[j]!=':' ){ |
| 401 | @ %h(z)<br> |
| 402 | }else{ |
| 403 | z[j] = 0; |
| 404 | @ <b>%h(z):</b> %h(z+j+1)<br> |
| @@ -408,11 +435,16 @@ | |
| 408 | @ <hr><b>Messsage Body #%d(i): %h(p->aBody[i].zMimetype) \ |
| 409 | if( p->aBody[i].zFilename ){ |
| 410 | @ "%h(p->aBody[i].zFilename)" |
| 411 | } |
| 412 | @ </b> |
| 413 | if( strncmp(p->aBody[i].zMimetype, "text/", 5)!=0 ) continue; |
| 414 | switch( p->aBody[i].encoding ){ |
| 415 | case EMAILENC_B64: { |
| 416 | int n = 0; |
| 417 | decodeBase64(p->aBody[i].zContent, &n, p->aBody[i].zContent); |
| 418 | break; |
| @@ -452,10 +484,14 @@ | |
| 452 | style_submenu_element("Delete", "%s", |
| 453 | url_render(pUrl,"trash","1",zENum,"1")); |
| 454 | style_submenu_element("Mark As Unread", "%s", |
| 455 | url_render(pUrl,"unread","1",zENum,"1")); |
| 456 | } |
| 457 | |
| 458 | db_end_transaction(0); |
| 459 | style_footer(); |
| 460 | return; |
| 461 | } |
| @@ -463,21 +499,27 @@ | |
| 463 | /* |
| 464 | ** Scan the query parameters looking for parameters with name of the |
| 465 | ** form "eN" where N is an integer. For all such integers, change |
| 466 | ** the state of every emailbox entry with ebid==N to eStateNew provided |
| 467 | ** that either zUser is NULL or matches. |
| 468 | */ |
| 469 | static void webmail_change_state(int eNewState, const char *zUser){ |
| 470 | Blob sql; |
| 471 | int sep = '('; |
| 472 | int i; |
| 473 | const char *zName; |
| 474 | int n; |
| 475 | if( !cgi_csrf_safe(0) ) return; |
| 476 | blob_init(&sql, 0, 0); |
| 477 | blob_append_sql(&sql, "UPDATE emailbox SET estate=%d WHERE ebid IN ", |
| 478 | eNewState); |
| 479 | for(i=0; (zName = cgi_parameter_name(i))!=0; i++){ |
| 480 | if( zName[0]!='e' ) continue; |
| 481 | if( !fossil_isdigit(zName[1]) ) continue; |
| 482 | n = atoi(zName+1); |
| 483 | blob_append_sql(&sql, "%c%d", sep, n); |
| @@ -502,11 +544,12 @@ | |
| 502 | static void webmail_d_submenu(void){ |
| 503 | static const char *az[] = { |
| 504 | "0", "InBox", |
| 505 | "1", "Unread", |
| 506 | "2", "Trash", |
| 507 | "3", "Everything", |
| 508 | }; |
| 509 | style_submenu_multichoice("d", sizeof(az)/(2*sizeof(az[0])), az, 0); |
| 510 | } |
| 511 | |
| 512 | /* |
| @@ -576,10 +619,11 @@ | |
| 576 | webmail_d_submenu(); |
| 577 | db_begin_transaction(); |
| 578 | if( P("trash")!=0 ) webmail_change_state(2,zUser); |
| 579 | if( P("unread")!=0 ) webmail_change_state(0,zUser); |
| 580 | if( P("read")!=0 ) webmail_change_state(1,zUser); |
| 581 | blob_init(&sql, 0, 0); |
| 582 | blob_append_sql(&sql, |
| 583 | "CREATE TEMP TABLE tmbox AS " |
| 584 | "SELECT ebid," /* 0 */ |
| 585 | " efrom," /* 1 */ |
| @@ -601,11 +645,15 @@ | |
| 601 | } |
| 602 | case 2: { /* Trashcan only */ |
| 603 | blob_append_sql(&sql, " WHERE estate=2"); |
| 604 | break; |
| 605 | } |
| 606 | case 3: { /* Everything */ |
| 607 | blob_append_sql(&sql, " WHERE 1"); |
| 608 | break; |
| 609 | } |
| 610 | } |
| 611 | if( showAll ){ |
| @@ -635,17 +683,19 @@ | |
| 635 | @ <form action="%R/webmail" method="POST"> |
| 636 | @ <table border="0" width="100%%"> |
| 637 | @ <tr><td align="left"> |
| 638 | if( d==2 ){ |
| 639 | @ <input type="submit" name="read" value="Undelete"> |
| 640 | }else{ |
| 641 | @ <input type="submit" name="trash", value="Delete"> |
| 642 | if( d!=1 ){ |
| 643 | @ <input type="submit" name="unread" value="Mark as unread"> |
| 644 | } |
| 645 | @ <input type="submit" name="read" value="Mark as read"> |
| 646 | } |
| 647 | @ </td><td align="right"> |
| 648 | if( pg>0 ){ |
| 649 | sqlite3_snprintf(sizeof(zPPg), zPPg, "%d", pg-1); |
| 650 | @ <a href="%s(url_render(&url,"pg",zPPg,0,0))">< Newer</a> |
| 651 | } |
| 652 |
| --- src/webmail.c | |
| +++ src/webmail.c | |
| @@ -352,10 +352,38 @@ | |
| 352 | } |
| 353 | } |
| 354 | emailtoc_free(p); |
| 355 | blob_reset(&email); |
| 356 | } |
| 357 | |
| 358 | /* |
| 359 | ** Add the select/option box to the timeline submenu that shows |
| 360 | ** the various email message formats. |
| 361 | */ |
| 362 | static void webmail_f_submenu(void){ |
| 363 | static const char *az[] = { |
| 364 | "0", "Normal", |
| 365 | "1", "Decoded", |
| 366 | "2", "Raw", |
| 367 | }; |
| 368 | style_submenu_multichoice("f", sizeof(az)/(2*sizeof(az[0])), az, 0); |
| 369 | } |
| 370 | |
| 371 | /* |
| 372 | ** If the first N characters of z[] are the name of a header field |
| 373 | ** that should be shown in "Normal" mode, then return 1. |
| 374 | */ |
| 375 | static int webmail_normal_header(const char *z, int N){ |
| 376 | static const char *az[] = { |
| 377 | "To", "Cc", "Bcc", "Date", "From", "Subject", |
| 378 | }; |
| 379 | int i; |
| 380 | for(i=0; i<sizeof(az)/sizeof(az[0]); i++){ |
| 381 | if( sqlite3_strnicmp(z, az[i], N)==0 ) return 1; |
| 382 | } |
| 383 | return 0; |
| 384 | } |
| 385 | |
| 386 | /* |
| 387 | ** Paint a page showing a single email message |
| 388 | */ |
| 389 | static void webmail_show_one_message( |
| @@ -366,10 +394,11 @@ | |
| 394 | Blob sql; |
| 395 | Stmt q; |
| 396 | int eState = -1; |
| 397 | char zENum[30]; |
| 398 | style_submenu_element("Index", "%s", url_render(pUrl,"id",0,0,0)); |
| 399 | webmail_f_submenu(); |
| 400 | blob_init(&sql, 0, 0); |
| 401 | db_begin_transaction(); |
| 402 | blob_append_sql(&sql, |
| 403 | "SELECT decompress(etxt), estate" |
| 404 | " FROM emailblob, emailbox" |
| @@ -382,23 +411,21 @@ | |
| 411 | style_header("Message %d",emailid); |
| 412 | if( db_step(&q)==SQLITE_ROW ){ |
| 413 | Blob msg = db_column_text_as_blob(&q, 0); |
| 414 | int eFormat = atoi(PD("f","0")); |
| 415 | eState = db_column_int(&q, 1); |
| 416 | if( eFormat==2 ){ |
| 417 | @ <pre>%h(db_column_text(&q, 0))</pre> |
| 418 | }else{ |
| 419 | EmailToc *p = emailtoc_from_email(&msg); |
| 420 | int i, j; |
| 421 | @ <p> |
| 422 | for(i=0; i<p->nHdr; i++){ |
| 423 | char *z = p->azHdr[i]; |
| 424 | email_hdr_unfold(z); |
| 425 | for(j=0; z[j] && z[j]!=':'; j++){} |
| 426 | if( eFormat==0 && !webmail_normal_header(z, j) ) continue; |
| 427 | if( z[j]!=':' ){ |
| 428 | @ %h(z)<br> |
| 429 | }else{ |
| 430 | z[j] = 0; |
| 431 | @ <b>%h(z):</b> %h(z+j+1)<br> |
| @@ -408,11 +435,16 @@ | |
| 435 | @ <hr><b>Messsage Body #%d(i): %h(p->aBody[i].zMimetype) \ |
| 436 | if( p->aBody[i].zFilename ){ |
| 437 | @ "%h(p->aBody[i].zFilename)" |
| 438 | } |
| 439 | @ </b> |
| 440 | if( eFormat==0 ){ |
| 441 | if( strncmp(p->aBody[i].zMimetype, "text/plain", 10)!=0 ) continue; |
| 442 | if( p->aBody[i].zFilename ) continue; |
| 443 | }else{ |
| 444 | if( strncmp(p->aBody[i].zMimetype, "text/", 5)!=0 ) continue; |
| 445 | } |
| 446 | switch( p->aBody[i].encoding ){ |
| 447 | case EMAILENC_B64: { |
| 448 | int n = 0; |
| 449 | decodeBase64(p->aBody[i].zContent, &n, p->aBody[i].zContent); |
| 450 | break; |
| @@ -452,10 +484,14 @@ | |
| 484 | style_submenu_element("Delete", "%s", |
| 485 | url_render(pUrl,"trash","1",zENum,"1")); |
| 486 | style_submenu_element("Mark As Unread", "%s", |
| 487 | url_render(pUrl,"unread","1",zENum,"1")); |
| 488 | } |
| 489 | if( eState==3 ){ |
| 490 | style_submenu_element("Delete", "%s", |
| 491 | url_render(pUrl,"trash","1",zENum,"1")); |
| 492 | } |
| 493 | |
| 494 | db_end_transaction(0); |
| 495 | style_footer(); |
| 496 | return; |
| 497 | } |
| @@ -463,21 +499,27 @@ | |
| 499 | /* |
| 500 | ** Scan the query parameters looking for parameters with name of the |
| 501 | ** form "eN" where N is an integer. For all such integers, change |
| 502 | ** the state of every emailbox entry with ebid==N to eStateNew provided |
| 503 | ** that either zUser is NULL or matches. |
| 504 | ** |
| 505 | ** Or if eNewState==99, then delete the entries. |
| 506 | */ |
| 507 | static void webmail_change_state(int eNewState, const char *zUser){ |
| 508 | Blob sql; |
| 509 | int sep = '('; |
| 510 | int i; |
| 511 | const char *zName; |
| 512 | int n; |
| 513 | if( !cgi_csrf_safe(0) ) return; |
| 514 | blob_init(&sql, 0, 0); |
| 515 | if( eNewState==99 ){ |
| 516 | blob_append_sql(&sql, "DELETE FROM emailbox WHERE estate==2 AND ebid IN "); |
| 517 | }else{ |
| 518 | blob_append_sql(&sql, "UPDATE emailbox SET estate=%d WHERE ebid IN ", |
| 519 | eNewState); |
| 520 | } |
| 521 | for(i=0; (zName = cgi_parameter_name(i))!=0; i++){ |
| 522 | if( zName[0]!='e' ) continue; |
| 523 | if( !fossil_isdigit(zName[1]) ) continue; |
| 524 | n = atoi(zName+1); |
| 525 | blob_append_sql(&sql, "%c%d", sep, n); |
| @@ -502,11 +544,12 @@ | |
| 544 | static void webmail_d_submenu(void){ |
| 545 | static const char *az[] = { |
| 546 | "0", "InBox", |
| 547 | "1", "Unread", |
| 548 | "2", "Trash", |
| 549 | "3", "Sent", |
| 550 | "4", "Everything", |
| 551 | }; |
| 552 | style_submenu_multichoice("d", sizeof(az)/(2*sizeof(az[0])), az, 0); |
| 553 | } |
| 554 | |
| 555 | /* |
| @@ -576,10 +619,11 @@ | |
| 619 | webmail_d_submenu(); |
| 620 | db_begin_transaction(); |
| 621 | if( P("trash")!=0 ) webmail_change_state(2,zUser); |
| 622 | if( P("unread")!=0 ) webmail_change_state(0,zUser); |
| 623 | if( P("read")!=0 ) webmail_change_state(1,zUser); |
| 624 | if( P("purge")!=0 ) webmail_change_state(99,zUser); |
| 625 | blob_init(&sql, 0, 0); |
| 626 | blob_append_sql(&sql, |
| 627 | "CREATE TEMP TABLE tmbox AS " |
| 628 | "SELECT ebid," /* 0 */ |
| 629 | " efrom," /* 1 */ |
| @@ -601,11 +645,15 @@ | |
| 645 | } |
| 646 | case 2: { /* Trashcan only */ |
| 647 | blob_append_sql(&sql, " WHERE estate=2"); |
| 648 | break; |
| 649 | } |
| 650 | case 3: { /* Outgoing email only */ |
| 651 | blob_append_sql(&sql, " WHERE estate=3"); |
| 652 | break; |
| 653 | } |
| 654 | case 4: { /* Everything */ |
| 655 | blob_append_sql(&sql, " WHERE 1"); |
| 656 | break; |
| 657 | } |
| 658 | } |
| 659 | if( showAll ){ |
| @@ -635,17 +683,19 @@ | |
| 683 | @ <form action="%R/webmail" method="POST"> |
| 684 | @ <table border="0" width="100%%"> |
| 685 | @ <tr><td align="left"> |
| 686 | if( d==2 ){ |
| 687 | @ <input type="submit" name="read" value="Undelete"> |
| 688 | @ <input type="submit" name="purge" value="Delete Permanently"> |
| 689 | }else{ |
| 690 | @ <input type="submit" name="trash", value="Delete"> |
| 691 | if( d!=1 ){ |
| 692 | @ <input type="submit" name="unread" value="Mark as unread"> |
| 693 | } |
| 694 | @ <input type="submit" name="read" value="Mark as read"> |
| 695 | } |
| 696 | @ <a href="%s(url_render(&url,0,0,0,0))">refresh</a> |
| 697 | @ </td><td align="right"> |
| 698 | if( pg>0 ){ |
| 699 | sqlite3_snprintf(sizeof(zPPg), zPPg, "%d", pg-1); |
| 700 | @ <a href="%s(url_render(&url,"pg",zPPg,0,0))">< Newer</a> |
| 701 | } |
| 702 |