#!/usr/bin/php4
<?php // vim: set binary noeol et sw=4 sts=4:
+// Incluyo directorio del ejecutable como posible directorio de bibliotecas
+set_include_path(get_include_path().':'.dirname($argv[0]));
+
require_once 'T/general.php';
define('R_ERR', 0);
$gconf = $CONF['general'];
$mailbox = @$mconf['mailbox'];
-switch (@$mconf['protocol'] ? $mconf['protocol'] : 'mbox') {
+switch (@$mconf['protocol']) {
case 'mbox':
$mailbox = $mconf['server'];
break;
$mailbox = "{{$mconf['server']}$port/{$mconf['protocol']}$options}$mailbox";
break;
default:
- die("Error: el protocolo {$mconf['protocol']} no está soportado.\n");
+ logsdie("Error: el protocolo {$mconf['protocol']} no está soportado");
}
#$mbox = imap_open($mailbox, @$mconf['user'], @$mconf['pass']);
$claves = $gconf['claves'];
+// Errores tratando de conectar al mail
+$mbox_errcount = 0;
+
// Sin cesar.
while (1) {
// Reseteo intervalo
$intervalo = $gconf['intervalo'];
// Abro mailbox o chillo.
- if (!($mbox = imap_open($mailbox, @$mconf['user'], @$mconf['pass']))) {
- logs('No se pudo conectar al servidor ('.imap_last_error().')', L_ERR);
+ if (!($mbox = @imap_open($mailbox, @$mconf['user'], @$mconf['pass']))) {
+ if ($mbox_errcount * $intervalo > 120) { // 2 horas sin poder conectarse
+ logs('Hace 2 horas que no se puede conectar al servidor ('.imap_last_error().')', ERROR);
+ $mbox_errcount = 0;
+ } else {
+ logs('No se pudo conectar al servidor ('.imap_last_error().')', WARNING);
+ }
+ $mbox_errcount++;
sleep($intervalo);
+ continue;
}
- logs('Conectado como '.@$mconf['user']." a $mailbox", L_DBG);
+ $mbox_errcount = 0;
+ logs('Conectado como '.@$mconf['user']." a $mailbox", DEBUG);
if (imap_num_msg($mbox) and $hdr = imap_headerinfo($mbox, 1)) {
- logs("Nuevo mail '{$hdr->subject}' de {$hdr->fromaddress}");
+ logs(sprintf("Nuevo mail '%s' de %s", decode_header($hdr->subject), decode_header($hdr->subject)));
@list($padron, $ej, $ent, $codigo) = validar_cabecera($hdr);
if ($padron) {
- logs('Cabecera válida', L_DBG);
+ logs('Cabecera válida', DEBUG);
$intento = new T_Intento($padron, $ej, $ent);
if (!($err = $intento->validar_entrega($codigo, $claves))) {
logs('Entrega aceptada ('.$intento->to_line().')');
if (!($err = preparar_entrega($intento, $mbox, 1, $gconf['data_dir']))) {
- logs('Intento preparado', L_DBG);
+ logs('Intento preparado', DEBUG);
$res = $intento->hacer_entrega($hdr->fromaddress);
if (PEAR::isError($res)) {
- logs('Error al hacer entrega (' . $res->getMessage() . ')', L_ERR);
- enviar_respuesta(R_ERR, $hdr->fromaddress, "Error al preparar entrega:\nError en la base de datos.\n\nSe envió un mensaje al administrador avisando del problema.", $intento);
- enviar_respuesta(R_ERR, $mconf['mail_admin'], "Error al preparar entrega:\n" . $res->getMessage(), $intento);
+ logs('Error al hacer entrega (' . $res->getMessage() . ')', ERROR);
+ enviar_respuesta(R_ERR, $hdr->fromaddress, "Error interno al preparar entrega.\n\nSe envió un mensaje al administrador avisando del problema.", $intento);
+ enviar_respuesta(R_ERR, $mconf['admin'], "Error de la DB al preparar entrega:\n" . $res->getMessage(), $intento);
} else {
- logs('Intento encolado para compilar');
+ logs('Intento encolado para compilar', DEBUG);
enviar_respuesta(R_OK, $hdr->fromaddress, null, $intento);
guardar_mbox($mbox, 1, $hdr, @$mconf['mbox_bak']);
}
} else {
- logs("Error al preparar entrega ($err)", L_ERR);
- enviar_respuesta(R_ERR, $hdr->fromaddress, "Error al preparar entrega:\n$err", $intento);
- enviar_respuesta(R_ERR, $mconf['mail_admin'], "Error al preparar entrega:\n$err.\n\nSe envió un mensaje al administrador avisando del problema.", $intento);
+ logs("Error al preparar entrega ($err)", ERROR);
+ enviar_respuesta(R_ERR, $hdr->fromaddress, "Error interno al preparar entrega.\n\nSe envió un mensaje al administrador avisando del problema.", $intento);
+ enviar_respuesta(R_ERR, $mconf['admin'], "Error al preparar entrega:\n$err", $intento);
}
} else {
- logs("Entrega rechazada ($err)");
+ logs("Entrega rechazada ($err)", WARNING);
enviar_respuesta(R_ERR, $hdr->fromaddress, $err, $intento);
}
} else {
- logs('Entrega rechazada (subject inválido)');
+ logs('Entrega rechazada (subject inválido)', WARNING);
enviar_respuesta(R_ERR, $hdr->fromaddress, "Asunto (subject) inválido.\n\n"
. "Recuerde que el formato del asunto es estricto:\n"
. "[padrón] [ejercicio].[entrega] [código]\n\n"
. "Donde [padrón] es su número de padrón, [ejercicio] es el número de\n"
- . "ejercicio (1 a 4), [entrega] el número de entrega (1 o 2) y [código]\n"
- . "es el código verificador que le fue asignado por la cátedra.\n"
+ . "ejercicio (1 a 4), [entrega] el número de entrega (1 entrega, 2 reentrega)\n"
+ . "y [código] es el código verificador que le fue asignado por la cátedra.\n"
);
}
imap_delete($mbox, 1);
- logs('Mail borrado');
+ logs('Mail borrado', DEBUG);
imap_expunge($mbox);
- logs('Mensajes purgandos', L_DBG);
+ logs('Mensajes purgandos', DEBUG);
$intervalo = 0; // Que tome el próximo mail enseguida.
} else {
- logs('No hay mail nuevo', L_DBG);
+ logs('No hay mail nuevo', DEBUG);
}
- logs('Cerrando conexión', L_DBG);
+ logs('Cerrando conexión', DEBUG);
imap_close($mbox);
sleep($intervalo);
}
function enviar_respuesta($tipo, $to, $mensaje = '', $intento = null) {
global $mconf;
- $subject = $mconf['prefijo'] . ' Entrega ';
+ $subject = '[' . $mconf['prefijo'] . '] Entrega ';
if ($tipo == R_OK) $estado = 'ACEPTADA';
else $estado = 'RECHAZADA';
$subject .= $estado;
$body .= "Estado: $estado\n";
if ($mensaje) $body .= "\n$mensaje\n";
if ($intento) $body .= "\n" . $intento->__toString() . "\n";
- logs("Envío de mail '$subject' a '$to'\n$body\n", L_DBG);
+ logs("Envío de mail '$subject' a '$to'\n$body\n", DEBUG);
$headers = <<<EOT
From: {$mconf['from']}
-Reply-To: {$mconf['mail_admin']}
-X-Mailer: {$mconf['mailer']}
+Reply-To: {$mconf['admin']}
+Return-Path: {$mconf['admin']}
+X-Mailer: $NAME $VERSION
X-Priority: 5
EOT;
- mail($to, $subject, $body, $headers);
+ mail(decode_header($to), $subject, $body, $headers);
return true;
}
*/
function validar_cabecera($hdr) {
// Subject: padron nro_ej nro_entrega clave_alumno
- if (preg_match('/^\s*(\d{5})\s+([1-4])\.([12])\s+(.*)$/', $hdr->subject, $m)) {
+ $subject = decode_header($hdr->subject);
+ if (preg_match('/^\s*(\d{5})\s+([1-4])\.([12])\s+(.*)$/', $subject, $m)) {
return array_slice($m, 1, 5);
}
return false;
}
function preparar_entrega($intento, $mbox, $msgid, $dir) {
- logs('Acá debería verificar el cuerpo del mensaje', L_DBG);
+ logs('Acá debería verificar el cuerpo del mensaje', DEBUG);
+ $path = "$dir/" . $intento->path('intentos');
$mail = imap_fetchstructure($mbox, $msgid);
+ if (!mkdir_p($path)) return 'No se pudo crear el directorio';
foreach ($mail->parts as $id => $part) {
$fname = part_filename($part);
if ($fname) {
- logs("Escribiendo archivo '$fname' [enc={$part->encoding}]", L_DBG);
+ logs("Escribiendo archivo '$fname' [enc={$part->encoding}]", DEBUG);
$body = imap_fetchbody($mbox, $msgid, $id + 1);
- $path = "$dir/" . $intento->path();
- if (!mkdir_p($path)) return 'No se pudo crear el directorio';
if (!file_put_contents("$path/$fname", decode_body($body, $part->encoding))) return "Error al guardar el archivo $fname";
}
//if (part_is_source($part) $has_sources = true;
case ENCQUOTEDPRINTABLE: return imap_qprint($body);
case ENCOTHER: return $body;
}
- logs('Encoding no reconocido.', L_ERR);
+ logs('Encoding no reconocido.', WARNING);
return $body;
}
return str_replace("\r\n", "\n", $str);
}
+function decode_header($str) {
+ $elems = imap_mime_header_decode($str);
+ $result = '';
+ foreach ($elems as $elem) {
+ $result .= $elem->text;
+ }
+ return $result;
+}
+
?>
\ No newline at end of file