SuSE 9.2 снаружи и изнутри Обзор дистрибутива SuSE Professional 9.2 Алексей Барабанов rpm –root /mnt –dbpath /var/lib/rpm -U –-persent --nosignature {а вдруг мантейнеры «левые» попадутся} --force {систему ставить, затирая все конфликтные файлы} --nodeps {авторы linuxrc вообще не доверяют никому из suse/people} --ignoresize {игнорировать, так все, «до кучи»!} /var/adm/YaST/InstSrcManager/IS_CACHE_0x00000001/MEDIA/suse/...*.rpm # ls -l /mnt/suse/i586 | perl -ni -e '@s=split(/\d\d\:\d\d); @q=split(/-(\d)*\./,$s[1]); print $q[0], "\n"' | sort -u >i586.list # cat x86_64.list | grep -v 32bit >x86_64only.list # diff x86_64only.list i586.list > x86_64-i586.list # rpm --requires -qp OpenOffice_org-tr-1.1.3-16.i586.rpm | grep -v ^rpmlib # rpm --requires -qp OpenOffice_org-it-1.1.3-16.i586.rpm | grep -v ^rpmlib # rpm --requires -qp OpenOffice_org-en-help-1.1.3-16.i586.rpm | grep -v ^rpmlib # rpm --provides -qp OpenOffice_org-tr-1.1.3-16.i586.rpm Прокси-сервер oops: первые впечатления Сергей Супрунов # portupgrade oops group ourlan { networks 192.168.0.0/24; badports [0:79],110,138,139,513,[6000:6010] ; bandwidth 16k; per_ip_bw 4k; http { allow dstdomain * ; } } group ouradmin { networks 192.168.0.25/32; badports [0:79],110,138,139,513,[6000:6010] ; http { allow dstdomain * ; } } http { deny dstdomain ru ; allow dstdomain narod.ru ; } deny dstdomain include:baddomains.lst ; Регулярное_выражение [Действие] static internal_doc_t redir_internals[] = { {"nospam1x1", "image/gif", sizeof(nospam1x1gif), 3600, nospam1x1gif}, {"nospam468x60", "image/gif", sizeof(nospam468x60gif), 3600, nospam468x60gif}, {"nospam_close", "text/html", sizeof(nospam_close)-1, 3600, nospam_close}, {"nospam_empty", "text/html", sizeof(nospam_empty)-1, 3600, nospam_empty}, {"nospam_js", "application/x-javascript", sizeof(nospam_js)-1, 3600, nospam_js}, {""} }; # Если запрос соответствует нескольким правилам, # применяется первое (на microsoft.com мы попасть не сможем) .*soft.* .*micro.* allow # Запрещаем доступ на все домены третьего уровня, имя # которых содержит строку amsand, за исключением amsand.narod.ru http://.*amsand.narod.ru allow http://.*amsand\..+.ru # Проверка работы «внутренних» перенаправлений http://.*/.*test1x1.* internal:nospam1x1 http://.*/.*test468x60.* internal:nospam468x60 http://.*/.*test_close.* internal:nospam_close http://.*/.*test_empty.* internal:nospam_empty http://.*/.*test_js.* internal:nospam_js # Любой запрос, содержащий в имени ресурса упоминание # Альтависты, будет перенаправлен на стартовую страницу # Яндекса (кстати, вы даже не сможете выполнить поиск в том же # Яндексе по запросу «altavista.com», поскольку в результате # будет отправлен запрос # «http://www.yandex.ru/yandsearch?rpt=rad&text=altavista.com», # который так же будет соответствовать данному правилу) altavista.com http://yandex.ru # Перенаправляет на ya.ru все запросы, имеющие цифры в части # имени, соответвтующей домену 3-го уровня, например: # http://www.max2.dom.ru/ # http://www3.w3c.org/index.html http://.*[[:digit:]]+.*\.[[:alnum:]]+\.[a-z]{2,4}/.* ya.ru # В ответ на любой запрос, завершающийся символами shtml, # будет возвращена пустая страница (содержит только тег
) shtml$ internal:nospam_empty # Будет запрещен доступ к любому ресурсу, адрес которого # заканчивается именем файла page с одним из перечисленных # расширений http://.*/page.(html|htm|phtml)$ # Запрещаем доступ ко всем сайтам в зоне com, доменное имя # которых имеет длину 7-9 символов (3-5 плюс ".com") и для # которых не указано имя конкретного файла или папки, # например: http://qwer.com/ http://.{3,5}\.com/?$ # Запрос к Яндексу будет перенаправлен на «аскетичный поиск», # что можно использовать для снижения трафика, создаваемого # пользователями http://(www.)?yandex\.ru/?$ http://ya.ru # Блокируем все запросы со словом porno, в том числе # и формируемые поисковиками porno # Вместо любых изображений возвращаем «пустой» рисунок (gif|jpg|jpe|jpeg)$ internal:nospam1x1 # ipfw add 1000 fwd localhost,3128 ip from 192.168.0.0/24 to any dst-port 80 # oops –c /usr/local/etc/oops/oops.cfg –z # oopsctl start # oopsctl stat # oopsctl stop # oopsctl reconfigure # oopsctl help #!/usr/local/bin/python import sys try: logfile = sys.argv[1] except: logfile = 'access.log' logs = open(logfile, 'r').readlines() traffic = {} counter = {} for log in logs: splitted = log.split() ip = splitted[2] if traffic.has_key(ip): traffic[ip] = traffic[ip] + int(splitted[4]) counter[ip] = counter[ip] + 1 else: traffic[ip] = int(splitted[4]) counter[ip] = 1 keys = traffic.keys() keys.sort() for ip in keys: print '%s | %7d | %15d (%7.2f) |' % (ip.ljust(18), counter[ip], traffic[ip], traffic[ip] / 1048576.0) # ./getstat Программное управление файловой системой с помощью VBScript Иван Коробко Set fso=WScript.CreateObject(“Scripting.FileSystemObject”) path="…" Set fso=WScript.CreateObject("Scripting.FileSystemObject") Set oFolders=fso.GetFolder(path) path="…" Set fso=WScript.CreateObject("Scripting.FileSystemObject") If fso.FolderExists(path) then Set oFolders=fso.GetFolder(path) … Else MsgBox "Folder " + path + " Not Exists" End If path="C:\Windows" Temp="" Set fso=WScript.CreateObject("Scripting.FileSystemObject") If fso.FolderExists(path) then Set oFolders=fso.GetFolder(path) Set OSubFolders=oFolders.Subfolders For each i In OSubFolders Temp=Temp+i.Name+chr(13) Next Else Temp= "Folder " + path + " Not Exists" End If MsgBox Temp Path="C:\RootFolder" i=0 Dim Array() 'Объявление динамического массива Set fso=Wscript.CreateObject("Scripting.FileSystemObject") Set oFolder=fso.GetFolder(path) Set oFolders=oFolder.SubFolders ' Изменение размера динамического массива Redim Preserve Array(oFolders.count) For Each of In oFolders Array(i)=cstr(oF.Path) ' Запись элементов в массив i=i+1 Next 'Чтение элементов массива: Temp="" For i=Lbound(Array) to Ubound(Array) Temp=Temp+cstr(Array(i))+chr(13)+chr(10) Next MsgBox Temp ……….. ' Вызов функции RecFolder в теле сценария RecFolder index, path ……….. Function Recfolder (idx, path) ……….. ……….. ……….. Call Recfolder (idx+1, path) ……….. End Function dim path_array() path="c:\windows" i=0 temp="" detect(q) MsgBox "oFolders_count: "+cstr(detect(q)) For j=0 to cstr(ubound(path_array)-1) path=cstr(path_array(j)) temp=temp+cstr(j)+": "+path+chr(13) Next MsgBox temp Function detect(c) i=0 Set fso=Wscript.CreateObject("Scripting.FileSystemObject") Set oFolder=fso.GetFolder(path) Set oFolders=oFolder.SubFolders Redim Preserve path_array(oFolders.count) detect=oFolders.count For Each oF In oFolders path_array(i)=path+"\"+cstr(oF.Name) i=i+1 Next End Function path="c:\windows" Set WSHShell = WScript.CreateObject("WScript.Shell") Set fso=createobject("Scripting.filesystemobject") Set oFolder=fso.GetFolder(path) Set oFiles=oFolder.files MsgBox "oFiles_count: "+cstr(oFiles.count) temp="" For each oFile in oFiles temp=temp & oFile.name & chr(13) Next MsgBox text path="c:\boot.ini" Set WSHShell = WScript.CreateObject("WScript.Shell") Set fso=createobject("Scripting.filesystemobject") Set oFile=fso.GetFile(path) MsgBox oFile.Name&": "& oFile.Attributes path="c:\boot.ini" Set WSHShell = WScript.CreateObject("WScript.Shell") Set fso=createobject("Scripting.filesystemobject") if fso.FileExists(path) then Set oFile=fso.GetFile(path) Attr_value=oFile.Attributes temp=A_detect() MsgBox oFile.Name&": "& temp else MggBox "Файл " &path& " не существует" end if function A_detect() t="" if (Attr_value and &H01)> 0 Then t=t+"Только для чтения; " if (Attr_value and &H02)> 0 Then t=t+"Скрытый; " if (Attr_value and &H04)> 0 Then t=t+"Системный; " if (Attr_value and &H20)> 0 Then t=t+"Архивный; " if (Attr_value and &H800)> 0 Then t=t+"Сжатый; " A_detect=t end function path="c:\readme.txt" Set WSHShell = WScript.CreateObject("WScript.Shell") Set fso=createobject("Scripting.filesystemobject") Set oFile=fso.GetFile(path) MsgBox oFile.Name&": "& oFile.Attributes oFile.Attributes=39 MsgBox oFile.Name&": "& oFile.Attributes path="C:\TempFolder" Temp="" Set fso=WScript.CreateObject("Scripting.FileSystemObject") If fso.FolderExists(path)=0 then fso.CreateFolder(path) Temp= "Folder " + path + " Created " Else Temp= "Folder " + path + " Already Exists" End If MsgBox Temp path="C:\TempFolder" Temp="" Set fso=WScript.CreateObject("Scripting.FileSystemObject") If fso.FolderExists(path)<>0 then fso.DeleteFolder(path) Temp= "Folder " + path + " Deleted" Else Temp= "Folder " + path + " is Absent " End If MsgBox Temp OldPath="C:\TempFolderOld" NewPath="C:\TempFolderNew" Set fso=WScript.CreateObject("Scripting.FileSystemObject") fso.CopyFolder OldPath, NewPath, 1 MsgBox "Папка " + OldPath + " скопирована в " + NewPath OldPath="C:\TempFolderOld" NewPath="C:\TempFolderNew" Set fso=WScript.CreateObject("Scripting.FileSystemObject") fso.MoveFolder OldPath, NewPath, 1 MsgBox "Папка " + OldPath + " перемещена в " + NewPath PathOld="C:\Folder\FileNameOld" PathNew="C:\Folder\FileNameNew" Set fso=WScript.CreateObject("Scripting.FileSystemObject") If (fso.FileExistes(PathOld)) Then Set oFile=fso.GetFile(PathOld) oFile.**** PathNew End If PathOld="C:\Folder\1.txt" PathNew="C:\Folder\2.txt" Set fso=WScript.CreateObject("Scripting.FileSystemObject") If (fso.FileExistes(PathOld)) Then Set oFile=fso.GetFile(PathOld) oFile.Copy PathNew End If PathDel="C:\Folder\1.txt" Set fso=WScript.CreateObject("Scripting.FileSystemObject") If (fso.FileExistes(PathDel)) Then Set oFile=fso.GetFile(PathDel) oFile.Delete End If regsvr32.exe /s ADsSequrity.dll Set sec = CreateObject("ADsSecurity") Set sd = sec.GetSecurityDescriptor("FILE://c:\folder") Set dacl = sd.DiscretionaryAcl For Each ace In dacl Wscript.Echo cstr(ace.Trustee)+" " + cstr(ace.AccessMask) + " " + cstr(ace.AceType) + chr(13)+chr(10) Next Wscript.Echo dacl.AceCount Set sec = CreateObject("ADsSecurity") Set sd = sec.GetSecurityDescriptor("FILE://c:\Folder") Set dacl = sd.DiscretionaryAcl Set ace = CreateObject("AccessControlEntry") ace.Trustee = "Domain\Administrator" ace.AccessMask = &h20000000 ace.AceType = &h0 ace.AceFlags = &h3 dacl.AddAce ace1 sd.DiscretionaryAcl = dacl sec.SetSecurityDescriptor sd set dacl=nothing set sec=nothing Set sec = CreateObject("ADsSecurity") Set sd = sec.GetSecurityDescriptor("FILE://c:\Folder") Set dacl = sd.DiscretionaryAcl Set ace1 = CreateObject("AccessControlEntry") ace1.Trustee = "msk\corwin" ace1.AccessMask = &h20000000 ace1.AceType = &h0 ace1.AceFlags = &h3 dacl.AddAce ace1 for i=0 to 10000000 next Set ace2 = CreateObject("AccessControlEntry") ace2.Trustee = "msk\sneretin" ace2.AccessMask = &h20000000 ace2.AceType = &h0 ace2.AceFlags = &h3 dacl.AddAce ace2 sd.DiscretionaryAcl = dacl sec.SetSecurityDescriptor sd set dacl=nothing set sec=nothing Set sec = CreateObject("ADsSecurity") Set sd = sec.GetSecurityDescriptor("FILE://c:\2") Set dacl = sd.DiscretionaryAcl For Each ace In dacl If (ace.Trustee="EveryOne") dacl.RemoveAce ace end if Next sd.DiscretionaryAcl = dacl set dacl=nothing set sec=nothing HOTSPOT – это просто! Андрей Платонов bd.asp 1 2 3 tbLogs 4 5 6 ------ Таблица tbLogs -------

7 8 <% set MyConnection = Server.CreateObject("ADODB.Connection") 9 10 MyConnection.Open "Driver={Microsoft Access Driver (*.mdb)};" & _ 11 "DBQ=WinRadius.mdb;" & _ 12 "DefaultDir=C:\(radius)\WinRadius;" & _ 13 "Uid=Admin;Pwd=;" 14 15 set rsLogs=MyConnection.Execute ("SELECT * FROM tbLogs") 16 17 response.write "" 18 response.write "" 21 22 do while not rsLogs.EOF 23 response. write "" 24 response.write "" 26 response. write "" 27 rsLogs.movenext 28 loop 29 30 response.write "
happenusernameduration" 19 response.write "inputoutput " 20 response.write "fee
" & rsLogs("happen") & "" & rsLogs ("username") & "" & rsLogs("duration") 25 response.write "" & rsLogs ("input") & "" & rsLogs ("output") & "" & rsLogs ("fee") & "
" 31 rsLogs.Close 32 rsLogs = null %> 33 34 bd2.asp 1 2 3 tbLogs 4 5 6 7 <% 8 Dim sSearchLogin 9 Dim sSearchPassword 10 11 sSearchLogin = Request.Form("login") 12 sSearchPassword = Request.Form("password") 13 14 if sSearchLogin = "" or sSearchPassword = "" Then 15 16 response.write "
 
" 17 response.write "

Mega Wi-Fi network billing system

 



" 18 response.write "--- Сервер статистики --- " 19 response.write "

Логин: " 20 response.write "
Пароль: " 21 response.write "
" 22 Response.End 23 24 End If 25 %> 26 <% 27 set Connection = Server.CreateObject("ADODB.Connection") 28 29 Connection.Open "Driver={Microsoft Access Driver (*.mdb)};" & _ 30 "DBQ=WinRadius.mdb;" & _ 31 "DefaultDir=C:\(radius)\WinRadius;" & _ 32 "Uid=Admin;Pwd=;" 33 34 strSQL="SELECT password FROM tbUsers WHERE username = " & "'"& sSearchLogin &"'" 35 36 set rsUsers=Connection.Execute (strSQL) 37 pas="" 38 do while not rsUsers.EOF 39 pas=rsUsers("password") 40 rsUsers.movenext 41 loop 42 43 If pas = sSearchPassword then 44 45 strSQL1="SELECT * FROM tbLogs WHERE username = " & "'"& sSearchLogin &"'" 46 set rsLogs1=Connection.Execute (strSQL1) 47 48 response.write "

Личная статистика пользователя " & sSearchLogin & "



" 49 response.write "" 50 response.write "" 53 do while not rsLogs1.EOF 54 input=input+rsLogs1("input") 55 output=output+rsLogs1("output") 56 duration=duration+rsLogs1("duration") 57 fee=fee+rsLogs1("fee") 58 59 response. write "" 60 response.write "" 63 rsLogs1.movenext 64 response. write "" 65 loop 66 67 response.write "
начало сессииusernameпродолжительность [мин]" 51 response.write "input [Mb]output[Mb] " 52 response.write "стоимость [$]
" & rsLogs1("happen") & " " & rsLogs1("username") & "" & round((rsLogs1("duration")/60),2) 61 response.write "" & Round(((rsLogs1 ("input"))/1024/1024) ,3) & "" & Round(((rsLogs1 ("output"))/1024/1024) ,3) 62 response.write "" & ((rsLogs1("fee")) /100) & "
" 68 response.write "


__________________________________
" 69 response.write "суммарный исходящий трафик: " & round((output/1024/1024),3) & " Mb

" 70 response.write "суммарный входящий трафик: " & round((input/1024/1024),3) & " Mb

" 71 response.write "суммарная продолжительность сессий: " & round((duration/60/60),2) & " часов

" 72 response.write "расход за отчётный период: " & (fee/100) & " $
__________________________________________

" 73 rsLogs1.Close 74 rsLogs1 = null 75 response.end 76 77 End If 78 79 response.write "Неправильное или несуществующее имя пользователя или пароль!" 80 %> 81 82 83 Как защищают программное обеспечение Крис Касперски if (IsHaspPresent() != OK) exit(); FILE *f = 0; main(){if (!f) f = fopen(,,)…} Сетевой полицейский Сергей Яремчук http://Green _address:81/ 0.0.0.0 www. Site_1.com 0.0.0.0 www. Site_2.org # tar vxzf addons-2.2-CLI-b2.tar.gz -C / # cd /addons # ./setup –u или ./setup –i Защита сетевых сервисов с помощью stunnel Часть 2 Андрей Бешков swat 901/tcp # Samba web configuration tool swat stream tcp nowait/400 root /usr/local/sbin/swat swat [swats] accept = 902 connect = 901 [swats] accept = 901 exec = /usr/local/bin/swat execargs = swat # tar zxvf stunnel-4.05.tar.gz # cd stunnel-4.05 # ./configure # make all # make install # adduser stunnel # id stunnel # mkdir /var/tmp/stunnel # mkdir /usr/local/etc/stunnel/certs/ # chown stunnel:stunnel /var/tmp/stunnel/usr/local/etc/stunnel/certs/ # chmod –R 700 /var/tmp/stunnel/usr/local/etc/stunnel/certs/ cert = /usr/local/etc/stunnel/certs/mailserver.cert key = /usr/local/etc/stunnel/certs/mailserver.key chroot = /var/tmp/stunnel/ pid = /stunnel.pid setuid = stunnel setgid = stunnel debug = 7 output = /var/log/stunnel.log client = yes [mysqls] accept = 127.0.0.1:3307 connect = 10.10.21.29:3307 cert = /usr/local/etc/stunnel/certs/mailserver.cert key = /usr/local/etc/stunnel/certs/mailserver.key chroot = /var/tmp/stunnel pid = /stunnel.pid setuid = stunnel setgid = stunnel debug = 7 output = /var/log/stunnel.log [mysqls] accept = 10.10.21.29:3307 connect = 3306 # stunnel /usr/local/etc/stunnel/mysql-client.conf # stunnel /usr/local/etc/stunnel/mysql-server.conf netstat –na | grep LISTEN # mysql -h 127.0.0.1 -P 3307 -u root -p # mysql Все в одном, или Hogwash как пример Gateway-IDS Сергей Яремчук ebtables -A FORWARD -p IPv4 --ip-src 192.168.1.4 -s ! 00:11:22:33:44:55 -j DROP iptables -A FORWARD -s 192.168.1.4 -m mac --mac-source ! :11:22:33:44:55 -j DROP echo "0" > /proc/sys/net/ipv4/ip_forward # tar xzvf devel-0.5-latest.tar.gz # cd devel-0.5 # ./configure # make # cp ./hogwash /usr/sbin/ # mkdir /etc/hogwash # cp -R rules /etc/hogwash/ # cp ./stock.config /etc/hogwash # mkdir /var/log/hogwash Name=Hogwash Sensor ID=1001 Threads=1 # количество потоков, предназначенных для обработки пакетов, # как правило, один поток на один интерфейс (т.е. Threads=1), # при работе на многопроцессорных системах или в кластерах # значение можно увеличить. AlertHeader=%ac %m/%d/%y %h:%min:%s %sip:%sp->%dip:%dp # эта необязательная секция указывает формат заголовков # предупреждений, можно изменить на любой другой, # необходимые данные приведены в таблице 1. Type=INTERFACE TYPE # и две необязательных опции # пока поддерживается только этот протокол, поэтому можно # его опустить Proto= Ethernet Role = INTERFACE ROLE Type=linux_raw Proto=Ethernet Role=Normal 10.34.10.0/16 0.0.0.0/0 23.3.14.10 10.2.10.3-10.2.10.6 23.3.14.111 192.168.100.0/24 WebServers DNSServers FTPServers 10.14.10.1 response=alert console # вывод сообщения на консоль response=alert file(/var/log/hogwash/hogwash.alert) # запись предупреждающего сообщения в указанный файл response=dump packet(/var/log/hogwash/packet.log) # захват пакета, который сгенерировал сообщение и запись в файл response=alert console response=alert file(/var/log/hogwash/hogwash.alert) response=dump packet(/var/log/hogwash/packet.log) response=drop # отбрасывание пакета (игнорируется при работе в IDS-режиме) response=alert console response=alert file(/var/log/hogwash/hogwash.alert) response=alert syslog(facility=LOG_AUTH, priority=LOG_INFO, options=LOG_NDELAY|LOG_PID) response=alert socket(www.logger.com:12345) response=alert mysql(user=hogwash,dbase=hogwash5, host=localhost,port=3306,pass=password, logpackets=1) response=email(host, from, to, subject) response=bns(, ) response=alert console response=alert file(/var/log/hogwash/hogwash.alert) response=bns(3600, Green) filename=(/var/log/hogwash/TEST_%y_%m_%d_%h.ats) dbase=hogwash5 user=hogwash password=password host=localhost servers=WebServers logfile=WebUnique.log dbase=hogwash5 user=hogwash password=password host=localhost servers= DNSServers logfile= DNSUnique.log MacFilter(eth0, eth1, …) ip dst(WebServers) tcp dst(80) tcp nocase(cmd.exe) message=%sip:%sip->%dip:%dp cmd.exe attempt action=default ip dst(WebServers) tcp nocase(/bin/sh) message=attempt to execute /bin/sh action= drop icmp type(8) message=%sip-%dip icmp echo request action=log # /usr/sbin/hogwash -c stock.conf -r stock.rules & # mcedit /etc/hogwash/hogwash.sh #!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin cd /etc/hogwash killall hogwash echo "0" > /proc/sys/net/ipv4/ip_forward hogwash -c stock.conf -r stock.rules –d # chmod 700 /etc/hogwash/hogwash.sh # echo /etc/hogwash/hogwash.sh >> /etc/init.d/rc.local Путешествие из Perl в Excel Использование Spreadsheet::WriteExcel для формирования отчетов Сергей Супрунов Пример 1 #!/usr/bin/perl -w # Spreadsheel::WriteExcel tests # Стандартный модуль для осуществления перекодировок use Encoding; # Модуль для работы с файлами Excel use Spreadsheet::WriteExcel; # Подавление предупреждений о многобайтных символах nowarnings “utf8”; # Формируется HTTP-заголовок print "Content-Type: text/html\n\n"; print '

Spreadsheet::WriteExcel test

'; # Создается xls-файл my $workbook = Spreadsheet::WriteExcel->new('../public_html/excel/test.xls'); # Создается «рабочий лист» с именем Report my $worksheet = $workbook->add_worksheet('Report'); # Объявляется формат ячеек, используемый в дальнейшем my $tabformat = $workbook->add_format(); $tabformat->set_border(); # Пример вывода данных без перекодировки $worksheet->write(1, 1, 'Русский текст с рамкой', $tabformat); # Вывод ASCII-текста $worksheet->write(‘B3’, 'English text.'); # Вывод данных с перекодировкой $worksheet->write(3, 1, decode(‘koi8-r’, ' Русский текст с рамкой '), $tabformat); # Ссылка на сформированный файл print "Результат"; Пример 2. Сценарий getexcel.cgi #!/usr/local/bin/perl -w # getexcel.cgi use CGI; $root = '/var/tmp/excel'; # Получаем имя файла из HTTP-запроса $cgi = CGI->new(); $file = $cgi->param('file'); # Вырезаем небезопасные символы – имя файла может содержать # только цифры и буквы в нижнем регистре. # Расширение не указывается $file =~ s/[^a-z0-9]//g; $file = "$root/$file.xls"; # Открываем файл на чтение, устанавливаем двоичный режим open(F, "$file") || &nosuchfile; binmode(F); # Формируем нужный заголовок print "Content-Disposition: form/data; name=\"$file\";filename=\"$file\"\n"; print "Content-Type: application/vnd.ms-excel;name=\"file.xls\"\n"; print "Content-Transfer-Encoding: binary\n\n"; # Выводим содержимое файла while() { print; } close(F); #----------------------------------- subs sub nosuchfile { print "Content-Type: text/html\n\n"; print "

Файл '$file' не найден.

"; return(-1); } #!/usr/bin/perl -w # Spreadsheel::WriteExcel tests use Encode; use Spreadsheet::WriteExcel; nowarnings “utf8”; print "Content-Type: application/vnd.ms-excel\n\n"; my $workbook = Spreadsheet::WriteExcel->new('-'); . . . $worksheet->write(cell, text[, format]) $worksheet->write(rownum, colnum, text[, format]) test=> create table trf_adsl (trfname varchar, test(> payment numeric(7,2), test(> traflimit numeric(5), test(> overlimit numeric(5,2), test(> comment varchar); CREATETABLE Пример 3. Сценарий showtrf.cgi #!/usr/local/bin/perl -w # showtrf.cgi use DBI; $dbh = DBI->connect('dbi:Pg:dbname=test', 'serg', ''); $hres = $dbh->selectall_hashref('SELECT * FROM trf_adsl', 'traflimit'); print <<__ENDHTML__; Content-Type: text/html

Тарифы на услуги доступа в Интернет по ADSL

__ENDHTML__ @sorted = keys %$hres; @sorted = sort(@sorted); foreach $payment (@sorted) { print "\t\n"; } print "
Тарифный план Абонентская плата Включенный трафик Стоимость
сверхлимитного
трафика
Примечание
${$$hres{$payment}}{'trfname'}\n"; print "\t${$$hres{$payment}}{'payment'}\n"; print "\t${$$hres{$payment}}{'traflimit'}\n"; print "\t${$$hres{$payment}}{'overlimit'}\n"; print "\t${$$hres{$payment}}{'comment'}\n"; print "
\n"; Пример 4. Сценарий exceltrf.cgi #!/usr/local/bin/perl -w # exceltrf.cgi # Подключение нужных модулей useDBI; use Encode; use Spreadsheet::WriteExcel; nowarnings “utf8”; # Функция перекодировки из koi8-r в utf8 sub koi2utf { $text = shift; return decode(‘koi8-r’, $text); } # Запрос к базе данных $dbh = DBI->connect('dbi:Pg:dbname=test', 'serg', ''); $hres = $dbh->selectall_hashref('SELECT * FROM trf_adsl', 'traflimit'); # Создаем «книгу» и лист с именем «ADSL» $fn = 'tr' . time() . '.xls'; my $wb = Spreadsheet::WriteExcel->new('../public_html/excel/' . $fn); my $ws = $wb->add_worksheet(‘ADSL'); # Задаем альбомное расположение листа $ws->set_landscape(); # Формат текста, используемый для формирования заголовка my $textfmt = $wb->add_format(font => 'Arial', size => 18, color => 'blue', italic => 1); $textfmt->set_merge(); # Формат «шапки» таблицы my $headfmt = $wb->add_format(); $headfmt->set_bold(); $headfmt->set_align('center'); $headfmt->set_align('vcenter'); $headfmt->set_text_wrap(); $headfmt->set_border(); $headfmt->set_bottom(6); my $mygray = $wb->set_custom_color(40, '#AAAAAA'); $headfmt->set_bg_color($mygray); # Формат остальных ячеек таблицы my $tabfmt = $wb->add_format(num_format => '0.00', border => 1); # Объединение ячеек A1-E1 $ws->merge_range('A1:E1', koi2utf('Тарифы на услуги доступа в Интернет по ADSL'), $textfmt); # Вывод «шапки» таблицы $ws->write('A3', koi2utf('Тарифный план'), $headfmt); $ws->write('B3', koi2utf('Абонентская плата'), $headfmt); $ws->write('C3', koi2utf('Включенный трафик'), $headfmt); $ws->write('D3', koi2utf('Стоимость сверхлимитного трафика'), $headfmt); $ws->write('E3', koi2utf('Примечание'), $headfmt); # Начальные значения ширины столбцов @rowidth = (15, 10, 10, 15, 15); # Основную таблицу выводим, начиная с 4-й строки $row = 3; # Построчный вывод таблицы @sorted = keys %$hres; @sorted = sort(@sorted); foreach $payment (@sorted) { $tmp = ${$$hres{$payment}}{'trfname'}; if(length($tmp) > $rowidth[0]) { $rowidth[0] = length($tmp); } $ws->write($row, 0, koi2utf($tmp), $tabfmt); $tmp = ${$$hres{$payment}}{'payment'}; if(length($tmp) > $rowidth[1]) { $rowidth[1] = length($tmp); } $ws->write($row, 1, koi2utf($tmp), $tabfmt); $tmp = ${$$hres{$payment}}{'traflimit'}; if(length($tmp) > $rowidth[2]) { $rowidth[2] = length($tmp); } $ws->write($row, 2, koi2utf($tmp), $tabfmt); $tmp = ${$$hres{$payment}}{'overlimit'}; if(length($tmp) > $rowidth[3]) { $rowidth[3] = length($tmp); } $ws->write($row, 3, koi2utf($tmp), $tabfmt); $tmp = ${$$hres{$payment}}{'comment'}; if(length($tmp) > $rowidth[4]) { $rowidth[4] = length($tmp); } $ws->write($row, 4, koi2utf($tmp), $tabfmt); $row++; } # Устанавливаем уточненную ширину столбцов for($i = 0; $i < 5; $i++) { $ws->set_column($i, $i, $rowidth[$i] + 3); } # Выводим ссылку, по которой можно добраться до сформированного файла print <<__ENDHTML__; Content-Type: text/html $fn __ENDHTML__ Нити в Perl Алексей Мичурин #!/usr/bin/perl use Config; print "Content-Type: text/plain\n\n"; print join "\n", map {$_.' => '. (defined $Config{$_}? ($Config{$_} eq ''? '[EMPTY STRING]': "'$Config{$_}'"): '[UNDEFINED]')} sort keys %Config; sub thread_function { print "Ok!\n" } $thread = threads->create(\&thread_function); $thread->join; $thread = threads->create(sub { print "Ok!\n" }); $thread = new threads(sub { print "Ok!\n" }); threads->create(sub { print "Ok!\n" })->join; #!/usr/bin/perl -w use strict; use threads; sub f { my ($a)=@_; print "WAIT $a\n"; sleep 1; print "DONE $a\n"; return "RESULT $a\n"; } my $a = threads->create(\&f, 'A'); my $b = threads->create(\&f, 'B'); print $a->join; print $b->join; #!/usr/bin/perl -w use strict; use threads; sub f { my ($a, $t)=@_; print "WAIT $a\n"; sleep $t; print "DONE $a\n"; return "RESULT $a\n"; } my $kida = threads->create(\&f, 'A', 2); my $kidb = threads->create(\&f, 'B', 1); print $kida->join; print $kidb->join; #!/usr/bin/perl -w use strict; use threads; my $a; sub f { my $aa=$a; $a=7; return "DONE (a=$aa)\n" } $a=0; my $kida = threads->create(\&f); $a=1; my $kidb = threads->create(\&f); $a=2; print "(a=$a)\n"; print $kida->join; $a=3; print "(a=$a)\n"; print $kidb->join; #!/usr/bin/perl -w use strict; use threads; my $a; my $b=\$a; sub f { print "in thread b=$b\n" } my $kid = threads->create(\&f); print "in main b=$b\n"; $kid->join; # создаём разделяемый скаляр my $a; share($a); # создаём разделяемый массив my @a; share(@a); # создаём разделяемый хэш my %a; share(%a); # указатель на разделяемый массив my $a=&share([]); # указатель на разделяемый хэш (!) my $a=&share(); my $a; share($a); my $b; $a=\$b; my $a; share($a); my $b; share($b); $a=\$b; my $a : shared = 1; #!/usr/bin/perl -w use strict; use threads; use threads::shared; my $a : shared = 0; sub f { my $c=$a; $c++; $a=$c; } my $p=threads->create(\&f); my $q=threads->create(\&f); $p->join; $q->join; print "$a\n"; sub f { my $c=$a; sleep 1; $c++; $a=$c; } sub f { $a++ } sub f { lock($a); $a++; } sub f { { lock($a); $a++ } { lock($b); $b++ } # забл. только $b } #!/usr/bin/perl -w use strict; use threads; use threads::shared; my $a : shared; my $b : shared; my $p=threads->create( sub { lock($a); sleep 1; lock($b) } ); my $q=threads->create( sub { lock($b); sleep 1; lock($a) } ); $p->join; $q->join; { lock($x); lock($x); } sub a { $x++; # $x осталась заблокирована } sub b { lock($x); a(); } use threads; use Thread::Semaphore; my $s = new Thread::Semaphore; my $a : shared = 0; sub f { $s->down; $a++; $s->up; } my $p=threads->create(\&f); my $q=threads->create(\&f); $p->join; $q->join; print "$a\n"; use threads; use Thread::Semaphore; $|=1; my $s = Thread::Semaphore->new(2); my $a : shared = 0; sub f { my ($name, $time, $greed)=@_; print "$name: Пытаюсь опустить семафор, захватив $greed шт. ресурсов\n"; $s->down($greed); print "$name: Семафор опущен, работаю с $greed шт. ресурсов $time с.\n"; sleep $time; print "$name: Поднимаю семафор\n"; $s->up($greed); {lock($a); $a++} } foreach (qw/A B C D E F/) { threads->create(\&f, $_, 1+int(rand(3)), 1+int(rand(2)))->detach; } for (my $i=0; $a<6; $i++) { print "Идёт секунда $i\n"; sleep 1; } my $q=Thread::Queue->new; $q->enqueue('text'); $q->enqueue(1, 2, 3); my $var=$q->dequeue; #!/usr/bin/perl -w use strict; use threads; use Thread::Queue; my $q=Thread::Queue->new; sub f { $q->enqueue("I'm going sleep"); sleep 1; $q->enqueue("I'm waiking up"); $q->enqueue(undef); } my $p=threads->create(\&f); $p->detach; while (my $t=$q->dequeue) { print "He say: '$t'\n"; } ... use Config; ... die "Я работаю только с нитями\n" unless ($Config{'useithreads'}); ... use Config; BEGIN { if ($Config{'useithreads'}) { require my_threads_dep; import my_threads_dep; } else { require my_threads_indep; import my_threads_indep; } } JpGraph Динамическая графика – это просто Кирилл Сухов $im = ImageCreate (50, 100) or die ("Cannot create a new GD image."); $background_color = ImageColorAllocate ($im, 255, 255, 255); $text_color = ImageColorAllocate ($im, 233, 14, 91); ImageString ($im, 1, 5, 5, "A Simple Text String", $text_color); header ("Content-type: image/png"); ImagePng ($im); // Special unicode cyrillic language support DEFINE("LANGUAGE_CYRILLIC",false); // If you are setting this config to true the conversion // will assume that the input text is windows 1251, if // false it will assume koi8-r DEFINE("CYRILLIC_FROM_WINDOWS",false); DEFINE('TTF_DIR',…); include ("../jpgraph.php"); include ("../jpgraph_line.php"); $graph = new Graph(450, 200,"auto"); $graph->SetScale( "textlin"); $lineplot =new LinePlot($traff); $graph->Add( $lineplot); $graph->Stroke(); $graph->xaxis->SetTickLabels($days); $graph->title->SetFont(FF_VERDANA,FS_NORMAL,12); $graph->xaxis->title->SetFont(FF_VERDANA,FS_NORMAL,8); $graph->yaxis->title->SetFont(FF_VERDANA,FS_NORMAL,8); $graph->title->Set("Трафик"); $graph->xaxis->title->Set("Период"); $graph->yaxis->title->Set("Трафик (Mb)"); $graph->SetMargin(60,40,40,40); $graph->yaxis->SetTitlemargin(40); $lineplot->mark->SetType(MARK_IMG_DIAMOND, 'blue', 0.3); $lineplot->value->Show() ; $lineplot->value->SetColor("darkgray"); $lineplot->value->SetFont(FF_FONT0,FS_BOLD); $lineplot->value->SetFormat(" %01.0f Mb"); $lineplot ->SetColor("blue"); $graph->SetColor('cadetblue1'); $graph->SetMarginColor('lightblue3'); $graph->SetShadow(); $traff = array(810,480, 550, 715, 688, 785, 847,902, 350, 280, 450, 615, 588,755, 547,320, 380); // трафик (Мб) $days = array (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17); // даты include "../jpgraph.php"; include "../jpgraph_line.php"; include "../jpgraph_regstat.php"; $spline = new Spline($days,$traff); list($newx,$newy) = $spline->Get(100); $g = new Graph(300,200); $g->SetMargin(30,20,40,30); $g->SetScale('linlin'); $g->xaxis->SetLabelFormat('%0.0f'); $lplot = new LinePlot($newy,$newx); $g->Add($lplot); $g->Stroke(); include "../jpgraph_scatter.php"; $splot = new ScatterPlot($traff, $days); $splot->mark->SetFillColor('blue@0.3'); $splot->mark->SetColor('green@0.5'); $g->Add($splot); $g->xgrid->Show(); $pepl = array(8, 16, 10, 7, 4,12, 7,15, 11, 22); // количество подключений $days = array (9, 10, 11, 12, 13, 14, 15, 16, 17, 18); // даты $width=480; $height=280; $graph = new Graph($width,$height,'auto'); $graph->SetScale("textlin"); $graph->SetBox(); $graph->xaxis->SetTickLabels($days); $bplot = new BarPlot($pepl); $bplot->SetWidth(0.5); $graph->Add($bplot); $graph->Stroke(); $graph->title->SetFont(FF_VERDANA,FS_BOLD,11); $graph->title->Set("Подключения"); $graph->subtitle->SetFont(FF_VERDANA,FS_NORMAL,9); $graph->subtitle->Set("(Декабрь 2004)"); $bplot->value->Show(); $bplot->value->SetFont(FF_ARIAL,FS_BOLD,8); $bplot->value->SetAlign('left','center'); $bplot->value->SetColor("white"); $bplot->value->SetFormat('%.0f'); $bplot->SetValuePos('max'); $graph->SetMarginColor('white'); $graph->SetBackgroundGradient('white','lightblue', GRAD_HOR,BGRAD_PLOT); $graph->SetFrame(false); $graph->xaxis->SetFont(FF_VERDANA,FS_NORMAL,8); $graph->xaxis->SetLabelMargin(10); $graph->xaxis->SetLabelAlign('right','center'); $graph->yaxis->scale->SetGrace(20); $bplot->SetShadow(); $bplot->SetFillGradient('green','blue',GRAD_HOR); Add($p1); $graph->Stroke(); ? $graph->title->SetFont(FF FF_VERDANA,FS_BOLD,8); $graph->title->Set("Распределение трафика"); $graph->legend->SetColor('navy'); $graph->legend->SetFillColor('lightgreen'); $graph->legend->SetLineWeight(1); $graph->legend->SetFont(FF_ARIAL,FS_NORMAL,8); $graph->legend->SetShadow('gray@0.4',3); $graph->legend->SetAbsPos(10,100,'right','bottom'); $legends = array('Физ лица','Юр Лица','Служебный'); $p1->SetLegends($legends); include ("../jpgraph_pie3d.php"); //$p1 = new PiePlot($data); $p1 = new PiePlot3D($data); $p1->ExplodeSlice(2); $p1->SetSliceColors(array('skyblue3','yellow3','darkred')); $graph->SetFrame(false); $graph = new Graph(450, 200, "traf”, 1464, true); Запись дисков CD-R/RW в Linux Часть 3 Владимир Мешков __u32 read_buff_cap() { __u8 read_buff_cap_cmd[10]; __u8 data_buff[12]; __u32 buff_alen = 0; memset(read_buff_cap_cmd, 0, 10); read_buff_cap_cmd[0] = 0x5C; read_buff_cap_cmd[8] = 0x0C; send_cmd(read_buff_cap_cmd, 10, SG_DXFER_FROM_DEV, data_buff,0x0C, 20); memcpy((void *)&buff_alen, data_buff + 8, 4); buff_alen = __swab32(buff_alen); printf("\tAvailable length - %u\n", buff_alen); return buff_alen; } int write_iso(__u8 *file_name) { .... while(read(in_f, write_buff, CD_FRAMESIZE) > 0) { read_buff_cap(); printf("lba - %6d", lba1); lba = __swab32(lba1); memcpy((write_cmd + 2), (void *)&lba, 4); lba1 += 1; send_cmd(write_cmd, 10, SG_DXFER_TO_DEV, write_buff, CD_FRAMESIZE, 20); } return 0; } while(read_buff_cap() == 0) continue; int send_cmd(__u8 *cmd, __u8 cmdlen, int direction, __u8 *data, __u32 datalen, unsigned int timeout) { sg_io_hdr_t io_hdr; __u8 sense_buffer[32]; #define SK sense_buffer[2] #define ASC sense_buffer[12] #define ASCQ sense_buffer[13] memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); io_hdr.interface_id = 'S'; io_hdr.cmd_len = cmdlen; io_hdr.mx_sb_len = sizeof(sense_buffer); io_hdr.dxfer_direction = direction; io_hdr.dxfer_len = datalen; // размер данных io_hdr.dxferp = data; // указатель на блок данных io_hdr.cmdp = cmd; io_hdr.sbp = sense_buffer; io_hdr.timeout = timeout * 1000; if(ioctl(sg_fd, SG_IO, &io_hdr) < 0) { perror("SG_IO ioctl"); return -1; } if((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) { if(io_hdr.sb_len_wr > 0) { /* Если SK/ASC/ASCQ == 02/04/08 (Not Ready. Long Write in Progress), то необходимо повторить команду WRITE_10 */ if((SK == NOT_READY) && (ASC == 0x04) && (ASCQ == 0x08)) return 1; syslog(LOG_INFO,"Command: 0x%02X", io_hdr.cmdp[0]); syslog(LOG_INFO,"Sense data (SK/ASC/ASCQ): 0x%02X/0x%02X/0x%02X", SK,ASC,ASCQ); } if(io_hdr.masked_status) syslog(LOG_INFO, "SCSI status = 0x%x\n", io_hdr.status); if(io_hdr.host_status) syslog(LOG_INFO, "Host status = 0x%x\n", io_hdr.host_status); if(io_hdr.driver_status) syslog(LOG_INFO, "Driver status = 0x%x\n", io_hdr.driver_status); return -1; } return 0; } while(1) { ret = send_cmd(write_cmd, 10, SG_DXFER_TO_DEV, write_buff, BUFF_SIZE, 20); if(ret == 1) continue; // LONG WRITE IN PROGRESS if(ret == 0) break; if(ret < 0) return -1; // ошибка записи! } cdrecord -dev=X,Y,Z -msinfo /* Формат записи TOC (см. [1], [2]) */ typedef struct { __u8 snum; // Session Number __u8 ctrl :4; // Control __u8 adr :4; // ADR __u8 tno; // TNO (always 0) __u8 point; // POINT __u8 min; // AMIN __u8 sec; // ASEC __u8 frame; // AFRAME __u8 zero; // 0 __u8 pmin; // PMIN __u8 psec; // PSEC __u8 pframe; // PFRAME } toc_t; int read_raw_toc() { int i; __u8 read_toc_cmd[10]; __u8 *data_buff; // результаты чтения TOC __u16 toc_data_len = 0; // длина записей TOC __u32 lba; int toc_entries = 0; // число записей TOC int last = 0; // номер последней сессии toc_t *t; data_buff = (__u8 *)malloc(0xFFFF); memset(data_buff, 0, 0xFFFF); memset(read_toc_cmd, 0, 10); read_toc_cmd[0] = READ_TOC; read_toc_cmd[2] = 2; // Format Field = 10b - RAW TOC read_toc_cmd[7] = 0xFF; read_toc_cmd[8] = 0xFF; send_cmd(read_toc_cmd, 10, SG_DXFER_FROM_DEV, data_buff, 0xFFFF, 20); /* Размер TOC */ *((__u8 *)&toc_data_len) = data_buff[1]; *((__u8 *)&toc_data_len + 1) = data_buff[0]; /* Число записей TOC */ toc_entries = (toc_data_len - 2)/11; /* Число сессий */ last = data_buff[3]; printf("Число сессий на диске - %d\n", last); t = (toc_t *)malloc(toc_data_len); memset((void *)t, 0, toc_data_len); memcpy((void *)t, data_buff + 4, toc_data_len); free(data_buff); printf("Entry\tSession\tPoint\tMin\tSec\tFrame\tPMin\tPsec\tPFrame\tLBA\n"); for(i = 0; i < toc_entries; i++) { printf("%d\t", i); printf("%d\t", (t + i)->snum); printf("%X\t", (t + i)->point); printf("%d\t", (t + i)->min); printf("%d\t", (t + i)->sec); printf("%d\t", (t + i)->frame); printf("%d\t", (t + i)->pmin); printf("%d\t", (t + i)->psec); printf("%d\t", (t + i)->pframe); #define PMIN(i) (t + i)->pmin #define PSEC(i) (t + i)->psec #define PFRAME(i) (t + i)->pframe #define MIN(i) (t + i)->min #define SEC(i) (t + i)->sec #define FRAME(i) (t + i)->frame #define POINT(i) (t + i)->point if((POINT(i) == 0xC0) || (POINT(i) == 0xC1)) { printf("\n"); continue; } /* Координаты начала следующей возможной области программ содержит указатель B0 * в полях Min/Sec/Frame. Переводим эти координаты в LBA-формат, с учетом того, что * перед треком находится Pre-gap область размером 150 секторов */ if(POINT(i) == 0xB0) lba = MSF2LBA(MIN(i), SEC(i), FRAME(i)) + 150; else lba = MSF2LBA(PMIN(i), PSEC(i), PFRAME(i)); printf("%u\n", lba); } free(t); return 0; } #define MSF2LBA(Min, Sec, Frame) (((Min * 60 + Sec) * 75 + Frame) - 150) typedef struct { __u8 res1; __u8 ctrl :4; __u8 adr :4; __u8 first_trk; // номер первого трека посл. сессии __u8 res2; __u32 start_addr; // стартовый адрес трека } ms_info_t; void read_ms_info() { int first_trk = 0; // номер первого трека посл. сессии __u8 read_toc_cmd[10]; // CDB - Command Descriptor Block __u8 data_buff[12]; __u32 start_addr = 0; // стартовый адрес трека ms_info_t *ms_info; memset(data_buff, 0, 12); ms_info = (void *)(data_buff + 4); /* Формируем CDB */ memset(read_toc_cmd, 0, 10); read_toc_cmd[0] = READ_TOC; read_toc_cmd[2] = 1; // Format = 1, Multi-session Information read_toc_cmd[8] = 12; // размер блока данных send_cmd(read_toc_cmd, 10, SG_DXFER_FROM_DEV, data_buff, 12, 20); first_trk = ms_info->first_trk; start_addr = __swab32(ms_info->start_addr); printf("Первый трек последней сессии - %d\n", first_trk); printf("Стартовый адрес трека - %u\n", start_addr); return; } __u32 read_track_info(int trk_num) { __u8 read_track_info_cmd[10]; __u8 data_buff[40]; __u32 lba = 0; memset(data_buff, 0, 40); memset(read_track_info_cmd, 0, 10); read_track_info_cmd[0] = 0x52; read_track_info_cmd[1] = 1; read_track_info_cmd[5] = trk_num; // 0xFF - invisible track read_track_info_cmd[8] = 40; send_cmd(read_track_info_cmd, 10, SG_DXFER_FROM_DEV, data_buff, 40, 20); memcpy((void *)&lba, (void *)(data_buff + 8), 4); return __swab32(lba); } mkisofs -R -J -C 23510,32534 -M [имя файла устройства] -o track-04.iso [входной файл] int read_disk_info() { __u8 read_disk_info_cmd[10]; __u8 data_buff[34]; memset(data_buff, 0, 34); memset(read_disk_info_cmd, 0, 10); read_disk_info_cmd[0] = 0x51; read_disk_info_cmd[8] = 34; send_cmd(read_disk_info_cmd, 10, SG_DXFER_FROM_DEV, data_buff, sizeof(data_buff), 20); switch(data_buff[2] & 3) { case(0): printf("Диск пустой\n"); break; case(1): printf("Можно дописывать информацию\n"); break; case(2): printf("Запись невозможна\n"); break; default: break; } return 0; } #include struct stat s; memset((void *)&s, 0, sizeof(struct stat)); /* argv[1] - имя файла-образа, передается в командной строке программы */ if(stat(argv[1], &s)) { perror("stat"); exit(errno); } /* Размер файла-образа в блоках */ track_size = s.st_size/CD_FRAMESIZE; void reserv_track(__u32 track_size) { __u8 reserv_track_cmd[10]; __u32 size = 0; memset(reserv_track_cmd, 0, 10); reserv_track_cmd[0] = 0x53; size = __swab32(track_size); memcpy((void *)(reserv_track_cmd + 5), (void *)&size, 4); send_cmd(reserv_track_cmd, 10, SG_DXFER_NONE, NULL, 0, 20); return; } Обучение при помощи ATutor Сергей Яремчук # cd /var/www/htdocs # tar xzvf /home/source/ATutor-1.4.2.tar.gz LoadModule php4_module libexec/libphp4.so AddModule mod_php4.c AddType application/x-httpd-php .php DirectoryIndex index.html index.php Восстановление NTFS – undelete своими руками Крис Касперски CreateFile("\\.\X:", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0),