Openvpn, или Кроссплатформенная частная сеть Андрей Бешков # apt-get update # apt-get install iptables openssl liblzo liblzo-devel openvpn # useradd openvpn # openvpn --show-ciphers # openvpn --show-digests #openvpn --genkey --secret /etc/openvpn/static.key # openvpn --test-crypto --secret /etc/openvpn/static.key proto udp dev tun port 5000 comp-lzo ping 15 verb 3 user openvpn group openvpn remote 80.80.20.129 ifconfig 10.3.0.9 10.3.0.10 route 10.10.120.0 255.255.255.0 10.3.0.10 secret /etc/openvpn/static.key auth MD5 cipher DES-CBC tun-mtu 1500 proto udp dev tun port 5002 comp-lzo ping 15 verb 3 user openvpn group openvpn remote 80.80.20.128 ifconfig 10.3.0.6 10.3.0.5 route 10.10.130.0 255.255.255.0 10.3.0.5 secret /etc/openvpn/static.key tun-mtu 1500 auth MD5 cipher DES-CBC # cd /usr/ports/archivers/lzo # make install clean # cd ../../security/openssl # make install clean # cd ../openvpn # make install clean # make deinstall # pkg_add openvpn-1.6.0.tgz # adduser openvpn dev tun port 5000 comp-lzo ping 15 verb 3 user openvpn group openvpn remote 80.80.20.131 ifconfig 10.3.0.10 10.3.0.9 route 10.10.140.0 255.255.255.0 10.3.0.9 secret /etc/openvpn/static.key auth MD5 cipher DES-CBC tun-mtu 1500 comp-lzo dev tun remote 80.80.20.128 port 5001 ifconfig 10.3.0.1 10.3.0.2 route 10.10.130.0 255.255.255.0 10.3.0.2 secret /etc/openvpn/static.key ping 10 verb 3 tun-mtu 1500 user openvpn group openvpn auth MD5 cipher DES-CBC comp-lzo # openvpn --config /etc/openvpn/linux-freebsd.conf # openvpn --config /etc/openvpn/freebsd-linux.conf # openvpn --remote 80.80.20.128 --dev tun --port 5001 --ifconfig 10.3.0.1 10.3.0.2 --route 10.10.130.0 255.255.255.0 10.3.0.2 --secret /etc/openvpn/static.key --ping 10 --verb 3 --tun-mtu 1500 --user openvpn --group openvpn --auth MD5 --cipher DES-CBC #! /bin/sh case x$1 in xstart) /usr/local/sbin/openvpn --config /etc/openvpn/freebsd-linux.conf & /usr/local/sbin/openvpn --config /etc/openvpn/freebsd-windows.conf & ;; xstop) killall -SIGTERM openvpn route delete 10.10.130.0 route delete 10.10.140.0 ;; *) echo >&2 "Usage: $0 {start|stop}" esac remote 80.80.20.129 dev-node FreeBSD dev tun port 5001 ifconfig 10.3.0.2 10.3.0.1 secret static.txt ping 10 verb 3 route 10.10.120.0 255.255.255.0 10.3.0.1 auth MD5 cipher DES-CBC comp-lzo remote 80.80.20.131 dev tun dev-node Linux port 5002 ifconfig 10.3.0.5 10.3.0.6 secret static.txt ping 10 verb 3 route 10.10.140.0 255.255.255.0 10.3.0.6 tun-mtu 1500 comp-lzo # service openvpn stop # service openvpn start # /usr/local/etc/rc.d/openvpn.sh stop # /usr/local/etc/rc.d/openvpn.sh start # tcpdump –i tun0 -lenx # tcpdump –i lnc1 -lenx Linux и NTFS Сергей Яремчук # dmesg | grep -i ntfs # grep -i ntfs /var/log/messages # cat /proc/filesystems #rpm -ihv --noscripts kernel-ntfs-2.6.5-1.358.i586.rpm #/sbin/depmod -a # bunzip2 linux-2.4.25-ntfs-2.1.6a.patch.bz2 #cd /usr/src #cd linux #patch -p1 < ../linux-2.4.25-ntfs-2.1.6a.patch #grep -i ntfs /var/log/messages # fdisk -l | grep -i ntfs # mount /dev/hda7 /mnt/temp/ -t ntfs # cat /proc/mounts | grep -i ntfs #mount /dev/hda7 /mnt/temp/ -t ntfs -r -o nls=koi8-r -o uid=500,gid=winuser,umask=0222 #ntfsclone --output system.img /dev/hda1 #ntfsclone --overwrite /dev/hda1 system.img #mount -t ntfs -o loop system.img /mnt/ntfsclone #./ntfscluster /dev/hda7 # ./ntfslabel -v /dev/hda7 # ./ntfsls -v -d /dev/hda7 #./ntfsundelete /dev/hda7 #./ntfsundelete /dev/hda7 --force #./ntfsundelete /dev/hda7 -s -m home.jpg --force # mount -t captive-ntfs /dev/hda7 /mnt/utils/ #cat /var/log/messages | grep captive-lufs #mount -t ufsd /dev/hda7 /mnt/test_ntfs # mount -t ufsd -o iocharset=koi8-r /dev/hda7 /mnt/test_ntfs # ./ntfsresize -i /dev/hda7 # ./ntfsresize --no-action --size 500M /dev/hda7 # ./ntfsresize -s 500M /dev/hda7 #./ntfsresize --info --force /dev/hda7 # dd if=/dev/hda of=hda.mbr bs=512 count=1 # fdisk /dev/hda # ./ntfsresize -i -f /dev/hda7 Еще раз о ClamAV: особенности установки во FreeBSD Сергей Супрунов CONFIGURE_ARGS= --with-dbdir=${DATADIR} --disable-clamuko --disable-clamav --enable-bigstack --disable-dependency-tracking CONFIGURE_ARGS+= --enable-milter OPTIONS= MILTER “Compile the milter interface” off /usr/local/etc/rc.d/clamav-clamd.sh start #!/bin/sh # Manager for ClamAV: clamd & clamav-milter case $1 in start) if [ -e /var/run/clamav/clamd.pid ]; then echo 'Ingored - clamd already started.' exit 0 fi if [ -e /var/run/clamav/clmilter.sock ]; then rm /var/run/clamav/clmilter.sock fi /usr/local/sbin/clamd /usr/local/sbin/clamav-milter -blo /var/run/clamav/clmilter.sock echo 'clamd & clamav-milter started' ;; stop) killall clamav-milter kill -15 `cat /var/run/clamav/clamd.pid` echo 'clamd & clav-milter stopped' ;; restart) kill -1 `cat /var/run/clamav/clamd.pid` echo 'clamd restarted' ;; fresh) /usr/local/bin/freshclam ;; *) echo "Usage: `basename $0` ї {start|stop|restart|fresh}" >&2 ;; esac exit 0 0 0,12 * * * /usr/local/bin/freshclam В яблочко! Краткий обзор ОС Darwin 7.0 на платформе x86 (Mac OS X 10.3 Jaguar) Антон Борисов wget -ct0 http://opendarwin.org/downloads/darwin-701.iso.gz gzip -d darwin-701.iso.gz cdrecord -v darwin-701.iso # DarwinOS begins other = /dev/hdd2 label = DarwinOS # DarwinOS ends # ifconfig en0 inet 10.0.0.10 netmask 255.255.255.0 up # cat Network #!/bin/sh ## # Configure network interfaces and host name ## . /etc/rc.common StartService () { ConsoleMessage "Initializing network" ipconfig waitall > /dev/null 2>&1 if [ "${IPV6:=-YES-}" = "-NO-" ] then sysctl -w net.inet6.ip6.auto_on=0 > /dev/null ip6 -x fi if [ "${IPFORWARDING:=-NO-}" = "-YES-" ] then sysctl -w net.inet.ip.forwarding=1 > /dev/null else sysctl -w net.inet.ip.forwarding=0 > /dev/null fi ifconfig en0 10.0.0.10 netmask 255.255.255.0 } StopService () { return 0 } RestartService () { return 0 } RunService "$1" Kernel mach_kernel Kernel Flags -v Boot Graphics Yes APM Yes killall -1 inetd # cat /etc/hostconfig # /etc/hostconfig ## # This file is maintained by the system control panels ## # Network configuration HOSTNAME=DarwinOS # Services AUTOMOUNT=-NO- CUPS=-NO- IPFORWARDING=-NO- IPV6=-YES- NETINFOSERVER=-NO- NISDOMAIN=-NO- RPCSERVER=-YES- QTSSERVER=-YES- WEBSERVER=-YES- DNSSERVER=-NO- COREDUMPS=-NO- VPNSERVER=-NO- #!/bin/sh # Include system wide configuration options . /etc/rc.common # Start SMB services if [ "${SMBSERVER:=-NO-}" = "-YES-" ]; then ConsoleMessage "Starting SMB services" /usr/sbin/smbd -D /usr/sbin/nmbd -D fi { Description = "smb file server"; Provides = ("Samba"); Requires = ("Resolver"); OrderPreference = "None"; Messages = { start = "Starting Samba"; stop = "Stopping Samba"; }; } cd /etc ln -s /usr/share/zoneinfo/Europe/Moscow localtime niutil -create / /users/Bob niutil -createprop / /users/Bob shell /bin/tcsh niutil -createprop / /users/Bob realname UncleBob niutil -createprop / /users/Bob home /Users/Bob niutil -createprop / /users/Bob _shadow_passwd cd /Users mkdir Bob chown -R Bob:wheel Bob niutil -list . / niutil -read . /locations/resolver niutil -createprop . /locations/resolver nameserver 10.0.0.100 nidump -r / / > nidump.txt # cat ~/.xinitrc /usr/X11R6/bin/xterm & /usr/X11R6/bin/twm # chmod +x .xinitrc # startx wget -ct0 http://prdownloads.sf.net/blackboxwm/blackbox-0.65.0.tar.gz mkdir ~/sources mv blackbox-0.65.0.tar.gz sources tar xzvf blackbox-0.65.0.tar.gz cd blackbox-0.65.0 ./configure --prefix=/usr/local/blackbox make && make install echo “/usr/local/blackbox/bin/blackbox” > ~/.xinitrc # kextstat rootfuji:# /usr/local/nmap/bin/nmap -v -sS -O darwin DarwinOS:~ root# smbclient -L fuji -I fuji 2> /dev/null DarwinOS:~ root# fdisk /dev/rdisk1 # ls /System/Library/Filesystems # mount /dev/hdd2 /mnt/hd –t ufs –o, ufstype=44bsd Практика работы с NetBSD: профилирование ядра Александр Байрак # cd /sys/arch/i386/conf/ # config –p GENERIC # cd ../compile/GENERIC.PROF/ # make depend && make # cp /netbsd /netbsd.old # cp netbsd /netbsd # reboot # kgmon – b # kgmon –h # kgmon –p #gprof /netbsd > gprof.out for (x = 0; x < 100000000; x++) { y = x; } int x; int y; Создание и настройка IVR для голосовых шлюзов Cisco Systems Михаил Заграевский voice-port 1/0/0 cptone RU timeouts initial 20 timeouts interdigit 20 timeouts wait-release 10 dial-peer voice 1 pots application debitcard port 1/0/0 call application voice debitcard slot0:/ivr/debitcard.tcl call application voice debitcard uid-len 8 call application voice debitcard pin-len 3 call application voice debitcard warning-time 10 call application voice debitcard language 1 ru call application voice debitcard language 2 en call application voice debitcard set-location ru 0 slot0:/ivr/prompts/ru/ call application voice debitcard set-location en 0 slot0:/ivr/prompts/en/ call application voice debitcard say_seconds yes proc init { } { global param; global retryCnt; global LangPattern; global ParamForCard; global ParamForDest; global AccountLen; global PinLen; global CardLen; global WarnTime; set param(abortKey) * set param(interruptPrompt) true set param(ignoreInitialTermKey) true set LangPattern(1) {[1,2]} set AccountLen [string trim [infotag get cfg_avpair uid-len]]; set PinLen [string trim [infotag get cfg_avpair pin-len]]; set retryCnt [string trim [infotag get cfg_avpair retry-count]]; set WarnTime [string trim [infotag get cfg_avpair warning-time]]; set CardLen [expr $AccountLen + $PinLen]; set ParamForCard(abortKey) * set ParamForCard(initialDigitTimeout) 10 set ParamForCard(terminationKey) # set ParamForCard(maxDigits) $CardLen; set ParamForCard(interruptPrompt) true set ParamForDest(abortKey) * set ParamForDest(initialDigitTimeout) 10 set ParamForDest(terminationKey) # set ParamForDest(interruptPrompt) true set ParamForDest(dialPlanTerm) true; set ParamForDest(ignoreInitialTermKey) true; return; } proc init_perCallVars { } { global NumLangPrompt; global NumCardPrompt; global NumDestPrompt; global PromptFlag; global DestPromptFlag; global NoPlayWarn; global NoTimeLimit; global SetupDone; set NumLangPrompt 0; set NumCardPrompt 0; set NumDestPrompt 0; set PromptFlag 0; set DestPromptFlag 0; set NoPlayWarn 0; set NoTimeLimit 0; set SetupDone 0; return; } proc act_Setup { } { init_perCallVars; leg setupack leg_incoming; infotag set med_language prefix "ru"; SelectLanguageMenu; return; } set ivr_fsm(CALLCOMES,ev_setup_indication) "act_Setup same_state"; leg collectdigits 1 callInfo leg collectdigits 2 callInfo leg setup 295786 setupInfo $callID5 puts "\nThis will be executed immediately i.e. before the collect digits or call setup is actually complete" set array(curr_state,curr_event) “act_proc NEXTSTATE” set ivr_fsm(CALLCOMES,ev_setup_indication) "act_Setup same_state"; call application voice debitcard set-location ru 0 slot0:/ivr/prompts/ru/ proc SelectLanguageMenu { } { global param; global retryCnt; global NumLangPrompt; global LangPattern; if {$NumLangPrompt < $retryCnt} { media play leg_incoming %s2000 _RUS_lang_sel1.au %s500 _ENG_lang_sel2.au leg collectdigits leg_incoming param LangPattern; } else { media play leg_incoming _final.au; fsm setstate CALLDISCONNECT; } return; } set ivr_fsm(CALLCOMES,ev_collectdigits_done) "CheckLangSelection CHECKLANG"; proc CheckLangSelection { } { global NumLangPrompt; set collect_status [infotag get evt_status]; set collect_digits [infotag get evt_dcdigits]; switch $collect_status { "cd_001" { incr NumLangPrompt; media play leg_incoming _no_digits_entered.au; return; } "cd_002" { SelectLanguageMenu; fsm setstate CALLCOMES; return; } "cd_005" { infotag set med_language $collect_digits; fsm setstate CARDSELECTION; act_GetCard; return; } "cd_006" { incr NumLangPrompt; media play leg_incoming _wrong_lang_sel.au; return; } default { media play leg_incoming _no_aaa.au; fsm setstate CALLDISCONNECT; } } return; } proc act_GetCard { } { global ParamForCard; global NumCardPrompt; global PromptFlag; global retryCnt; if {$NumCardPrompt < $retryCnt} { switch $PromptFlag { 0 {media play leg_incoming %s500_enter_card_num.au; #first play} 1 {media play leg_incoming _invalid_digits.au; #Not enuf digits pressed} 3 {media play leg_incoming _no_card_entered.au; #Timeout - no digits entered} default { media play leg_incoming _no_aaa.au; fsm setstate CALLDISCONNECT; return; } } leg collectdigits leg_incoming ParamForCard; } else { media play leg_incoming _final.au; fsm setstate CALLDISCONNECT; } return; } proc act_GotCardNumber { } { global NumCardPrompt global AccountLen; global PinLen; global CardLen; global PromptFlag; global retryCnt; global account; global pin; set status [infotag get evt_status]; switch $status { "cd_005" { set card_number [infotag get evt_dcdigits]; set card_len [string length $card_number]; if {$card_len == $CardLen} { set account [string range $card_number 0 [expr $AccountLen - 1]]; set pin [string range $card_number $AccountLen [expr $card_len - 1]] puts "account = $account pin = $pin"; aaa authorize $account $pin "" "" leg_incoming; } else { incr NumCardPrompt; set PromptFlag 1; act_GetCard; return; } } "cd_001" { incr NumCardPrompt; set PromptFlag 3; act_GetCard; return; } "cd_002" { set PromptFlag 0 act_GetCard; return; } } return; } aaa authorize $account $pin "" "" leg_incoming; set ivr_fsm(CARDSELECTION,ev_authorize_done) "act_CardAuthorize same_state"; proc act_CardAuthorize { } { global PromptFlag; global NumCardPrompt; global ParamForDest; global ParamForCard; global retryCnt; set status [infotag get evt_status]; if {$status == "ao_000"} { if {[infotag get aaa_avpair_exists h323-credit-amount]} { set amt [infotag get aaa_avpair h323-credit-amount] } else { media play leg_incoming _no_aaa.au; fsm setstate CALLDISCONNECT; return; } fsm setstate DESTSELECTION; if {$amt <= 999999.99} { media play leg_incoming _you_have.au %a$amt_enter_dest.au; } else { media play leg_incoming _enter_dest.au; } leg collectdigits leg_incoming ParamForDest; return; } if {[infotag get aaa_avpair_exists h323-return-code]} { set return_code [infotag get aaa_avpair h323-return-code]; } else { media play leg_incoming _no_aaa.au; fsm setstate CALLDISCONNECT; return; } incr NumCardPrompt; if {$NumCardPrompt < $retryCnt} { leg collectdigits leg_incoming ParamForCard; act_PlayCardReturnCode $return_code; } else { ct_GetCard; } return; } infotag get aaa_avpair_exists h323-return-code set ivr_fsm(CARDSELECTION,ev_collectdigits_done) proc act_PlayCardReturnCode { return_code } { switch $return_code { 2 {media play leg_incoming _auth_fail.au;} 7 {media_play leg_incoming _zero_bal.au;} default { media play leg_incoming _no_aaa.au; fsm setstate CALLDISCONNECT; return; } } return; } proc act_GetDestination { } { global retryCnt; global ParamForDest; global DestPromptFlag; global NumDestPrompt; if {$NumDestPrompt < $retryCnt} { switch $DestPromptFlag { 0 {media play leg_incoming _enter_dest.au; #Abortkey pressed} 1 {media play leg_incoming _no_dest_entered.au; #Timeout -no digits entered} 2 {media play leg_incoming _reenter_dest.au; #Not mutch to the dial plan} default { media play leg_incoming _no_aaa.au; fst setstate CALLDISCONNECT; return; } } leg collectdigits leg_incoming ParamForDest; } else { media play leg_incoming _dest_collect_fail.au; fsm setstate CALLDISCONNECT; } return; } proc act_GotDestination { } { global NumDestPrompt; global DestPromptFlag; global account; global pin; global destination; set status [infotag get evt_status]; switch $status { "cd_001" { incr NumDestPrompt; set DestPromptFlag 1; act_GetDestination; return; } "cd_002" { set DestPromptFlag 0; act_GetDestination; return; } "cd_004" { set destination [infotag get evt_dcdigits]; puts "\n************dest_number = $destination"; aaa authorize $account $pin "" $destination leg_incoming; return; } default { incr NumDestPrompt; set DestPromptFlag 2; act_GetDestination; return; } } return; } set ivr_fsm(DESTSELECTION,ev_collectdigits_done) "act_GotDestination same_state"; aaa authorize $account $pin "" $destination leg_incoming; set ivr_fsm(DESTSELECTION,ev_authorize_done) "act_CallAuthorize same_state"; proc act_CallAuthorize { } { global NumDestPrompt; global DestPromptFlag; global WarnTime; global NoPlayWarn; global NoTimeLimit; global creditTime; global retryCnt; global ParamForDest; global param; set status [infotag get evt_status]; set param(enableReporting) true; set param(interruptPrompt) false; if {$status == "ao_000"} { if {[infotag get aaa_avpair_exists h323-credit-time]} { set creditTime [infotag get aaa_avpair h323-credit-time]; } else { media play leg_incoming _no_aaa.au; fsm setstate CALLDISCONNECT; return; } if {$creditTime <= $WarnTime} {set NoPlayWarn 1;} if {$creditTime == "unlimited"} {set NoTimeLimit 1;} media play leg_incoming _you_have.au %t$creditTime; leg collectdigits leg_incoming param; #For Fast leg setup fsm setstate PLACECALL; return; } incr NumDestPrompt; #Call authorize failed if {[infotag get aaa_avpair_exists h323-return-code]} { set return_code [infotag get aaa_avpair h323-return-code]; } else { media play leg_incoming no_aaa.au; fsm setstate CALLDISCONNECT; return; } if {$NumDestPrompt < $retryCnt} { act_PlayDestReturnCode $return_code; leg collectdigits leg_incoming ParamForDest; } else { act_GetDestination; } return; } set ivr_fsm(PLACECALL,ev_media_done) "act_CallSetup same_state; set ivr_fsm(DESTSELECTION,ev_collectdigits_done) "act_GotDestination same_state"; set param(enableReporting) true set param(interruptPrompt) false; set ivr_fsm(PLACECALL,ev_digit_end) "act_FastSetup same_state"; proc act_FastSetup { } { global SetupDone; if {[infotag get evt_digit] != "#" || $SetupDone} { return; } media stop leg_incoming; act_CallSetup; set SetupDone 1; return; } proc act_CallSetup { } { global destination; global account; global SetupDone; set callinfo(accountNum) $account; set callinfo(alertTime) 60; set SetupDone 1; leg setup $destination callinfo leg_incoming; return; } leg setup $destination callinfo leg_incoming set ivr_fsm(PLACECALL,ev_setup_done) "act_CallSetupDone same_state"; proc act_CallSetupDone { } { global DestPromptFlag; global ParamForDest; global param; global NoTimeLimit; global creditTime; global WarnTime; global NoPlayWarn; global SetupDone; set status [infotag get evt_status]; switch $status { "ls_000" { if {!$NoTimeLimit} { #Setting call timer if {$NoPlayWarn} { timer start leg_timer [expr $creditTime - 1] leg_incoming; fsm setstate CALLLASTACTIVE; } else { set delay [expr $creditTime - $WarnTime]; timer start leg_timer $delay leg_incoming; fsm setstate CALLACTIVE; } } set param(enableReporting) true; leg collectdigits leg_incoming param; #For long pound return; } "ls_007" { set DestPromptFlag 0; set SetupDone 0; media play leg_incoming _dest_busy.au; leg collectdigits leg_incoming ParamForDest; fsm setstate DESTSELECTION; return; } default { set DestPromptFlag 0; set SetupDone 0; media play leg_incoming _dest_unreachable.au %s200 _enter_dest.au; leg collectdigits leg_incoming ParamForDest; fsm setstate DESTSELECTION; return; } } return; } set ivr_fsm(CALLACTIVE,ev_leg_timer) "act_ActiveTimer CALLWARN"; set ivr_fsm(CALLLASTACTIVE,ev_leg_timer) "act_LastActiveTimer same_state"; set ivr_fsm(CALLACTIVE,ev_digit_end) "act_LongPound CONNDESTROY"; set ivr_fsm(DESTSELECTION,ev_collectdigits_done) "act_GotDestination same_state"; proc act_PlayDestReturnCode {return_code} { switch $return_code { 9 {media play leg_icoming _dest_blocked.au %s500_enter_dest.au;} 12 {media play leg_incoming _not_enuf.au %s500_enter_dest.au;} default { media play leg_incoming _no_aaa.au; fsm setstate CALLDISCONNECT; return; } } return; } proc act_ActiveTimer { } { global WarnTime; global incoming; global outgoing; set incoming [infotag get leg_incoming]; set outgoing [infotag get leg_outgoing]; connection destroy con_all; timer start leg_timer [expr $WarnTime - 1] leg_incoming; return; } set ivr_fsm(CALLWARN,ev_destroy_done) "act_CallWarnDestroy same_state"; proc act_LastActiveTimer { } { connection destroy con_all; return; } set ivr_fsm(CALLLASTACTIVE,ev_leg_timer) "act_LastActiveTimer same_state"; set ivr_fsm(CALLLASTACTIVE,ev_destroy_done) "act_PlayDisconnect CALLDISCONNECT"; proc act_PlayDisconnect { } { media play leg_incoming _disconnected.au fsm setstate CALLDISCONNECT; return; } proc act_CallWarnDestroy { } { global WarnTime; media play leg_incoming _you_have.au %t$WarnTime; return; } set ivr_fsm(CALLWARN,ev_destroy_done) "act_CallWarnDestroy same_state"; set ivr_fsm(CALLWARN,ev_media_done) "act_CallWarnMedia CALLLASTACTIVE"; proc act_CallWarnMedia { } { global incoming; global outgoing; connection create $incoming $outgoing; return; } proc act_LongPound { } { if {[infotag get evt_digit] != "#"} { fsm setstate same_state; return; } set duration [infotag get evt_digit_duration]; if {$duration < 300} { fsm setstate same_state; return; } connection destroy con_all; return; } set ivr_fsm(CALLACTIVE,ev_digit_end) "act_LongPound CONNDESTROY"; set ivr_fsm(CALLLASTACTIVE,ev_digit_end) "act_LongPound CONNDESTROY"; set ivr_fsm(CONNDESTROY,ev_destroy_done) "act_ConnDestroyed same_state"; proc act_ConnDestroyed { } { leg disconnect leg_outgoing; init_perCallVars; act_GetDestination; fsm setstate DESTSELECTION; return; } proc act_Cleanup { } { call close; } requiredversion 2.0 init set ivr_fsm(any_state,ev_disconnected) "act_Cleanup same_state"; set ivr_fsm(CALLCOMES,ev_setup_indication) "act_Setup same_state"; set ivr_fsm(CALLCOMES,ev_collectdigits_done) "CheckLangSelection CHECKLANG"; set ivr_fsm(CHECKLANG,ev_media_done) "SelectLanguageMenu CALLCOMES"; set ivr_fsm(CARDSELECTION,ev_collectdigits_done) "act_GotCardNumber same_state"; set ivr_fsm(CARDSELECTION,ev_authorize_done) "act_CardAuthorize same_state"; set ivr_fsm(DESTSELECTION,ev_collectdigits_done) "act_GotDestination same_state"; set ivr_fsm(DESTSELECTION,ev_authorize_done) "act_CallAuthorize same_state"; set ivr_fsm(PLACECALL,ev_media_done) "act_CallSetup same_state"; set ivr_fsm(PLACECALL,ev_setup_done) "act_CallSetupDone same_state"; set ivr_fsm(PLACECALL,ev_digit_end) "act_FastSetup same_state"; set ivr_fsm(CALLACTIVE,ev_digit_end) "act_LongPound CONNDESTROY"; set ivr_fsm(CALLACTIVE,ev_leg_timer) "act_ActiveTimer CALLWARN"; set ivr_fsm(CALLWARN,ev_destroy_done) "act_CallWarnDestroy same_state"; set ivr_fsm(CALLWARN,ev_media_done) "act_CallWarnMedia CALLLASTACTIVE"; set ivr_fsm(CALLLASTACTIVE,ev_leg_timer) "act_LastActiveTimer same_state"; set ivr_fsm(CALLLASTACTIVE,ev_destroy_done) "act_PlayDisconnect CALLDISCONNECT"; set ivr_fsm(CALLLASTACTIVE,ev_digit_end) "act_LongPound CONNDESTROY"; set ivr_fsm(CONNDESTROY,ev_destroy_done) "act_ConnDestroyed same_state"; set ivr_fsm(CALLDISCONNECT,ev_media_done) "act_Cleanup same_state"; set ivr_fsm(CALLDISCONNECT,ev_disconnect_done) "act_Cleanup same_state"; fsm define ivr_fsm CALLCOMES; Разгон и торможение Windows NT Крис Касперски Листинг 1. Измеритель скорости переключения контекста thread() { // отдаем процессорное время в бесконечном цикле while(1) Sleep(0); } #define defNthr 300 #define argNthr ((argc > 1)?atol(argv[1]):defNthr) main(int argc, char **argv) { int a, zzz; printf("creating %d threads...", argNthr); // создаем argNthr потоков for (a = 0; a < argNthr; a++) CreateThread(0, 0, (void*)thread, 0,0, &zzz); printf("OK\n"); thread(); return 0; } Листинг 2. Измеритель скорости переключения процессов thread() { while(1) Sleep(0); } #define defNthr 3 #define argNthr ((argc > 1)?atol(argv[1]):defNthr) #define argProc "-666" main(int argc, char **argv) { int a, zzz; char buf[1000]; STARTUPINFO st; PROCESS_INFORMATION pi; memset(&st, 0, sizeof(st)); st.cb = sizeof(st); if ((argc > 1) && !strcmp(argv[1], argProc)) thread(); sprintf(buf,"%s %s",argv[0], argProc); printf("creating %d proc...", argNthr); for (a = 0; a < argNthr; a++) CreateProcess(0, buf, 0,0,0, NORMAL_PRIORITY_CLASS,0, 0, &st, &pi); printf("OK\n"); thread(); return 0; } Листинг 3. Функции ядра, прямо или косвенно относящиеся к планированию 4484 ntoskrnl.exe ExReleaseResourceForThread 4362 ntoskrnl.exe KiDispatchInterrupt 4333 ntoskrnl.exe SeTokenImpersonationLevel 2908 ntoskrnl.exe KeDelayExecutionThread 2815 ntoskrnl.exe KiIpiServiceRoutine 300 ntoskrnl.exe RtlPrefetchMemoryNonTemporal 73 ntoskrnl.exe KeDisconnectInterrupt 41 ntoskrnl.exe ExFreePoolWithTag Листинг 4. Измеритель продолжительности квантов thread() { int a, b; while(!f) Sleep(0); while (f != 2); while(1) { for (a = 1; a< 100; a++) b = b + (b % a); } } #define defNthr 300 #define argNthr ((argc > 1)?atol(argv[1]):defNthr) main(int argc, char **argv) { int a, zzz; SYSTEMTIME st; printf("creating %d threads...", argNthr); for (a = 0; a < argNthr; a++) CreateThread(0, 0, (void*)thread, 0,0, &zzz); f = 1; printf("OK\n"); Sleep(0); f = 2; while(1) { GetSystemTime(&st); printf("* %02d:%02d:%02d\n",st.wHour, st.wMinute, st.wSecond); Sleep(0); } return 0; } Листинг 5. Время обработки очереди из 100 потоков при исполнении на переднем плане (слева) и в фоновом режиме (справа) на Windows 2000 Professional 00:14:48 00:23:10 00:15:02 00:23:12 00:15:16 00:23:14 00:15:30 00:23:16 00:15:46 00:23:18 00:15:59 00:23:20 00:16:11 00:23:22 00:16:27 00:23:24 00:16:41 00:23:27 00:16:55 00:23:29 Поисковая система своими руками Андрей Сапронов Листинг 1. search.html – форма для ввода запроса пользователя Простая форма для поиска
Я ищу:
Листинг 2. search.idq – скрипт для запроса на поиск # [Query] – обязательная секция для idq-файла [Query] # возможные поля для отображения в результатах поиска # имя файла, размер, релевантность, описание, полный путь, # заголовок документа, дата последней модификации CiColumns=filename, size, rank, characterization, vpath, DocTitle, write # строка запроса (сужения) – то, что хочет найти пользователь CiRestriction=%CiRestriction% # максимально возможное количество документов CiMaxRecordsInResultSet=100 # число найденных документов на страницу CiMaxRecordsPerPage=10 # каталог(и) для поиска (относительно корневой папки веб-узла) CiScope=/DaT, / # DEEP указывает, что поиск идет во всех подкаталогах # каталогов из CiScope CiFlags=DEEP # шаблонная страница для отображения результатов поиска CiTemplate=/search.htx # порядок сортировки найденных документов (здесь по уменьшению # релевантности) # d - уменьшение признака, a - увеличение CiSort=rank[d] Листинг 3. search.htx – шаблонная страница для представления результатов поиска <%include /search.html%>
<%if CiMatchedRecordCount eq 0%>

Не найдено документов, соответствующих запросу "<%CiRestriction%>".

<%else%>

Документы с <%CiFirstRecordNumber%> по <%CiLastRecordNumber%> из <%CiMatchedRecordCount%> соответствующих запросу "<%CiRestriction%>".

<%endif%> <%begindetail%>
<%CiCurrentRecordNumber%>. <%filename%> Описание: <%characterization%>
<%rank%> - <%vpath%> - размер <%size%> байт - <%write%> GMT
<%enddetail%> <%if CiContainsFirstRecord eq 0%> <%endif%> <%if CiContainsLastRecord eq 0%> -->
<%endif%> null.htw?CiWebhitsFile=pageforhighlight.html&CiRestriction=IIS Листинг 4. Ссылка на подробный отчет о совпадениях в документе подробней “%EF%F0%EE%E8%E7%E2%EE%E4%E8%F2%E5%EB%FC%ED%EE%F1%F2%FC%20%26%20IIS” HTML-шаблоны для PHP и Perl, или не делайте инструмент самоцелью! Дмитрий Горяинов ::title:: ::body:: #!/usr/bin/perl ... use lib $ENV{DOCUMENT_ROOT}."/../lib"; # Другой способ добавить каталог размещения библиотеки: # unshift( @INC, $ENV{DOCUMENT_ROOT}."/../lib" ); use HTML::Template; my $template = HTML::Template->new( filename => полное_имя_файла_шаблона ); Пример 1
Значения переменных добавляются в XTemplate через метод assign( PARAM, value ):
$VARIABLE = {VARIABLE}
Пример 1
Значения переменных добавляются в HTML::Template через метод param( PARAM => value );:
$VARIABLE =
{TOPIC}
{DATA.NAME}{DATA.VAL}
{DATA.NAME}{DATA.VAL}
... {имя_переменной_для_подстановки} {имя_массива.имя_ключа} ... assign( TOPIC, "Вывод таблицы с чередованием фона строк" ); $even = 0; // Цикл для формирования строк таблицы for ($i=1; $i<=10; $i++) { $row = array( NAME => "Строка", VAL => $i ); $xtpl->assign(DATA, $row); // В зависимости от четности строки указываем // блок-шаблон вывода «odd» или «even» if ( ($even = ($even XOR 1)) ) { $xtpl->parse("main.item.odd"); } else { $xtpl->parse("main.item.even"); } $xtpl->parse("main.item"); } // Разбор главного блока шаблона $xtpl->parse("main"); // Вывод результата разбора $xtpl->out("main"); ?> BLOCK::= [<Имя_блока>.]<Имя_блока> ... $xtpl->parse(“main.item.odd”); ... $xtpl->parse(“main.item”); ... $xtpl->parse(“main”); ... $xtpl->assign( TOPIC, "Вывод таблицы с чередованием фона строк" ); ... $out = $xtpl->text("main"); echo $out;
... ... ... ... #!/usr/bin/perl use strict; # Путь к каталогу библиотеки use lib $ENV{DOCUMENT_ROOT}."/../lib"; # Подключение библиотеки use HTML::Template; # Создание нового объекта. В данном случае мы отдельно # указываем в конструкторе краткое имя файла шаблона # ex2.html и путь к каталогу htdocs/../data/htmltemp, # где размещен шаблон my $template = HTML::Template->new( filename => "ex2.html", path => $ENV{DOCUMENT_ROOT}."/../data/htmltemp/" ); # Простая подстановка значения в . # Делается вызовом метода param( PARAM => value) $template->param(TOPIC => "Вывод таблицы с чередованием фона строк" ); my $even = 0; # Создание массива для вывода строк таблицы my $items = (); # Цикл заполнения массива данными for (my $i=1; $i<=10; $i++) { # Каждый элемент массива (строка таблицы) представляет # собой хэш вида: [ { "NAME" => значение1, "VAL" => # значение2, "odd" => [0|1] } ] my $row = { "NAME" => "Строка", "VAL" => $i }; # Для нечетных элементов устанавливаем значение "odd", # равным "1", для четных - "0" if ( ($even = ($even xor 1)) ) { $row->{"odd"} = 1; } else { $row->{"odd"} = 0; } # Добавляем новый хэш-элемент в массив push(@{$items}, $row); } # Ассоциируем массив с повторяющимся блоком ( ) $template->param(item => $items); # Результат разбора шаблона возвращает нам в виде строки # вызов метода output(). # Мы можем сохранить его в переменную, записать в файл # или вывести, как любое другое значение: print "Content-type: text/html\n\n"; print $template->output(); __END__ {FILE "имя_вложенного_файла_шаблона"} my $template = HTML::Template->new( filename => "ex2.html", path => $ENV{DOCUMENT_ROOT}."/../data/htmltemp/" ); {FILE "{TEMP_FILE}"} class XTemplate { ... /* Новый член класса */ var $path = ""; /***[ constructor ]*** / function XTemplate ($file,$mainblock="main", $path="") { /* Инициализируем значение path, если соответствующий параметр не пуст */ if ($path) $this->path= str_replace("\\", "/", $path)."/"; … } … /***[ getfile ]*** / /* returns the contents of a file */ function getfile($file) { /* Используем конкатенацию значения path и переданного имени файла */ $file = $this->path.$file; if (!isset($file)) { $this->set_error("!isset file name!"); return ""; } ... } ... } /* end of XTemplate class. */ Вложенные шаблоны

Подключение шаблона таблицы "{TEMPLATE}" через { FILE "{TEMPLATE}" }

{FILE "ex2.html"} assign( TEMPLATE, "ex2.html"); /* Инициализация данных вложенного шаблона. При обращении к методу parse() нужно учитывать, что элементы шаблона ex2.html вложены в блок "main" более верхнего шаблона – ex_inc.html. Поэтому указывать придется как $xtpl->parse("main.main.item") и т. п. */ $xtpl->assign( TOPIC, "Вывод таблицы с чередованием ї фона строк" ); $even = 0; for ($i=1; $i<=10; $i++) { $row = array( NAME => "Строка", VAL => $i ); $xtpl->assign(DATA, $row); if ( ($even = ($even XOR 1)) ) { $xtpl->parse("main.main.item.odd"); } else { $xtpl->parse("main.main.item.even"); } $xtpl->parse("main.main.item"); } /* Разбор вложенного шаблона */ $xtpl->parse("main.main"); Вложенные шаблоны

Подключение шаблона таблицы "" через <TMPL_INCLUDE NAME="ex2.html">

#!/usr/bin/perl use strict; # Путь к каталогу библиотеки use lib $ENV{DOCUMENT_ROOT}."/../lib"; # Подключение библиотеки use HTML::Template; # Создание нового объекта. В данном случае мы отдельно # указываем в конструкторе краткое имя файла шаблона # ex_inc.html и путь к каталогу htdocs/../data/htmltemp, # где размещен шаблон my $template = HTML::Template->new( filename => "ex_inc.html", path => $ENV{DOCUMENT_ROOT}."/../data/htmltemp/" ); $template->param(TEMPLATE => "ex2.html" ); # Заполнение данных вложенного шаблона $template->param(TOPIC => "Вывод таблицы с чередованием фона строк"); my $even = 0; my $items = (); for (my $i=1; $i<=10; $i++) { my $row = { "NAME" => "Строка", "VAL" => $i }; if ( ($even = ($even xor 1)) ) { $row->{"odd"} = 1; } else { $row->{"odd"} = 0; } push(@{$items}, $row); } $template->param(item => $items); print "Content-type: text/html\n\n"; print $template->output(); __END__
  1. {ITEM}
Вложенные шаблоны

Список 1: {FILE "list.html"} Список 2: {FILE "list.html"} assign(ITEM, $item); $xtpl->parse("main.first.list.item"); } // Разбираем блок "first" $xtpl->parse("main.first.list"); $xtpl->parse("main.first"); // Данные для второго списка $list = array("раз", "два", "три"); foreach($list as $item) { $xtpl->assign(ITEM, $item); $xtpl->parse("main.second.list.item"); } // Разбираем блок "second" $xtpl->parse("main.second.list"); $xtpl->parse("main.second"); $xtpl->parse("main"); $xtpl->out("main"); ?>
Вложенные шаблоны

Список 1: Список 2: #!/usr/bin/perl use strict; # Путь к каталогу библиотеки use lib $ENV{DOCUMENT_ROOT}."/../lib"; # Подключение библиотеки use HTML::Template; my $template = HTML::Template->new( filename => "ex_inc2.html", path => $ENV{DOCUMENT_ROOT}."/../lib/data/htmltemp/" ); # Заполняем массив для шаблона list.html my $items = (); push( @{$items}, ({"item" => "one"}, {"item" => "two"}, {"item" => "three"}) ); # Организуем обрамляющий массив для my $list = (); push(@{$list}, {"item" => $items}); # Ассоциируем значение $template->param("first" => $list); # Обнуляем и заполняем массивы заново $items = (); push( @{$items}, ({"item" => "раз"}, {"item" => "два"}, {"item" => "три"}) ); $list = (); push(@{$list}, {"item" => $items}); # Ассоциируем значение $template->param("second" => $list); print "Content-type: text/html\n\n"; print $template->output(); __END__ Обработка HTML-шаблонов off-line. Возможности и ограничения Алексей Мичурин 01: #!/usr/bin/perl -w 02: 03: #use strict; 04: 05: my $INPUT_PATH ='; 14: close FH; 15: $level++; 16: $text=~s{\(##[#\s]*([^#\s]+)[#\s]*##\)}{ 17: my ($fn, $k)=($1, $key); 18: $fn=~s/\?/$key/g; 19: $fn=~s/\(([^)]+)\)/($key eq $1)?'yes':'no'/ge; 20: ($fn, $k)=($1, $2) if ($fn=~m/^([^:]+):(.+)$/); 21: assemble_step($level, $fn, $k); 22: }ge; 23: return $text; 24: } 25: 26: sub assemble { 27: my ($output, $input_root, $init_key)=@_; 28: my $text=assemble_step(0, $input_root, $init_key); 29: open FH, $OUTPUT_PATH.$output or die $output.' : '.$!; 30: print FH $text; 31: close FH; 32: } 33: 34: while (<>) { assemble(split) } (## NAME ##) (############### NAME ###############) (## ## ## NAME ## ## ##) (## text-for-? ##) (## is-i-home-(index).txt ##) 01: index.html skeleton index 02: contact.html skeleton contact 03: about.html skeleton about 04: index-print.html skeleton-print index 05: contact-print.html skeleton-print contact 06: about-print.html skeleton-print about 01: (### body-open ###) 02: (### sep #########) 03: 04: 05: 06: 07: 08:
09: (####### sep #######) 10: 11: 12: 13: 20: 21:
(## toc ##) 14: (## ?-head ##) 15:
16: 17: версия для печати 18:
(## ?-text ##) 19:
22: (### sep ##########) 23: (### body-close ###) 01: 02: 03: (## ?-head ##) 04: 05: 01: О нас 01: 02: 03: 06: 07:
04: СТЕЛЬКИ Inc. 05:
01: index-print.html 01: Корпорация «СТЕЛЬКИ Inc.» производит 02: недорогие, но высококачественные корпоративные стельки. 03: Мы всегда делаем упор на имиджевые элементы, но 04: предлагаем и универсальные готовые решения... 01: (### body-open ###) 02:
03: (## ?-head ##) 04:
05: © СТЕЛЬКИ Inc. 06:
07: (############## 08: ### ?-text ### 09: ##############) 10:
11: адрес ресурса 12: http://www.stelki.biz/(## ?-url ##) 13:
14: назад 15: (### body-close ###) 01: index.html 01: 02: (## toc-(index):index ##) 03: (## toc-(about):about ##) 04: (## toc-(contact):contact ##) 05:
01: 02: • 03: (## ?-head ##) 04: 01: 02: • 03: (## ?-head ##) 04: 05: 01: skeleton:index 02: . body-open:index 03: . . index-head:index 04: . sep:index 05: . sep:index 06: . toc:index 07: . . toc-yes:index 08: . . . index-head:index 09: . . toc-no:about 10: . . . about-url:about 11: . . . about-head:about 12: . . toc-no:contact 13: . . . contact-url:contact 14: . . . contact-head:contact 15: . index-head:index 16: . index-url-print:index 17: . index-text:index 18: . sep:index 19: . body-close:index Автоматизация процессов в сети Иван Коробко Пример 1 [L1] SERVER=Main SHARE=Consultant ACCESSGROUP1=everyone ACCESSGROUP2=Все DESCRIPTION="Консультант+" [W1] SERVER=Second SHARE=work\department1 ACCESSGROUP1=department1 ACCESSGROUP2=department3 DESCRIPTION="Ресурсы отдела 1" [W2] SERVER=Second SHARE=work\department2 ACCESSGROUP1=department2 ACCESSGROUP2= DESCRIPTION="Ресурсы отдела 2" Пример 2. По умолчанию установлен английский язык, переключение между раскладками клавиатур осуществляется нажатием CTRL+SHIFT. Windows Registry Editor Version 5.00 [HKEY_USERS\.DEFAULT\Keyboard Layout\Preload] "1"="00000409" "2"="00000419" [HKEY_USERS\.DEFAULT\Keyboard Layout\Toggle] "Hotkey"="2" Пример 3. По умолчанию установлен английский язык, переключение между раскладками клавиатур осуществляется нажатием CTRL+SHIFT. Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Keyboard Layout\Preload] "1"="00000409" "2"="00000419" [HKEY_CURRENT_USER\Keyboard Layout\Toggle] "Hotkey"="2" kixwin "dialog" ["arguments"] ["options"] dialogHeight:sHeight dialogLeft:sXPos dialogTop:sYPos dialogWidth:sWidth center:{ yes | no | 1 | 0 | on | off } dialogHide:{ yes | no | 1 | 0 | on | off } edge:{ sunken | raised } help:{ yes | no | 1 | 0 | on | off } resizable:{ yes | no | 1 | 0 | on | off } scroll:{ yes | no | 1 | 0 | on | off } status:{ yes | no | 1 | 0 | on | off } unadorned:{ yes | no | 1 | 0 | on | off } Пример 4 shell '%0/../kixwin.exe $html "$system_info ^ $hardware_info ^ Установленные программы: $en $prog ^ Подключенные сетевые диски:$en $n1 ^ Подключенные сетевые принтеры:$en $n2" "scroll:off;resizable:on"' Пример 5 … … Пример 6 @ECHO OFF if c:\%os%==c:\ goto win9x if not c:\%os%==c:\ goto winnt :winnt start /wait Kix32.exe Script.kix goto kix :win9x copy %0\..\win9x\*.dll c:\windows\system /y %0\..\Kix32.exe %0\..\Script.kix goto kix :kix @echo End Of Batch File Пример 7 ; Это комментарий // И это комментарий CLASS USER // Определение класса USER, отвечающего за пользовательские настройки CLASS MACHINE // Определение класса MACHINE, отвечающего за общекомпьютерные настройки Пример 8а) CLASS Machine POLICY "Пример политики" ……………… END POLICY Пример 8б) CLASS Machine POLICY !!Pname ……………… END POLICY [Strings] Pname="Пример политики" CLASS Name CATEGORY Name KEYMAME SubKey ……………………….. END CATEGORY Пример 9 CLASS USER CATEGORY "POLICIES" CATEGORY !!SubPol1 KEYNAME "Software\Policies\SubPol1" ………………………… END CATEGORY CATEGORY !!SubPol2 KEYNAME "Software\Policies\SubPol1" ………………………… END CATEGORY END CATEGORY [strings] SubPol1="Policy1" SubPol2="Policy2" POLICY Name [KEYNAME SubKey] EXPLAIN Help VALUENAME Value [PARTS] ………………. END POLICY VALUEON [NUMERIC] VValue VALUEOFF [NUMERIC] VValue Пример 10 CLASS USER CATEGORY "Admin Policies" CATEGORY "Keyboard Toggle " KEYNAME ".Default\Keyboard Layout\Toggle" POLICY "Toggle Policy" EXPLAIN !!help VALUENAME "Hotkey" VALUEON 2 VALUEOFF 1 END POLICY END CATEGORY END CATEGORY [strings] help="Управление переключением раскладки клавиатуры при регистрации пользователя в сети \n\n При включенной политике переключение раскладки клавиатуры осуществляется с помощью комбинации клавиш CTRL+SHIFT, при выключенной – ALT+SHIFT." PART Name Type Keywords [KEYNAME Subkey] [DEFAULT Default] VALUENAME Name END PART PART Name CHECKBOX [DEFCHEKED] VALUENAME Value VALUEON [NUMERIC] Value1 VALUEOFF [NUMERIC] Value2 END PART PART Name COMBOBOX SUGGESTIONS “Suggestion1” “Suggestion2” … “Suggestionm” END SUGGESTIONS [DEFAULT Default] [EXPANDABLETEXT] [MAXLENGHT] Max [NOSORT] [REQUIRED] VALUENAME Value END PART PART Name DROPDOWNLIST ITEMLIST NAME Item VALUE Data END ITEMLIST [DEFAULT Default] [EXPANDABLETEXT] [NOSORT] [REQUIRED] VALUENAME Value END PART PART Name EDITTEXT [DEFAULT Default] [EXPANDABLETEXT] [MAXLENGHT] Max [NOSORT] [REQUIRED] VALUENAME Value END PART PART Name LISTBOX [EXPANDABLETEXT] [NOSORT] [ADDITIVE] [EXPLICITVALUE| VALUEPREFIX Prefix] END PART PART Name NUMERIC [DEFAULT Default] [MAX Max] [MIN Min] [REQUIRED] [SPIN] [TXTCONVERT] VALUENAME Value END PART PART Text TEXT END PART Пример 11 CLASS Machine CATEGORY "Office 200" KEYNAME "Software\Policies" POLICY "Office2000" EXPLAIN !!help PART "Parametr1" EDITTEXT KEYNAME "SOFTWARE\Classes\Installer\Products\914000001E872D116BF00006799C897E\SourceList" VALUENAME LastUsedSource MAXLEN 100 EXPANDABLETEXT END PART PART !!help1 TEXT END PART PART "Parametr2" EDITTEXT KEYNAME "SOFTWARE\Classes\Installer\Products\914000001E872D116BF00006799C897E\SourceList\Net" VALUENAME 1 MAXLEN 100 EXPANDABLETEXT END PART PART !!help2 TEXT END PART END POLICY END CATEGORY [strings] help1="Exapmle1: n;3;\\Server\software\Office2000\" help2="Exapmle2: \\Server\software\Office2000\" help="\n\nCorrecting path to Microsoft Office 2000"