| 1 | /******************************************************************************
 | 
|---|
| 2 |  * REXX OS/2 CUPS API Interface (REXXCUPS.DLL)                                *
 | 
|---|
| 3 |  * (C) 2017 Alexander Taylor                                                  *
 | 
|---|
| 4 |  *                                                                            *
 | 
|---|
| 5 |  * LICENSE:                                                                   *
 | 
|---|
| 6 |  *                                                                            *
 | 
|---|
| 7 |  *   Redistribution and use in source and binary forms, with or without       *
 | 
|---|
| 8 |  *   modification, are permitted provided that the following conditions are   *
 | 
|---|
| 9 |  *   met:                                                                     *
 | 
|---|
| 10 |  *                                                                            *
 | 
|---|
| 11 |  *   1. Redistributions of source code must retain the above copyright        *
 | 
|---|
| 12 |  *      notice, this list of conditions and the following disclaimer.         *
 | 
|---|
| 13 |  *                                                                            *
 | 
|---|
| 14 |  *   2. Redistributions in binary form must reproduce the above copyright     *
 | 
|---|
| 15 |  *      notice, this list of conditions and the following disclaimer in the   *
 | 
|---|
| 16 |  *      documentation and/or other materials provided with the distribution.  *
 | 
|---|
| 17 |  *                                                                            *
 | 
|---|
| 18 |  *   3. The name of the author may not be used to endorse or promote products *
 | 
|---|
| 19 |  *      derived from this software without specific prior written permission. *
 | 
|---|
| 20 |  *                                                                            *
 | 
|---|
| 21 |  *   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR     *
 | 
|---|
| 22 |  *   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED           *
 | 
|---|
| 23 |  *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE   *
 | 
|---|
| 24 |  *   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,       *
 | 
|---|
| 25 |  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES       *
 | 
|---|
| 26 |  *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR       *
 | 
|---|
| 27 |  *   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)       *
 | 
|---|
| 28 |  *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,      *
 | 
|---|
| 29 |  *   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
 | 
|---|
| 30 |  *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          *
 | 
|---|
| 31 |  *   POSSIBILITY OF SUCH DAMAGE.                                              *
 | 
|---|
| 32 |  *                                                                            *
 | 
|---|
| 33 |  ******************************************************************************/
 | 
|---|
| 34 | 
 | 
|---|
| 35 | #define INCL_DEV
 | 
|---|
| 36 | #define INCL_DOSERRORS
 | 
|---|
| 37 | #define INCL_DOSMISC
 | 
|---|
| 38 | #define INCL_DOSMODULEMGR
 | 
|---|
| 39 | #define INCL_DOSPROFILE
 | 
|---|
| 40 | #define INCL_SPL
 | 
|---|
| 41 | #define INCL_SPLDOSPRINT
 | 
|---|
| 42 | #define INCL_SPLERRORS
 | 
|---|
| 43 | #define INCL_PM
 | 
|---|
| 44 | #define INCL_WIN
 | 
|---|
| 45 | #define INCL_WINWORKPLACE
 | 
|---|
| 46 | #ifndef OS2_INCLUDED
 | 
|---|
| 47 |     #include <os2.h>
 | 
|---|
| 48 | #endif
 | 
|---|
| 49 | #include <ctype.h>
 | 
|---|
| 50 | #include <stdio.h>
 | 
|---|
| 51 | #include <stdlib.h>
 | 
|---|
| 52 | #include <string.h>
 | 
|---|
| 53 | #define INCL_RXSHV
 | 
|---|
| 54 | #define INCL_RXFUNC
 | 
|---|
| 55 | #include <rexxsaa.h>
 | 
|---|
| 56 | 
 | 
|---|
| 57 | #include <cups/cups.h>
 | 
|---|
| 58 | #include "shfuncs.h"
 | 
|---|
| 59 | 
 | 
|---|
| 60 | 
 | 
|---|
| 61 | // CONSTANTS
 | 
|---|
| 62 | 
 | 
|---|
| 63 | #define SZ_LIBRARY_NAME         "REXXCUPS"  // Name of this library
 | 
|---|
| 64 | #define SZ_VERSION              "0.1"       // Current version of this library
 | 
|---|
| 65 | 
 | 
|---|
| 66 | 
 | 
|---|
| 67 | 
 | 
|---|
| 68 | // Maximum string lengths...
 | 
|---|
| 69 | #define US_INTEGER_MAXZ         12                                   // ...of an integer string
 | 
|---|
| 70 | #define US_STEM_MAXZ          ( US_COMPOUND_MAXZ - US_INTEGER_MAXZ ) // ...of a stem
 | 
|---|
| 71 | #define US_DRVINFO_MAXZ       ( CCHMAXPATH + 8 + 32 )                // ...of an driver/port info string
 | 
|---|
| 72 | #define US_DESTINFO_MAXZ        255                                  // ...of a destination (queue) info string
 | 
|---|
| 73 | 
 | 
|---|
| 74 | 
 | 
|---|
| 75 | // DATA TYPES
 | 
|---|
| 76 | 
 | 
|---|
| 77 | // GLOBALS
 | 
|---|
| 78 | 
 | 
|---|
| 79 | // List of functions to be registered by RPULoadFuncs
 | 
|---|
| 80 | static PSZ RxFunctionTbl[] = {
 | 
|---|
| 81 |     "RxCupsLoadFuncs",         // drop only
 | 
|---|
| 82 |     "RxCupsDropFuncs",
 | 
|---|
| 83 |     "RxCupsVersion",
 | 
|---|
| 84 |     "RxCupsGetQueues"
 | 
|---|
| 85 | };
 | 
|---|
| 86 | 
 | 
|---|
| 87 | 
 | 
|---|
| 88 | // FUNCTION DECLARATIONS
 | 
|---|
| 89 | 
 | 
|---|
| 90 | // Exported REXX functions
 | 
|---|
| 91 | #ifndef __EMX__
 | 
|---|
| 92 | RexxFunctionHandler RxCupsLoadFuncs;
 | 
|---|
| 93 | RexxFunctionHandler RxCupsDropFuncs;
 | 
|---|
| 94 | RexxFunctionHandler RxCupsVersion;
 | 
|---|
| 95 | RexxFunctionHandler RxCupsGetQueues;
 | 
|---|
| 96 | #endif
 | 
|---|
| 97 | 
 | 
|---|
| 98 | 
 | 
|---|
| 99 | /* ************************************************************************* *
 | 
|---|
| 100 |  * EXPORTED REXX FUNCTIONS                                                   *
 | 
|---|
| 101 |  * ************************************************************************* */
 | 
|---|
| 102 | 
 | 
|---|
| 103 | /* ------------------------------------------------------------------------- *
 | 
|---|
| 104 |  * RxCupsLoadFuncs                                                           *
 | 
|---|
| 105 |  *                                                                           *
 | 
|---|
| 106 |  * Register all RxCups* REXX functions except this one.                      *
 | 
|---|
| 107 |  *                                                                           *
 | 
|---|
| 108 |  * REXX ARGUMENTS:    None                                                   *
 | 
|---|
| 109 |  * REXX RETURN VALUE: ""                                                     *
 | 
|---|
| 110 |  * ------------------------------------------------------------------------- */
 | 
|---|
| 111 | APIRET APIENTRY RxCupsLoadFuncs( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
 | 
|---|
| 112 | {
 | 
|---|
| 113 |     int entries,
 | 
|---|
| 114 |         i;
 | 
|---|
| 115 | 
 | 
|---|
| 116 |     // Reset the error indicator
 | 
|---|
| 117 |     WriteErrorCode( 0, NULL );
 | 
|---|
| 118 | 
 | 
|---|
| 119 |     if ( argc > 0 ) return ( 40 );
 | 
|---|
| 120 |     entries = sizeof(RxFunctionTbl) / sizeof(PSZ);
 | 
|---|
| 121 | 
 | 
|---|
| 122 |     // Start from 1 to skip RPULoadFuncs (we don't want to re-register ourselves)
 | 
|---|
| 123 |     for ( i = 1; i < entries; i++ )
 | 
|---|
| 124 |         RexxRegisterFunctionDll( RxFunctionTbl[i], SZ_LIBRARY_NAME, RxFunctionTbl[i] );
 | 
|---|
| 125 | 
 | 
|---|
| 126 |     SaveResultString( prsResult, NULL, 0 );
 | 
|---|
| 127 |     return ( 0 );
 | 
|---|
| 128 | }
 | 
|---|
| 129 | 
 | 
|---|
| 130 | 
 | 
|---|
| 131 | /* ------------------------------------------------------------------------- *
 | 
|---|
| 132 |  * RxCupsDropFuncs                                                           *
 | 
|---|
| 133 |  *                                                                           *
 | 
|---|
| 134 |  * Deregister all RxCups* REXX functions, including this one.                *
 | 
|---|
| 135 |  *                                                                           *
 | 
|---|
| 136 |  * REXX ARGUMENTS:    None                                                   *
 | 
|---|
| 137 |  * REXX RETURN VALUE: ""                                                     *
 | 
|---|
| 138 |  * ------------------------------------------------------------------------- */
 | 
|---|
| 139 | APIRET APIENTRY RxCupsDropFuncs( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
 | 
|---|
| 140 | {
 | 
|---|
| 141 |     int entries,
 | 
|---|
| 142 |         i;
 | 
|---|
| 143 | 
 | 
|---|
| 144 |     // Reset the error indicator
 | 
|---|
| 145 |     WriteErrorCode( 0, NULL );
 | 
|---|
| 146 | 
 | 
|---|
| 147 |     if ( argc > 0 ) return ( 40 );
 | 
|---|
| 148 |     entries = sizeof(RxFunctionTbl) / sizeof(PSZ);
 | 
|---|
| 149 |     for ( i = 0; i < entries; i++ )
 | 
|---|
| 150 |         RexxDeregisterFunction( RxFunctionTbl[i] );
 | 
|---|
| 151 | 
 | 
|---|
| 152 |     SaveResultString( prsResult, NULL, 0 );
 | 
|---|
| 153 |     return ( 0 );
 | 
|---|
| 154 | }
 | 
|---|
| 155 | 
 | 
|---|
| 156 | 
 | 
|---|
| 157 | /* ------------------------------------------------------------------------- *
 | 
|---|
| 158 |  * RxCupsVersion                                                             *
 | 
|---|
| 159 |  *                                                                           *
 | 
|---|
| 160 |  * Returns the current library version.                                      *
 | 
|---|
| 161 |  *                                                                           *
 | 
|---|
| 162 |  * REXX ARGUMENTS:    None                                                   *
 | 
|---|
| 163 |  * REXX RETURN VALUE: Current version in the form "major.minor.refresh"      *
 | 
|---|
| 164 |  * ------------------------------------------------------------------------- */
 | 
|---|
| 165 | APIRET APIENTRY RxCupsVersion( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
 | 
|---|
| 166 | {
 | 
|---|
| 167 |     CHAR szVersion[ 12 ];
 | 
|---|
| 168 | 
 | 
|---|
| 169 |     // Reset the error indicator
 | 
|---|
| 170 |     WriteErrorCode( 0, NULL );
 | 
|---|
| 171 | 
 | 
|---|
| 172 |     if ( argc > 0 ) return ( 40 );
 | 
|---|
| 173 |     sprintf( szVersion, "%s", SZ_VERSION );
 | 
|---|
| 174 | 
 | 
|---|
| 175 |     SaveResultString( prsResult, szVersion, strlen(szVersion) );
 | 
|---|
| 176 |     return ( 0 );
 | 
|---|
| 177 | }
 | 
|---|
| 178 | 
 | 
|---|
| 179 | 
 | 
|---|
| 180 | /* ------------------------------------------------------------------------- *
 | 
|---|
| 181 |  * RxCupsGetQueues                                                           *
 | 
|---|
| 182 |  *                                                                           *
 | 
|---|
| 183 |  *                                                                           *
 | 
|---|
| 184 |  * REXX ARGUMENTS:                                                           *
 | 
|---|
| 185 |  * REXX RETURN VALUE: Number of destinations found.                          *
 | 
|---|
| 186 |  * ------------------------------------------------------------------------- */
 | 
|---|
| 187 | APIRET APIENTRY RxCupsGetQueues( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
 | 
|---|
| 188 | {
 | 
|---|
| 189 |     int i,
 | 
|---|
| 190 |         iDests;
 | 
|---|
| 191 |     cups_dest_t *pDests,
 | 
|---|
| 192 |                 *pThisDest;
 | 
|---|
| 193 |     CHAR szStem[ US_STEM_MAXZ ],
 | 
|---|
| 194 |          szNumber[ US_INTEGER_MAXZ ],
 | 
|---|
| 195 |          szDestInfo[ US_DESTINFO_MAXZ ];
 | 
|---|
| 196 | 
 | 
|---|
| 197 |     // Reset the error indicator
 | 
|---|
| 198 |     WriteErrorCode( 0, NULL );
 | 
|---|
| 199 | 
 | 
|---|
| 200 |     // First argument: stem name
 | 
|---|
| 201 |     if (( argc < 1 ) ||                        // Make sure we have at least one argument...
 | 
|---|
| 202 |         ( ! RXVALIDSTRING(argv[0]) ) ||         // ...which is a valid REXX string...
 | 
|---|
| 203 |         ( RXSTRLEN(argv[0]) > US_STEM_MAXZ ))   // ...that isn't too long.
 | 
|---|
| 204 |         return ( 40 );
 | 
|---|
| 205 | 
 | 
|---|
| 206 |     // Generate the stem variable name from the argument (stripping any final dot)
 | 
|---|
| 207 |     if ( argv[0].strptr[ argv[0].strlength-1 ] == '.') argv[0].strlength--;
 | 
|---|
| 208 |     strncpy( szStem, argv[0].strptr, RXSTRLEN(argv[0]) );
 | 
|---|
| 209 |     szStem[ RXSTRLEN(argv[0]) ] = '\0';
 | 
|---|
| 210 | 
 | 
|---|
| 211 | //printf("Got parameters.\n");
 | 
|---|
| 212 | /* TODO
 | 
|---|
| 213 |     // Second argument: server name (optional)
 | 
|---|
| 214 |     if ( argc >= 2 && RXVALIDSTRING(argv[1]) ) {
 | 
|---|
| 215 |     }
 | 
|---|
| 216 | 
 | 
|---|
| 217 |     else
 | 
|---|
| 218 | */
 | 
|---|
| 219 |     iDests = cupsGetDests( &pDests );
 | 
|---|
| 220 | //printf("Got dests.\n");
 | 
|---|
| 221 | 
 | 
|---|
| 222 |     if ( iDests && pDests ) {
 | 
|---|
| 223 |         pThisDest = pDests;
 | 
|---|
| 224 |         for ( i = iDests; i > 0; pThisDest++ ) {
 | 
|---|
| 225 |             if ( pThisDest->instance )
 | 
|---|
| 226 |                 sprintf( szDestInfo, "%s/%s", pThisDest->name, pThisDest->instance );
 | 
|---|
| 227 |             else
 | 
|---|
| 228 |                 sprintf( szDestInfo, "%s", pThisDest->name );
 | 
|---|
| 229 |             if ( pThisDest->is_default )
 | 
|---|
| 230 |                 strcat( szDestInfo, "D");
 | 
|---|
| 231 |             WriteStemElement( szStem, i+1, szDestInfo );
 | 
|---|
| 232 | //printf("%s\n", szStem );
 | 
|---|
| 233 |         }
 | 
|---|
| 234 |         cupsFreeDests( iDests, pDests );
 | 
|---|
| 235 |     }
 | 
|---|
| 236 | 
 | 
|---|
| 237 |     // Create the stem.0 element with the number of destinations found
 | 
|---|
| 238 |     sprintf( szNumber, "%u", iDests );
 | 
|---|
| 239 |     WriteStemElement( szStem, 0, szNumber );
 | 
|---|
| 240 | 
 | 
|---|
| 241 |     // And also return the number as the REXX return string
 | 
|---|
| 242 |     SaveResultString( prsResult, szNumber, strlen(szNumber) );
 | 
|---|
| 243 | 
 | 
|---|
| 244 |     return ( 0 );
 | 
|---|
| 245 | }
 | 
|---|
| 246 | 
 | 
|---|
| 247 | 
 | 
|---|
| 248 | /* ------------------------------------------------------------------------- *
 | 
|---|
| 249 |  * RxCups                                                                    *
 | 
|---|
| 250 |  *                                                                           *
 | 
|---|
| 251 |  *                                                                           *
 | 
|---|
| 252 |  * REXX ARGUMENTS:                                                           *
 | 
|---|
| 253 |  * REXX RETURN VALUE:                                                        *
 | 
|---|
| 254 |  * ------------------------------------------------------------------------- */
 | 
|---|
| 255 | 
 | 
|---|