• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

LS2J, deployment

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
Как можно автоматизировать в Notes:
получаем переменную java.home (прям из агента), проверяем наличие библы:
Java:
System.getProperty("java.home") + "/lib/ext"
ежели нет - копируем, просим перезапустить клиент
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
"по следам" и для упрощения процесса
традиционно - связка java + LS
библиотека java
Java:
/* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004
 
Copyright (C) 2016 Mikhail Cholokov <mikhail.cholokov@gmail.com>
 
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
 
            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
  0. You just DO WHAT THE FUCK YOU WANT TO.
*/
package org.files;
 
import java.io.*;
import java.util.*;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
//import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
 
public class ZipUtil {
//    private String enc = "Windows-1251";
    final static ArrayList arrFiles = new ArrayList();
    boolean bFullPath = false;
    private static final String sep = System.getProperty("file.separator");
    final int BUFFER = 2048;
 
    public void addForCompress(String fileName) {
        arrFiles.add(fileName);
    }
 
    public void setFullPath(boolean b) {
        bFullPath = b;
    }
 
    public void compressToZip(String zipFileName) {
        try {
            byte[] buffer = new byte[18024];
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
                    zipFileName));
            out.setLevel(Deflater.BEST_COMPRESSION);
            FileInputStream in = null;
            String s;
            for (int i = 0; i < arrFiles.size(); i++) {
                s = (String) arrFiles.get(i);
                out.putNextEntry(new ZipEntry(
                        (!bFullPath) ?
                                (!(s.lastIndexOf(sep) < 0) ?
                                        s.substring(s.lastIndexOf(sep) + 1) : s)
                                : s));
                in = new FileInputStream(s);
                int len;
                while ((len = in.read(buffer)) > 0) {
                    out.write(buffer, 0, len);
                }
                out.closeEntry();
                in.close();
            }
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
/*
    public void decompress(String zipFileName, String path) {
        arrFiles.clear();
        try {
            BufferedOutputStream dest = null;
            FileInputStream fis = new FileInputStream(zipFileName);
            ZipInputStream zis = new ZipInputStream(
                    new BufferedInputStream(fis));
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                System.out.println("Extracting: " + entry);
                arrFiles.add(entry.toString());
                int count;
                byte data[] = new byte[BUFFER];
                // write the files to the disk
                //if (bFullPath) System.out.println("Full path>"+path + sep+entry.getName());
                FileOutputStream fos = ((!bFullPath) ? (new FileOutputStream(path + sep
                        + entry.getName())):(new FileOutputStream(entry.getName())));
                dest = new BufferedOutputStream(fos, BUFFER);
                while ((count = zis.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, count);
                }
                dest.flush();
                dest.close();
            }
            zis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void decompressExt(String zipFileName, String path) {
        arrFiles.clear();
        try {
            BufferedOutputStream dest = null;
            BufferedInputStream is = null;
            ZipEntry entry;
            ZipFile zipfile = new ZipFile(zipFileName);
            Enumeration e = zipfile.entries();
            while(e.hasMoreElements()) {
                entry = (ZipEntry) e.nextElement();
                System.out.println("Extracting: " +entry);
                arrFiles.add(entry.toString());
                is = new BufferedInputStream
                (zipfile.getInputStream(entry));
                int count;
                byte data[] = new byte[BUFFER];
                FileOutputStream fos = new
                FileOutputStream(path + sep+entry.getName());
                dest = new
                BufferedOutputStream(fos, BUFFER);
                while ((count = is.read(data, 0, BUFFER))
                        != -1) {
                    dest.write(data, 0, count);
                }
                dest.flush();
                dest.close();
                is.close();
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    */
    public void unZipIt(String zipFile, String outputFolder, String filter) {
        byte[] data = new byte[BUFFER];
        arrFiles.clear();
        try {
            //create output directory is not exists
            File folder = new File(outputFolder);
            if (!folder.exists()) {
                folder.mkdir();
            }
            BufferedOutputStream dest = null;
            BufferedInputStream is = null;
            //get the zip file content
            ZipFile zipfile = new ZipFile(zipFile);
            //get the zipped file list entry
            Enumeration e = zipfile.entries();
            ZipEntry ze;
            while(e.hasMoreElements()) {
                ze=(ZipEntry)e.nextElement();
                String fileName = ze.getName();
                if (!fileName.matches(filter)) continue;
                if (ze.isDirectory()) {
                    ze = (ZipEntry)e.nextElement();
                    continue;
                }
                System.out.println("origin file: " + fileName);
                //String orgPath=new File(fileName).getParent();
                //System.out.println("origin path:"+orgPath);
                //strip full path
                //fileName = new File(fileName).getName();
                //File newFile = new File(outputFolder + File.separator +orgPath+ File.separator + fileName);
                File newFile = new File(outputFolder + File.separator +fileName);
                System.out.println("file unzip : " + newFile.getAbsoluteFile());
                arrFiles.add(fileName);
                //create all non exists folders
                //else you will hit FileNotFoundException for compressed folder
                new File(newFile.getParent()).mkdirs();
         
                is = new BufferedInputStream(zipfile.getInputStream(ze));
                int count;
                //byte data[] = new byte[BUFFER];
                FileOutputStream fos = new FileOutputStream(newFile);
                dest = new BufferedOutputStream(fos, BUFFER);
                while ((count = is.read(data, 0, BUFFER))
                        != -1) {
                    dest.write(data, 0, count);
                }
                dest.flush();
                dest.close();
                is.close();
            }
 
            System.out.println("Done");
 
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    public String[] files() {
        return (String[]) arrFiles.toArray(new String[]{});
    }
    public static String fs_sep(){return sep;}
}
ничего сверх естественного ... закоменчен способ с ZipInputStream link removed
Note: Another fundamental difference between ZIPInputStream and ZipFile is in terms of caching. Zip entries are not cached when the file is read using a combination of ZipInputStream and FileInputStream. However, if the file is opened using ZipFile(fileName) then it is cached internally, so if ZipFile(fileName) is called again the file is opened only once. The cached value is used on the second open. If you work on UNIX, it is worth noting that all zip files opened using ZipFile are memory mapped, and therefore the performance of ZipFile is superior to ZipInputStream. If the contents of the same zip file, however, are be to frequently changed and reloaded during program execution, then using ZipInputStream is preferred.
кэширование входа, а менять файл мы не собираемся
классы для LS
см. в добавленном ниже
класс используется JarLib старый код (Deploy) я оставил (на современных виндях с ним будут траблы, да и не корректно с либами себя ведет), новый DeployExt
агент для теста
Visual Basic:
    Dim doc As NotesDocument, ses As New NotesSession
    Set doc = ses.Documentcontext
    Dim jarlib As New JarLib
    Call jarlib.DeployExt(doc, {name})
особенности с кот. пришлось столкнуться:
-LS2J не принимал длинные строки в массиве (полный путь к распакованному файлу) и пришлось передавать укороченные, кот. потом обрабатывать
-можно былобы обойтись без LS в части создания каталогов (java код это сам прекрасно сделает), но нужен некий (простой) контроль что уже "все" выгружалось, а вводить привязки в "общую" java либу - не совсем хорошо
-ввел фильтр для файлов (регэксп), ибо либы (например для POI) тянут еще много чего, а "засирать" диск не хоца
-динамически (очищаются) формируются названия переменных и JavaUserClassExt
нек. константы (кот. у мя определены в др. либах)
Visual Basic:
Const ENV_JAREXT={JavaUserClassesExt}
Const ENV_JAR={JavaUserClasses}
Const JAR_BASE={JAR} 'directory (relatively to userhome) for catalogs with jars (for jar deployment)
увы - все выковыривать у меня не было времени (да и не нужно все здесь)
[DOUBLEPOST=1463999498][/DOUBLEPOST]либа обработки ошибок (как она есть) очередной её клон на форуме
Visual Basic:
Option Public
Option Declare
UseLSX "*javacon"
%Include "lserr.lss"
'Uselsx "*lsxlc"
%Include "lsconst.lss"
'%Include "lsxsd.lss"
Const ERR_FIELDFORMAT=1100
Const ERR_CHILDSOURCE=1200
Const MSG_FIELDFORMAT="индекс вне диапозона массива форматирования"
Const MSG_CHILSOURCE={элемент списка "0" д.б. равен имени view}
Dim debug As Boolean
Dim log2file As Boolean
 
Dim logStream As NotesStream
Private ses As NotesSession
Private db As NotesDatabase
Class ErrorHandler
    Private rtTrace As NotesRichTextItem
    Sub ClrError()
    End Sub
    Sub New()
        Call Me.ClrError()
    End Sub
    Function GetModuleInfo() As String
        Dim thisType As String, modInfo As String
        thisType= TypeName(Me)
        ' Not a class, use the calling module instead
        If (thisType = "") Then thisType = GetThreadInfo(11)
        modInfo = thisType & "::"
        GetModuleInfo=modInfo
    End Function
    Function RaiseError() As String
        Dim es As String
        es=Me.GetModuleInfo()& GetThreadInfo(10) & ": "
        If (Err = 0) Then
            es = es + "Manually raised an error"
        Else
            es = es + "err. (" + Trim(Str(Err)) + ") " + Error$ + " l. "+ Trim(Str(Erl))
        End If
        Print es
        Me.RaiseError=es & Chr(10)
        If (Not logStream Is Nothing) And log2file Then Call logStream.WriteText(es,EOL_PLATFORM)
        Call Me.ClrError()
    End Function
    %REM
        Function ErrInfo
        Description: Comments for Function
    %END REM
    Function ErrInfo(callerName As String)
        If Len(callerName)<1 Then
            callerName= Me.GetModuleInfo & GetThreadInfo(LSI_THREAD_CALLPROC) & {: }
        Else
            callerName= Me.GetModuleInfo & callerName & {: }
        End If
        Dim es As String
        If (Err = 0) Then
            es = callerName + "Manually raised an error"
        Else
            es = callerName + "err. (" + Trim(Str(Err)) + ") " + Error$ + " l. "+ Trim(Str(Erl))
        End If
 
        Print es
        Me.ErrInfo=es & Chr(10)
        If (Not logStream Is Nothing) And log2file Then _
        Call logStream.WriteText(callerName,EOL_PLATFORM)
        Call Me.ClrError()
    End Function
    %REM
    *--------------------------------------------
        Function PrintTrace
        Description: Comments for Function
    %END REM
    Public Function PrintTrace(msg As String) As NotesRichTextItem
        Dim routineName As String
        routineName="PrintTrace"
        On Error GoTo ErrH
        'your code here
        If me.rtTrace Is Nothing Then GoTo Quit
        Call me.rtTrace.AppendText(TypeName(Me) &{.} &GetThreadInfo(LSI_THREAD_CALLPROC) &{->} &msg)
        Call me.rtTrace.Addnewline(1, True)
        Set PrintTrace=me.rtTrace
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
End Class
 
Class ErrorHandlerWJ As ErrorHandler
    Private jSession As JavaSession
    Private jError As JavaError
    Sub New()
        On Error GoTo errorhandler
        Set jSession= New JAVASESSION
ExitFunction:
        Exit Sub
errorhandler:
        Call ErrorHandler..RaiseError()
        Resume ExitFunction
    End Sub
    Function RaiseError() As String
        Set jError = jSession.getLastJavaError()
        Dim es As String
        If (jError.errorMsg = "") Then
            es=ErrorHandler..ErrInfo(GetThreadInfo(LSI_THREAD_CALLPROC))
        Else
            es=GetModuleInfo() &GetThreadInfo(LSI_THREAD_CALLPROC) _
            & {: } & jError.errorMsg &{; l.}& Erl
            Print es
            es=es & Chr(10)
            jSession.ClearJavaError   
        End If
        Dim RT, rtObj, mb As Long:mb=CLng(1024)*CLng(1024)
        Set RT=jSession.Getclass({java/lang/Runtime})
        Set rtObj=RT.getRuntime()
        Print {Total Memory:} & CStr(rtObj.totalMemory() \ mb) & {MB}
        Print {Max Memory:} + CStr(rtObj.maxMemory() \ mb) & {MB}
        Print {Free Memory:} & CStr(rtObj.freeMemory() \ mb) & {MB}
        RaiseError=es
        If (Not logStream Is Nothing) And log2file Then Call logStream.WriteText(es,EOL_PLATFORM)
    End Function
End Class
Sub Initialize
    debug=False
    Set ses=New NotesSession
    Set db=ses.CurrentDatabase
    Set logStream=ses.CreateStream
    Dim dt As New NotesDateTime({Today})
    dt.SetNow
    Dim fname As String
    fname= {_} &Replace(Replace(Replace(dt.LocalTime,{:},{-}),{ },{_}),{.},{-}) &_
    {#} &db.ReplicaID &_
    {-} &Replace(GetThreadInfo(LSI_THREAD_CALLMODULE),{*},{}) &_
    {.log}
 
    If Not logStream.Open(fname,{UTF-8}) Then
'       logStream=Nothing
    End If
'   Msgbox fname &Chr(10) &logStream.WriteText({*-------------start ------------*})
End Sub
 
Sub Terminate
'   If Not logStream Is Nothing Then logStream.Close
End Sub
Function RaiseErrorMsg()
    Dim thisType As String
    Dim es As String
'thisType = Typename(Me)
' Not a class, use the calling module instead
    If (thisType = "") Then thisType = GetThreadInfo(11)
    es = thisType & "::" & GetThreadInfo(10) & ": "
    If (Err = 0) Then
        es = es + "Manually raised an error"
    Else
        es = es + "Run time error: (" + Trim(Str(Err)) + ") " + Error$ + " at line: "+ Trim(Str(Erl))
    End If
    MsgBox es
End Function
Sub DbgMsg(txt As String)
    If (debug) Then Print txt
End Sub
Sub Alert(s As String)
    MessageBox s, MB_OK+MB_ICONSTOP
End Sub
Function RaiseError() As String
    Dim thisType As String
    Dim es As String
'thisType = Typename(Me)
' Not a class, use the calling module instead
    If (thisType = "") Then thisType = GetThreadInfo(11)
    es = thisType & "::" & GetThreadInfo(10) & ": "
    If (Err = 0) Then
        es = es + "Manually raised an error"
    Else
        es = es + "err. (" + Trim(Str(Err)) + ") " + Error$ + " l."+ Trim(Str(Erl))
    End If
    Print es
    RaiseError=es + Chr(10)
    If (Not logStream Is Nothing) And log2file Then Call logStream.WriteText(es,EOL_PLATFORM)
End Function
Function LogMsg(curLine As Long, msg As String)
    If (Not logStream Is Nothing) And log2file Then Call logStream.WriteText({#} &Format(CStr(curLine), {000000}) &{:} &msg,EOL_PLATFORM)
End Function
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
Visual Basic:
Option Public
Option Declare
Use "CommonUI.lib"'(Collections.lib)
Use "Files"
Use "JarDeploy"
Use "FolderBrowse"
%REM
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004
 
 Copyright (C) 2016 Mikhail Cholokov <mikhail.cholokov@gmail.com>
 
 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.
 
            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
  0. You just DO WHAT THE FUCK YOU WANT TO.
%END REM
 
Const ERRBASE_FILES=1110
Const ERRLS2JINIT=ERRBASE_FILES+1, CS_ERRLS2JINIT={ошибка инициализации класса Java}
Const ERRFILEACCESS=ERRBASE_FILES+2, CS_ERRFILEACCESS={ошибка доступа к файлу}
 
Const CS_RELOAD={Перезагрузите, пожалуйста, программу}
Const CS_RETRY={повторите попытку}
Const CM_JARLIBNAME_BLANK={Имя библиотеки не задано}
Const CM_LIBPATHDEFINED={Путь библиотеки уже определен} 'уже библиотека выгружалась
 
Const ERR_UNSUPPORTED_PLATFORM = 20300 ' arbitrary value
 
Const OPT_JARLIB={optJarLib}
Const WINFS_SEP={\}
Const FS_SEP={/}
Const JARVER_SEP={-}'version separtor for jars lib (example: POI-3.14)
Const JAREXT_SEP={_}'variable num separator for jars (example: POI-3.14_0)
Private Const PREF_SEP={_}
Private UNID_Pref As Boolean
 
 
Dim agentLog As NotesLog
Declare Function w32_OSGetSystemTempDirectory Lib "nnotes" Alias "OSGetSystemTempDirectory" ( ByVal S As String) As Integer
Declare Function mac_OSGetSystemTempDirectory Lib "NotesLib" Alias "OSGetSystemTempDirectory" ( ByVal S As String) As Integer
Declare Function linux_OSGetSystemTempDirectory Lib "libnotes.so" Alias "OSGetSystemTempDirectory" ( ByVal S As String) As Integer
%REM
*********************************************
    Class JarLib
    Description: выгружает файлы jar из дока, на диск
        в каталог соответ библиотекам JVM
        в имени библиотеки д.б. версия
        например: POI-3.14
        это и будет именем каталога и частью имени переменной в notes.ini
        если в библиотеку входят доп. jar - их имена д.б. сокращены (или захешированы)
        возможен вариант просто порядковый номер
        т.о. все сопутствующие библиотеки будут перечислены в виде переменных
        типа: POI-3.14_1,POI-3.14_2
%END REM
Class JarLib As ErrorHandlerWJ
    Private JarLibObj   As JavaObject
    Private JavaSystem As Javaclass
    Private SystemObj As Javaobject
    Private JarLibClass As JavaClass
    Private ses As NotesSession
    Private db As NotesDatabase
    Private libPath As String
    Private rtName As String
    Private jarExt As String
    Private userhome As String
    Private FilesObj As FilesObj
    Private sep As String
    Private fssep As String
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Sub New()
        Dim fail As Boolean
        On Error GoTo errorhandler
        Set FilesObj=New FilesObj
        Set ses=New NotesSession
        Set JavaSystem=me.jSession.Getclass(SYSTEM_CLASS)
        Set SystemObj=me.JavaSystem.Createobject()
        me.userhome=SystemObj.getProperty({user.home})
        me.jarExt=ses.Getenvironmentstring(ENV_JAREXT, True)
        Print {User Home>}me.userhome
        Print {JavaUserClasses=}me.jarExt
        me.sep=me.SystemObj.getProperty({path.separator})
        me.fssep=me.SystemObj.getProperty({file.separator})
       
        Set JarLibClass = jSession.GetClass({org.files.JarDeploy})
        Set JarLibObj = jarLibClass.CreateObject
        libPath=JarLibObj.getLibPath()
        Set db=ses.CurrentDatabase
        rtName={Body}
ExitFunction:
       Exit Sub
errorhandler:
        Error Err, Me.RaiseError()
    End Sub
    %REM
    *--------------------------------------------
        Function Deploy
        Description: выгрузка файлов на диск
    %END REM
    Function Deploy(unid As String) As Boolean
        On Error GoTo ErrH
        Dim doc As NotesDocument
        Set doc=db.GetDocumentByUNID(unid)
        Dim filesList List As String
        Dim fName As String
        fName=DetachDocFiles(doc,{*.jar},filesList)
        If fName<>"" Then
            ForAll f In filesList
                Dim sfile As String
                sfile=ListTag(f)
                If MoveFile(libPath & sfile, libPath & sfile & {.old})=70 Then
                    'файл заблокирован
                    MessageBox CS_ERRFILEACCESS & Chr(10)_
                    & (CS_RELOAD) & Chr(10)_
                    & CS_RETRY, MB_OK + MB_APPLMODAL + MB_ICONEXCLAMATION
                    Exit Function
                End If
                Call MoveFile(CStr(f) & sfile, libPath & sfile)
            End ForAll
            Deploy=True
        End If
Quit:
        Exit Function
ErrH:
        Call Me.RaiseError()
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function DeployExt
        Description: Comments for Function
    %END REM
    Function DeployExt(doc As NotesDocument, fldName As String)
        Dim routineName As String
        routineName="DeployExt"
        On Error GoTo ErrH
        'your code here
        Dim filesList List As String, libName As String
        libName=doc.Getitemvalue(fldName)(0)
        If Len(libName)<1 Then Error 1024, Chr(10) &CM_JARLIBNAME_BLANK &Chr(10)
 
        Dim fName As String
        fName=DetachDocFiles(doc,{},filesList)
        If WINFS_SEP<>me.fssep Then _
        fName=Replace(fName, WINFS_SEP, me.fssep)
        If FS_SEP<>me.fssep Then _
        fName=Replace(fName, FS_SEP, me.fssep)
       
        If LCase(fName) Like {*.zip} Then
            Dim dirTo As String, bDirBlank As Boolean
            dirTo=userhome & FilesObj.FSSEP &JAR_BASE
            'check JAR dir exists
            On Error ErrPathNotFound GoTo Resume0
            Dim tmp As String
            tmp=Dir(dirTo &fssep)
            'protect from all code exept GoTo
            If False Then
Resume0:
            Resume Create0
Create0:
            Print {Dir Creating>}dirTo
            MkDir(dirTo)
            End If
           
            'check library dir
            dirTo=dirTo & FilesObj.FSSEP &libName
            bDirBlank=True
            On Error ErrPathNotFound GoTo Resume1
            tmp=Dir(dirTo &fssep)
            Print {check path>} dirTo{;for first file>}tmp
            bDirBlank=Len(tmp)<1
            'protect from all code exept GoTo
            If False Then
Resume1:
            Resume Create1
Create1:
            Print {Dir Creating>}dirTo
            MkDir(dirTo)
            End If
            If Not bDirBlank Then Error 1024, Chr(10) &CM_LIBPATHDEFINED &Chr(10)
            Dim files, fTo As String
            fTo=dirTo &fssep &StrRightBack(fName,me.fssep)
            Call MoveFileErr(fName, fTo)
            files=FilesObj.Decompress(fTo)
            Call Me.UpdateNotesIni(files, Libname, dirTo)
        End If
       
        'DeployExt=
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function UpdateNotesIni
        Description: accept files list, filter .jar
        and assign corresponding notes.ini var
    %END REM
    Private Function UpdateNotesIni(files, libName As String, dirTo As String)
        Dim routineName As String
        routineName="UpdateNotesIni"
        On Error GoTo ErrH
        'your code here
        Dim i As Integer
        me.jarExt=Me.StripOldLibs(Libname)
        ForAll f In files
            Dim s As String, slib As String
            s=dirTo & fssep &Replace(CStr(f), FS_SEP, me.fssep)
            If LCase(s) Like {*.jar} Then
                slib=libName &JAREXT_SEP &CStr(i)
                Call ses.Setenvironmentvar(slib, s, True)
                If Len(me.jarExt)<1 Then
                    me.jarExt=slib
                Else
                    me.jarExt=me.jarExt &me.sep &slib
                End If
                i=i+1
            End If
        End ForAll
        Call ses.Setenvironmentvar(ENV_JAREXT, me.jarExt, True)
        'UpdateNotesIni=
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function StripOldLibs
        Description: strip info about old lib version
            in the notes.ini me.jarExt
    %END REM
    Private Function StripOldLibs(libName As String) As String
        Dim routineName As String
        routineName="StripOldLibs"
        On Error GoTo ErrH
        'your code here
        Dim ptn As String
        ptn=StrLeft(libName,JARVER_SEP)
        Dim i As Integer, res,vars:vars=Split(me.jarExt, me.sep):res=Split({},{})
        ForAll v In vars
            If InStr(1, CStr(v), ptn, 5)<1 Then
                If i=0 Then
                    res(0)=CStr(v)
                Else
                    res=ArrayAppend(res,CStr(v))
                End If
            Else
                'remove variable
                Call ses.Setenvironmentvar(CStr(v), {}, True)
            End If
        End ForAll
        StripOldLibs=Join(res,me.sep)
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function SetRtName
        Description: имя поля для выгрузки приложения
    %END REM
    Function SetRtName(xName As String) As String
        rtName=xName
        setRtName=xName
    End Function
End Class
%REM
*********************************************
    Class FilesObj
    Description: получение списка файлов (в каталоге)
        сжатие, распаковка в/из архива
%END REM
Class FilesObj As ErrorHandlerWJ
    Private ZipObj  As JavaObject
    Private ZipClass As JavaClass
    Private DirObj As JavaObject
    Private DirClass As JAVACLASS
    Private fCount As Integer
    Private sep As String
    Private JavaSystem As Javaclass
    Private SystemObj As Javaobject
   
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Sub New()
        Dim fail As Boolean
        On Error GoTo errorhandler
        Set JavaSystem=me.jSession.Getclass(SYSTEM_CLASS)
        Set SystemObj=me.JavaSystem.Createobject()
        sep=SystemObj.getProperty({file.separator})
        Set ZipClass = jSession.GetClass(ZIPUTIL_CLASS)
        Set ZipObj = ZipClass.CreateObject
        Set DirClass=jSession.GetClass({org/files/DirProcess})
        Set DirObj=DirClass.CreateObject
ExitFunction:
        Exit Sub
errorhandler:
        Error Err, RaiseError
    End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Sub Delete()
        If Not ZipObj Is Nothing Then
            Delete ZipObj
        End If
    End Sub
    %REM
    *--------------------------------------------
        Function Add
        Description: добавление файла, в список, для архивации
    %END REM
    Function Add(s As String) As Boolean
        On Error GoTo errorhandler
        Call ZipObj.addForCompress(s)
        fCount=fCount+1
        Add=True
ExitFunction:
        Exit Function
errorhandler:
        Call Me.RaiseError()
        Resume ExitFunction
    End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    %REM
    *--------------------------------------------
        Property Get Count
        Description: счетчик файлов подлежыщих архивации
    %END REM
    Property Get Count As Integer
        Count=fCount
    End Property
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Function Compress(zipName As String) As Boolean
        On Error GoTo errorhandler
        If Not Count > 0 Then GoTo Quit
        Call ZipObj.compressToZip(zipName)
        Compress=True
Quit:
        Exit Function
errorhandler:
        Error Err, RaiseError
        Resume Quit
    End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    %REM
*--------------------------------------------
    Function Decompress
    Description: распаковка архива
    используется полный путь, кот получается из имени файла
    %END REM
    Function Decompress(zipName As String)
        Dim routineName As String
        routineName="Decompress"
        On Error GoTo ErrH
        'your code here
        Dim path As String
        'коррекция разделителей если они к-л образом не соответ. таковым из ОС
        If WINFS_SEP<>sep Then _
        zipName=Replace(zipName, WINFS_SEP, sep)
        If FS_SEP<>sep Then _
        zipName=Replace(zipName, FS_SEP, sep)
 
        path=StrLeftBack(zipName, sep)
        Print {Decompressing to path:} path
        'ZipObj.setFullPath(True)
        Call ZipObj.unZipIt(zipName, path, {.+\.jar})
        Decompress=ZipObj.files()
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Function Files
        Description: получение полного списка файлов в каталоге
    %END REM
    Function Files(path As String)
        On Error GoTo ErrH
        Call DirObj.visitAllDirsAndFiles(path)
        Files=DirObj.Result()
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
    %REM
    *--------------------------------------------
        Property Get FSSEP
        Description: Comments for Property Get
    %END REM
    Property Get FSSEP As String
        Dim routineName As String
        routineName="FSSEP"
        On Error GoTo ErrH
        'your code here
        FSSEP=me.sep
Quit:
        Exit Property
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Property
End Class
%REM
*********************************************
    Class TempFolderManager
    Description: создание и удаление временных файлов
%END REM
Class TempFolderManager As ErrorHandlerWJ
    m_path As String
    m_files List As Integer
    Private sep As String
    Private ZipClass As Javaclass
   
    Function Unique As String
        Dim unik
        unik = Evaluate("@Unique")
        Unique = StrToken(unik(0), "-", -1) ' drop the username part of the ID which is always the same for this user
    End Function
   
    Sub New
        On Error GoTo ErrH
        Set ZipClass = jSession.GetClass("org.files.ZipUtil")
        sep=ZipClass.fs_sep()
        m_path = GetNotesTempDirectory & sep & Unique
        MkDir m_path
Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
    End Sub
   
    Public Property Get Path As String
        Path = m_path
    End Property
   
    Function NewFilename(ByVal strSuffix$, ByVal bManage As Boolean) As String
        Dim strFName$
        strFName = Unique
        If Len(strSuffix) > 0 Then strFName = strFName & "." & strSuffix
        NewFilename = m_path & sep & strFName
        If bManage Then
            m_files(NewFilename) = 0
        End If
    End Function
   
    Sub Manage(ByVal strPath$)
        m_files(strPath) = 1
    End Sub
   
    Sub Unmanage(ByVal strPath$)
        On Error Resume Next
        Erase m_files(strPath)
    End Sub
   
    Function ClearFiles( ) As Boolean
        ' erase all files under management but leave the directory so that we can use it more.
        ' return True if all files were successfully erased.
        On Error GoTo failed
        ClearFiles = True
        ForAll ffileno In m_files
            Kill ListTag(ffileno)
nextFile:
        End ForAll
        Erase m_files
        Exit Function
failed:
        ClearFiles = False
        Resume nextFile
    End Function
   
    Sub Delete
        On Error Resume Next
        If ClearFiles Then RmDir m_path
    End Sub
End Class
%REM
*********************************************
    Class NDCFile
    Description: получить коллекцию документов
    по списку UNID из файла
    или записать в Файл
%END REM
Class NDCFile As FilesObj
    Private NDC As NotesDocumentCollection
    Private db As NotesDatabase
    Private ses As NotesSession
    Private arrFiles As Variant
    Private path As String
    Private tmp As TempFolderManager
    %REM
    *--------------------------------------------
        Sub New
        Description: Comments for Sub
    %END REM
    Sub New()
        Dim routineName As String
        routineName="New"
        On Error GoTo ErrH
    'your code here
        Set me.ses=New NotesSession
        Set me.db=me.ses.Currentdatabase
Quit:
        Exit Sub
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
        Property Get Collection
        Description: path is directory
    %END REM
    Property Get Collection(path As String) As NotesDocumentCollection
        Dim routineName As String
        routineName="Collection"
        On Error GoTo ErrH
'your code here
        Set NDC=db.CreateDocumentCollection()
        me.path=path
        me.arrFiles=Me.Files(me.path)
        If DataType(me.arrFiles)=V_STRING Then
            Me.NDCFromFile(CStr(me.arrFiles))
        Else
            ForAll f In me.arrFiles
                Me.NDCFromFile(CStr(f))
            End ForAll
        End If
        Set Collection=NDC
Quit:
        Exit Property
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Property
    %REM
    *--------------------------------------------
        Function NDCFromStream
        Description: Comments for Function
    %END REM
    Private Sub NDCFromFile(fname As String)
        Dim stream As NotesStream
        Set stream=ses.Createstream()
        Dim routineName As String
        routineName="NDCFromStream"
        On Error GoTo ErrH
    'your code here
            If stream.Open(fname) Then
                Dim unid As String
                Do
                    unid=stream.Readtext(STMREAD_LINE, EOL_PLATFORM)
                    Dim doc As NotesDocument
                    Set doc=GetDocumentByUNIDSilent(me.db, unid)
                    If Not doc Is Nothing Then Call NDC.Adddocument(doc)
                Loop Until stream.Iseos
            End If
    Quit:
        Exit Sub
    ErrH:
        Error Err, RaiseError
        Resume Quit
    End Sub
    %REM
    *--------------------------------------------
        Property Set Collection
        Description: path is full path to file
    %END REM
    Property Set Collection(path As String) As NotesDocumentCollection
        Dim routineName As String
        routineName="Collection"
        On Error GoTo ErrH
'your code here
        Dim doc As NotesDocument, stream As NotesStream
        Set doc=Me.Collection.Getfirstdocument()
        Set stream=ses.Createstream()
        Set tmp=New TempFolderManager
        me.path=tmp.NewFilename({txt}, True)
        path=me.path
        Call stream.Open(me.path)
        Do While Not doc Is Nothing
            Call stream.Writetext(doc.Universalid, EOL_PLATFORM)
            Set doc=Me.Collection.Getnextdocument(doc)
        Loop
        Set NDC=Collection
Quit:
        Exit Property
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Property
End Class
%REM
*--------------------------------------------
    Function DetachDocFiles
    Description: выгружает файлы не только из RT полей (mime тоже)
%END REM
Function DetachDocFiles(objdoc As NotesDocument, ByVal filter As String, filesList List As String) As String
    Dim file As String, path As String
    Dim fNames As Variant
    Dim o As NotesEmbeddedObject
   
    On Error GoTo ErrorHandler
    Erase filesList
   
    path=Replace(GetNotesTempDirectory(),WINFS_SEP,FS_SEP) & FS_SEP
    file=""
   
    fNames=AttachmentsName(objdoc)
    Dim detach As Boolean, negative As Boolean
    If Left$(filter,1)={!} Then negative=True
    If negative And Len(filter)>0 Then filter=Right$(filter,Len(filter)-1)
    filter=UCase(filter)
    ForAll a In fNames
        Set o=objdoc.GetAttachment(a)
        detach=True
        If Len(filter)>0 Then
            If Not (UCase(o.Name) Like filter) Then
                detach=False
            End If
            detach=detach Xor negative
        End If
        If detach Then
            file=o.Name
            If UNID_pref Then file=objdoc.UniversalID & PREF_SEP &file
            filesList(file)=path
            Call o.ExtractFile(path & file)
        End If
    End ForAll
    If Len(file)>0 Then DetachDocFiles=path & file: Print {First Detached:} DetachDocFiles
Quit:
    Exit Function
ErrorHandler:
    Call RaiseError()
    Erase filesList
    Resume Quit
End Function
 
%REM
*--------------------------------------------
    Function SetPrefix
    Description: флаг для установки UNID как префикса к имени файла
%END REM
Function SetPrefix(b As Boolean) As Boolean
    SetPrefix=UNID_pref
    UNID_pref=b
End Function
%REM
*--------------------------------------------
    Function DeleteFile
    Description: удаление файла на диске
%END REM
Function DeleteFile(fName As String) As Boolean
    On Error GoTo ErrorHandler
    Kill fName
    DeleteFile=True
ExitFunction:
    Exit Function
ErrorHandler:
    Print {Error Delete path:} &fName
    If agentLog Is Nothing Then
        Call RaiseError()
    Else
        Call agentLog.LogAction("Delete file:"& fName & " error:" & Error$)
    End If
    Resume ExitFunction
End Function
%REM
*--------------------------------------------
    Function MoveFileErr
    Description: throw exception if not sucess
%END REM
Function MoveFileErr(srcName As String, dstName As String) As Integer
    Dim routineName As String
    routineName="MoveFileErr"
    On Error GoTo ErrH
    'your code here
    Call DeleteFile(dstName)
    Name srcName As dstName
    MoveFileErr=-1
Quit:
    Exit Function
ErrH:
    MoveFileErr=Err
    Error Err, RaiseError &Chr(10) &_
    srcName & Chr(10)& "->" & dstName &Chr(10)
    Resume Quit
End Function
%REM
*--------------------------------------------
    Function AttachmentsName
    Description: список имен приложенных файлов
%END REM
Function AttachmentsName(objdoc As NotesDocument) As Variant
    AttachmentsName=Evaluate("@AttachmentNames(0)", objdoc)
End Function
Function MoveFile(srcName As String, dstName As String) As Integer
    On Error GoTo ErrorHandler
    Call DeleteFile(dstName)
    Name srcName As dstName
    MoveFile=-1
ExitFunction:
    Exit Function
ErrorHandler:
    Print "Move file:"& srcName & "->" & dstName
    If agentLog Is Nothing Then
        Call RaiseError()
    Else
        Call agentLog.LogAction("Move file:"& srcName & "->" & dstName & " error:" & Error$)
    End If
    MoveFile=Err
    Resume ExitFunction
End Function
 
 
%REM
*--------------------------------------------
    Function GetNotesTempDirectory
    Description: CAPI для получения временного каталога notes
%END REM
Function GetNotesTempDirectory() As String
    ' Returns the path of the temporary directory used by Notes.
    ' Not same as system or user temp dir that you can get e.g. with Environ("TEMP") in Windows.
    ' Main reasons to use this instead: works crossplatform, and partitioned servers each need
    ' their own temp dir to avoid interfering with each other.
    Dim session As New NotesSession
    Dim d As String * 256
    'd=Space(256)
    Dim s%
    Select Case UCase(session.Platform)
        Case {LINUX},{UNIX}:'{UNIX} from test on CentOS 6.5
            s% = linux_OSGetSystemTempDirectory(d)
            Print {TempDir len:}s%
            'temporary hardcoded
            If s%<1 Then d={/tmp}:s%=Len({/tmp})
        Case {MACINTOSH}:'Macintosh}
            s% = mac_OSGetSystemTempDirectory(d)
        Case {WINDOWS/32},{WINDOWS/64}:
            s% = w32_OSGetSystemTempDirectory(d)
        Case Else
            Error ERR_UNSUPPORTED_PLATFORM, "In GetNotesTempDirectory, platform not supported: " & session.Platform
    End Select
    Dim res As String
    res=Left$(d, s%)
    Print {TempDir>}res
    GetNotesTempDirectory =res
End Function
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
обнаружил ошибку
Visual Basic:
me.sep = me.SystemObj.getProperty({path.separator})
д.б. me.sep = {,}
потому что в JavaUserClassesExt разделителем д.б. ","
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
еще ошибка (тестировал на нескольких либах...) ф-ция
Visual Basic:
    %REM
    *--------------------------------------------
        Function StripOldLibs
        Description: strip info about old lib version
            in the notes.ini me.jarExt
    %END REM
    Private Function StripOldLibs(libName As String) As String
        Dim routineName As String
        routineName="StripOldLibs"
        On Error GoTo ErrH
        'your code here
        Dim ptn As String
        ptn=StrLeft(libName,JARVER_SEP)
        Dim i As Integer, res,vars:vars=Split(me.jarExt, me.sep):res=Split({},{})
        ForAll v In vars
            Dim pos As Integer
            pos=InStr(1, CStr(v), ptn &JARVER_SEP, 5)
            'Me.PrintMsg({Check value:} &CStr(v))
            If pos<1 Then
                If i=0 Then
                    res(0)=CStr(v)
                    i=i+1
                Else
                    res=ArrayAppend(res,CStr(v))
                    i=i+1
                End If
            Else
                'Me.PrintMsg({*Delete value:} &CStr(v))
                If pos=1 Then
                    'remove variable
                    Print {Variable remove:}CStr(v)
                    Call ses.Setenvironmentvar(CStr(v), {}, True)
                End If
            End If
        End ForAll
        StripOldLibs=Join(res,me.sep)
Quit:
        Exit Function
ErrH:
        Error Err, RaiseError
        Resume Quit
    End Function
д.б. i = i + 1
[DOUBLEPOST=1464024205,1464024016][/DOUBLEPOST]да... ограничение строки в 255 символов никто не снимал ;) - а потому либы с масштабными зависимостями так деплоить не получится
я с трудом впихнул xdocreport (и то - не проверял рабочесть) оставив там только docx и itext , учитывая что нужен еще и POI
пришлось обзывать P- и X- :)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
кстати - никто не пробовал составлять манифест в jar для других и т.о. подсовывать classpath в jvm?
типа
Код:
Manifest-Version: 1.0
Class-Path: ... ...
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
йопыт... "сын ошибок трудных" - РАБОТАЕТ!
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
Рассказываю - создал артифакт на Idea как jar в опциях сказал - копировать либы и создать линки, через манифест
забилдил артефакт
сунул
Код:
JavaUserClassesExt=P-W_0
P-W_0=C:\Documents and Settings\mikelocal\JAR\P-\POI-sax.jar
в ини
в каталог засунул все либы из artifact - и... оно запустилось на клиенте
есть НО - дизигнер так не видит либ, но для деплоя это и не надо
т.о. обходим ограничение на проекты где куча либ тянется
[DOUBLEPOST=1464089432,1464089361][/DOUBLEPOST]манифест такой:
Код:
Manifest-Version: 1.0
Class-Path: poi-3.14-20160307.jar poi-examples-3.14-20160307.jar poi-e
 xcelant-3.14-20160307.jar poi-ooxml-3.14-20160307.jar poi-ooxml-schem
 as-3.14-20160307.jar poi-scratchpad-3.14-20160307.jar commons-codec-1
 .10.jar commons-logging-1.2.jar junit-4.12.jar log4j-1.2.17.jar curve
 sapi-1.03.jar xmlbeans-2.6.0.jar
Main-Class: POI2CSV
 

savl

Lotus Team
28.10.2011
2 597
310
BIT
180
@lmike, DDE должен видеть, там только с MacOS косяк был, хотя может на nix тоже...
Может переоткрыть надо?
И еще, у тебя XP или 7? D 7-ке вместо "Documents and Settings" лучше писать Users.
Может он не видит, потому "Documents and Settings" не может распознать?
Попробуй на другой папке, в корне.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
@lmike, DDE должен видеть, там только с MacOS косяк был, хотя может на nix тоже...
Может переоткрыть надо?
И еще, у тебя XP или 7? D 7-ке вместо "Documents and Settings" лучше писать Users.
Может он не видит, потому "Documents and Settings" не может распознать?
Попробуй на другой папке, в корне.
у мя хрюля..., и не видит, но код работает
подозреваю - что и не должен видеть, не наблюдал в дизайн-тайм таких фокусов (на др. IDE тоже)
фокус именно в том что jvm получит класспаз на обработке (как я понимаю) статического main (не запуск, а просто - подготовку окружения), вместе с манифестом
а в дизайн-тайм - оно этого и делать не подумает (main обрабатывать)
[DOUBLEPOST=1464090615,1464090559][/DOUBLEPOST]если обратишь внимание - я не указываю остальные либы!
[DOUBLEPOST=1464090746][/DOUBLEPOST]не вникал в детали - просто на шару потестил
 
Последнее редактирование модератором:

savl

Lotus Team
28.10.2011
2 597
310
BIT
180
@lmike, аа, догнал. DDE зависимостей не видит, которые ты через манифест пустил...
Саму POI-sax.jar видеть должен. Хм... интересно.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
215
@savl, это интересно именно в смысле деплоймента - экономия на символах в notes.ini
засада по путям (общая длина) к каталогам в JavaUserClasses, а в JavaUserClassesExt вынуждены указывать каждый jar и опять втыкаемся в ограничение 255 символов, либы разные не обозначишь 1-ой буквой, да и в "этом" варианте - воткнемся в 127 зависимостей, на все jar (это маловато). На практике получится 5-символов (включая ,), т.е. - 51 либа
для сравнения - в xdocreport из 56 (и это без 11-ти от POI)
потому, в тесте, мне пришлось урезать xdocreport до 22 либ (выкинуть все кроме docx)
 
Последнее редактирование модератором:
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!