Odyssey
throtlpkt.i
1 <?php
2 
3  $dbx = db_pconnect();
4  $stx = db_query("select liveserver from cuadmin where cu = '$cu'",$dbx);
5  list($fetcher) = db_fetch_array($stx,0);
6 
7 
8 
9  /**
10  * DETERMINE THE SOURCE of the calls
11  * Any script wishing to set their own value will first set the value
12  * client_source_override PRIOR to including this file
13  *
14  * If client_source_override is set, I will use that value, ELSE use CLS for classic
15  * Options may be
16  * CLS - Classic
17  * APP - iPhone App
18  * MBL - New Mobile Banking
19  */
20  $client_source = ($client_source_override != '' ? $client_source_override : 'CLS');
21 
22 #
23 # if we don't have a fetcher value, something is too wrong to continue
24 #
25 
26  if (trim($fetcher)=='') {
27  # give an error and bail
28  print "<html><head><title>" . $MC->msg('Login Canceled') .
29  "</title></head><BODY><CENTER><H1>" .
30  $MC->msg('Feature Not Set') . "</H1><br>" .
31  $MC->msg('Contact CU Details') .
32  "</body></html>";
33  exit;
34  }
35 
36 function get_data($rqx) {
37 # returns open_fail as 0 no error or 1 fopen/popen failed
38 # pipe_err as termination code from piped command (always zero if fopen?)
39 # packet as data returned from core
40 
41  global $fetcher;
42  global $Cu;
43  global $Cn;
44  global $client_source; // RETRIEVE the client_source that was set at inclusion of file
45 
46  $open_fail=0;
47  $pipe_err=0;
48  $packet="";
49 
50  $pipe=1; # force use of popen but allow for easy recoding
51 
52  $opts = "--connect-timeout 5 --retry 3 --retry-delay 2";
53 // if ($Cu == 'SOCU' || $Cu == 'ALLOYCU') {
54  $opts .= ' --max-time 180';
55 // }
56 
57  // ** Add the SOURCE specification onto the end of the requesting data.
58  if ($client_source != '') {
59  $rqx .= "&SRC={$client_source}";
60  }
61 
62  if ($pipe) {
63  $fd=popen("/usr/bin/curl -k -N --silent $opts '$rqx'","r");
64  if (!$fd) {
65  $open_fail=1;
66  } else {
67  while ($buff = fread ($fd, 1500)) {
68  $packet .= $buff;
69  }
70  $pipe_err=pclose($fd);
71  }
72  return array($open_fail,$pipe_err,$packet);
73  } else {
74  $fd = @fopen("$rqx", "r");
75  if (!$fd) {
76  $open_fail=1;
77  } else {
78  $pkti = stream_get_meta_data($fd);
79  while ((!feof($fd)) && (!$pkti['timed_out'])) {
80  $packet .= fread($fd, 4096);
81  $pkti = stream_get_meta_data($fd);
82  }
83  fclose($fd);
84  if ($pkti['timed_out']) {
85  $open_fail=1;
86  $packet = "";
87  }
88  return array($open_fail,$pipe_err,$packet);
89  }
90  }
91 }
92 function get_data_post($postdata) {
93 // ** This will create a connection and send the data using POST rather than the default GET method
94 // * This is useful for post_application function
95 # returns open_fail as 0 no error or 1 fopen/popen failed
96 # pipe_err as termination code from piped command (always zero if fopen?)
97 # packet as data returned from core
98 
99  global $fetcher;
100  global $Cu;
101  global $Cn;
102 
103  $open_fail=0;
104  $pipe_err=0;
105  $packet="";
106 
107  $pipe=1; # force use of popen but allow for easy recoding
108  $opts = "--connect-timeout 5 --retry 3 --retry-delay 2";
109 // if ($Cu == 'SOCU' || $Cu == 'ALLOYCU') {
110  $opts .= ' --max-time 180';
111 // }
112 
113 
114 
115  if ($pipe) {
116  $fd=popen("/usr/bin/curl -k -N --silent $opts -d '$postdata' '$fetcher'","r");
117  if (!$fd) {
118  $open_fail=1;
119  } else {
120  while ($buff = fread ($fd, 1500)) {
121  $packet .= $buff;
122  }
123  $pipe_err=pclose($fd);
124  }
125  return array($open_fail,$pipe_err,$packet);
126  } else {
127  // ** For fopen to use posted values, we will first setup an array with the POST HEADER information,
128  // * then create a stream_context, then include this context on the file open
129 
130  $params = array('http' => array('method' => 'POST', 'content' => $postdata));
131  $ctx = stream_context_create($params);
132 
133  // ** fopen - the 'rb' r specifies read only 'b' specifies binary mode (Other option may be t)
134  $fd = @fopen($fetcher, 'r', false, $ctx);
135  if (!$fd) {
136  $open_fail=1;
137  } else {
138  $pkti = stream_get_meta_data($fd);
139  while ((!feof($fd)) && (!$pkti['timed_out'])) {
140  $packet .= fread($fd, 4096);
141  $pkti = stream_get_meta_data($fd);
142  }
143  fclose($fd);
144  if ($pkti['timed_out']) {
145  $open_fail=1;
146  $packet = "";
147  }
148  return array($open_fail,$pipe_err,$packet);
149  }
150  }
151 }
152 
153 
154 function fetch_packet($Cu,$Cn,$Clw) {
155 
156  #
157  # set environment for programs.
158  #
159  global $fetcher;
160  global $dbh;
161  global $Fhdays;
162  global $Fset2;
163  global $CU2_SHOWHOLD;
164  global $CU2_ESCHEMA;
165  global $Ml;
166 
167  $R3=(trim($Ml) == "" || $Ml=="no\@email.com" ? "NULL" : urlencode(trim($Ml)));
168  $FETCHER = "$fetcher";
169 # syslog(LOG_INFO,"fetcher: $fetcher");
170 
171  $PKTINTERVAL = ((is_null($Clw) || $Clw == 0) ? 300 : $Clw);
172 
173  # read last pktstamp from database. Calculate new threshold as
174  # now - pktinterval; if pktstamp > threshold, return (use existing)
175  #
176  $dbh = db_pconnect();
177  $sql = "select pktstamp, pktdate, coalesce(pktattempt,1), lastlogin from cuusers
178  where cu = '" . $Cu . "' and user_name = '" . $Cn . "'";
179  $sth = db_query($sql,$dbh);
180  list($pktstamp, $pktdate, $pktattempt, $lastlogin) = db_fetch_array($sth,0);
181  $pktstamp = (empty($pktstamp) ? 1 : $pktstamp);
182  $pktdate = (empty($pktdate) ? date("D M j Y H:i:s T") : $pktdate);
183  $lastlogin = (empty($lastlogin) ? 'NULL' : urlencode(trim($lastlogin)));
184 
185  $threshold = mktime() - $PKTINTERVAL;
186 // if ($Cu == 'SOCU' || $Cu == 'ALLOYCU') {
187  if (abs($pktstamp) > $threshold || $pktattempt > $threshold) { return array(0,$pktdate, "Too soon to ask again"); }
188 // } else {
189 // if (abs($pktstamp) > $threshold) { return array(0,$pktdate, "Too soon to ask again"); }
190 // }
191  $sql = "update cuusers set pktattempt=" . time() . "
192  where cu = '" . $Cu . "' and user_name = '" . $Cn . "'";
193  $sth = db_query($sql,$dbh);
194 
195  $pktstamp = ($pktstamp < 0 ? 1 : $pktstamp);
196 
197  #$fs = date("D M j Y H:i:s T",$pktstamp);
198  #$ft = date("D M j Y H:i:s T",$threshold);
199 
200  #syslog(LOG_INFO,"packetstamp: $pktstamp");
201  # Calculate a cutoff date to determine how much data to retrieve
202  #
203  # if this feature is turned off in cuadmin, the cutoff is very old
204  #
205  $cutoff = "20000101";
206 
207  #
208  # if the last packet is newer than 20000101 and history days is set
209  # calculate a newer cutoff to reduce the packet size
210  #
211  if ($pktstamp > 946710000 && $Fhdays > 0 ) {
212 
213  # If the last packet was fairly recent, only fetch 7 days
214  # "recent" defined as 3 times the packet timeout setting
215 
216  $throttle = mktime() - (3 * $Clw);
217  if ($pktstamp > $throttle) {
218  $cutoff = date("Ymd",mktime()-604800);
219  } else {
220  $cutoff = date("Ymd",$pktstamp-(86400 * $Fhdays));
221  }
222  }
223  $delim = (strpos($FETCHER,'?')=== false ? '?' : '&');
224  $rqx = "{$FETCHER}{$delim}member=$Cn&type=I&if_mod_since=$pktstamp&cutoff=$cutoff&ref3=$R3&lastlogin=$lastlogin";
225 
226 list ($open_fail, $pipe_err, $packet) = get_data($rqx);
227 
228 if (trim("$packet") == "") {
229  if ($open_fail == 1) {
230  trigger_error("$Cu:$Cn Inquiry open failed", E_USER_ERROR);
231  } else {
232  trigger_error("$Cu:$Cn Inquiry empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
233  }
234  return array(999, 1, "Unable to retrieve data");
235  }
236  if (preg_match("/<inquiry>/si",$packet) &&
237  !preg_match("/<\/inquiry>/si",$packet)) {
238  trigger_error("$Cu:$Cn Inquiry short packet response(pipe_err $pipe_err)", E_USER_ERROR);
239  $fp=@fopen("/tmp/packetnew.txt", "a");
240  @fwrite($fp,"$Cu:$Cn Inquiry short packet\n${rqx}\n");
241  @fwrite($fp,"$packet\n");
242  @fclose($fp);
243  return array(999, 1, "Unable to retrieve data");
244  } else {
245 
246  $pktpieces = array();
247 
248  $parameters = (preg_match("/<parameters>\n?(.*)\n?<\/parameters>/si",$packet,$pktpieces) ? $pktpieces[1] : "");
249  list($mem, $pcutoff) = explode("\t",$parameters);
250 
251  # if the packet presents a cutoff date, let it override our request
252  $cutoff = (trim($pcutoff) == "" ? trim($cutoff) : trim($pcutoff));
253  $status = (preg_match("/<status>\n?(.*)\n?<\/status>/si",$packet,$pktpieces) ? $pktpieces[1] : "");
254  $member = (preg_match("/<member>\n?(.*)\n?<\/member>/si",$packet,$pktpieces) ? $pktpieces[1] : "");
255  list($mem, $statcode, $statdesc) = explode("\t",$status);
256  if ("$member" > "") {list($mem) = explode("\t",$member);}
257  if (trim("$mem") != "$Cn") {
258  trigger_error("$Cu possibly out-of-sync ($member:$mem:$Cn)", E_USER_ERROR);
259 
260  $fp=@fopen("/tmp/packetnew.txt", "a");
261  @fwrite($fp,".${mem}:${Cn}. mismatch for $Cu\n");
262  @fwrite($fp,"${rqx}\n");
263  @fwrite($fp,"${packet}\n");
264  @fwrite($fp,"${p}\n");
265  @fclose($fp);
266  return array(999, 1, "Unable to retrieve data");
267  }
268  $time = (preg_match("/<time>\n?(.*)<\/time>/si",$packet,$pktpieces) ? $pktpieces[1] : "");
269  if ($time > "" ) { list($pktstamp, $pktdate) = explode ("\t",$time);}
270 
271  # check the return status to decide what to do here
272 
273  # 101 New Data -- process packet, update pktstamp
274  # 201 System Unavailable, New Data -- process packet, update pktstamp
275  # 100 No New Data -- update pktstamp
276  # 200 System Unavailable, No New Data -- return immediately
277  # 202 System Unavailable, No Data -- return immediately
278  # 001 Invalid Account Number -- return immediately
279  # 002 Invalid Password -- change to 001 Invalid Account and return
280  # 003 Closed Account -- change to 001 Invalid Account and return
281  # 999 Calling error or Invalid Parms -- return immediately
282  #
283  $errstat = 0;
284  switch ($statcode) {
285  case 101:
286  case 201:
287  # Need to refresh the db data. Start parsing that packet...
288  # just in case a packet is in process, check the db first,
289  # if the timestamp is negative and new, return instead
290 
291  $sql = "select pktstamp, pktdate from cuusers
292  where cu = '" . $Cu . "' and user_name = '" . $Cn . "'";
293  $sth = db_query($sql,$dbh);
294  list($ps, $pd) = db_fetch_array($sth,0);
295  $ps = (empty($ps) ? 1 : $ps);
296  $pd = (empty($pd) ? date("D M j Y H:i:s T") : $pd);
297  if (abs($ps) > $threshold) { return array(0,$pd, "Too soon to ask again"); }
298 
299  # set pktstamp to negative of current pktstamp so if we die
300  # in the middle next query will force reload
301 
302  $sql = "update cuusers set pktstamp = " . mktime() * -1 . ",
303  pktdate = '" . date("D M j Y H:i:s T") . "'
304  where cu = '" . $Cu . "'
305  and user_name = '" . $Cn . "'";
306  $sth = db_query($sql,$dbh);
307 
308  $tblist = array("accountbalance", "loanbalance", "accounthistory", "loanhistory", "messages");
309  if (($Fset2 & $CU2_SHOWHOLD) == $CU2_SHOWHOLD) { $tblist[]="holds"; }
310  foreach($tblist as $tbl) {
311  preg_match("/<$tbl>\n?(.*)<\/$tbl>/si",$packet,$pktpieces);
312  $$tbl = explode ("\n",$pktpieces[1]);
313  array_pop($$tbl);
314 
315  # stuff each piece in the db
316 
317  $sql = "delete from ${Cu}${tbl}
318  where accountnumber='" . $Cn . "'";
319  if ($tbl == "accounthistory" || $tbl == "loanhistory"){
320  $sql .= " and date >= '$cutoff'";
321  }
322  $sth = db_query($sql,$dbh);
323 
324  if (sizeof($$tbl)) {
325  if ($tbl == "loanhistory") {
326  $cql = "copy ${Cu}${tbl} (AccountNumber, LoanNumber, TraceNumber,
327  Date, PrincipleAmount, InterestAmount, Description,
328  Balance, SortKey";
329  if (($Fset2 & $CU2_ESCHEMA) == $CU2_ESCHEMA)
330  $cql .= ", Fee, Escrow";
331  $cql .= ") from stdin with null as ''";
332  } else {
333  $cql = "copy ${Cu}${tbl} from stdin with null as ''";
334  }
335 
336  $sth = db_query($cql,$dbh);
337  reset($$tbl);
338  $pgerr = '';
339 
340  while (list ($key, $line) = each ($$tbl)) {
341  $line = preg_replace("/ ?\t ?/","\t",$line);
342  $line = preg_replace("/ $/","",$line);
343  $line = preg_replace("/\\0/"," ",$line);
344  @pg_put_line($dbh, "$line\n");
345  }
346  if (!@pg_put_line($dbh,"\\.\n")) {$pgerr .= @pg_last_error($dbh);}
347  if (!@pg_end_copy($dbh)) {
348  $errstat ++;
349 # define_syslog_variables();
350 # syslog(LOG_ERR,"FAILED copying $tbl for $Cu:$Cn Statcode $statcode Cutoff $cutoff Error: $pgerr Browser " . $_SERVER['HTTP_USER_AGENT'] . "\n");
351  $fp=@fopen("/tmp/packetdump.txt", "a");
352  @fwrite($fp,".${Cn}:${Cu}. copy failed\n");
353  @fwrite($fp,"${rqx}\n");
354  @fwrite($fp,$packet);
355  reset($$tbl);
356  while (list ($key, $line) = each ($$tbl)) {
357  $line = preg_replace("/ ?\t ?/","\t",$line);
358  $line = preg_replace("/ $/","",$line);
359  $line = preg_replace("/\\0/"," ",$line);
360  @fwrite($fp,"$line\n");
361  }
362 
363  @fclose($fp);
364  }
365  }
366  }
367 
368  case 100:
369  if($errstat == 0) {
370  $sql = "update cuusers set pktstamp = $pktstamp,
371  pktdate = '" . $pktdate . "',
372  pktattempt = " . time() . "
373  where cu = '" . $Cu . "'
374  and user_name = '" . $Cn . "'";
375  $sth = db_query($sql,$dbh);
376  if (!$sth) {
377  #syslog(LOG_ERR,"FAILED setting pktstamp for $Cu:$Cn\n$sql");
378  }
379  }
380  case 200:
381  case 202:
382  if($errstat == 0 ) {
383  return array("$statcode", "$pktdate", "$statdesc");
384  } else {
385  return array("$statcode", 1, "Error loading member data. Please contact Credit Union");
386  }
387  break;
388  case 002:
389  case 003:
390  $statcode = '001';
391  $statdesc = 'INVALID ACCOUNT NUMBER';
392  case 001:
393  case 999:
394  return array("$statcode", 1, "$statdesc");
395  }
396  }
397 }
398 function fetch_mir($Cu,$Cn) {
399 
400  #
401  # set environment for programs.
402  #
403  global $fetcher;
404 
405  $FETCHER = "$fetcher";
406 # syslog(LOG_INFO,"fetcher: $fetcher");
407 
408  $mirinfo=array();
409  $delim = (strpos($FETCHER,'?')=== false ? '?' : '&');
410  $rqx = "{$FETCHER}{$delim}member=$Cn&type=MIR&f=xxxx";
411 
412 list ($open_fail, $pipe_err, $packet) = get_data($rqx);
413 
414 if (trim("$packet") == "") {
415  if ($open_fail == 1) {
416  trigger_error("$Cu:$Cn MIR open failed", E_USER_ERROR);
417  } else {
418  trigger_error("$Cu:$Cn MIR empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
419  }
420  $mirinfo[status][status]=999;
421  $mirinfo[status][asofdate]=1;
422  $mirinfo[status][reason]="Unable to retrieve data";
423  return $mirinfo;
424  }
425  if (preg_match("/<memberinfo>/si",$packet) &&
426  !preg_match("/<\/memberinfo>/si",$packet)) {
427  trigger_error("$Cu:$Cn MIR short packet response(pipe_err $pipe_err)", E_USER_ERROR);
428  $fp=@fopen("/tmp/packetnew.txt", "a");
429  @fwrite($fp,"$Cu:$Cn MIR short packet\n${rqx}\n");
430  @fwrite($fp,"$packet\n");
431  @fclose($fp);
432  $mirinfo[status][status]=999;
433  $mirinfo[status][asofdate]=1;
434  $mirinfo[status][reason]="Unable to retrieve data";
435  return $mirinfo;
436  } else {
437 
438  $pktpieces = array();
439 
440  $status = (preg_match("/<status>\n?(.*)\n?<\/status>/si",$packet,$pktpieces) ? $pktpieces[1] : "");
441  $member = (preg_match("/<member>\n?(.*)\n?<\/member>/si",$packet,$pktpieces) ? $pktpieces[1] : "");
442  list($mem, $statcode, $statdesc) = explode("\t",$status);
443  if ("$member" > "") {list($mem) = explode("\t",$member);}
444  if (trim("$mem") != "$Cn") {
445  trigger_error("$Cu possibly out-of-sync ($mem:$Cn)", E_USER_ERROR);
446  $fp=@fopen("/tmp/packetnew.txt", "a");
447  @fwrite($fp,".${mem}:${Cn}. mismatch for $Cu\n");
448  @fwrite($fp,"${rqx}\n");
449  @fwrite($fp,"${packet}\n");
450  @fwrite($fp,"${p}\n");
451  @fclose($fp);
452  $mirinfo[status][status]=999;
453  $mirinfo[status][asofdate]=1;
454  $mirinfo[status][reason]="Unable to retrieve data";
455  return $mirinfo;
456  }
457 
458  # check the return status to decide what to do here
459 
460  # 101 New Data -- process packet
461  # 201 System Unavailable, New Data -- can't use stale for MIR
462  # -- change to 200 and return
463  # 100 No New Data -- return immediately
464  # 200 System Unavailable, No New Data -- return immediately
465  # 202 System Unavailable, No Data -- return immediately
466  # 001 Invalid Account Number -- return immediately
467  # 002 Invalid Password -- change to 001 Invalid Account and return
468  # 003 Closed Account -- change to 001 Invalid Account and return
469  # 999 Calling error or Invalid Parms -- return immediately
470  #
471  $errstat = 0;
472  switch ($statcode) {
473  case 101:
474  # New data. Start parsing that packet...
475 
476  $tblist = array("info");
477  foreach($tblist as $tbl) {
478  preg_match("/<$tbl>\n?(.*)<\/$tbl>/si",$packet,$pktpieces);
479  $$tbl = explode ("\n",$pktpieces[1]);
480  array_pop($$tbl);
481 
482  if (sizeof($$tbl)) {
483 
484 # format and return array ala new cu_data functions
485  while (list ($key, $line) = each ($$tbl)) {
486  $line = preg_replace("/ ?\t ?/","\t",$line);
487  $line = preg_replace("/ $/","",$line);
488  $line = preg_replace("/\\0/"," ",$line);
489  list($AccountNumber, $FirstName,$MiddleName,$LastName,$Email,$HomePhone,$WorkPhone,$CellPhone,$Fax,$SSN,$Address1,$Address2,$City,$State,$Zip,$CC,$DOB) = explode("\t",$line);
490 
491  $mirinfo[status][status]=$statcode;
492  $mirinfo[status][asofdate]= date("D M j Y H:i:s T");
493  $mirinfo[status][reason]=$statdesc;
494 
495  $mirinfo[$tbl]['AccountNumber']=$AccountNumber;
496  $mirinfo[$tbl]['FirstName']=$FirstName;
497  $mirinfo[$tbl]['MiddleName']=$MiddleName;
498  $mirinfo[$tbl]['LastName']=$LastName;
499  $mirinfo[$tbl]['Email']=$Email;
500  $mirinfo[$tbl]['HomePhone']=$HomePhone;
501  $mirinfo[$tbl]['WorkPhone']=$WorkPhone;
502  $mirinfo[$tbl]['CellPhone']=$CellPhone;
503  $mirinfo[$tbl]['Fax']=$Fax;
504  $mirinfo[$tbl]['SSN']=$SSN;
505  $mirinfo[$tbl]['Address1']=$Address1;
506  $mirinfo[$tbl]['Address2']=$Address2;
507  $mirinfo[$tbl]['City']=$City;
508  $mirinfo[$tbl]['State']=$State;
509  $mirinfo[$tbl]['Zip']=$Zip;
510  $mirinfo[$tbl]['CC']=$CC;
511  $mirinfo[$tbl]['DOB']=$DOB;
512  }
513  }
514  }
515  break;
516 
517  case 201:
518  $mirinfo[status][status]='201';
519  $mirinfo[status][asofdate]= date("D M j Y H:i:s T");
520  $mirinfo[status][reason]="Unusable Stale Data";
521  break;
522 
523  case 100:
524  case 200:
525  case 202:
526  $mirinfo[status][status]=$statcode;
527  $mirinfo[status][asofdate]= date("D M j Y H:i:s T");
528  $mirinfo[status][reason]=$statdesc;
529  break;
530 
531  case 002:
532  case 003:
533  $mirinfo[status][status]='001';
534  $mirinfo[status][asofdate]= 1;
535  $mirinfo[status][reason]='INVALID ACCOUNT NUMBER';
536  break;
537 
538  case 001:
539  case 999:
540  $mirinfo[status][status]=$statcode;
541  $mirinfo[status][asofdate]= 1;
542  $mirinfo[status][reason]=$statdesc;
543  break;
544 
545  }
546  return $mirinfo;
547  }
548 }
549 
550 // post_application -- This will post an external application to the core
551 // note this does a POST request, not a GET..
552 // userresp_table -- The table that is to be updated with any status.. The schema will need to be dmsappuserresponse
553 // apprespid -- The respid value for the record being sent, it is used to properly update the table
554 // purpose -- Purpose of post -- valid values are {NEWAPP, INQAPP}
555 // appdata -- The data being sent for the particular purpose
556  // NEWAPP - this is the serialized element of fields being sent based on the core specifications
557  // INQAPP - this is the LOAN_APP_ID that will be sent to the core for an inquiry update
558 // appmember -- (optional) IF this is included, then send the member number to the core. OTHERWISE only send value NULL
559 function post_application($userresp_table, $apprespid, $purpose, $appemail, $appdata, $appmember='NULL') {
560 
561  global $fetcher, $dbh;
562 
563  $FETCHER = $fetcher;
564  $sql_set = '';
565  $ret_stat = '';
566  $ret_statdesc = '';
567 
568 
569  // ** Build the params to send
570 
571  $packetdata = "member={$appmember}&type=$purpose&tran_code=NULL&ref1=" . urlencode($appdata) . "&ref2=NULL&ref3=" . urlencode($appemail). "&ref4=NULL&ref5=NULL&amount=0.00";
572 
573 /* -- DO NOT USE fopen
574  $params = array('http' => array('method' => 'POST', 'content' => $packetdata));
575  $ctx = stream_context_create($params);
576 
577  // ** fopen - the 'rb' r specifies read only b specifies binary mode (Other option may be t)
578  $fp = @fopen($FETCHER, 'rb', false, $ctx);
579 
580  -- End of fopen
581 */
582  $rqx = $packetdata;
583 
584  // ** CALL get_data and process the
585  list ($open_fail, $pipe_err, $packet) = get_data_post($rqx);
586 
587  if (trim($packet) == "") {
588  if ($open_fail == 1) {
589  trigger_error("$Cu:$Cn Transaction open failed", E_USER_ERROR);
590  } else {
591  trigger_error("$Cu:$Cn Transaction empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
592  }
593  // ** Error -- Report an back to user...
594  // ** Unknown Error - Unable to update any information
595  $ret_stat = "999";
596  //$ret_statdesc = "An unknown error occurred. Please try again.";
597  $ret_statdesc = "We are unable to contact your Credit Union at this time. You may still save the application and submit it later.";
598  } else {
599  // * Should I allow this function to update the database with the loan_app_id and status??
600 
601  $pkgpattern = "/<status>\n?(.*)\n?<\/status>/si";
602 
603  preg_match("$pkgpattern",$packet,$pktpieces);
604  list($returned_loan_app_id, $statcode, $statdesc) = explode("\t",$pktpieces[1]);
605 
606  $ret_stat = trim($statcode);
607  $ret_statdesc = trim($statdesc);
608 
609  switch (trim($statcode)) {
610  case "000":
611  // ** NO ERROR -- Loan ACCEPTED -- UPDATE
612  // * {respcoreloanappid}
613  // * {respsubmiton}
614  // * {respstatus}
615  // * {respstatusdesc}
616  $ret_statdesc = "Loan was successfully submitted.";
617  $sql_set = "respcoreloanappid = " . intval($returned_loan_app_id) . ",
618  respsubmiton = now(),
619  respstatus = '000',
620  resplastinquire = now(),
621  respstatusdesc = '" . prep_save ($ret_statdesc) . "' ";
622  break;
623  case "020":
624  // ** SUBMIT ERROR - Missing Field
625  case "021":
626  // ** SUBMIT ERROR - Invalid Member #
627  case "022":
628  // ** SUBMIT ERROR - Member # and SSN mismatch
629 
630  // ** Something was missing on the NEW LOAN -- Unable to retrieve a loanappid
631  // * UPDATE THE FIELDS
632  // * {respstatus}
633  // * {respstatusdesc}
634  $sql_set = "respstatus = '$statcode',
635  respstatusdesc = '" . prep_save($statdesc) . "' ";
636  break;
637  // ** 025, 026, 027, 028, 029 -- are relevent to an INQAPP request
638  case "025":
639  // ** Invalid Application ID
640  // *nothing to do right now for this..
641  break;
642  case "027":
643  // ** Application Approved -_ NEED APPROVAL DATE
644  case "028":
645  // ** Application Rejected -- NEED REJECTED DATE
646  case "026":
647  // ** Application Pending
648  case "029":
649  // ** Application Submitted -- Needs further review
650  case "030":
651  // ** Application Submitted -- Contact Credit Union for additional information
652  $sql_set = "respstatus = '$statcode',
653  resplastinquire = now(),
654  respstatusdesc = '" . prep_save($statdesc) . "' ";
655  break;
656  case "999":
657  // ** Unable to contact Credit Union
658  $ret_stat = "999";
659  $ret_statdesc = "We are currently having problems communicating with the credit union. Please save your application and try to submit again later. <br>$statdesc";
660  break;
661  }
662  if ($sql_set != '') {
663  // ** Update the information on the {dmsapp}userresponse table
664  $sql = "UPDATE $userresp_table
665  SET $sql_set
666  WHERE respid = " . intval($apprespid);
667  if (!$resp_rs = db_query($sql, $dbh)) {
668  $ret_stat = "999";
669  $ret_statdesc = "An unknown error occurred. Please try again.";
670  }
671  } else {
672  // ** IF we are asking for an INQAPP and we are here, then
673  }
674 
675  }
676 
677  return array($ret_stat, $ret_statdesc);
678 }
679 
680 /*
681  * GetElertsData
682  *
683  * Interact with the third party vendor providing the eAlerts Form for the member to
684  * populate and post
685  *
686  * Parameters
687  *
688  * pDbh int - database handle for the current session
689  * pHbEnv array - HB_ENV Array
690  * pFetcher string - The Fetcher URL, this URL is the location of the hculive script on the appliance for the Credit Union
691  * pFormData array - The form data that will be processed and sent to the interface
692  *
693  * Returns
694  * string - This will return an HTML string to be slurped in to the form
695  *
696  */
697 function GetEalertsData($pDbh, $pHbEnv, $pFetcher, $pFormData) {
698 
699  $retData = Array('status' => '', 'desc' => '', 'data' => '');
700  $packetDataTag = 'DataBase64';
701 
702 
703  // ** Build the options to send
704  $packetdata = "member={$pHbEnv['Cn']}&type=OTHER&product=EALERTS&ref3=" . urlencode($pHbEnv['Ml']) . "&options[]=" . base64_encode($pFormData);
705 
706  $rqx = $packetdata;
707 
708  // ** CALL get_data and process the
709  list ($open_fail, $pipe_err, $packet) = get_data_post($rqx);
710  if (trim($packet) == "") {
711  /*
712  **** EMPTY PACKET ****
713  */
714 
715  if ($open_fail == 1) {
716  trigger_error("$Cu:$Cn Ealerts open failed", E_USER_ERROR);
717  } else {
718  trigger_error("$Cu:$Cn Ealerts empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
719  }
720 
721  // ** Error -- Report an back to user...
722  // ** Unknown Error - Unable to update any information
723  $retData['status'] = "999";
724  $retData['desc'] = "We are unable to contact your Credit Union at this time. You may still save the application and submit it later.";
725 
726  } else {
727  /*
728  ***** PROCESS PACKET *****
729  */
730 
731  $statusLine = GetPktSegment('status', $packet);
732  list($cumember, $statcode, $statdesc) = explode("\t", $statusLine);
733 
734  // ** Retrieve the member section returned by the core --
735  // ** REQUIRED
736  $memberLine = GetPktSegment('member', $packet);
737  list($coremember, $coreproduct) = explode("\t", $memberLine);
738 
739  $retData['status'] = trim($statcode);
740  $retData['desc'] = trim($statdesc);
741 
742  // ** CHECK MEMBER <member>MBRNUM</member> to ensure the member number returned is the correct member
743  if ($coremember != $pHbEnv['Cn']) {
744  // ** Unable to contact Credit Union
745  $retData['status'] = "999";
746  $retData['desc'] = "Unable to retrieve data";
747 
748  trigger_error("$Cu possibly out-of-sync ($member:$mem:$Cn) EAlert", E_USER_ERROR);
749  $fp = @fopen("/tmp/packetnew.txt", "a");
750  @fwrite($fp,".${mem}:${Cn}. mismatch for $Cu Ealert\n");
751  @fwrite($fp,"${rqx}\n");
752  @fwrite($fp,"${packet}\n");
753  @fwrite($fp,"${p}\n");
754  @fclose($fp);
755 
756  } else {
757  switch (trim($statcode)) {
758  case "101":
759  /*
760  * Get the From from the datapacket and return the data
761  */
762  $retData['data'] = GetPktSegment($packetDataTag, $packet);
763  break;
764  default:
765  // ** Unable to contact Credit Union
766  $retData['status'] = "999";
767  $retData['desc'] = "We are currently having problems communicating with the credit union. Please save your application and try to submit again later. <br>$statdesc";
768  break;
769  }
770  }
771  }
772 
773  return $retData;
774 }
775 
776 
777 function post_packet($Mem, $Tc, $R1, $R2, $R3, $R4, $R5, $Amt) {
778  global $Cu;
779  global $Cn;
780  global $fetcher;
781  global $Clw;
782  $FETCHER = "$fetcher";
783 
784  $Clw = ((is_null($Clw) || $Clw == 0) ? 300 : $Clw);
785  $pktpieces = array();
786 
787  $R1 = (trim($R1) == "" ? "NULL" : $R1);
788  $R2 = (trim($R2) == "" ? "NULL" : $R2);
789  $R3 = (trim($R3) == "" ? "NULL" : urlencode($R3));
790  $R4 = (trim($R4) == "" ? "NULL" : urlencode($R4));
791  $R5 = (trim($R5) == "" ? "NULL" : $R5);
792 #
793 $delim = (strpos($FETCHER,'?')=== false ? '?' : '&');
794 $rqx = "{$FETCHER}{$delim}member=$Mem&type=T&tran_code=$Tc&ref1=$R1&ref2=$R2&ref3=$R3&ref4=$R4&ref5=$R5&amount=$Amt";
795 
796 list ($open_fail, $pipe_err, $packet) = get_data($rqx);
797 
798 if (trim("$packet") == "") {
799  if ($open_fail == 1) {
800  trigger_error("$Cu:$Cn Transaction open failed", E_USER_ERROR);
801  } else {
802  trigger_error("$Cu:$Cn Transaction empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
803  }
804  return array(999, 1, "Unable to retrieve data");
805  }
806 
807  $pkgpattern = "/<status>\n?(.*)\n?<\/status>/si";
808 
809  preg_match("$pkgpattern",$packet,$pktpieces);
810  list($mem, $statcode, $statdesc) = explode("\t",$pktpieces[1]);
811  # update packetstamp so next query gets new data
812  # 10/30/09 ONLY if pktstamp is within (3*Clw) -- avoid leaving holes by
813  # getting short packets when they haven't gotten a good full packet
814  $tstamp = mktime()-(2*$Clw);
815  $onlyif = mktime()-(3*$Clw);
816  $dbh = db_pconnect();
817  $sql = "update cuusers set pktstamp = $tstamp,
818  pktdate = '" . date("D M j Y H:i:s T") . "',
819  pktattempt = $tstamp
820  where cu = '" . $Cu . "'
821  and ((user_name = '" . $Cn . "' and pktstamp > $onlyif)";
822  if ($R5 <> "NULL" && $R5 <> $Cn) {
823  $sql .= " or (user_name = '" . $R5 . "' and pktstamp > $tstamp)";
824  }
825  $sql .= ")";
826  $sth = db_query($sql,$dbh);
827  if (!$sth) {
828  #syslog(LOG_ERR,"FAILED setting pktstamp for $Cu:$Cn\n$sql");
829  }
830  return array($statcode, $statdesc);
831 }
832 function post_exp_pkt($Mem, $Tc, $R1, $R2, $R3, $R4, $R5, $Amt, $tauth, $tmemo) {
833  global $Cu;
834  global $Cn;
835  global $fetcher;
836  global $Clw;
837  $FETCHER = "$fetcher";
838 
839  $Clw = ((is_null($Clw) || $Clw == 0) ? 300 : $Clw);
840  $pktpieces = array();
841 
842  $R1 = (trim($R1) == "" ? "NULL" : $R1);
843  $R2 = (trim($R2) == "" ? "NULL" : $R2);
844  $R2 = (trim($R2) == "-" ? "NULL" : $R2);
845  $R3 = (trim($R3) == "" ? "NULL" : urlencode($R3));
846  $R4 = (trim($R4) == "" ? "NULL" : urlencode($R4));
847  $R5 = (trim($R5) == "" ? "NULL" : $R5);
848  $tauth = (trim($tauth) == "" ? "$Cn" : trim($tauth));
849  $tmemo = (trim($tmemo) == "" ? "NULL" : urlencode(trim($tmemo)));
850 
851 $delim = (strpos($FETCHER,'?')=== false ? '?' : '&');
852 $rqx = "{$FETCHER}{$delim}member=$Mem&type=T&tran_code=$Tc&ref1=$R1&ref2=$R2&ref3=$R3&ref4=$R4&ref5=$R5&amount=$Amt&tauth=$tauth&tmemo=$tmemo";
853 
854 list ($open_fail, $pipe_err, $packet) = get_data($rqx);
855 
856 if (trim("$packet") == "") {
857  if ($open_fail == 1) {
858  trigger_error("$Cu:$Cn Transaction open failed", E_USER_ERROR);
859  } else {
860  trigger_error("$Cu:$Cn Transaction empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
861  }
862  return array(999, 1, "Unable to retrieve data");
863  }
864 
865  $pkgpattern = "/<status>\n?(.*)\n?<\/status>/si";
866 
867  preg_match("$pkgpattern",$packet,$pktpieces);
868  list($mem, $statcode, $statdesc) = explode("\t",$pktpieces[1]);
869  # update packetstamp so next query gets new data
870  # 10/30/09 ONLY if pktstamp is within (3*Clw) -- avoid leaving holes by
871  # getting short packets when they haven't gotten a good full packet
872  $tstamp = mktime()-(2*$Clw);
873  $onlyif = mktime()-(3*$Clw);
874  $dbh = db_pconnect();
875  $sql = "update cuusers set pktstamp = $tstamp,
876  pktdate = '" . date("D M j Y H:i:s T") . "',
877  pktattempt = $tstamp
878  where cu = '" . $Cu . "'
879  and ((user_name = '" . $Cn . "' and pktstamp > $onlyif)";
880  if ($R5 <> "NULL" && $R5 <> $Cn) {
881  $sql .= " or (user_name = '" . $R5 . "' and pktstamp > $tstamp)";
882  }
883  $sql .= ")";
884  $sth = db_query($sql,$dbh);
885  if (!$sth) {
886  #syslog(LOG_ERR,"FAILED setting pktstamp for $Cu:$Cn\n$sql");
887  }
888  return array($statcode, $statdesc);
889 }
890 function post_pkt_track($Mem, $Tc, $R1, $R2, $R3, $R4, $R5, $Amt, $tauth, $tmemo) {
891  global $Cu;
892  global $Cn;
893  global $fetcher;
894  global $Clw;
895  $FETCHER = "$fetcher";
896 
897  $Clw = ((is_null($Clw) || $Clw == 0) ? 300 : $Clw);
898  $pktpieces = array();
899 
900  $R1 = (trim($R1) == "" ? "NULL" : $R1);
901  $R2 = (trim($R2) == "" ? "NULL" : $R2);
902  $R2 = (trim($R2) == "-" ? "NULL" : $R2);
903  $R3 = (trim($R3) == "" ? "NULL" : urlencode($R3));
904  $R4 = (trim($R4) == "" ? "NULL" : urlencode($R4));
905  $R5 = (trim($R5) == "" ? "NULL" : $R5);
906  $tauth = (trim($tauth) == "" ? "$Cn" : trim($tauth));
907  $tmemo = (trim($tmemo) == "" ? "NULL" : urlencode(trim($tmemo)));
908 
909 $delim = (strpos($FETCHER,'?')=== false ? '?' : '&');
910 $rqx = "{$FETCHER}{$delim}member=$Mem&type=T&tran_code=$Tc&ref1=$R1&ref2=$R2&ref3=$R3&ref4=$R4&ref5=$R5&amount=$Amt&tauth=$tauth&tmemo=$tmemo";
911 
912 list ($open_fail, $pipe_err, $packet) = get_data($rqx);
913 
914 if (trim("$packet") == "") {
915  if ($open_fail == 1) {
916  trigger_error("$Cu:$Cn Transaction open failed", E_USER_ERROR);
917  track_pkt($Cu,$Cn,$Tc, $R1, $R2, $R3, $R4, $R5, $Amt, $tauth, $tmemo,'F','999','Transaction open failed');
918  } else {
919  trigger_error("$Cu:$Cn Transaction empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
920  track_pkt($Cu,$Cn,$Tc, $R1, $R2, $R3, $R4, $R5, $Amt, $tauth, $tmemo,'F','999','Transaction empty packet response (pipe_err ' . $pipe_err . ')');
921  }
922  return array(999, 1, "Unable to retrieve data");
923  }
924 
925  $pkgpattern = "/<status>\n?(.*)\n?<\/status>/si";
926 
927  preg_match("$pkgpattern",$packet,$pktpieces);
928  list($mem, $statcode, $statdesc) = explode("\t",$pktpieces[1]);
929 
930  $pf = ($statcode != '000' ? 'F' : 'P');
931  list($confcode) = track_pkt($Cu,$Cn,$Tc, $R1, $R2, $R3, $R4, $R5, $Amt, $tauth, $tmemo,$pf,$statcode,$statdesc);
932 
933  # update packetstamp so next query gets new data
934  # 10/30/09 ONLY if pktstamp is within (3*Clw) -- avoid leaving holes by
935  # getting short packets when they haven't gotten a good full packet
936  $tstamp = mktime()-(2*$Clw);
937  $onlyif = mktime()-(3*$Clw);
938  $dbh = db_pconnect();
939  $sql = "update cuusers set pktstamp = $tstamp,
940  pktdate = '" . date("D M j Y H:i:s T") . "',
941  pktattempt = $tstamp
942  where cu = '" . $Cu . "'
943  and ((user_name = '" . $Cn . "' and pktstamp > $onlyif)";
944  if ($R5 <> "NULL" && $R5 <> $Cn) {
945  $sql .= " or (user_name = '" . $R5 . "' and pktstamp > $tstamp)";
946  }
947  $sql .= ")";
948  $sth = db_query($sql,$dbh);
949  if (!$sth) {
950  #syslog(LOG_ERR,"FAILED setting pktstamp for $Cu:$Cn\n$sql");
951  }
952  return array($statcode, $statdesc, $confcode);
953 }
954 function track_pkt($Cu,$Cn,$Tc, $R1, $R2, $R3, $R4, $R5, $Amt, $tauth, $tmemo,$pf,$statcode,$statdesc) {
955 
956  $sql = "insert into cutransactionlog (cu, accountnumber, transactioncode, r1fsfx, r2tsfx, r3email,
957  r4misc1, r5tmem, memberto, amount, date, tauth, tmemo, corestatus, corecode, coremsg, ipaddr)
958  values ('$Cu','$Cn','$Tc','$R1','$R2', '" . prep_save($R3) . "','$R4','$R5','$R5',$Amt,now(), '$tauth','"
959  . prep_save($tmemo) . "','$pf','$statcode','" . prep_save($statdesc) . "','{$_SERVER['REMOTE_ADDR']}'); ";
960  $sql.="select currval('cutransactionlog_id_seq'); ";
961 
962  $sth = db_query($sql, $dbh);
963 
964  if (!$sth) {
965  # error occurred
966  trigger_error("$Cu:$Cn Track transaction failed ($sql)", E_USER_ERROR);
967  $tid='00-00-00-00';
968  } else {
969  # everything ok
970  list($tid) = db_fetch_array($sth,0);
971  // eventually return $tid as confirmation code (as batch does)
972  // but for now continue to return hex-encoded date
973  //
974  # confirmation code is julian day . (seconds since midnight as 7digits)
975  # then converted to hex and formatted as 2-2-2-2 to minimize hex swearing
976 
977  $condate=getdate();
978 
979  $tid=sprintf('%08s',dechex(($condate['yday'] + 1 .
980  sprintf('%07u',(
981  $condate['hours'] * 3600 +
982  $condate['minutes'] * 60 +
983  $condate['seconds'] )))));
984  $tid = sprintf('%s-%s-%s-%s',substr($tid,0,2),substr($tid,2,2),substr($tid,4,2),substr($tid,6,2));
985 
986  }
987  return ($tid);
988 }
989 
990 function fetch_user($Cu, $Cn, $pwd, $insflag) {
991  global $dbh;
992  global $fetcher;
993  global $CU2_SHOWHOLD;
994  global $CU2_ESCHEMA;
995  global $Ml;
996  global $MEM_LOGIN_FAILED_PWD;
997 
998  if ($pwd === '0') {$pwd = '00';}
999 
1000  $R3 = (trim($Ml) == "" || $Ml == "no\@email.com" ? "NULL" : urlencode(trim($Ml)));
1001  $FETCHER = $GLOBALS['fetcher'];
1002 
1003  #syslog(LOG_ERR,"Fetch User from $FETCHER with $Cu $Cn $pwd $insflag");
1004  $dbh = db_pconnect();
1005  $sql = "select coalesce(retrylimit,5) as retry,
1006  coalesce(gracelimit,5) as grace, flagset, flagset2
1007  from cuadmin where cu = '$Cu'";
1008  $sth = db_query($sql, $dbh);
1009  list($retry, $grace, $Fset, $Fset2) = db_fetch_array($sth, 0);
1010 
1011  $retry = ($retry <= 0 ? 5 : $retry);
1012  $grace = ($grace <= 0 ? 5 : $grace);
1013  $msg_tx = (($Fset & 32) == 32 ? 512 : 0);
1014 
1015 # define_syslog_variables();
1016  #syslog(LOG_INFO,"$FETCHER?member=$Cn&type=I&if_mod_since=1&pass=$pwd");
1017  $delim = (strpos($FETCHER, '?') === false ? '?' : '&');
1018  $rqx = "{$FETCHER}{$delim}member=$Cn&type=I&if_mod_since=1&cutoff=20060101&pass=" . urlencode($pwd) . "&ref3=$R3";
1019 
1020  list ($open_fail, $pipe_err, $packet) = get_data($rqx);
1021 
1022  if (trim("$packet") == "") {
1023  if ($open_fail == 1) {
1024  trigger_error("$Cu:$Cn Inquiry open failed", E_USER_ERROR);
1025  } else {
1026  trigger_error("$Cu:$Cn Inquiry empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
1027  }
1028  return array(999, 1, "Unable to retrieve data");
1029  }
1030 
1031  if (preg_match("/<inquiry>/si", $packet) &&
1032  !preg_match("/<\/inquiry>/si", $packet)) {
1033  trigger_error("$Cu:$Cn Inquiry short packet response(curl_err $curl_err)", E_USER_ERROR);
1034  $fp = @fopen("/tmp/packetnew.txt", "a");
1035  @fwrite($fp, "$Cu:$Cn Inquiry short packet\n${rqx}\n");
1036  @fwrite($fp, "$packet\n");
1037  @fclose($fp);
1038  return array(999, 1, "Unable to retrieve data");
1039  } else {
1040 
1041  $pktpieces = array();
1042 
1043  $parameters = (preg_match("/<parameters>\n?(.*)\n?<\/parameters>/si", $packet, $pktpieces) ? $pktpieces[1] : "");
1044  list($mem, $pcutoff) = explode("\t", $parameters);
1045 
1046  # if the packet presents a cutoff date, let it override our request
1047  $cutoff = (trim($pcutoff) == "" ? "20060101" : trim($pcutoff));
1048  $status = (preg_match("/<status>\n?(.*)\n?<\/status>/si", $packet, $pktpieces) ? $pktpieces[1] : "");
1049  list($mem, $statcode, $statdesc) = explode("\t", $status);
1050  if (trim($mem) != $Cn) {
1051  return array(999, 1, "Unable to retrieve data");
1052  }
1053  $time = (preg_match("/<time>\n?(.*)\n?<\/time>/si", $packet, $pktpieces) ? $pktpieces[1] : "");
1054  list($pktstamp, $pktdate) = explode("\t", $time);
1055  $member = (preg_match("/<member>\n?(.*)\n?<\/member>/si", $packet, $pktpieces) ? $pktpieces[1] : "");
1056  list($pktuser, $pktpwd) = explode("\t", $member);
1057  $pktpwd = trim($pktpwd);
1058 
1059  # check the return status to decide what to do here
1060  # 101 New Data -- process packet, update pktstamp
1061  # 201 System Unavailable, New Data -- ignore packet, couldn't verify
1062  # password with core system
1063  # 100 No New Data -- update pktstamp
1064  # 200 System Unavailable, No New Data -- return immediately
1065  # 202 System Unavailable, No Data -- return immediately
1066  # 002 Invalid Password -- If insflag is set, insert user record
1067  # so we can lockout 'brute force' hack attempts
1068  # 003 Closed Account -- change to 001 Invalid Account and return
1069  # 001 Invalid Account Number -- return immediately
1070  # 999 Calling error or Invalid Parms -- return immediately
1071  #
1072  $errstat = 0;
1073  switch ($statcode) {
1074  case 101:
1075  # Need to refresh the db data. Start parsing that packet...
1076  # Insert the user record
1077  # or update an existing 'NULL PASSWORD' record
1078  # set pktstamp to 1 so if we die in the middle next query will force reload
1079 
1080  $salt = compute_salt(0);
1081  $hashpwd = crypt($pwd, $salt);
1082  $hashpwd = crypt($pwd);
1083 
1084  if ($insflag == 1) {
1085  $sql = "insert into cuusers (
1086  cu, user_name, passwd, pktstamp, pktdate,
1087  forcechange, forceremain, failedremain, pwchange, msg_tx)
1088  values (
1089  '$Cu', '$Cn', '$hashpwd'," . mktime() * -1 . ", '" .
1090  date("D M j Y H:i:s T") . "',
1091  'Y',$grace, $retry, now(),$msg_tx)";
1092  } else {
1093  $sql = "update cuusers set passwd = '$hashpwd',
1094  pktstamp = " . mktime() * -1 . ",
1095  pktdate = '" . date("D M j Y H:i:s T") . "',
1096  forcechange = 'Y', forceremain = $grace,
1097  failedremain = $retry, pwchange = now(),
1098  msg_tx = $msg_tx
1099  where cu = '$Cu' and user_name = '$Cn'";
1100  }
1101  $sth = db_query($sql, $dbh);
1102  if (!$sth) {
1103  $pg_error = pg_errormessage();
1104 # syslog(LOG_INFO,"$pg_error : $sql");
1105  $errstat = 1;
1106  } else {
1107  #syslog(LOG_INFO,"User inserted: $sql");
1108 
1109 
1110  $tblist = array("accountbalance", "loanbalance", "accounthistory", "loanhistory", "messages");
1111  if (($Fset2 & $CU2_SHOWHOLD) == $CU2_SHOWHOLD) {
1112  $tblist[] = "holds";
1113  }
1114  foreach ($tblist as $tbl) {
1115  preg_match("/<$tbl>\n?(.*)<\/$tbl>/si", $packet, $pktpieces);
1116  $$tbl = explode("\n", $pktpieces[1]);
1117  array_pop($$tbl);
1118 
1119  # stuff each piece in the db
1120 
1121  $sql = "delete from ${Cu}${tbl}
1122  where accountnumber='$Cn'";
1123  if ($tbl == "accounthistory" || $tbl == "loanhistory") {
1124  $sql .= " and date >= '$cutoff'";
1125  }
1126  $sth = db_query($sql, $dbh);
1127 
1128  if (sizeof($$tbl)) {
1129 #
1130  if ($tbl == "loanhistory") {
1131  $cql = "copy ${Cu}${tbl} (AccountNumber, LoanNumber, TraceNumber,
1132  Date, PrincipleAmount, InterestAmount, Description,
1133  Balance, SortKey";
1134  if (($Fset2 & $CU2_ESCHEMA) == $CU2_ESCHEMA)
1135  $cql .= ", Fee, Escrow";
1136  $cql .= ") from stdin with null as ''";
1137  } else {
1138  $cql = "copy ${Cu}${tbl} from stdin with null as ''";
1139  }
1140 
1141  $sth = db_query($cql, $dbh);
1142 #
1143  reset($$tbl);
1144 
1145  while (list ($key, $line) = each($$tbl)) {
1146  $line = preg_replace("/ ?\t ?/", "\t", $line);
1147  $line = preg_replace("/ $/", "", $line);
1148  $line = preg_replace("/\\0/", " ", $line);
1149  @pg_put_line($dbh, "$line\n");
1150  }
1151  @pg_put_line($dbh, "\\.\n");
1152  if (!@pg_end_copy($dbh)) {
1153  $errstat++;
1154 # define_syslog_variables();
1155 # syslog(LOG_ERR,"FAILED copying $tbl for $Cu:$Cn Statcode $statcode Cutoff $cutoff Error " . pg_last_error($dbh) . "\n");
1156  }
1157  }
1158  }
1159  }
1160 
1161  case 100:
1162  if ($errstat == 0) {
1163  $sql = "update cuusers set pktstamp = $pktstamp,
1164  pktdate = '" . $pktdate . "'
1165  where cu = '" . $Cu . "'
1166  and user_name = '" . $Cn . "'";
1167  $sth = db_query($sql, $dbh);
1168  if (!$sth) {
1169  #syslog(LOG_ERR,"FAILED setting pktstamp for $Cu:$Cn\n$sql");
1170  }
1171  }
1172  case 200:
1173  case 201:
1174  case 202:
1175  if ($errstat == 0) {
1176  return array("$statcode", "$pktdate", "$statdesc");
1177  } else {
1178  return array("$statcode", 1, "Error loading member data. Please contact Credit Union");
1179  }
1180  break;
1181  case 002:
1182  # fetching user data for the first time but the pin doesn't match
1183  # If the insflag is set, insert a user record so the login lockout
1184  # feature can prevent brute force pin-cracking
1185  # Otherwise, just return the 001 message and the login
1186  # program will handle the lockout stuff
1187  #
1188 # syslog(LOG_ERR,"Got 002 with $Cu $Cn $pwd $insflag");
1189  if ($insflag == 1) {
1190 
1191  $sql = "insert into cuusers (
1192  cu, user_name, passwd, pktstamp, pktdate,
1193  forcechange, forceremain, failedremain, pwchange, userflags)
1194  values (
1195  '$Cu', '$Cn', 'NULL PASSWORD',1, '" . date("D M j Y H:i:s T") . "',
1196  'Y',$grace, $retry, now(), {$MEM_LOGIN_FAILED_PWD})";
1197  $sth = db_query($sql, $dbh);
1198  if (!$sth) {
1199  $pg_error = pg_errormessage();
1200  #syslog(LOG_INFO,"$pg_error : $sql");
1201  $errstat = 1;
1202  } else {
1203  #syslog(LOG_INFO,"Bad 1st Password but User inserted: $sql");
1204  }
1205  }
1206  case 003:
1207  $statcode = '001';
1208  $statdesc = 'INVALID ACCOUNT NUMBER';
1209  case 001:
1210  case 999:
1211  return array("$statcode", 1, "$statdesc");
1212  }
1213  }
1214 }
1215 
1216 function fetch_XA() {
1217 # this function not currently in use 9/22/11 MH
1218 #
1219 # set environment for programs.
1220 #
1221 global $Cu;
1222 global $Cn;
1223 global $fetcher;
1224 global $dbh;
1225 $FETCHER = "$fetcher";
1226 
1227 #
1228 $dbh = db_pconnect();
1229 
1230 $delim = (strpos($FETCHER,'?')=== false ? '?' : '&');
1231 $rqx = "{$FETCHER}{$delim}member=$Cn&type=X";
1232 list ($open_fail, $pipe_err, $packet) = get_data($rqx);
1233 
1234 if (trim("$packet") == "") {
1235  if ($open_fail == 1) {
1236  trigger_error("$Cu:$Cn XA open failed", E_USER_ERROR);
1237  } else {
1238  trigger_error("$Cu:$Cn XA empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
1239  }
1240  return array(999, 1, "Unable to retrieve data");
1241  }
1242 
1243  if (preg_match("/<crossaccount>/si",$packet) &&
1244  !preg_match("/<\/crossaccount>/si",$packet)) {
1245  trigger_error("$Cu:$Cn CrossAccount short packet response(curl_err $curl_err)", E_USER_ERROR);
1246  $fp=@fopen("/tmp/packetnew.txt", "a");
1247  @fwrite($fp,"$Cu:$Cn CrossAccount short packet\n${rqx}\n");
1248  @fwrite($fp,"$packet\n");
1249  @fclose($fp);
1250  return array(999, 1, "Unable to retrieve data");
1251  } else {
1252 
1253 
1254  $pktpieces = array();
1255 
1256  $status = (preg_match("/<status>\n?(.*)\n?<\/status>/si",$packet,$pktpieces) ? $pktpieces[1] : "");
1257  list($mem, $statcode, $statdesc) = explode("\t",$status);
1258  if (trim($mem) != $Cn) {
1259  return array(999, 1, "Unable to retrieve data");
1260  }
1261 
1262  # check the return status to decide what to do here
1263 
1264  # 101 New Data -- process packet, update pktstamp
1265  # 200 System Unavailable, No New Data -- return immediately
1266  # 001 Invalid Account Number -- return immediately
1267  # 003 Invalid Account Number -- return immediately
1268  # 999 Calling error or Invalid Parms -- return immediately
1269  #
1270  $errstat = 0;
1271  $u = date("U");
1272  switch ($statcode) {
1273  case 101:
1274  # Need to refresh the db data. Start parsing that packet...
1275 
1276  preg_match("/<txaccount>\n?(.*)<\/txaccount>/si",$packet,$pktpieces);
1277  $txaccount = explode ("\n",$pktpieces[1]);
1278  array_pop($txaccount);
1279 
1280  # stuff each piece in the db
1281 
1282 
1283  $sql = "delete from ${Cu}txaccount
1284  where accountnumber='$Cn'";
1285  $sth = db_query($sql,$dbh);
1286 
1287  if (sizeof($txaccount)) {
1288  reset($txaccount);
1289  $sth = db_query("copy ${Cu}txaccount from stdin with null as ''",$dbh);
1290 
1291  while (list ($key, $line) = each ($txaccount)) {
1292  $line = preg_replace("/ ?\t ?/","\t",$line);
1293  $line = preg_replace("/ $/","",$line);
1294  $line = preg_replace("/\\0/"," ",$line);
1295  @pg_put_line($dbh, "$line\n");
1296  }
1297  @pg_put_line($dbh, "\\.\n");
1298  if (!@pg_end_copy($dbh)) {
1299  $errstat ++;
1300 # define_syslog_variables();
1301 # syslog(LOG_ERR,"FAILED copying txaccounts for $Cu:$Cn Statcode $statcode Error " . pg_last_error($dbh) . "\n");
1302  }
1303  }
1304 
1305  if($errstat == 0 ) {
1306  return array("$statcode", "$u", "$statdesc");
1307  } else {
1308  return array("$statcode", 1, "Error loading member data. Please contact Credit Union");
1309  }
1310  break;
1311  case 003:
1312  $statcode = '001';
1313  $statdesc = 'INVALID ACCOUNT NUMBER';
1314  case 200:
1315  case 001:
1316  case 999:
1317  return array("$statcode", 1, "$statdesc");
1318  }
1319 
1320  }
1321 }
1322 
1323 function fetch_XS($switchfrom, $Cu, $Cn, $fetcher) {
1324 #
1325 # set environment for programs.
1326 #
1327 global $dbh;
1328 $FETCHER = "$fetcher";
1329 global $Ml;
1330 
1331 $R3=(trim($Ml) == "" || $Ml=="no\@email.com" ? "NULL" : urlencode(trim($Ml)));
1332 
1333 #define_syslog_variables();
1334 #syslog(LOG_ERR,"fetch_XS($switchfrom) for $Cu:$Cn");
1335 #
1336 $dbh = db_pconnect();
1337 
1338 $delim = (strpos($FETCHER,'?')=== false ? '?' : '&');
1339 $rqx = "{$FETCHER}{$delim}member=$Cn&type=X&ref3=$R3&f=xxxxxxxxxxxxxxxxxxxxxxxxxxx";
1340 
1341 list ($open_fail, $pipe_err, $packet) = get_data($rqx);
1342 
1343 if (trim("$packet") == "") {
1344  if ($open_fail == 1) {
1345  trigger_error("$Cu:$Cn XA open failed", E_USER_ERROR);
1346  } else {
1347  trigger_error("$Cu:$Cn XA empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
1348  }
1349  return array(999, 1, "Unable to retrieve data");
1350  }
1351 
1352  if (preg_match("/<crossaccount>/si",$packet) &&
1353  !preg_match("/<\/crossaccount>/si",$packet)) {
1354  trigger_error("$Cu:$Cn CrossAccount short packet response(curl_err $curl_err)", E_USER_ERROR);
1355  $fp=@fopen("/tmp/packetnew.txt", "a");
1356  @fwrite($fp,"$Cu:$Cn CrossAccount short packet\n${rqx}\n");
1357  @fwrite($fp,"$packet\n");
1358  @fclose($fp);
1359  return array(999, 1, "Unable to retrieve data");
1360  } else {
1361 
1362 
1363  $pktpieces = array();
1364 
1365  $status = (preg_match("/<status>\n?(.*)\n?<\/status>/si",$packet,$pktpieces) ? $pktpieces[1] : "");
1366  list($mem, $statcode, $statdesc) = explode("\t",$status);
1367  if (trim($mem) != $Cn) {
1368  return array(999, 1, "Unable to retrieve data");
1369  }
1370 
1371  # check the return status to decide what to do here
1372 
1373  # 101 New Data -- process packet, update pktstamp
1374  # 200 System Unavailable, No New Data -- return immediately
1375  # 001 Invalid Account Number -- return immediately
1376  # 003 Closed Account -- change to 001 and return immediately
1377  # 999 Calling error or Invalid Parms -- return immediately
1378  #
1379  $errstat = 0;
1380  $u = date("U");
1381  switch ($statcode) {
1382  case 101:
1383  # Need to refresh the db data. Start parsing that packet...
1384 
1385  # find out what we have in the database...
1386 
1387  $sql = "select trim(accountnumber), trim(tomember),
1388  trim(accounttype), deposittype, description, misc1, id
1389  from culivetx where cu = '$Cu' and accountnumber = '$Cn'";
1390  if ($switchfrom == 'A') {
1391  $sql .= " and deposittype not in ('W','w')";
1392  }
1393 
1394  $sth = db_query($sql,$dbh);
1395  $db_keys = array();
1396  for ($row=0; $rec = db_fetch_row($sth, $row); $row++) {
1397  $db_keys["$rec[0]\t$rec[1]\t$rec[2]\t$rec[3]"] = "$rec[4]\t$rec[5]\t$rec[6]";
1398  }
1399 
1400  # make an array from the stuff in the packet
1401 
1402  preg_match("/<txaccount>\n?(.*)<\/txaccount>/si",$packet,$pktpieces);
1403  $txaccount = explode ("\n",$pktpieces[1]);
1404  array_pop($txaccount);
1405  reset ($txaccount);
1406  $tx_keys = array();
1407 
1408  while (list ($key, $line) = each ($txaccount)) {
1409  $line = preg_replace("/ ?\t ?/","\t",$line);
1410  $rec=array();
1411  $rec = explode("\t",$line);
1412  if (sizeof($rec) < 5) {
1413  // throw away partial rec
1414  continue;
1415  }
1416  $tx_keys["$rec[0]\t$rec[1]\t$rec[2]\t$rec[3]"] = "$rec[4]\t$rec[5]";
1417  }
1418 
1419  $inserts = array_diff(array_keys($tx_keys), array_keys($db_keys));
1420  $deletes = array_diff(array_keys($db_keys), array_keys($tx_keys));
1421  $updates = array_intersect(array_keys($tx_keys), array_keys($db_keys));
1422 
1423  $sql = "";
1424  reset ($updates);
1425  while (list ($key, $line) = each ($updates)) {
1426  $rec = explode("\t",$db_keys["$line"]);
1427  $trec = array_merge(explode("\t",$line),explode("\t",$tx_keys["$line"]));
1428 # don't update descriptions
1429 # If the member changes the description we want it to 'stick'.
1430 # so only update if the misc1 value changed on a cross-account
1431 # nothing to update on switch-accounts, if they ever come from the core
1432 
1433  if ($trec[3] != 'W' && $trec[3] != 'w' && $rec[1] != $trec[5]) {
1434  $sql .= "update culivetx set
1435  misc1 = '${trec[5]}' where id = ${rec[2]};\n";
1436  }
1437  }
1438 
1439  reset ($inserts);
1440  while (list ($key, $line) = each ($inserts)) {
1441  $rec = array_merge(explode("\t",$line),explode("\t",$tx_keys["$line"]));
1442 
1443 # switchfrom is A when switchaccts are maintained in admin. Only insert the
1444 # switchacct records coming from the core if that's where we expect to get 'em.
1445 
1446  if ($switchfrom != 'A' || ($rec[3] != 'W' && $rec[3] != 'w')) {
1447  $sql .= "insert into culivetx (cu, accountnumber, tomember,
1448  accounttype, deposittype, description, misc1) values (
1449  '$Cu','${rec[0]}','${rec[1]}', '${rec[2]}', '${rec[3]}',
1450  '" . prep_save($rec[4]) . "', '${rec[5]}');\n";
1451  }
1452  }
1453 
1454  reset ($deletes);
1455  while (list ($key, $line) = each ($deletes)) {
1456  $rec = explode("\t",$db_keys["$line"]);
1457  $sql .= "delete from culivetx where id = ${rec[2]};\n";
1458  }
1459 
1460  if ($sql > '') {
1461  $sth = db_query($sql,$dbh);
1462  if(!($sth)) {
1463  $err = pg_last_error();
1464  $errstat ++;
1465 # syslog(LOG_ERR,"FAILED $err setting txaccounts for $Cu:$Cn\n$sql");
1466  }
1467  }
1468  db_free_result($sth);
1469 
1470  if($errstat == 0 ) {
1471  return array("$statcode", "$u", "$statdesc");
1472  } else {
1473  return array("$statcode", 1, "Error loading member data. Please contact Credit Union");
1474  }
1475  break;
1476  case 003:
1477  $statcode = '001';
1478  $statdesc = 'INVALID ACCOUNT NUMBER';
1479  case 200:
1480  case 001:
1481  case 999:
1482  return array("$statcode", 1, "$statdesc");
1483  }
1484  }
1485 }
1486 function fetch_estatement($HB_ENV, $Command, $eStatementID = '') {
1487 
1488  $FETCHER = $GLOBALS['fetcher'];
1489 
1490  $estmt = array();
1491  try {
1492  # throw error 999 missing / invalid parameters if:
1493  # missing $HB_ENV['Cn'] or $HB_ENV['Cu']
1494  # Command not in (ETOC, ESTM)
1495  # Command == ESTM and empty(eStatementID)
1496 
1497  if (empty($HB_ENV['Cn']) || empty($HB_ENV['Cu']) ||
1498  ($Command == 'ESTM' && empty($eStatementID))) {
1499  throw new Exception('Missing Parameters', '999');
1500  }
1501 
1502  if ($Command != 'ESTM' && $Command != 'ETOC') {
1503  throw new Exception('Invalid Command', '999');
1504  }
1505 
1506  $delim = (strpos($FETCHER, '?') === false ? '?' : '&');
1507  $Ml = (trim($HB_ENV['Ml']) == "" || $HB_ENV['Ml'] == "no\@email.com" ? "NULL" : urlencode(trim($HB_ENV['Ml'])));
1508  $Cauth = (trim($HB_ENV['Cauth']) == "" ? $HB_ENV['Cn'] : $HB_ENV['Cauth']);
1509 
1510  # https://208.53.36.134/hculive/hculive2me.mp?member=555&type=ETOC&ref3=nobody@nowhere.com
1511  # https://208.53.36.134/hculive/hculive2me.mp?member=555&type=ESTM&ref1=2015-02&ref3=nobody@nowhere.com
1512  $rqx = "{$FETCHER}{$delim}member={$HB_ENV['Cn']}&type=$Command&f=xxxx";
1513  if ($Command == 'ESTM')
1514  $rqx .= "&ref1={$eStatementID}";
1515  $rqx .= "&ref3=" . urlencode($HB_ENV['Ml']) . "&tauth=$Cauth";
1516 
1517  list ($open_fail, $pipe_err, $packet) = get_data($rqx);
1518 
1519  if (trim("$packet") == "") {
1520  if ($open_fail == 1) {
1521  trigger_error("{$HB_ENV['Cu']}:{$HB_ENV['Cn']} Estmt open failed", E_USER_ERROR);
1522  } else {
1523  trigger_error("{$HB_ENV['Cu']}:{$HB_ENV['Cn']} Estmt empty packet response (pipe_err $pipe_err)", E_USER_ERROR);
1524  }
1525  throw new Exception('Unable to retrieve data', '999');
1526  }
1527 
1528 // if ($Command == 'ETOC') {
1529 // $fp = @fopen("/tmp/stmntpkt.txt", "a");
1530 // @fwrite($fp, "{$HB_ENV['Cu']}:{$HB_ENV['Cn']}\n${rqx}\n");
1531 // @fwrite($fp, "$packet\n");
1532 // @fwrite($fp, "++++++++++++++++++++++\n");
1533 // @fclose($fp);
1534 // }
1535  $pktpieces = array();
1536 
1537  # find something besides preg_match -- won't work with large data
1538  # do the preg_match on just the first 2k - <status> and <member> should
1539  # always be in the beginning of the packet
1540 
1541  $pktheader = substr($packet,0,2048);
1542  $status = (preg_match("/<status>\n?(.*)\n?<\/status>/si", $pktheader, $pktpieces) ? $pktpieces[1] : "");
1543  $member = (preg_match("/<member>\n?(.*)\n?<\/member>/si", $pktheader, $pktpieces) ? $pktpieces[1] : "");
1544  list($mem, $statcode, $statdesc) = explode("\t", $status);
1545  if ("$member" > "") {
1546  list($mem) = explode("\t", $member);
1547  }
1548  if (trim("$mem") != $HB_ENV['Cn']) {
1549  trigger_error("{$HB_ENV['Cu']} possibly out-of-sync ($mem:{$HB_ENV['Cn']})", E_USER_ERROR);
1550  throw new Exception('Unable to retrieve data', '999');
1551  }
1552 
1553  # check the return status to decide what to do here
1554  # 101 New Data -- process packet
1555  # 201 System Unavailable, New Data -- can't use stale for EStatement
1556  # -- change to 200 and return
1557  # 100 No New Data -- return immediately
1558  # 200 System Unavailable, No New Data -- return immediately
1559  # 202 System Unavailable, No Data -- return immediately
1560  # 001 Invalid Account Number -- return immediately
1561  # 002 Invalid Password -- change to 001 Invalid Account and return
1562  # 003 Closed Account -- change to 001 Invalid Account and return
1563  # 010 Member not enrolled for E-statements
1564  # 012 Statement not found
1565  # 999 Calling error or Invalid Parms -- return immediately
1566  #
1567  $errstat = 0;
1568  switch (sprintf('%03d',$statcode)) {
1569  case 101:
1570  # New data. Start parsing that packet...
1571  if ($Command == 'ETOC') {
1572  $stPtrn = '<EStatementTOC>';
1573  $ePtrn = '</EStatementTOC>';
1574  } elseif ($Command == 'ESTM') {
1575  $stPtrn = '<EStatement>';
1576  $ePtrn = '</EStatement>';
1577  } else {
1578  # probably redundant since we checked $Command above....
1579  throw new Exception('Invalid Command', '999');
1580  }
1581 
1582  if (stripos($packet, $stPtrn) === false ||
1583  stripos($packet, $ePtrn, stripos($packet, $stPtrn)) === false) {
1584  trigger_error("{$HB_ENV['Cu']}:{$HB_ENV['$Cn']} EStatement short packet response(pipe_err $pipe_err)", E_USER_ERROR);
1585  throw new Exception("$Command Unable to retrieve data", '999');
1586  }
1587 
1588  /*
1589  * This '101' is the only "successful" statcode for this call
1590  * return '000' instead
1591  * $estmt[status][status] = $statcode;
1592  */
1593  $estmt[status][status] = "000";
1594  $estmt[status][asofdate] = date("D M j Y H:i:s T");
1595  $estmt[status][reason] = $statdesc;
1596 
1597  if ($Command == 'ETOC') {
1598  $tblist = array("TOC");
1599  foreach ($tblist as $tbl) {
1600  # find a different way to do this, as large data will foul it up
1601  preg_match("/<$tbl>\n?(.*)<\/$tbl>/si", $packet, $pktpieces);
1602  $$tbl = explode("\n", $pktpieces[1]);
1603  array_pop($$tbl);
1604 
1605  if (sizeof($$tbl)) {
1606  $tblidx = 0;
1607 # format and return array ala new cu_data functions
1608  while (list ($key, $line) = each($$tbl)) {
1609  $line = preg_replace("/ ?\t ?/", "\t", $line);
1610  $line = preg_replace("/ $/", "", $line);
1611  $line = preg_replace("/\\0/", " ", $line);
1612  list($Member, $ID, $sType, $PeriodEnd, $Description, $Format) = explode("\t", $line);
1613 
1614  $estmt[$tbl][$tblidx]['Member'] = $Member;
1615  $estmt[$tbl][$tblidx]['ID'] = $ID;
1616  $estmt[$tbl][$tblidx]['Type'] = $sType;
1617  $estmt[$tbl][$tblidx]['PeriodEnd'] = $PeriodEnd;
1618  $estmt[$tbl][$tblidx]['Description'] = $Description;
1619  $estmt[$tbl][$tblidx]['Format'] = $Format;
1620  $tblidx++;
1621  }
1622  }
1623  }
1624  } else {
1625  # presumably ESTM - parse <member> into TOC and pop off <data>...</data>
1626  $start = stripos($packet,"<MEMBER>");
1627  $end = stripos($packet,"</MEMBER>");
1628  if($start === false || $end === false) {
1629  $estmt['TOC']=array();
1630  } else {
1631  $start += 8; # move past the <MEMBER> tag
1632  $line = substr($packet,$start,$end-$start);
1633  $line = trim($line);
1634  $line = preg_replace("/ ?\t ?/", "\t", $line);
1635  $line = preg_replace("/ $/", "", $line);
1636  $line = preg_replace("/\\0/", " ", $line);
1637  list($Member, $ID, $sType, $PeriodEnd, $Description, $Format) = explode("\t", $line);
1638 
1639  $estmt[TOC][0]['Member'] = $Member;
1640  $estmt[TOC][0]['ID'] = $ID;
1641  $estmt[TOC][0]['Type'] = $sType;
1642  $estmt[TOC][0]['PeriodEnd'] = $PeriodEnd;
1643  $estmt[TOC][0]['Description'] = $Description;
1644  $estmt[TOC][0]['Format'] = $Format;
1645 
1646  }
1647  $start = stripos($packet,"<DATA>");
1648  $end = strripos($packet,"</DATA>");
1649  if($start === false || $end === false) {
1650  $estmt['data']='';
1651  } else {
1652  $start += 6; # move past the <DATA> tag
1653  $estmt['data'] = substr($packet,$start,$end-$start);
1654  }
1655  }
1656  break;
1657 
1658  # 001 Invalid Account Number
1659  # 002 Invalid Password -- change to 001 Invalid Account
1660  # 003 Closed Account -- change to 001 Invalid Account
1661  case 002:
1662  case 003:
1663  case 001:
1664  throw new Exception('INVALID ACCOUNT NUMBER', '001');
1665  break;
1666 
1667  case 201:
1668  # 201 System Unavailable, New Data -- can't use stale for EStatement
1669  throw new Exception('Unusable Stale Data', $statcode);
1670  break;
1671 
1672  # 100 No New Data
1673  # 200 System Unavailable, No New Data
1674  # 202 System Unavailable, No Data
1675  # 010 Member not enrolled for E-statements
1676  # 012 Statement not found
1677  # 999 Calling error or Invalid Parms
1678  case 100:
1679  case 200:
1680  case 202:
1681  case 010:
1682  case 012:
1683  case 999:
1684  default:
1685  throw new Exception($statdesc, $statcode);
1686  break;
1687  }
1688  } catch (Exception $e) {
1689  $code = $e->getCode();
1690  $reason = $e->getMessage();
1691 
1692  $estmt[status][status] = sprintf('%03d',$code);
1693  $estmt[status][asofdate] = date("D M j Y H:i:s T");
1694  $estmt[status][reason] = $reason;
1695  }
1696  return $estmt;
1697 }
1698 
1699 /*
1700  * GetPktSegment
1701  *
1702  * Purpose: To retrieve a section of the packet being returned from the HomeCU Appliance (hculive)
1703  *
1704  * Parameters:
1705  *
1706  * pSegment string This is the tagname being sought ie 'accountbalance' to search for <accountbalance>...data returned ....</accountbalance> (it will be case insensitive)
1707  * pContent string This is the string that will be searched
1708  *
1709  * Returns:
1710  * string This will return the actual <data> from within the specified tags OR 'ERROR' if there was a problem
1711  *
1712  */
1713 function GetPktSegment($pSegment, $pContent) {
1714  $startTag = "<{$pSegment}>";
1715  $endTag = "</{$pSegment}>";
1716 
1717  $startTagPos = stripos($pContent, $startTag);
1718  $endTagPos = stripos($pContent, $endTag);
1719 
1720  if ($startTagPos !== FALSE && $endTagPos !== FALSE) {
1721  $startTagPos += strlen($startTag);
1722 
1723  $retData = substr($pContent, $startTagPos, ($endTagPos - $startTagPos));
1724  // ** trim should remove the newlines from start and end of data
1725  // * ONLY remove new lines from the beginning -- Be sure to NOT remove tabs
1726  $retData = ltrim($retData, "\n\r");
1727  } else {
1728  // FAIL
1729  $retData = 'ERROR';
1730  }
1731  return $retData;
1732 }
1733 
1734 include_once('cu_pass.i');