Резервное копирование с помощью 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('
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 – история с математикой
Кирилл Сухов
MathLM in action
5
x
2
x
8
7
a
x
2
+
b
x
+
c
=
0
b
+
c
3
7F800000
227
2 3.1415
π
C
2
x
1
t
1
x
x
1
t
1
x
∫
1
t
ⅆ
x
x
-----------------------------------------------------------------------------------------------------------------