Резервное копирование с помощью Windows Backup и PowerShell Сергей Горбановский # Загружаем snap-in Windows Backup $SnapIn = "Windows.ServerBackup" if (Get-PSSnapin -Name $SnapIn -ea "SilentlyContinue") { Write-Log "Оснастка $SnapIn уже подключена" } elseif (Get-PSSnapin -Name $SnapIn -registered -ea "SilentlyContinue") { Write-Log "Оснастка $SnapIn зарегистрирована, но не подключена" Write-Log "Подключаем оснастку $SnapIn" Add-PSSnapin -Name $SnapIn } else { Write-Log "Оснастка $SnapIn не найдена! Возможно, не установлен компонент Windows Backup." Write-Log "Общее время выполнения: $($ElapsedTime.Elapsed.ToString())" Exit } # Создаем политику $WBPolicy = New-WBPolicy Write-Log "Создаем политику: $WBPolicy" # Задаем цель для бэкапа $WBTarget = New-WBBackupTarget -NetworkPath $FullBackupPath Write-Log "Задаем цель для бэкапа: $WBTarget" # Задаем цель для бэкапа $WBTarget = New-WBBackupTarget -VolumePath ($BackupPath) Write-Log "Задаем цель для бэкапа: $WBTarget" # Добавляем цель к созданной политике Add-WBBackupTarget -Policy $WBPolicy -Target $WBTarget -force | Out-Null # Добавляем объекты для бэкапа if($BackupType) { Write-Log "Добавляем объект System State" Add-WBSystemState -Policy $WBPolicy | Out-Null } else { Write-Log "Добавляем объект Bare Metal Recovery" Add-WBBareMetalRecovery -Policy $WBPolicy | Out-Null } # Запуск созданного задания Write-Log "Запускаем задание" Start-WBBackup -Policy $WBPolicy | Out-Null # Проверяем, успешно ли выполнен бэкап if (!(Get-WBSummary).LastBackupResultHR) { Write-Log "Бэкап завершился успешно" if ((!$IsNetworkBackup) -and (!$BackupType)) { # Получаем ID снэпшота для последнего бэкапа $CurrSnapshotId = (Get-WBBackupSet).SnapshotId | Select -Last 1 # Обновляем лог Bare Metal Recovery UpdateBmrLog "Add" $CurrSnapshotId } } else { $WBError = (Get-WBSummary).DetailedMessage Write-Log "Бэкап завершился с ошибкой!" Write-Log "$WBError" } # Записываем в лог результат работы задания Write-Log "Лог успешных операций Windows Backup: $((Get-WBJob -Previous 1).SuccessLogPath)" Write-Log "Лог операций Windows Backup с ошибками: $((Get-WBJob -Previous 1).FailureLogPath)" # Получаем имя локального компьютера $SName=$env:ComputerName # Удаляем бэкапы на локальном диске для System State &WBADMIN DELETE SYSTEMSTATEBACKUP -backupTarget:$Path -machine:$SName -keepVersions:$MaxBackups | Out-Null # С помощью кода возврата проверяем, успешно ли удален бэкап if(!$LastExitCode) { Write-Log "Устаревшие бэкапы System State удалены" } else { Write-Log "Ошибка удаления бэкапов System State!" } # Проверяем наличие каталога для логов Bare Metal Recovery if (!(Test-Path $script:BmrLogFolder)) { Write-Log "Отсутствует папка для лога Bare Metal Recovery, создаем" # Каталог отсутствует, создаем New-Item (Join-Path -Path $script:SDirPath -ChildPath $script:BmrLogFolder) -Type Directory | Out-Null } # Читаем содержимое лога в массив $BmrLogContent = @(Get-Content $script:BmrLogFilePath) # Записываем/читаем ID снэпшотов if ($Action -eq "Add") { Write-Log "Добавляем в лог Bare Metal Recovery запись о снэпшоте $SnapshotIdList" # Добавляем новый ID к уже существующим в файле $BmrLogContent = $BmrLogContent + $SnapshotIdList # Сохраняем файл Set-Content $script:BmrLogFilePath $BmrLogContent } elseif ($Action -eq "Remove") { Write-Log "Удаляем из лога Bare Metal Recovery запись о снэпшоте $SnapshotIdList" # Сравниваем список ID из файла и переданные ID, # удаляем совпадения $BmrLogContent = Compare-Object -ReferenceObject $BmrLogContent -DifferenceObject $SnapshotIdList -PassThru # Сохраняем файл Set-Content $script:BmrLogFilePath $BmrLogContent } # Генерируем имя временного файла для скрипта DiskShadow $TmpFile = Join-Path -Path $Env:TEMP -ChildPath ([System.IO.Path]::GetRandomFileName()) # Генерируем тело скрипта для удаления снэпшота Set-Content $TmpFile "delete shadows ID {$SnapshotId}" # Запускаем DiskShadow $DelOutput = &diskshadow -s $TmpFile # Сохраняем код возврата DiskShadow $DelExitCode = $LastExitCode # Удаляем временный файл $TmpFile | Remove-Item -Force -Confirm:$false # С помощью кода возврата проверяем, успешно ли удален снэпшот if (!$DelExitCode) { # Снэпшот удален успешно Write-Log "Успешно удален снэпшот $SnapshotId" return $true } else { # Произошла ошибка, сохраняем в лог вывод DiskShadow Write-Log "Ошибка при удалении снэпшота $SnapshotId" Write-Log "$DelOutput" return $false } # Функция удаления снэпшотов возвращает статус операции if ($Ret) { # Снэпшот успешно удален, обновляем лог Bare Metal Recovery Write-Log "Обновляем лог Bare Metal Recovery" UpdateBmrLog "Remove" $SnapshotIdList[$i] } else { # Произошла ошибка во время удаления снэпшота Write-Log "Ошибка удаления снэпшота, не обновляем лог Bare Metal Recovery" } [Backup] BackupPath=D: IsNetworkBackup=0 BackupType=1 MaxBackups=5 [Email] SendEmail=1 Sender=WinBackup@mycompany.ru Receipt=admin@mycompany.ru Server=mail.mycompany.ru Login=winbackup Password=password Port=25 SSL=0 TrustAnyCert=0 ----------------------------------------------------------------------------------------------------------------- VMware ESXi. Система виртуальных машин для малого бизнеса. Часть 1 Рашид Ачилов # esxcli software acceptance set --level=CommunitySupported # esxcli software vib install -v /vmfs/volumes/a/DLink-528T-1.x86_64.vib # scp vibname.vib root@esxi:/tmp/vibname.vib # cd /vmfs/volumes/datastore1000/vmdks/bigcat/ # ls -l /vmfs/devices/disks # vmkfstools -r /vmfs/devices/disks/t10.ATA_____ST31000524AS________________________________________6VPK7TP6 raw1tb.vmdk ----------------------------------------------------------------------------------------------------------------- Установка CentOS из Debian LiveCD Дмитрий Стремковский fdisk /dev/sda sfdisk -d /dev/sda | sfdisk /dev/sdb mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1 --metadata=0.90 mdadm --create /dev/md2 --level=1 --raid-devices=2 /dev/sda2 /dev/sdb2 mkfs.ext2 -m0 -Lboot /dev/md1 mkfs.ext4 -m5 /dev/md2 mkdir /mnt/centos mount /dev/md2 /mnt/centos mkdir /mnt/centos/boot mount /dev/md1 /mnt/centos/boot apt-get -y update apt-get -y install yum rpm python-m2crypto mkdir -p /mnt/centos/var/lib/rpm rpm --root /mnt/centos --initdb wget http://mirror.yandex.ru/centos/6.4/os/x86_64/Packages/centos-release-6-4.el6.centos.10.x86_64.rpm rpm -ivh --force-debian --nodeps --root /mnt/centos centos-release-6-4.el6.centos.10.x86_64.rpm ln -s /mnt/centos/etc/pki /etc/pki yum -y --installroot /mnt/centos/ install yum mount -t proc foo /mnt/centos/proc mount -t sysfs foo /mnt/centos/sys mount -t devtmpfs foo /mnt/centos/dev chroot /mnt/centos /bin/bash -login echo "nameserver 8.8.8.8" > /etc/resolv.conf echo "nameserver 8.8.4.4" >> /etc/resolv.conf BVER=$(cat /etc/redhat-release | cut -d" " -f3); sed -i s/\$releasever/$BVER/g /etc/yum.repos.d/CentOS-Base.repo BREL=$(uname -p); sed -i s/\$basearch/$BREL/g /etc/yum.repos.d/CentOS-Base.repo yum -y install mdadm grub mdadm -Es | grep ^ARRAY | sed -r 's/\/dev\/md\//\/dev\/md/g; s/(\ [^\ ]+\=[^\ ]+)+\ UUID/ UUID/g;' | grep -oP "^ARRAY /dev/md[0-9]+ UUID=[^\s]+" > /etc/mdadm.conf echo "tmpfs /dev/shm tmpfs defaults 0 0" > /etc/fstab echo "devpts /dev/pts devpts gid=5,mode=620 0 0" >> /etc/fstab echo "sysfs /sys sysfs defaults 0 0" >> /etc/fstab echo "proc /proc proc defaults 0 0" >> /etc/fstab echo "$(blkid /dev/md1 | grep -Po 'UUID=[^\s]+' | sed 's/\"//g;') /boot ext3 defaults 1 2" >> /etc/fstab echo "$(blkid /dev/md2 | grep -Po 'UUID=[^\s]+' | sed 's/\"//g;') / ext4 defaults 1 1" >> /etc/fstab cp /usr/share/grub/x86_64-redhat/* /boot/grub/ printf "root (hd0,0)\nsetup (hd0)\nroot (hd1,0)\nsetup (hd1)\nquit" | grub yum -y install kernel KVER=$(ls /lib/modules/ | head -n1 | tail -n1); echo "default=0" > /boot/grub/grub.conf echo "timeout=3" >> /boot/grub/grub.conf echo -e >> /boot/grub/grub.conf echo "title CentOS ($KVER) (hd0)" >> /boot/grub/grub.conf echo " root (hd0,0)" >> /boot/grub/grub.conf echo " kernel /vmlinuz-$KVER ro root=$(blkid /dev/md2 | cut -d' ' -f2 | sed 's/\"//g;') nomodeset rd_NO_LUKS LANG=en_US.UTF-8 quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto panic=10 KEYBOARDTYPE=pc KEYTABLE=us" >> /boot/grub/grub.conf echo " initrd /initramfs-$KVER.img" >> /boot/grub/grub.conf echo -e >> /boot/grub/grub.conf echo "title CentOS ($KVER) (hd1)" >> /boot/grub/grub.conf echo " root (hd1,0)" >> /boot/grub/grub.conf echo " kernel /vmlinuz-$KVER ro root=$(blkid /dev/md2 | cut -d' ' -f2 | sed 's/\"//g;') nomodeset rd_NO_LUKS LANG=en_US.UTF-8 quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto panic=10 KEYBOARDTYPE=pc KEYTABLE=us" >> /boot/grub/grub.conf echo " initrd /initramfs-$KVER.img" >> /boot/grub/grub.conf ln -s /boot/grub/grub.conf /boot/grub/menu.lst yum -y install system-config-network-tui dhclient echo DEVICE=eth0 > /etc/sysconfig/network-scripts/ifcfg-eth0 system-config-network-tui echo NOZEROCONF=yes >> /etc/sysconfig/network sed -i 's/^.*ONBOOT.*/ONBOOT=yes/g;' /etc/sysconfig/network-scripts/ifcfg-eth0 yum -y install openssh-server openssh-clients useradd myuser usermod -aG wheel myuser sed -i 's/^.*DNS.*/UseDNS no/g;' /etc/ssh/sshd_config sed -i '0,/^.*PermitRootLogin.*/s//PermitRootLogin no/' /etc/ssh/sshd_config sed -i '0,/^.*ListenAddress.*/s//ListenAddress 0.0.0.0/' /etc/ssh/sshd_config sed -i '0,/^.*Port.*/s//Port 22/' /etc/ssh/sshd_config chkconfig sshd on echo -e "*filter\n:INPUT DROP [0:0]\n:FORWARD DROP [0:0]:OUTPUT ACCEPT [0:0]" > /etc/sysconfig/iptables echo -e "-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT" >> /etc/sysconfig/iptables echo -e "-A INPUT -m state --state ESTABLISHED -j ACCEPT" >> /etc/sysconfig/iptables for i in 0 3 8 11; do echo -e "-A INPUT -p icmp -m icmp --icmp-type $i -j ACCEPT" >> /etc/sysconfig/iptables; done; echo -e "-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT\nCOMMIT" >> /etc/sysconfig/iptables echo -e "*nat\n:PREROUTING ACCEPT [0:0]\n:POSTROUTING ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\nCOMMIT" >> /etc/sysconfig/iptables echo -e "*raw\n:PREROUTING ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]" >> /etc/sysconfig/iptables echo -e "-A PREROUTING ! -i lo -p udp -j RETURN" >> /etc/sysconfig/iptables echo -e "-A PREROUTING -j NOTRACK" >> /etc/sysconfig/iptables echo -e "-A OUTPUT ! -o lo -p udp -j RETURN" >> /etc/sysconfig/iptables echo -e "-A OUTPUT -j NOTRACK\nCOMMIT" >> /etc/sysconfig/iptables chkconfig iptables on passwd root passwd myuser exit reboot ----------------------------------------------------------------------------------------------------------------- Multipath I/O для программного iSCSI. Настраиваем Device-Mapper Multipath в Linux Александр Руденко # iscsiadm -m discovery -t sendtargets -p 192.168.0.10:3260 # iscsiadm -m discovery -t sendtargets -p 192.168.1.10:3260 # scsi_id -g /dev/sdb # scsi_id -g /dev/sdc # yum –y install device-mapper-multipath iscsi-initiator-utils # apt-get install open-iscsi open-iscsi-utils multipath-tools # /etc/init.d/iscsi restart # fdisk –l # cp /usr/share/doc/device-mapper-multipath-0.4.9 /multipath.conf /etc/multipath.conf defaults { udev_dir /dev polling_interval 10 path_selector "round-robin 0" path_grouping_policy failover getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n" prio alua path_checker readsector0 rr_min_io 100 max_fds 8192 rr_weight priorities failback immediate no_path_retry fail user_friendly_names yes } blacklist { wwid 26353900f02796769 devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" devnode "^hd[a-z]" # /etc/init.d/multipathd start # chkconfig multipathd on # lsmod | grep dm_ # modprobe dm_multipath # modprobe dm_round_robin # mkfs.ext3 /dev/mapper/mpathbp1 # mount /dev/mapper/mpathbp1 /test-dm # multipath -ll # multipath -ll # time -p dd if=/dev/<массив> of=/dev/null bs=1024k ----------------------------------------------------------------------------------------------------------------- Raspberry Pi: пентест на ладони Андрей Бирюков raspi_config expand_rootfs sudo apd-get update airmon-ng start wlan0 airodump-ng mon0 reaver -i mon0 –b MAC_addr -vv ----------------------------------------------------------------------------------------------------------------- Без потерь и сбоев. Репликация в MySQL Сергей Яремчук mysql> SHOW VARIABLES LIKE 'auto_inc%'; [mysqld] ... log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true master-info-repository=TABLE relay-log-info-repository=TABLE binlog-rows-query-log_events=1 mysql> SHOW VARIABLES LIKE '%gtid%'; 1000 мс / задержка в сети (мс) = производительность semi-synchronous mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; rpl_semi_sync_master_enabled =1 mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; rpl_semi_sync_slave_enabled =1 mysql> SHOW STATUS LIKE 'Rpl_semi_sync%'; ----------------------------------------------------------------------------------------------------------------- Разработка приложений на Node.js. Веб-сервер из двадцати строк Кирилл Сухов var http = require('http'); http.createServer(function (request, response) { console.log("HTTP works!"); }); http.listen(8080); $ node start.js $ node start.js http.createServer(function (request, response) { console.log("HTTP works!"); response.writeHead(200, {'Content-Type': 'text/html'}); response.end('

Hello!

'); }).listen(8080);
Node-page

Просто страница

var fs = require('fs'); var fileName = “page.html”; http.createServer(function (req, res) { fs.readFile(fileName, 'utf8', function(err, data) { if (err){ console.log('Could not find or open file for reading\n'); } else { res.writeHead(200, {'Content-Type': 'text/html'}); res.end(data); } }) }).listen(8080); console.log('Server running on 8124'); var http = require("http"); var fs = require('fs'); var url = require("url"); http.createServer(function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Получен запрос " + pathname); … Node-page

Сайт на Node.js

var pathname = url.parse(request.url).pathname; console.log("Получен запрос " + pathname); fs.readFile('index.html', 'utf8', function(error, data) { if(error){ console.log('Could not find ↵ or open file for reading\n'); } else { response.writeHead(200, {'Content-Type': 'text/html'}); response.end(data); } }) $ node start1.js http.createServer(function onRequest(request, response) { var postData = ""; var pathname = url.parse(request.url).path; if(pathname =='/') pathname = '/index.html'; // чтобы убрать начальный слэш pathname = pathname.substring(1, pathname.length); fs.readFile(pathname, 'utf8', function(err, data) { if (err){ console.log('Could not find or open file '+pathname +' for reading\n'); } else { response.writeHead(200, {'Content-Type': 'text/html'}); response.end(data); } }) }).listen(8080); var path = require('path'); var mimeTypes = { '.js' : 'text/javascript', '.html': 'text/html', '.css' : 'text/css', '.jpg' :'image/jpeg', '.gif' : 'image/gif' }; fs.readFile(pathname, 'utf8', function(err, data) { if (err){ console.log('Could not find or open file '+pathname +' for reading\n'); } else { response.writeHead(200, {'Content-Type': mimeTypes[path.extname(pathname)]}); response.end(data); } }) http.createServer(function onRequest(request, response) { var pathname = url.parse(request.url).path; if(pathname =='/'){ pathname = '/index.html'; } var extname = path.extname(pathname); console.log(extname); var mimeType = mimeTypes[path.extname(pathname)]; pathname = pathname.substring(1, pathname.length); if((extname == ".gif") || (extname==".jpg")){ var img = fs.readFileSync('./'+pathname); response.writeHead(200, {'Content-Type': mimeType }); response.end(img, 'binary'); } else { fs.readFile(pathname, 'utf8', function(err, data) { if (err){ console.log('Could not find ↵ or open file '+pathname +' for reading\n'); } else { console.log(pathname+" "+mimeType); response.writeHead(200, {'Content-Type': mimeType}); response.end(data); } }) } }).listen(8080); ----------------------------------------------------------------------------------------------------------------- Программирование для Android? Это просто! Часть 2 Сергей Ильичев $mkdir HelloAndroid $android create project --target 1 --name HelloAndroid --path ./HelloAndroid -activity HelloAndroid --package com.example.helloandroid $android list targets $android create project Листинг 1. Манифест-файл приложения HelloAndroid – AndroidManifest.xml $cd HelloAndroid $ant debug $cd bin $emulator @em1 $adb -e install HelloAndroid-debug.apk Листинг 2. Файл HelloAndroid.java из каталога src/com/example/helloandroid package com.example.helloandroid; import android.app.Activity; import android.os.Bundle; public class HelloAndroid extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } } Листинг 3. Файл /res/layout/main.xml Листинг 4. Файл /res/values/strings.xml HelloAndroid android:label="@string/app_name" setContentView(R.layout.main); ----------------------------------------------------------------------------------------------------------------- Искусство создания сценариев на PowerShell. Часть 1 Иван Коробко Листинг 1. Одиночный комментарий [string]$a # объявление строковой переменной Листинг 2. Пример заголовка сценария <######################################################### Описание: Подключение сетевых дисков на основе данных, хранящихся в каталоге Active Direсtory Автор: И.Коробко Дата создания: 08.09.2009г. Дата изменения: 03.05.2012г. Язык: PowerShell, C# (API-функции) Версия: 1.0 API реализовано на VB.NET 2.0 API реализовано на C# 2.1 Упрощен синтаксис в связи с обновлением оболочки PowerShell Комментарий: имя конфигурационного файла совпадает с названием сценария #########################################################> Clear-Host … Листинг 3а. Список всех переменных среды (get-item env:) | Out-GridView Листинг 3б. Определение значения заданного параметра (get-item env:).ПАРАМЕТР | Out-GridView (get-item env:).USERNAME Листинг 4. Определение значения заданного параметра $ScriptName=$null $ScriptPath=$null if ($Host.Name -like "ConsoleHost") { $ScriptName=$MyInvocation.MyCommand.Name $ScriptPath=$MyInvocation.InvocationName Write-Host ("Имя сценария: {0}" -f $ScriptName) Write-Host ("Путь к сценарию: {0}" -f $ScriptPath) } else { Write-Host "Ошибка: Некорректное имя хоста." } Листинг 5. Пример функции с именованными параметрами function Enum-Sum { Param ( [double]$X, [double]$Y ) $sum = $X+$Y return $sum } $SumXY = Enum-Sum -X 10.2 -Y 4.8 Write-Host ("Х + Y = {0}" -f $SumXY) Листинг 6. Пример функции, обрабатывающей произвольное количество параметров function Enum-Sum { $element=0 foreach($element in $args) {$sum+=$element} return $sum } $SumXY = Enum-Sum 10.2 4.8 5 Write-Host ("Summ = {0}" -f $SumXY) ----------------------------------------------------------------------------------------------------------------- Работаем с Active Directory на Perl. Запись данных Рашид Ачилов Листинг 1. Конфигурационный файл скрипта perlldapupdate.pl ldap_server=10.54.200.1 #LDAP сервер для подключения ldap_basedn="dc=shelton,dc=int" #Base DN для подключения ldap_binddn=ldapread@SHELTON.INT #Bind DN для подключения ldap_password="cXdlcnR5YXNkZgo 1" #Пароль для пользователя, от имени которого будет выполняться подключение ldap_users_filter= "(&(!(userAccountControl:1.2.840.113556.1.4.803:=2))(sAMAccountType=805306368))" #Фильтр отбора пользователей – все объекты типа «Пользователь»,у которых не установлено свойство «Заблокировать учетную запись» ldap_group_filter="(sAMAccountType=268435456)" #Фильтр отбора групп – все объекты типа «Группа» # echo somepassword | mmencode Листинг 3. Функция перекодировки строки из UTF-8 в KOI8-R # Перекодировка строки из UTF-8 в KOI8-R # Вход: $1 source (string) – строка в кодировке UTF-8 # Выход: dest (string) – строка в кодировке KOI8-R sub _from_utf8 { my $_src = shift(@_); my $converter = Text::Iconv->new("utf-8", "koi8-r"); my $converted = $converter->convert($_src); return($converted); } Листинг 4. Функция вывода сообщения в лог и на терминал # Основная функция вывода в лог и на терминал # Вход: $1 logline (string) – выводимая строка $2 important (string) – если DIE, немедленно завершиться # Выход: ничего # Глобал: _Command – хеш параметров командной строки # LOG – хэндл открытого файла лога sub safe_logger { our %_Command; my $logdate = time2str("%d/%m/%Y %T", time()); my ($logline, $important) = @_; my $line = sprintf("%s [%d] perlldapsetugid: $logline\n", $logdate, $$); print LOG $line; die $line if ($important =~ /DIE/); print $line if($_Command{'verbose'}); } Листинг 5. Запуск программы и подключение к AD # Расположение файла лога. Не настраивается my $logfile = ">>./ldapsetugid.log"; # Расположение файла конфига. Не настраивается, ищется только указанный файл my $config = "./ldapsetugid.conf"; # Прочитать файл конфигурации и импортировать все параметры в хеш _Config если файл существует и читается safe_logger(sprintf("Config file %s does not exist or does not readable", $_config), "DIE") if (! -e $config) || (! -r $config); Config::Simple->import_from($config, \%_Config) || die Config::Simple->error(); # Разобрать параметры командной строки, вернуть номер версии my $rev = parseOptions(\%_Config); # Открываем файл лога, если неуспешно, дальше не работаем open(LOG,$logfile) || die "Sorry, I could not open log file $logfile for writing : $!\n"; safe_logger(sprintf("PerlLDAPSetUGID ver. %s started", $rev), ""); # Получаем пароль для подключения к LDAP my $_ldap_pwd = demux_passwd($_Config{'default.ldap_password'}); # Подключаемся к LDAP my $ldap = Net::LDAP->new($_Config{'default.ldap_server'}) || die "Cannot connect to LDAP server $_Config{'default.ldap_server'}: $!\n"; my $msg = $ldap->bind("$_Config{'default.ldap_binddn'}", password => "$_ldap_pwd"); # Если подключиться не удалось, дальше не работаем safe_logger(sprintf "[%d] %s: %s",$msg->code(), $msg->error_name(),$msg->error_text(),"DIE") if ($msg->code()); Листинг 6. Получение NIS-имени домена # Первым делом ищем NIS-имя. Оно будет находиться в атрибуте cn my $nisattr = [ 'cn' ]; # Для поиска NIS-имени фильтруем данные особым образом my $nisres = $ldap->search (base => "$_Config{'default.ldap_basedn'}", scope => "sub", filter => "(msSFU30MaxUidNumber=*)", attrs => $nisattr ); # Если NIS-имя не нашли, дальше не работаем safe_logger(sprintf("Cannot read NIS domain name on LDAP server %s. " . "Install or configure IDMU first", $_Config{'default.ldap_server'}), "DIE") if (!$nisres->count); # Нужные данные в ячейке 0 my $nisentry = $nisres->entry(0); my $nisdomain = $nisentry->get_value('cn'); # Счетчики обработки UID и GID my $lngNextUID = 70000; my $lngNextGID = 70000; # Здесь будем хранить GID группы Domain Users my $intGIDomainUsers = 0; Листинг 7. Перебор групп AD и внесение изменений # Запрашиваемые атрибуты из AD для общего поиска my $ad_params = [ 'samaccountname' ]; # Для поиска групп используем фильтр групп my $groups = $ldap->search (base => "$_Config{'default.ldap_basedn'}", scope => "sub", filter => "$_Config{'default.ldap_group_filter'}", attrs => $ad_params ); # Вывести в лог количество прочитанных записей safe_logger(sprintf("Read %d group records from server %s", $groups->count, $_Config{'default.ldap_server'}), ""); # Обходим весь полученный массив и добавляем данные foreach $entry ($groups->entries) { # Предварительно преобразуем имя группы в кодировку KOI8-R my $groupname = _from_utf8($entry->get_value('samaccountname')); # Добавим атрибуты в локальную копию $entry->replace (gidNumber => $lngNextGID, msSFU30NisDomain => $nisdomain); safe_logger(sprintf("Group %s, assigned GID: ↵%d", $groupname, $lngNextGID), ""); # И обновим данные на сервере my $gres = $entry->update($ldap); # Если обновление неуспешно, дальше не работаем safe_logger(sprintf("Cannot write group %s attributes to LDAP server %s", $groupname, $_Config{'default.ldap_server'}), "DIE") if ($gres->code); # Сохраним GID группы Domain Users if ($entry->dn =~ /domain users/i) { safe_logger(sprintf("Found Domain Users group, GID: %d", $lngNextGID), ""); $intGIDomainUsers = $lngNextGID; } $lngNextGID++; } Листинг 8. Перебор пользователей AD и внесение изменений # Для обработки пользователей используем фильтр пользователей my $users = $ldap->search (base => "$_Config{'default.ldap_basedn'}", scope => "sub", filter => "$_Config{'default.ldap_users_filter'}", attrs => $ad_params ); # Вывести количество в лог safe_logger(sprintf("Read %d users records from server %s", $users->count, $_Config{'default.ldap_server'}), ""); # Обойти массив и добавить данные к каждому пользователю foreach $entry ($users->entries) { # Предварительно преобразовать имя пользователя в кодировку KOI8-R my $username = _from_utf8($entry->get_value('samaccountname')); # Добавить данные в локальную копию $entry->replace (gidNumber => $intGIDomainUsers, msSFU30NisDomain => $nisdomain, uidNumber => $lngNextUID); safe_logger(sprintf("User %s, assigned UID: %d", $username, $lngNextUID), ""); # И обновить на сервере my $ures = $entry->update($ldap); # Если обновление неуспешно, дальше не работаем safe_logger(sprintf("Cannot write user %s attributes to LDAP server %s", $username, $_Config{'default.ldap_server'}), "DIE") if ($ures->code); $lngNextUID++; } Листинг 9. Запись счетчиков в AD и завершение работы # DN для записи финальных счетчиков my $final = sprintf("CN=%s,CN=ypservers,CN=ypServ30, CN=RpcServices,CN=System,%s",$nisdomain, $_Config{'default.ldap_basedn'}); # Записать счетчики в AD my $mesg = $ldap->modify( $final,replace => {msSFU30MaxUidNumber => $lngNextUID, msSFU30MaxGidNumber => $lngNextGID,}); # Если неуспешно, дальше не работаем safe_logger(sprintf("Cannot write counters for NIS domain %s to LDAP server %s", $nisdomain, $_Config{'default.ldap_server'}), "DIE") if ($mesg->code); # Записать, сколько насчитали изменений safe_logger(sprintf("Renumbered %d users and %d groups", $lngNextUID - 70000, $lngNextGID - 70000), ""); # Завершиться $ldap->unbind; close(LOG); ----------------------------------------------------------------------------------------------------------------- Компьютерная графика на основе OpenGL. Часть 3. Основы 3D-математики с учетом SSE-технологий Алексей Верижников __m128 f1= _mm_mul_ps(xmm1, xmm0); asm { mulps xmm1, xmm0 ; }; __asm__ volatile ( "mulps %xmm0, %%xmm1\n\t" : : [a]"m"(*a), [b]"m"(*b) : "%xmm0", "%xmm1" ); Lib3dsFile* Load3ds(const char* filename) { FILE *file; Lib3dsFile *f = 0; Lib3dsIo io; int result; file = fopen(filename, "rb"); if (!file) { fprintf(stderr, "***ERROR***\nFile not found: %s\n", filename); return NULL; } f = lib3ds_file_new(); memset(&io, 0, sizeof(io)); io.self = file; io.seek_func = fileio_seek_func; io.tell_func = fileio_tell_func; io.read_func = fileio_read_func; io.write_func = fileio_write_func; io.log_func = fileio_log_func; result = lib3ds_file_read(f, &io); fclose(file); return f; } static long fileio_seek_func(void *self, long offset, Lib3dsIoSeek origin) static long fileio_tell_func(void *self) static size_t fileio_read_func(void *self, void *buffer, size_t size) static size_t fileio_write_func(void *self, const void *buffer, size_t size) static void fileio_log_func(void *self, Lib3dsLogLevel level, int indent, const char *msg) for (int i = 0; i < mesh3ds->nfaces; ++i) { int index0 = mesh3ds->faces[i].index[0]; int index1 = mesh3ds->faces[i].index[1]; int index2 = mesh3ds->faces[i].index[2]; mesh.indexes[3*i] = index0; mesh.indexes[3*i+1] = index1; mesh.indexes[3*i+2] = index2; nmemcpy(&va.m, mesh3ds->vertices[index0], 3*sizeof(GLfloat)); nmemcpy(&vb.m, mesh3ds->vertices[index1], 3*sizeof(GLfloat)); nmemcpy(&vc.m, mesh3ds->vertices[index2], 3*sizeof(GLfloat)); vn = normalize(cross(vc - va, vb - va))*minus; // Расчет сглаженных нормалей for (int j = 0; j < 3; ++j) { int index = mesh.indexes[3*i+j]; if (normalFacesCount[index] == 0) { nmemcpy(&mesh.normals[3*index], &vn.m, 3*sizeof(GLfloat)); normalFacesCount[index]++; } else { vec4 vn0; nmemcpy(&vn0.m, &mesh.normals[3*index], 3*sizeof(GLfloat)); vn0 = vn + vn0; nmemcpy(&mesh.normals[3*index], &vn0.m, 3*sizeof(GLfloat)); normalFacesCount[index]++; } }//for j ... }//for (int i = 0; i < mesh3ds->nfaces; ++i) vn = normalize(cross(vc - va, vb — va))*minus; glBegin(GL_TRIANGLES); glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(0.5f, 0.5f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.5f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glEnd(); ls_qube=glGenLists(1); glNewList(ls_qube,GL_COMPILE); … <команды OpenGL> glEndList(); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glNormalPointer(GL_FLOAT, 0, mesh.normals); glColorPointer(4, GL_FLOAT, 0, mesh.colors); glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes); glTexCoordPointer(2, GL_FLOAT, 0, mesh.texcoords); glDrawElements(GL_TRIANGLES, mesh.indexCount*3, GL_UNSIGNED_INT , mesh.indexes); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glNormalPointer(GL_FLOAT, 0, mesh.normals); glColorPointer(4, GL_FLOAT, 0, mesh.colors); glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes); glTexCoordPointer(2, GL_FLOAT, 0, mesh.texcoords); glDrawElements(GL_TRIANGLES, mesh.indexCount*3, GL_UNSIGNED_INT , mesh.indexes); GLfloat *vertex = new GLfloat[mesh->nvertices*3]; ... GLuint *indices = new GLuint[mesh->nfaces*3]; glGenBuffersARB(1, &mesh.vboIdVertex); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh.vboIdVertex); glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexSize+normalSize+colorSize+textureSize*4,0, GL_STATIC_DRAW_ARB); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vertexSize, mesh.vertexes); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vertexSize, normalSize, mesh.normals); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vertexSize+normalSize, colorSize, mesh.colors); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vertexSize+normalSize+colorSize, textureSize, mesh.texcoords); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vertexSize+normalSize+colorSize+textureSize, textureSize, mesh.texcoords); glGenBuffersARB(1, &mesh.vboIdIndex ); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mesh.vboIdIndex); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,indexSize, mesh.indexes, GL_STREAM_DRAW_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); glGenBuffersARB(1, &mesh.vboIdVertex); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh.vboIdVertex); glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexSize+normalSize+colorSize+textureSize*4,0, GL_STATIC_DRAW_ARB); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,indexSize, mesh.indexes, GL_STREAM_DRAW_ARB); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vertexSize, normalSize, mesh.normals); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh.vboIdVertex); glNormalPointer(GL_FLOAT, 0, BUFFER_OFFSET(vertexSize)); glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(vertexSize+normalSize)); glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)); glClientActiveTextureARB(GL_TEXTURE0_ARB); glTexCoordPointer(2,GL_FLOAT,0, BUFFER_OFFSET(vertexSize+normalSize+colorSize)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mesh.vboIdIndex); glDrawElements(GL_TRIANGLES, mesh.indexCount*3, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); glDisableClientState(GL_VERTEX_ARRAY); ... glDisableClientState(GL_TEXTURE_COORD_ARRAY); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); glNormalPointer(GL_FLOAT, 0, BUFFER_OFFSET(vertexSize)); glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(vertexSize+normalSize)); glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)); glTexCoordPointer(2,GL_FLOAT,0, BUFFER_OFFSET(vertexSize+normalSize+colorSize)); glGenVertexArrays(1, &mesh.vaoID); glBindVertexArray(mesh.vaoID); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh.vboIdVertex); glNormalPointer(GL_FLOAT, 0, BUFFER_OFFSET(vertexSize)); glEnableClientState(GL_NORMAL_ARRAY); glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(vertexSize+normalSize)); glEnableClientState(GL_COLOR_ARRAY); glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)); glEnableClientState(GL_VERTEX_ARRAY); glClientActiveTextureARB(GL_TEXTURE0_ARB); glTexCoordPointer(2,GL_FLOAT,0, BUFFER_OFFSET(vertexSize+normalSize+colorSize)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindVertexArray(0); glBindVertexArray(mesh.vaoID); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mesh.vboIdIndex); glDrawElements(GL_TRIANGLES, mesh.indexCount*3, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); glBindVertexArray(0); ----------------------------------------------------------------------------------------------------------------- MathML – история с математикой Кирилл Сухов i = 0 x i MathLM in action …........... 5 x 2 + 8x + 7 = 0 5 x 2 x 8 7 a x 2 + b x + c = 0 x 1 , 2 = - b ± b 2 - 4 a c 2 a b + c 3 0 1 f x x i = 0 A B i = 0 A B 7F800000 227 2 3.1415 π C 2 x 1 t 1 x x 1 t 1 x 1 t x x -----------------------------------------------------------------------------------------------------------------