#!/usr/bin/perl
# 
# form_sakla.pl
# Web üzerinden POST metoduyla doldurulan başvuru formlarını işler.
# Tüm alanlar düzgünce doldurulduysa diskteki bir çağrışımlı listeye
# kaydeder. Doldurma hataları varsa uygun bir hata mesajı sayfası
# görüntüler.
#
$yetkili_adresi = "personel\@cgi.com.tr";  # pers. md. e-posta adresi
$mail_programi  = "/usr/lib/sendmail -t";         # e-posta gönderme pgm'i

$gelen_bilgi = <STDIN>; 
 
# gelen_bilgi içinde 
#    AD_SOYAD=Ali+Bilir&CINS=e&D_TARIHI=12%2F12%2F1970...
# gibi bir satır var. ALAN_ADI=DEGERI şeklinde çiftleri aralarında
# birer & işaretiyle ayrılıyorlar. 
#
# Önce "alan_adı = değer" çiftlerini ayıkla

@ciftler = split("&", $gelen_bilgi);
foreach $cift (@ciftler) {
  # 
  # $cift içinde  AD_SOYAD=Ali+Bilir gibi şeyler var
  ($alan_adi, $degeri) = split("=", $cift);

  # http protokolü gereği tüm boşluklar + işaretiyle değiştirilmiş olmalı
  # tüm + ları boşlukla değiştir.
  $degeri =~ tr/+/ /;

  # Noktalama işaretleri, varsa Türkçe karakterler falan %Hex kodları
  # şeklinde geldiği için onları tekrar karaktere çevirmek gerekli
  $degeri =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

  # Programın devamında bu değişkenlere erişebilmek için alan adlarını
  # anahtar; alan değerlerini de değer olarak bir çağrışımlı listeye doldur. 
  $form{$alan_adi} = $degeri;
}

# Artık hata kontrollerine başlayabiliriz
$ad_soyad = $form{'AD_SOYAD'};

# çift boşluklar varsa teke indir
$ad_soyad =~ s/  / /g;
if ( $ad_soyad eq "" or $adsoyad eq " ") {
  hata("Ad ve soyadınızı girmediniz!");
  exit;
}

$d_tarihi = $form{'D_TARIHI'};
if ( $d_tarihi !~ /\d\d\/\d\d\/\d\d\d\d/) { 	# gg/aa/yyyy kontrolu
  hata("Doğum tarihiniz doğru görünmüyor!");
  exit
}

$e_posta = $form{'E_POSTA'};
if ( $e_posta !~ /([\w-.]+\@[\w-.]+)/ ) {	# e-posta adresi kontrolu
  hata("e-posta adresiniz pek anlamlı görünmedi!");
  exit;
}

$cinsiyet = $form{'CINS'};
$egitim   = $form{'EGITIM'};
$son_okul = $form{'SON_OKUL'};
$meslek   = $form{'MESLEK'};
$gorev    = $form{'GOREV'};
$adres1   = $form{'ADRES1'};
$adres2   = $form{'ADRES2'};
$adres3   = $form{'ADRES3'};
$tel      = $form{'TEL'};

$ip_adresi= $ENV{'REMOTE_ADDR'};

($sn, $dk, $saat, $gun, $ay, $yil) = localtime(time); 
# localtime() fonksiyonu yıl değerini 1900 yılına göreceli olarak verir.
#                        ay değerini de Ocak ayı sıfırıncı ay olacak şekilde
#                        verir. Bu nedenle bu iki değeri düzeltmek lazım.

$yil = $yil +1900;	
$ay = $ay + 1;
$ay  = "0".$ay  if ($ay  < 10);  	  # 3. ay 03. ay olsun diye
$gun = "0".$gun if ($gun < 10);  	  # ayın 8'i 08'i olsun diye
$basvuru_tarihi = $gun."/".$ay."/".$yil;  # gg/aa/yyyy

$dk   = "0".$dk     if ($dk   < 10);
$saat = "0".$saat   if ($saat < 10);
$basvuru_saati  = $saat.":".$dk;          # SS:DD 

# Artık kaydı saklanmak üzere diskteki çağrışımlı listeye kaydedebiliriz.
# Elimizdeki form alanı değerlerini tek bir karakter dizisi içinde
# toplayıp çağrışımlı listeye yerleştirebiliriz. Ancak alan uzunlukları
# belirsiz olduğu için sonradan bu dizi içinden değerleri
# ayıklayıp çıkarmak olanaksız olacaktır. O nedenle form değerlerini
# birleştirirken aralarına özel bir karakteri ayraç olarak yerleştirebiliriz.
# Ayraç olarak kullanacağımız karakter, ziyaretçinin form alanlarında
# hiç kullanmadığı bir karakter olmalı.
#
# Ayraç olarak "|" kullanıp, alan değerlerini birleştirmek için 
#   $dbm_kaydi = $ad_soyad . "|" . $cinsiyet. "|". $d_tarihi . "|" . $e_posta;
#   $dbm_kaydi .= "|" . $egitim .    "|" . $son_okul . "|" + $meslek;
#   $dbm_kaydi .= "|" . $goerv   .   "|" . $adres1 .   "|" . $adres2;
#   $dbm_kaydi .= "|" . $adres3 .    "|" . $tel ;
#   $dbm_kaydi .= "|" . $ip_adresi . "|" . $yil;
#   $dbm_kaydi .= "|" . $ay .        "|" . $gun . "|" . $saat . "|" . $dk;
#
# gibi bir komutlar dizisi kullanabiliriz ama ziyaretçi; örneğin
# adres bilgileri arasında bir tane bile "|" kullandıysa tüm tasarım çöker.
# Bu nedenle ya kullanıcının girdiği bilgiler arasında, varsa, "|" 
# karakterlerini yok etmeliyiz; ya da daha iyisi pack komutuyla değerleri 
# bizim seçeceğimiz uzunluklarla paketlemeyi tercih etmeliyiz.
# Bu örnekte pack yöntemini kullanmayı tercih ediyorum.
#
#  $ad_soyad 	: A30      En fazla 30 karakter, gerekirse sonuna boşluk eklenir
#  $cinsiyet    : A1
#  $d_tarihi 	: A10
#  $e_posta	: A40
#  $egitim, $son_okul, $meslek : A32
#  $gorev, $adres1, $adres2, $adres3, $tel : A32
#  $ip_adresi	: A16
#  $basvuru_tarihi : A10 (gg/aa/yyyy)
#  $basvusu_saati  : A5  (ss:dd)
#
$dbm_kaydi = pack ("A30A1A10A40A32A32A32A32A32A32A32A32A16A10A5", $ad_soyad,
                   $cinsiyet, $d_tarihi, $e_posta, $egitim, $son_okul,
                   $meslek, $gorev, $adres1, $adres2, $adres3, $tel, 
                   $ip_adresi, $basvuru_tarihi, $basvuru_saati);

# Aynı anahtarın birden fazla kez kullanılması durumunda, önceden
# kaydedilmiş bir başvuruyu kaybederiz. O yüzden ürettiğimiz anahtarla
# önceden bir kayıt girilmemiş olduğuna emin olmamız lazım.

dbmopen(%BASVURULAR, "basvurular", 0644) or &hata("Veri tabanı açılamadı!");
$anahtar = $ip_adresi . $yil . $ay . $gun . $saat . $dk;
while ( $BASVURULAR{$anahtar} ) {  	# bu anahtarla yapılmış kayıt
   $dk++;					# bulunduğu sürece anahtarı arttır
   $anahtar = $ip_adresi . $yil . $ay . $gun . $saat . $dk;
}
$BASVURULAR{$anahtar} = $dbm_kaydi;
dbmclose(%BASVURULAR);
#
# Personel Müdürüne yeni bir başvuru geldiğine ilişkin bir mesaj gönder
#
# Personel Müdürü'nun e-posta adresi bu modülün başında $personel_muduru
# değişkeninde belirtilmeli
#
open (MAIL, "| $mail_programi");
print MAIL "From: CGI Insan Kaynaklari\n";
print MAIL "Subject: Yeni bir basvuru\n";
print MAIL "To: $yetkili_adresi\n\n";
print MAIL "\nYeni bir is basvurusu var!\n";
print MAIL "Belki bakmak istersiniz: ";
print MAIL "http://www.cgi.com.tr/i_kaynak/sifre_sor.html\n";
close MAIL;
#
&html_baslat;
print "<h2>Teşekkür ederiz sayın $ad_soyad.</h2>\n";
print "Başvuru formunuz veri tabanımıza eklenmiş ve ilgililere \n";
print "iletilmiştir.<p><hr>\n";
&html_bitir;
exit;

sub html_baslat {
   #
   # HTML sayfalarının başına konacak satırları gönderir

   print "Content-type: text/html\n\n";

   print <<_SON_;
   <HTML>
   <HEAD>
   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
   <meta http-equiv="Content-Type" content="text/html; charset=windows-1254">
   </HEAD>
   <BODY>
_SON_
}

sub html_bitir {
   #
   # HTML sayfalarının sonuna konacak satırları gönderir
   print <<_SON_;
   </BODY></HTML>
_SON_
}

sub hata {
   # 
   # Parametre olarak gelen hata mesajından oluşan web sayfası hazırlar
   
   $mesaj = shift;

   &html_baslat;

   print "<p>Formu hatalı doldurdunuz!<p>\n";
   print "<font color=\"#FF0000\"><b>$mesaj</b></font><p>\n";
   print "Lütfen geri dönüp hatanızı düzeltiniz.<p><hr>\n";
 
   &html_bitir;

   exit;

}