/****************************************************************************** * REXX OS/2 CUPS API Interface (REXXCUPS.DLL) * * (C) 2017 Alexander Taylor * * * * LICENSE: * * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions are * * met: * * * * 1. Redistributions of source code must retain the above copyright * * notice, this list of conditions and the following disclaimer. * * * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * * * 3. The name of the author may not be used to endorse or promote products * * derived from this software without specific prior written permission. * * * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * * POSSIBILITY OF SUCH DAMAGE. * * * ******************************************************************************/ #define INCL_DEV #define INCL_DOSERRORS #define INCL_DOSMISC #define INCL_DOSMODULEMGR #define INCL_DOSPROFILE #define INCL_SPL #define INCL_SPLDOSPRINT #define INCL_SPLERRORS #define INCL_PM #define INCL_WIN #define INCL_WINWORKPLACE #ifndef OS2_INCLUDED #include #endif #include #include #include #include #define INCL_RXSHV #define INCL_RXFUNC #include #include #include "shfuncs.h" // CONSTANTS #define SZ_LIBRARY_NAME "REXXCUPS" // Name of this library #define SZ_VERSION "0.1" // Current version of this library // Maximum string lengths... #define US_INTEGER_MAXZ 12 // ...of an integer string #define US_STEM_MAXZ ( US_COMPOUND_MAXZ - US_INTEGER_MAXZ ) // ...of a stem #define US_DRVINFO_MAXZ ( CCHMAXPATH + 8 + 32 ) // ...of an driver/port info string #define US_DESTINFO_MAXZ 255 // ...of a destination (queue) info string // DATA TYPES // GLOBALS // List of functions to be registered by RPULoadFuncs static PSZ RxFunctionTbl[] = { "RxCupsLoadFuncs", // drop only "RxCupsDropFuncs", "RxCupsVersion", "RxCupsGetQueues" }; // FUNCTION DECLARATIONS // Exported REXX functions #ifndef __EMX__ RexxFunctionHandler RxCupsLoadFuncs; RexxFunctionHandler RxCupsDropFuncs; RexxFunctionHandler RxCupsVersion; RexxFunctionHandler RxCupsGetQueues; #endif /* ************************************************************************* * * EXPORTED REXX FUNCTIONS * * ************************************************************************* */ /* ------------------------------------------------------------------------- * * RxCupsLoadFuncs * * * * Register all RxCups* REXX functions except this one. * * * * REXX ARGUMENTS: None * * REXX RETURN VALUE: "" * * ------------------------------------------------------------------------- */ APIRET APIENTRY RxCupsLoadFuncs( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult ) { int entries, i; // Reset the error indicator WriteErrorCode( 0, NULL ); if ( argc > 0 ) return ( 40 ); entries = sizeof(RxFunctionTbl) / sizeof(PSZ); // Start from 1 to skip RPULoadFuncs (we don't want to re-register ourselves) for ( i = 1; i < entries; i++ ) RexxRegisterFunctionDll( RxFunctionTbl[i], SZ_LIBRARY_NAME, RxFunctionTbl[i] ); SaveResultString( prsResult, NULL, 0 ); return ( 0 ); } /* ------------------------------------------------------------------------- * * RxCupsDropFuncs * * * * Deregister all RxCups* REXX functions, including this one. * * * * REXX ARGUMENTS: None * * REXX RETURN VALUE: "" * * ------------------------------------------------------------------------- */ APIRET APIENTRY RxCupsDropFuncs( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult ) { int entries, i; // Reset the error indicator WriteErrorCode( 0, NULL ); if ( argc > 0 ) return ( 40 ); entries = sizeof(RxFunctionTbl) / sizeof(PSZ); for ( i = 0; i < entries; i++ ) RexxDeregisterFunction( RxFunctionTbl[i] ); SaveResultString( prsResult, NULL, 0 ); return ( 0 ); } /* ------------------------------------------------------------------------- * * RxCupsVersion * * * * Returns the current library version. * * * * REXX ARGUMENTS: None * * REXX RETURN VALUE: Current version in the form "major.minor.refresh" * * ------------------------------------------------------------------------- */ APIRET APIENTRY RxCupsVersion( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult ) { CHAR szVersion[ 12 ]; // Reset the error indicator WriteErrorCode( 0, NULL ); if ( argc > 0 ) return ( 40 ); sprintf( szVersion, "%s", SZ_VERSION ); SaveResultString( prsResult, szVersion, strlen(szVersion) ); return ( 0 ); } /* ------------------------------------------------------------------------- * * RxCupsGetQueues * * * * * * REXX ARGUMENTS: * * REXX RETURN VALUE: Number of destinations found. * * ------------------------------------------------------------------------- */ APIRET APIENTRY RxCupsGetQueues( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult ) { int i, iDests; cups_dest_t *pDests, *pThisDest; CHAR szStem[ US_STEM_MAXZ ], szNumber[ US_INTEGER_MAXZ ], szDestInfo[ US_DESTINFO_MAXZ ]; // Reset the error indicator WriteErrorCode( 0, NULL ); // First argument: stem name if (( argc < 1 ) || // Make sure we have at least one argument... ( ! RXVALIDSTRING(argv[0]) ) || // ...which is a valid REXX string... ( RXSTRLEN(argv[0]) > US_STEM_MAXZ )) // ...that isn't too long. return ( 40 ); // Generate the stem variable name from the argument (stripping any final dot) if ( argv[0].strptr[ argv[0].strlength-1 ] == '.') argv[0].strlength--; strncpy( szStem, argv[0].strptr, RXSTRLEN(argv[0]) ); szStem[ RXSTRLEN(argv[0]) ] = '\0'; /* TODO // Second argument: server name (optional) if ( argc >= 2 && RXVALIDSTRING(argv[1]) ) { } else */ iDests = cupsGetDests( &pDests ); if ( iDests && pDests ) { pThisDest = pDests; for ( i = iDests; i > 0; pThisDest++ ) { if ( pThisDest->instance ) sprintf( szDestInfo, "%s/%s", pThisDest->name, pThisDest->instance ); else sprintf( szDestInfo, "%s", pThisDest->name ); if ( pThisDest->is_default ) strcat( szDestInfo, "D"); WriteStemElement( szStem, i+1, szDestInfo ); } cupsFreeDests( iDests, pDests ); } // Create the stem.0 element with the number of destinations found sprintf( szNumber, "%u", iDests ); WriteStemElement( szStem, 0, szNumber ); // And also return the number as the REXX return string SaveResultString( prsResult, szNumber, strlen(szNumber) ); return ( 0 ); } /* ------------------------------------------------------------------------- * * RxCups * * * * * * REXX ARGUMENTS: * * REXX RETURN VALUE: * * ------------------------------------------------------------------------- */