#!/usr/bin/php4 fromaddress . "\n"; #var_dump(imap_headerinfo($mbox, $i, 80, 80)); } */ $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']))) { 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; } $mbox_errcount = 0; logs('Conectado como '.@$mconf['user']." a $mailbox", DEBUG); if (imap_num_msg($mbox) and $hdr = imap_headerinfo($mbox, 1)) { logs(sprintf("Nuevo mail '%s' de %s", decode_header($hdr->subject), decode_header($hdr->from))); @list($padron, $ej, $ent, $codigo) = validar_cabecera($hdr); if ($padron) { 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', DEBUG); $res = $intento->hacer_entrega($hdr->fromaddress); if (PEAR::isError($res)) { 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', DEBUG); enviar_respuesta(R_OK, $hdr->fromaddress, null, $intento); guardar_mbox($mbox, 1, $hdr, @$mconf['mbox_bak']); } } else { 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)", WARNING); enviar_respuesta(R_ERR, $hdr->fromaddress, $err, $intento); } } else { 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 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', DEBUG); imap_expunge($mbox); logs('Mensajes purgandos', DEBUG); $intervalo = 0; // Que tome el próximo mail enseguida. } else { logs('No hay mail nuevo', DEBUG); } logs('Cerrando conexión', DEBUG); imap_close($mbox); sleep($intervalo); } /* do { $mail = imap_fetchstructure($mbox, 1); var_dump($mail);exit; for ($mail->parts as $id => $part) { if ($part->type == TYPEAPPLICATION) { } } } while (!validate_header($header)); file_put_contents('attach', fetchbody_decoded($mbox, 4, 2)) or die("no se puede escribir archivo de salida\n"); imap_close($mbox); */ function enviar_respuesta($tipo, $to, $mensaje = '', $intento = null) { global $mconf; $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", DEBUG); $headers = <<subject); if (preg_match('/^\s*(\d{5})\s+(\d)\.(\d)\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', 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}]", DEBUG); $body = decode_body(imap_fetchbody($mbox, $msgid, $id + 1), $part->encoding); if (!$body) return "El archivo '$fname' está vacío"; if (!file_put_contents("$path/$fname", $body)) return "Error al guardar el archivo $fname"; } //if (part_is_source($part) $has_sources = true; //elseif (part_mime_type($part) == 'application/zip') $has_sources = true; } return ''; } function part_is_source($part) { if (part_mime_type($part) == 'application/zip') return true; /* if (part_mime_type($part) == 'application/octet-stream') { $extension = (part_filename($part)); if (, { } } */ return false; } function part_filename($part) { if (!@$part->dparameters or !is_array($part->dparameters)) { return ''; } foreach ($part->dparameters as $param) { if ($param->attribute == 'FILENAME') { return $param->value; } } return ''; } function part_mime_type($part) { switch ($part->type) { case TYPETEXT: return 'text/'.strtolower($part->subtype); case TYPEMULTIPART: return 'multipart/'.strtolower($part->subtype); case TYPEMESSAGE: return 'message/'.strtolower($part->subtype); case TYPEAPPLICATION: return 'application/'.strtolower($part->subtype); case TYPEAUDIO: return 'audio/'.strtolower($part->subtype); case TYPEIMAGE: return 'image/'.strtolower($part->subtype); case TYPEVIDEO: return 'video/'.strtolower($part->subtype); case TYPEOTHER: default: return 'other/'.strtolower($part->subtype); } } function decode_body($body, $encoding) { switch ($encoding) { case ENC7BIT: return fix_eol($body); case ENC8BIT: return fix_eol($body); //imap_8bit($body); case ENCBINARY: return imap_binary($body); case ENCBASE64: return imap_base64($body); case ENCQUOTEDPRINTABLE: return imap_qprint($body); case ENCOTHER: return $body; } logs('Encoding no reconocido.', WARNING); return $body; } function mkdir_p($target) { if (is_dir($target) or empty($target)) return 1; if (file_exists($target) and !is_dir($target)) return 0; if (mkdir_p(substr($target,0,strrpos($target,'/')))) return mkdir($target); return 0; } function guardar_mbox($mbox, $msgid, $hdr, $mbox_fname) { if ($mbox_fname) { $fo = @fopen($mbox_fname, 'a'); if (!$fo) { logserr("No se pudo abrir mbox '$mbox_fname'"); return false; } fputs($fo, sprintf("From %s@%s %s\n", $hdr->from[0]->mailbox, $hdr->from[0]->host, date('D M j H:i:s Y'))); fputs($fo, fix_eol(imap_fetchheader($mbox, $msgid, FT_PREFETCHTEXT))); fputs("\n"); fputs($fo, fix_eol(imap_body($mbox, $msgid))); fclose($fo); } return true; } function fix_eol($str) { 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; } ?>