1 /*
2  * Copyright (c) 1989 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 
8 /*
9  * Copyright (c) 2011 QUALCOMM Incorporated.  All rights reserved.
10  * The file License.txt specifies the terms for use, modification,
11  * and redistribution.
12  *
13  * Modifications:
14  *
15  * 10/13/00  [rcg]
16  *          -  Added LGL's changes for TLS.
17  *
18  * 03/01/00  [rcg]
19  *          -  Now calling msg_ptr to adjust for hidden msgs and check range.
20  *
21  * 02/04/00  [rcg]
22  *          -  Changed len param of mangle_count from int to long.
23  */
24 
25 
26 #include "config.h"
27 
28 #include <sys/types.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #if HAVE_STRINGS_H
34 #  include <strings.h>
35 #endif
36 
37 #include "popper.h"
38 #include "mmangle/mime.h"
39 #include "mmangle/mangle.h"
40 
41 void
mangle_count(void * mstate,char * buf,long len)42 mangle_count ( void *mstate, char *buf, long len )
43 {
44     char *p;
45 
46     *(long *)mstate += len;
47 
48     for ( p = buf; len > 0; p++, len-- )
49         if ( *p == '\n' )
50             (*(long *)mstate)++;
51 
52 }
53 
54 
55 
56 /*
57  *  list:   List the contents of a POP maildrop
58  */
59 
60 int
pop_list(p)61 pop_list (p)
62 POP     * p;
63 {
64     MsgInfoList         *   mp;         /*  Pointer to message info list */
65     register int            i;
66     register int            msg_num;
67     int                     show_mangled_length = 0;
68     long                    mangled_length      = 0;
69     char                    buffer [ MAXMSGLINELEN ];
70     MimeParsePtr            mimeParse;
71     ManglerStateType        mangleState;
72 
73     /*
74      * Were arguments provided ?
75      */
76     pop_lower ( p->pop_parm[1] );
77     if ( p->parm_count == 1 &&
78          strncmp ( p->pop_parm[1], "mangle", 6 ) == 0 ) {
79         show_mangled_length++;
80     }
81     else
82     if ( p->parm_count == 1 &&
83          strncmp ( p->pop_parm[1], "x-mangle", 8 ) == 0 ) {
84         show_mangled_length++;
85     }
86     else
87     if ( p->parm_count > 0 ) {
88         /*
89          * First arg must be a message number
90          */
91         msg_num = atoi ( p->pop_parm[1] );
92 
93         /*
94          * Get a pointer to the message in the message list
95          */
96         mp = msg_ptr ( p, msg_num );
97         if ( mp == NULL )
98             return ( pop_msg ( p, POP_FAILURE, HERE,
99                                "Message %d does not exist.", msg_num ) );
100 
101         /*
102          * Is the message already flagged for deletion?
103          */
104         if ( mp->del_flag )
105             return ( pop_msg ( p, POP_FAILURE, HERE,
106                                "Message %d has been deleted.", msg_num ) );
107 
108         /*
109          * If second arg, it must be "mangle" or "x-mangle"
110          */
111         if ( p->parm_count == 2 ) {
112             pop_lower ( p->pop_parm[2] );
113             if ( ( strncmp ( p->pop_parm[2], "mangle",   6 ) != 0 ) &&
114                  ( strncmp ( p->pop_parm[2], "x-mangle", 8 ) != 0 )  )
115                 return ( pop_msg ( p, POP_FAILURE, HERE,
116                                    "Unknown LIST argument: %.128s",
117                                     p->pop_parm[2] ) );
118             else
119                 show_mangled_length++;
120         }
121         if ( show_mangled_length ) {
122             memset ( (void *)&mangleState, 0, sizeof(ManglerStateType) );
123             mangleState.outFn             = mangle_count;
124             mangleState.outFnState        = &(mangled_length);
125             mangleState.lastWasGoodHeader = 0;
126             mangleState.outFnConstructor  = mangleState.outFnDestructor
127                                           = NULL;
128             if ( FillMangleInfo ( p->pop_parm[2], 0, &mangleState.rqInfo ) == -1 ) {
129                 return ( pop_msg ( p, POP_FAILURE, HERE,
130                                    "Syntax error in x-mangle" ) );
131             }
132             mimeParse = MimeInit ( MangleMapper, &mangleState, p->drop );
133             fseek ( p->drop, mp->offset, 0 );
134             /*
135              * Read the from envelope
136              */
137             fgets ( buffer, MAXMSGLINELEN, p->drop );
138             MSG_LINES = mp->lines;
139             while ( fgets ( buffer, MAXMSGLINELEN, p->drop ) && MSG_LINES-- ) {
140                 MimeInput ( mimeParse, buffer, strlen(buffer) );
141             }
142             FreeMangleInfo ( &mangleState.rqInfo );
143             MimeFinish ( mimeParse );
144         }
145 
146         /*
147          * Display message information
148          */
149         return ( pop_msg ( p, POP_SUCCESS, HERE,
150                            "%u %lu",
151                            msg_num,
152                            ( show_mangled_length ? mangled_length
153                                                  : mp->length    ) ) );
154     } /* p->parm_count > 0 */
155 
156 
157     /*
158      * Display the entire list of messages
159      */
160     if ( FillMangleInfo ( p->pop_parm[1], 0, &mangleState.rqInfo ) == -1 ) {
161         return ( pop_msg ( p, POP_FAILURE, HERE,
162                            "Syntax error in Mangle" ) );
163     }
164     pop_msg ( p, POP_SUCCESS, HERE,
165               "%d visible messages (%ld octets)",
166                p->visible_msg_count - p->msgs_deleted,
167                p->drop_size - p->bytes_deleted );
168 
169     /*
170      * Loop through the message information list.  Skip deleted & hidden messages
171      */
172     for ( i = p->msg_count, mp = p->mlp; i > 0; i--, mp++ ) {
173         if ( mp->del_flag || mp->hide_flag )
174             continue;
175         if ( show_mangled_length ) {
176             memset ( (void *)&mangleState, 0, sizeof(ManglerStateType) );
177             mangled_length                = 0;
178             mangleState.outFn             = mangle_count;
179             mangleState.outFnState        = &(mangled_length);
180             mangleState.lastWasGoodHeader = 0;
181             mangleState.outFnConstructor  = mangleState.outFnDestructor
182                                           = NULL;
183             FillMangleInfo ( p->pop_parm[1], 0, &mangleState.rqInfo );
184             mimeParse = MimeInit ( MangleMapper, &mangleState, p->drop );
185             fseek ( p->drop, mp->offset, 0 );
186             /*
187              * Read the from envelope
188              */
189             fgets ( buffer, MAXMSGLINELEN, p->drop );
190             MSG_LINES = mp->lines;
191             while ( fgets ( buffer, MAXMSGLINELEN, p->drop ) && MSG_LINES-- ) {
192                 MimeInput ( mimeParse, buffer, strlen(buffer) );
193             }
194             FreeMangleInfo ( &mangleState.rqInfo );
195             MimeFinish ( mimeParse );
196         } /* show_mangled_length */
197 
198         pop_write_fmt ( p, "%u %lu\r\n",
199                         mp->visible_num,
200                         (show_mangled_length ? mangled_length
201                                              : mp->length ) );
202     } /* for loop */
203 
204     /*
205      * "." signals the end of a multi-line transmission
206      */
207     POP_WRITE_LIT   ( p, ".\r\n" );
208     pop_write_flush ( p );
209 
210     return ( POP_SUCCESS );
211 }
212