LCOV - code coverage report
Current view: top level - cmail-popd - popfunctions.c (source / functions) Hit Total Coverage
Test: popd.info Lines: 31 133 23.3 %
Date: 2015-11-25 19:05:59 Functions: 3 9 33.3 %

          Line data    Source code
       1          12 : int pop_capa(LOGGER log, CONNECTION* client, DATABASE* database){
       2          12 :         CLIENT* client_data = (CLIENT*)client->aux_data;
       3          12 :         LISTENER* listener_data = (LISTENER*)client_data->listener->aux_data;
       4             : 
       5          12 :         logprintf(log, LOG_DEBUG, "Client requested capability listing\n");
       6             : 
       7          12 :         client_send(log, client, "+OK Capability listing\r\n");
       8             : 
       9             :         //allow tls-only auth
      10             :         #ifndef CMAIL_NO_TLS
      11          12 :         if(client->tls_mode == TLS_ONLY || !listener_data->tls_require){
      12             :         #endif
      13          10 :         client_send(log, client, "UIDL\r\n");
      14          10 :         client_send(log, client, "USER\r\n");
      15          10 :         client_send(log, client, "SASL LOGIN\r\n");
      16             :         #ifndef CMAIL_NO_TLS
      17             :         }
      18             :         #endif
      19             : 
      20             :         #ifndef CMAIL_NO_TLS
      21             :         //do not announce when already in tls or no tls possible
      22          12 :         if(client->tls_mode == TLS_NONE && client_data->listener->tls_mode == TLS_NEGOTIATE){
      23           2 :                 client_send(log, client, "STLS\r\n");
      24             :         }
      25             :         #endif
      26             : 
      27          12 :         client_send(log, client, "IMPLEMENTATION %s\r\n", VERSION);
      28          12 :         client_send(log, client, "XYZZY\r\n", VERSION);
      29          12 :         client_send(log, client, ".\r\n", VERSION);
      30             : 
      31          12 :         return 0;
      32             : }
      33             : 
      34           0 : int pop_stat(LOGGER log, CONNECTION* client, DATABASE* database){
      35           0 :         unsigned maildrop_bytes = 0, i;
      36           0 :         CLIENT* client_data = (CLIENT*)client->aux_data;
      37             : 
      38             :         //calculate maildrop size
      39           0 :         for(i = 0; i < client_data->maildrop.count; i++){
      40           0 :                 maildrop_bytes += client_data->maildrop.mails[i].mail_size;
      41             :         }
      42             : 
      43           0 :         client_send(log, client, "+OK %d %d\r\n", client_data->maildrop.count, maildrop_bytes);
      44           0 :         return 0;
      45             : }
      46             : 
      47           0 : int pop_list(LOGGER log, CONNECTION* client, DATABASE* database, unsigned mail){
      48             :         unsigned i;
      49           0 :         CLIENT* client_data = (CLIENT*)client->aux_data;
      50             : 
      51           0 :         if(mail == 0){
      52             :                 //list all mail, multiline
      53           0 :                 client_send(log, client, "+OK Scan listing follows\r\n");
      54           0 :                 for(i = 0; i < client_data->maildrop.count; i++){
      55           0 :                         if(!client_data->maildrop.mails[i].flag_delete){
      56           0 :                                 client_send(log, client, "%d %d\r\n", i + 1, client_data->maildrop.mails[i].mail_size);
      57             :                         }
      58             :                 }
      59           0 :                 client_send(log, client, ".\r\n");
      60             :         }
      61           0 :         else if(mail <= client_data->maildrop.count){
      62           0 :                 if(client_data->maildrop.mails[mail - 1].flag_delete){
      63           0 :                         client_send(log, client, "-ERR Mail marked for deletion\r\n");
      64           0 :                         return -1;
      65             :                 }
      66             :                 else{
      67           0 :                         client_send(log, client, "+OK %d %d\r\n", mail, client_data->maildrop.mails[mail - 1].mail_size);
      68             :                 }
      69             :         }
      70             :         else{
      71           0 :                 client_send(log, client, "-ERR No such mail\r\n");
      72           0 :                 return -1;
      73             :         }
      74             : 
      75           0 :         return 0;
      76             : }
      77             : 
      78           0 : int pop_uidl(LOGGER log, CONNECTION* client, DATABASE* database, unsigned mail){
      79             :         unsigned i;
      80           0 :         CLIENT* client_data = (CLIENT*)client->aux_data;
      81             : 
      82           0 :         if(mail == 0){
      83             :                 //list all mail, multiline
      84           0 :                 client_send(log, client, "+OK UID listing follows\r\n");
      85           0 :                 for(i = 0; i < client_data->maildrop.count; i++){
      86           0 :                         if(!client_data->maildrop.mails[i].flag_delete){
      87           0 :                                 client_send(log, client, "%d %s\r\n", i + 1, client_data->maildrop.mails[i].message_id);
      88             :                         }
      89             :                 }
      90           0 :                 client_send(log, client, ".\r\n");
      91             :         }
      92           0 :         else if(mail <= client_data->maildrop.count){
      93           0 :                 if(client_data->maildrop.mails[mail - 1].flag_delete){
      94           0 :                         client_send(log, client, "-ERR Mail marked for deletion\r\n");
      95           0 :                         return -1;
      96             :                 }
      97             :                 else{
      98           0 :                         client_send(log, client, "+OK %d %s\r\n", mail, client_data->maildrop.mails[mail - 1].message_id);
      99             :                 }
     100             :         }
     101             :         else{
     102           0 :                 client_send(log, client, "-ERR No such mail\r\n");
     103           0 :                 return -1;
     104             :         }
     105             : 
     106           0 :         return 0;
     107             : }
     108             : 
     109           0 : int pop_retr(LOGGER log, CONNECTION* client, DATABASE* database, unsigned mail){
     110           0 :         CLIENT* client_data = (CLIENT*)client->aux_data;
     111             :         sqlite3_stmt* fetch_stmt;
     112           0 :         char* mail_data = NULL;
     113           0 :         char* mail_bytestuff = NULL;
     114             : 
     115           0 :         if(mail == 0 || mail>client_data->maildrop.count){
     116           0 :                 client_send(log, client, "-ERR No such mail\r\n");
     117           0 :                 return -1;
     118             :         }
     119           0 :         else if(client_data->maildrop.mails[mail - 1].flag_delete){
     120           0 :                 client_send(log, client, "-ERR Mail marked for deletion\r\n");
     121           0 :                 return -1;
     122             :         }
     123             : 
     124           0 :         if(client_data->maildrop.mails[mail - 1].flag_master){
     125           0 :                 fetch_stmt = database->fetch_master;
     126             :         }
     127             :         else{
     128           0 :                 fetch_stmt = client_data->maildrop.fetch_user;
     129             :         }
     130             : 
     131           0 :         if(sqlite3_bind_int(fetch_stmt, 1, client_data->maildrop.mails[mail - 1].database_id) == SQLITE_OK){
     132           0 :                 switch(sqlite3_step(fetch_stmt)){
     133             :                         case SQLITE_ROW:
     134           0 :                                 client_send(log, client, "+OK Here it comes\r\n");
     135           0 :                                 mail_data = (char*)sqlite3_column_text(fetch_stmt, 0);
     136           0 :                                 if(mail_data[0] == '.'){
     137           0 :                                         client_send(log, client, ".");
     138             :                                 }
     139             :                                 do{
     140           0 :                                         mail_bytestuff = strstr(mail_data, "\r\n.");
     141           0 :                                         if(mail_bytestuff){
     142             :                                                 //logprintf(log, LOG_DEBUG, "Sending %d intermediate bytes\n", mail_bytestuff-mail_data);
     143           0 :                                                 client_send_raw(log, client, mail_data, mail_bytestuff - mail_data);
     144           0 :                                                 client_send(log, client, "\r\n..");
     145           0 :                                                 mail_data=mail_bytestuff + 3;
     146             :                                         }
     147             :                                         else{
     148             :                                                 //logprintf(log, LOG_DEBUG, "Sending %d bytes message data\n", strlen(mail_data));
     149           0 :                                                 client_send_raw(log, client, mail_data, strlen(mail_data));
     150             :                                         }
     151             :                                 }
     152           0 :                                 while(mail_bytestuff);
     153           0 :                                 break;
     154             :                         default:
     155           0 :                                 logprintf(log, LOG_WARNING, "Failed to fetch mail: %s\n", sqlite3_errmsg(database->conn));
     156           0 :                                 client_send(log, client, "-ERR Failed to fetch mail\r\n");
     157           0 :                                 break;
     158             :                 }
     159             :         }
     160             : 
     161           0 :         sqlite3_reset(fetch_stmt);
     162           0 :         sqlite3_clear_bindings(fetch_stmt);
     163             : 
     164           0 :         client_send(log, client, "\r\n.\r\n");
     165           0 :         return 0;
     166             : }
     167             : 
     168           8 : int pop_quit(LOGGER log, CONNECTION* client, DATABASE* database){
     169           8 :         CLIENT* client_data = (CLIENT*)client->aux_data;
     170             : 
     171           8 :         if(client_data->state == STATE_TRANSACTION){
     172             :                 //update the maildrop
     173           4 :                 if(maildrop_update(log, database, &(client_data->maildrop), client_data->auth.user.authorized) < 0){
     174           0 :                         client_send(log, client, "-ERR Failed to update the maildrop\r\n");
     175             :                 }
     176             :                 else{
     177           4 :                         client_send(log, client, "+OK Maildrop updated\r\n");
     178             :                 }
     179             :         }
     180             :         else{
     181           4 :                 client_send(log, client, "+OK No change\r\n");
     182             :         }
     183             : 
     184           8 :         return client_close(log, client, database);
     185             : }
     186             : 
     187           0 : int pop_dele(LOGGER log, CONNECTION* client, DATABASE* database, unsigned mail){
     188           0 :         CLIENT* client_data = (CLIENT*)client->aux_data;
     189             : 
     190           0 :         if(mail > client_data->maildrop.count || mail < 1){
     191           0 :                 client_send(log, client, "-ERR No such mail\r\n");
     192           0 :                 return -1;
     193             :         }
     194             : 
     195           0 :         if(client_data->maildrop.mails[mail - 1].flag_delete){
     196           0 :                 client_send(log, client, "-ERR Message already deleted\r\n");
     197           0 :                 return -1;
     198             :         }
     199             : 
     200             :         //add a mark in the deletion table
     201           0 :         if(maildrop_mark(log, database, client_data->auth.user.authorized, &(client_data->maildrop), mail - 1) < 0){
     202           0 :                 logprintf(log, LOG_ERROR, "Failed to mark message as deleted: %s");
     203             :         }
     204             : 
     205           0 :         client_data->maildrop.mails[mail - 1].flag_delete = true;
     206           0 :         client_send(log, client, "+OK Marked for deletion\r\n");
     207             : 
     208           0 :         return 0;
     209             : }
     210             : 
     211           0 : int pop_rset(LOGGER log, CONNECTION* client, DATABASE* database){
     212           0 :         unsigned i = 0;
     213           0 :         CLIENT* client_data = (CLIENT*)client->aux_data;
     214             : 
     215             :         //reset all deletion marks in the master database deletion table
     216           0 :         if(maildrop_unmark(log, database->conn, database->unmark_deletions, client_data->auth.user.authorized) < 0){
     217           0 :                 logprintf(log, LOG_ERROR, "Failed to reset the master database deletion marks\n");
     218           0 :                 client_send(log, client, "-ERR Internal error resetting\r\n");
     219           0 :                 return 0;
     220             :         }
     221             : 
     222           0 :         if(client_data->maildrop.user_conn && maildrop_unmark(log, client_data->maildrop.user_conn, client_data->maildrop.unmark_deletions, client_data->auth.user.authorized) < 0){
     223           0 :                 logprintf(log, LOG_ERROR, "Failed to reset the user database deletion marks\n");
     224           0 :                 client_send(log, client, "-ERR Internal error resetting\r\n");
     225           0 :                 return 0;
     226             :         }
     227             : 
     228           0 :         for(i = 0; i < client_data->maildrop.count; i++){
     229           0 :                 client_data->maildrop.mails[i].flag_delete = false;
     230             :         }
     231             : 
     232           0 :         client_send(log, client, "+OK Deletion flags cleared\r\n");
     233           0 :         return 0;
     234             : }
     235             : 
     236           4 : int pop_xyzzy(LOGGER log, CONNECTION* client, DATABASE* database){
     237           4 :         CLIENT* client_data = (CLIENT*)client->aux_data;
     238             : 
     239           4 :         logprintf(log, LOG_INFO, "Client performs incantation\n");
     240             :         #ifndef CMAIL_NO_TLS
     241           4 :         logprintf(log, LOG_DEBUG, "Client TLS status: %s\n", tls_modestring(client->tls_mode));
     242             :         #endif
     243           4 :         logprintf(log, LOG_DEBUG, "Auth state: %s, Method: %s\n", client_data->auth.auth_ok ? "true":"false", client_data->auth.method==AUTH_USER ? "USER":"SASL");
     244           4 :         logprintf(log, LOG_DEBUG, "Authentication: %s, Authorization: %s\n", client_data->auth.user.authenticated ? client_data->auth.user.authenticated:"null", client_data->auth.user.authorized ? client_data->auth.user.authorized:"null");
     245           4 :         logprintf(log, LOG_DEBUG, "Connection score: %d\n", client_data->connection_score);
     246           4 :         client_send(log, client, "+OK Nothing happens\r\n");
     247           4 :         return 0;
     248             : }

Generated by: LCOV version 1.11