Subversion Repositories computer_asset_manager_v1

Rev

Rev 24 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
23 rodolico 1
<?php
2
 
3
/*
4
 * getBackupMail.php
5
 * 
6
 * Author: R. W. Rodolico
7
 * Copyright: 20160218, Daily Data, Inc.
8
 * 
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
21
 * 
22
 * Read messages from mail server. If they are YAML or XML sysinfo reports
23
 * save them to local drive, then remove them from mail server.
24
 * Files will be named with the following values, separated by underscores
25
 * report date (YYYY-MM-DD)
26
 * report time (HH:MM:SS) (CONTAINS COLONS)
27
 * client name (MAY CONTAIN SPACES)
28
 * device name
29
 * serial number (default to 00000 if it is not in the report)
30
 * 
31
 * Requires php5-imap
32
 * apt-get install php5-imap
33
 * 
34
 * Good information taken from
35
 * http://docstore.mik.ua/orelly/webprog/pcook/ch17_04.htm
36
 * 
37
 * V0.1 201602018 RWR
38
 * copied from getSysinfoMail.php
39
 * 
40
 * 
41
 * 
42
 */
43
 
44
$VERSION = '0.1';
27 rodolico 45
$configuration['maxemail'] = 10000; // maximum number of e-mails to download at one time
24 rodolico 46
$LOGGING = 1;
23 rodolico 47
$CLI = isset( $_SERVER["TERM"]); // only set if we are not in a cron job
48
// where to load the configuration file from
49
$confFileName = "rsbackupRead.conf.yaml";
50
$searchPaths = array( '/etc/camp', '/opt/camp', '/opt/camp/backups', $_SERVER['SCRIPT_FILENAME'], getcwd() );
51
 
24 rodolico 52
 
23 rodolico 53
/*
54
 * function loadConfig
55
 * Parameters $confFileName - the name of the configuration file
56
 *            $searchPaths - an array of paths to be searched
57
 * Returns    An array containing the configuration 
58
 * will search for a configuration file in $searchPaths for $confFileName
59
 * in order (so as to give priorities). The configuration file is
60
 * assumed to be a YAML file
61
 */
62
 
63
function loadConfig ( $confFileName, $searchPaths ) {
64
 
65
   /*
66
    * we don't know where the configuration file will be, so we have a list
67
    * below (searchPaths) to look for it. It will load the first one it 
68
    * finds, then exit. THUS, you could have multiple configuration files
69
    * but only the first one in the list will be used
70
    */
71
 
72
   $configuration = array();
73
 
74
 
75
   foreach ( $searchPaths as $path ) {
76
      if ( file_exists( "$path/$confFileName" ) ) {
77
         print "Found $path/$confFileName\n";
78
         $configuration = yaml_parse_file( "$path/$confFileName" );
79
         #require "$path/$confFileName";
80
         break; // exit out of the loop; we don't try to load it more than once
81
      } // if
82
   } // foreach
83
   return $configuration;
84
}
85
 
86
/* 
87
 * function    OpenMailbox
88
 * Parameters: $username
89
 *             $password
90
 *             $server
91
 *             $ssl=true
92
 *             $port=null
93
 *             $mailbox='INBOX'
94
 * 
95
 * Returns:    The IMAP instance handle
96
 *             The server string (used by some functions)
97
 */
98
function OpenMailbox ( $username, $password, $server, $ssl = true, $port=null, $mailbox = 'INBOX' ) {
99
   if ( $port == null )
100
      if ( $ssl ) $port = 993;  else $port = 143;
101
   $server = gethostbyname( $server );
102
   $serverString = "$server:$port/imap";
103
   if ( $ssl ) $serverString .= '/ssl';
104
   $serverString .= '/novalidate-cert';
105
   $serverString = '{' . $serverString . '}' . $mailbox;
106
   $server = imap_open( $serverString, $username, $password );
107
 
108
   return array($server, $serverString);
109
}
110
 
111
 
112
/*
113
 * function  getContents
114
 * Paramters $mail - handle to the connection
115
 *           $n    - the # of the message to get
116
 * Returns   An array containing all attachments
117
 * 
118
 */
119
 
120
function getContents( $mail, $n ) {
121
 
122
   $header = imap_header( $mail, $n );
123
   $structure = imap_fetchstructure( $mail, $n );
124
   $attachments = array();
125
   if(isset($structure->parts) && count($structure->parts)) {
126
 
127
      for($i = 0; $i < count($structure->parts); $i++) {
128
 
129
         $attachments[$i] = array(
130
            'is_attachment' => false,
131
            'filename' => '',
132
            'name' => '',
133
            'attachment' => ''
134
         );
135
 
136
         if($structure->parts[$i]->ifdparameters) {
137
            foreach($structure->parts[$i]->dparameters as $object) {
138
               if(strtolower($object->attribute) == 'filename') {
139
                  $attachments[$i]['is_attachment'] = true;
140
                  $attachments[$i]['filename'] = $object->value;
141
               }
142
            }
143
         }
144
 
145
         if($structure->parts[$i]->ifparameters) {
146
            foreach($structure->parts[$i]->parameters as $object) {
147
               if(strtolower($object->attribute) == 'name') {
148
                  $attachments[$i]['is_attachment'] = true;
149
                  $attachments[$i]['name'] = $object->value;
150
               }
151
            }
152
         }
153
 
154
         if($attachments[$i]['is_attachment']) {
155
            $attachments[$i]['attachment'] = imap_fetchbody($mail, $n, $i+1);
156
            if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
157
               $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
158
            }
159
            elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
160
               $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
161
            }
162
         } else {
163
            $attachments[$i]['attachment'] = imap_fetchbody( $mail, $n, $i+1 );
164
         }
165
      }
166
   }
167
   return array( $header, $attachments );
168
}
169
 
170
 
171
function saveAttachments ( $attachments, $mailDate ) {
172
   $body = '';
24 rodolico 173
   $saved = false;
23 rodolico 174
   foreach ( $attachments as $thisOne ) {
175
      if ( $thisOne['is_attachment'] ) {
176
         saveFile( makeFileName( $thisOne['filename'] ), $thisOne['attachment'], $mailDate );
24 rodolico 177
         $saved = true;
23 rodolico 178
      } else {
179
         $body .= $thisOne['attachment'];
180
      }
181
   }
24 rodolico 182
   return array( $saved, $body );
23 rodolico 183
}
184
 
185
/* function makeFileName
186
 * Parameter $data
187
 *           $type - the type of the file
188
 * Returns   properly formatted file name for saving
189
 * 
190
 * The file name is created as a combination of the report date
191
 * client name, hostname and serial number, separated by the underscore
192
 * character. The type of the file is appended, and the configuration
193
 * value for outpath is prepended
194
 */
195
function makeFileName ( $body ) {
196
   global $configuration;
197
   $outpath = $configuration['outpath'];
198
   return $outpath . '/' . $body;
199
} 
200
 
201
/*
202
 * function saveFile
203
 * parameter $filename
204
 *           $contents
205
 *           $timestamp
206
 * returns   Number of bytes written
207
 * 
208
 * Saves $contents to file $filename, then sets the timestamp to
209
 * $timestamp. It is assumed $filename was created by makeFileName
210
 * and $contents is the content of a report. $timestamp is the actual
211
 * report timestamp
212
 */
213
function saveFile( $filename, $contents, $timestamp ) {
214
   $bytesWritten = file_put_contents( $filename, $contents );
215
   if ( $bytesWritten ) {
216
      if ( ! touch( $filename, $timestamp ) ) logError( "could not set timestamp of $filename to $timestamp" );
217
   }
218
   return $bytesWritten;
219
}
220
 
221
function logError ( $message ) {
222
   global $configuration;
223
   error_log( "$message\n", 3, $configuration['logFile'] );
224
}
225
 
226
/**************************************************************************************************************
227
 * Begin Main Program
228
 **************************************************************************************************************/
229
 
230
// get the configuration
231
$configuration = loadConfig( $confFileName, $searchPaths );
232
#print_r( $configuration ) ; die;
233
 
234
// ensure the path we want to write to exists
235
if ( ! is_dir( $configuration['outpath'] ) ) {
236
   if ( ! mkdir( $configuration['outpath'], 0777, true ) ) {
237
      die( "Could not create path " . $configuration['outpath'] . "\n" );
238
   }
239
}
240
 
241
$listMailboxes =  isset( $argv[1] ) ; // anything passed on cli results in a list of mailboxes instead of the job
242
 
24 rodolico 243
 
23 rodolico 244
foreach ( $configuration['servers'] as $thisServer ) {
27 rodolico 245
   if ($configuration['maxemail'] <= 0 ) break;
23 rodolico 246
   if ( ! $thisServer['enabled'] ) continue; // ignore anything that is not enabled
247
   print "Working on " . $thisServer['servername'] . "\n";
248
   $messagesToDelete = array(); // trap the UID's of messages to delete, more accurate than using message number
249
   print "Opening " . $thisServer['servername'] . "\n";
250
 
251
 
252
   // open the mail server connection. NOTE: the $connectString is used in other functions, so we need to preserve it
253
   list( $server, $connectString ) = OpenMailbox(  $thisServer['username'], 
254
                                                   $thisServer['password'], 
255
                                                   $thisServer['servername'] , 
256
                                                   $thisServer['ssl'],
257
                                                   $thisServer['port'], 
258
                                                   $listMailboxes ? '' : $thisServer['mailbox'] 
259
                                                );
260
   print "Success with $connectString\n";
261
   if ( $listMailboxes ) {
262
      $list = imap_list($server, $connectString, "*");
263
      print_r( $list ); print "\n";
264
      continue;
265
   }
266
   $count = 0;
24 rodolico 267
   $lookedAt = 0;
23 rodolico 268
   if ( $server ) {
269
      $folderCount = imap_num_msg( $server );
27 rodolico 270
      for ( $num = 1; ($num <= $folderCount) && $count < $configuration['maxemail']; $num++ ) {
23 rodolico 271
         list( $header, $attachments ) = getContents( $server, $num );
24 rodolico 272
         $lookedAt++;
23 rodolico 273
         # $mailDate = getMailDate( $header );
24 rodolico 274
         list($saved,$body) = saveAttachments( $attachments, strtotime($header->date) );
275
         if ( $saved ) {
276
            $messagesToDelete[] = imap_uid( $server, $num );
277
            $count++;
278
         }
23 rodolico 279
         if ( $CLI ) print '.'; // only do this if interactive session
280
      } // for
281
      if ( $thisServer['deleteProcessed'] ) {
282
         foreach ( $messagesToDelete as $uid ) {
283
            imap_delete( $server, $uid, FT_UID ) or logError( "Can't delete [$uid]: imap_last_error()" );
284
         }
285
         imap_expunge( $server );
286
      }  // if delete
287
      imap_close( $server );
288
   } else {
289
      print "Could not open server " . $thisServer['servername'] . "\n";
290
   } // if..else
24 rodolico 291
   print "\nLooked at $lookedAt messages, Processed $count\n\n";
23 rodolico 292
} // outer for
293
?>