diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dkwt-cp.c |
Initial commit
Diffstat (limited to 'support/dktools/dkwt-cp.c')
-rw-r--r-- | support/dktools/dkwt-cp.c | 793 |
1 files changed, 793 insertions, 0 deletions
diff --git a/support/dktools/dkwt-cp.c b/support/dktools/dkwt-cp.c new file mode 100644 index 0000000000..ea5e90fea5 --- /dev/null +++ b/support/dktools/dkwt-cp.c @@ -0,0 +1,793 @@ +/* + WARNING: This file was generated by dkct. + Changes you make here will be lost if dkct is run again! + You should modify the original source and run dkct on it. + Original source: dkwt-cp.ctr +*/ + +/* +Copyright (C) 2012-2017, Dirk Krause + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above opyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of the author nor the names of contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``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 COPYRIGHT OWNER OR CONTRIBUTORS 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. +*/ + +/** @file dkwt-cp.c The dkwt-cp module. +*/ + + +#line 10 "dkwt-cp.ctr" + +/** No warnings from WinSock about deprecated functions. +*/ +#define _WINSOCK_DEPRECATED_NO_WARNINGS 1 + +#include "dk3all.h" +#include "dkt.h" +#include "dkwt.h" + + + + + +#line 22 "dkwt-cp.ctr" + + +/** Buffer size to enumerate printers. +*/ +#define DKWT_PRINTER_ENUM_BUFFER_SIZE 1024 + +/** Buffer size to enumerate print jobs. +*/ +#define DKWT_PRINTER_ENUM_JOBS_SIZE 8192 + +/** Number of print jobs to show in one request. +*/ +#define DKWT_PRINTER_NUMBER_OF_JOBS 64 + + +/** Local print queue. +*/ +typedef struct { + dkChar *qn; /**< Queue name. */ +} DKWT_CP_QUEUE; + + + +/** Print job. +*/ +typedef struct { + DWORD jobId; /**< Job ID. */ + DWORD pos; /**< Position in queue. */ + dkChar const *docName; /**< Print job name. */ +} DKWT_CP_JOB; + + + +/** Compare two print queues by name. + @param l Left object. + @param r Right object. + @param cr Comparison criteria (0=queue/queue, 1=queue/name) + @return Comparison result. +*/ +static +int +dkwt_cp_queue_comp(void const *l, void const *r, int cr) +{ + DKWT_CP_QUEUE const *ql; + DKWT_CP_QUEUE const *qr; + int back = 0; + if(l) { + if(r) { + ql = (DKWT_CP_QUEUE const *)l; + switch(cr) { + case 1: { + if(ql->qn) { + back = dk3str_casecmp(ql->qn, (dkChar const *)r); + if(back < -1) back = -1; + if(back > 1) back = 1; + } else back = -1; + } break; + default: { + qr = (DKWT_CP_QUEUE const *)r; + if(ql->qn) { + if(qr->qn) { + back = dk3str_casecmp(ql->qn, qr->qn); + if(back < -1) back = -1; + if(back > 1) back = 1; + } else back = 1; + } else { + if(qr->qn) back = -1; + } + } break; + } + } else back = 1; + } else { + if(r) back = -1; + } + return back; +} + + + +/** Destroy queue structure, release memory. + @param q Queue structure to destroy. +*/ +static +void +dkwt_cp_queue_del(DKWT_CP_QUEUE *q) +{ + if(q) { + dk3_release(q->qn); + dk3_delete(q); + } +} + + + +/** Create queue structure, allocate memory. + @param app Application structure for diagnostics, may be NULL. + @param n Queue name. + @return Pointer to new structure on success, NULL on error. +*/ +static +DKWT_CP_QUEUE * +dkwt_cp_queue_new(dk3_app_t *app, dkChar const *n) +{ + DKWT_CP_QUEUE *back = NULL; + if(n) { + back = dk3_new_app(DKWT_CP_QUEUE,1,app); + if(back) { + back->qn = NULL; + back->qn = dk3str_dup_app(n, app); + if(!(back->qn)) { + dkwt_cp_queue_del(back); + back = NULL; + } + } + } + return back; +} + + + +/** Destroy job structure, release memory. + @param j Job structure to delete. +*/ +static +void +dkwt_cp_job_del(DKWT_CP_JOB *j) +{ + if(j) { + dk3_release(j->docName); + j->jobId = 0; + j->pos = 0; + dk3_delete(j); + } +} + + + +/** Create new job structure, allocate memory. + @param app Application structure for diagnostics. + @param jobid Job ID. + @param pos Job position in the queue. + @param dn Document name. + @return Pointer to new structure on success, NULL on error. +*/ +static +DKWT_CP_JOB * +dkwt_cp_job_new(dk3_app_t *app, DWORD jobid, DWORD pos, dkChar const *dn) +{ + DKWT_CP_JOB *back = NULL; + back = dk3_new_app(DKWT_CP_JOB,1,app); + if(back) { + back->docName = NULL; + back->jobId = jobid; + back->pos = pos; + if(dn) { + back->docName = dk3str_dup_app(dn, app); + if(!(back->docName)) { + dkwt_cp_job_del(back); + back = NULL; + } + } + } + return back; +} + + + +/** Compare 2 jobs to find which one to delete first. + @param l Left job. + @param r Right job. + @param cr Comparison criteria (ignored). + @return Comparison result, jobs with higher position are deleted first. +*/ +static +int +dkwt_cp_job_comp(void const *l, void const *r, int cr) +{ + DKWT_CP_JOB const *jl; + DKWT_CP_JOB const *jr; + int back = 0; + if(l) { + if(r) { + jl = (DKWT_CP_JOB const *)l; + jr = (DKWT_CP_JOB const *)r; + if(jl->pos < jr->pos) { + back = 1; + } else { + if(jl->pos > jr->pos) { + back = -1; + } + } + } else back = 1; + } else { + if(r) back = -1; + } + return back; +} + + + + +/** Remove all print jobs for one user from a single queue. + @param app Application structure for diagnostics. + @param msg Localized message texts. + @param kwnl Keywords, not localized. + @param userName User name. + @param hostName Host name. + @param queue Queue to modify. +*/ +static +void +dkwt_cp_remove_all_jobs( + dk3_app_t *app, + dkChar const * const *msg, + dkChar const * const *kwnl, + dkChar const *userName, + dkChar const *hostName, + DKWT_CP_QUEUE *queue +) +{ + char jeb[DKWT_PRINTER_ENUM_JOBS_SIZE]; /* Enum buffer. */ + dkChar idbuf[64]; + dk3_sto_t *s_j; /* Jobs storage. */ + dk3_sto_it_t *i_j; /* Iterator for jobs storage. */ + JOB_INFO_1 *ji1; /* Job information pointer. */ + DKWT_CP_JOB *job; /* Current job. */ + HANDLE hPrinter; /* Handle for printer. */ + DWORD szjeb; /* Size of jeb buffer. */ + DWORD bneed; /* Bytes needed. */ + DWORD nj; /* Number of jobs found. */ + DWORD i; /* Index of current job to process. */ + int rmj; /* Flag: Remove this job. */ + BOOL res; /* Operation result. */ + + +#line 256 "dkwt-cp.ctr" + s_j = NULL; i_j = NULL; + s_j = dk3sto_open_app(app); + if(s_j) { + dk3sto_set_comp(s_j, dkwt_cp_job_comp, 0); + i_j = dk3sto_it_open(s_j); + } + if((s_j) && (i_j)) { + /* PROGRESS: Cleaning up local queue... */ + dk3app_log_3(app, DK3_LL_PROGRESS, msg, 83, 84, queue->qn); +#if DK3_CHAR_SIZE > 1 + res = OpenPrinterW(queue->qn, &hPrinter, NULL); +#else + res = OpenPrinterA(queue->qn, &hPrinter, NULL); +#endif + if(res) { + /* Enumerate print jobs, save jobs to delete. + */ + szjeb = sizeof(jeb); bneed = 0; nj = 0; +#if DK3_CHAR_SIZE > 1 + res = EnumJobsW( + hPrinter, 0, DKWT_PRINTER_NUMBER_OF_JOBS, 1, (LPBYTE)jeb, szjeb, + &bneed, &nj + ); +#else + res = EnumJobsA( + hPrinter, 0, DKWT_PRINTER_NUMBER_OF_JOBS, 1, (LPBYTE)jeb, szjeb, + &bneed, &nj + ); +#endif + if(res) { + +#line 286 "dkwt-cp.ctr" + if(nj > 0) { + +#line 287 "dkwt-cp.ctr" + ji1 = (JOB_INFO_1 *)jeb; + for(i = 0; i < nj; i++) { + rmj = 0; + if(ji1[i].pUserName) { + +#line 291 "dkwt-cp.ctr" + if(0 == dk3str_casecmp(ji1[i].pUserName, userName)) { + +#line 292 "dkwt-cp.ctr" + rmj = 1; + if(hostName) { + +#line 294 "dkwt-cp.ctr" + rmj = 0; + if(ji1[i].pMachineName) { + +#line 296 "dkwt-cp.ctr" + if(0 == dk3str_casecmp(ji1[i].pMachineName, hostName)) { + +#line 297 "dkwt-cp.ctr" + rmj = 1; + } else { + if(dkT('\\') == (ji1[i].pMachineName)[0]) { + if(dkT('\\') == (ji1[i].pMachineName)[1]) { + if(0 == dk3str_casecmp(&((ji1[i].pMachineName)[2]), hostName)) { + rmj = 1; + } + } + } + } + } else { + +#line 308 "dkwt-cp.ctr" + rmj = 1; + } + } else { + +#line 311 "dkwt-cp.ctr" + } + } else { + +#line 313 "dkwt-cp.ctr" + } + } + if(rmj) { + +#line 316 "dkwt-cp.ctr" + job = dkwt_cp_job_new(app, ji1[i].JobId, ji1[i].Position, ji1[i].pDocument); + if(job) { + if(!dk3sto_add(s_j, (void *)job)) { + +#line 319 "dkwt-cp.ctr" + dkwt_cp_job_del(job); + } else { + } + } else { + +#line 323 "dkwt-cp.ctr" + } + } + } + } else { + +#line 327 "dkwt-cp.ctr" + } + } else { + +#line 329 "dkwt-cp.ctr" + } + /* Delete saved print jobs if any. + */ + dk3sto_it_reset(i_j); + while(NULL != (job = (DKWT_CP_JOB *)dk3sto_it_next(i_j))) { + + +#line 335 "dkwt-cp.ctr" +#if VERSION_20140716 + dk3sf_sprintf3(idbuf, dkT("%lu"), (unsigned long)(job->jobId)); +#else + if (!(dk3ma_um_to_string(idbuf, DK3_SIZEOF(idbuf,dkChar), (dk3_um_t)(job->jobId)))) { + idbuf[0] = dkT('\0'); + } +#endif + if(SetJob(hPrinter, job->jobId, 0, NULL, JOB_CONTROL_DELETE)) { + /* PROGRESS: Print job deleted. */ + +#line 344 "dkwt-cp.ctr" + dk3app_log_5( + app, DK3_LL_PROGRESS, msg, 85, 86, 87, idbuf, + ((job->docName) ? (job->docName) : msg[88]) + ); + } else { + +#line 349 "dkwt-cp.ctr" + /* ERROR: Failed to delete print job! */ + dk3app_log_5( + app, DK3_LL_ERROR, msg, 89, 90, 91, idbuf, + ((job->docName) ? (job->docName) : msg[88]) + ); + } + } + ClosePrinter(hPrinter); + } else { + +#line 358 "dkwt-cp.ctr" + /* ERROR: Failed to open printer! */ + dk3app_log_3(app, DK3_LL_ERROR, msg, 92, 93, queue->qn); + } + } else { + +#line 362 "dkwt-cp.ctr" + } + /* Release memory. + */ + if(s_j) { + if(i_j) { + dk3sto_it_reset(i_j); + while(NULL !=(job = (DKWT_CP_JOB *)dk3sto_it_next(i_j))) { + dkwt_cp_job_del(job); + } + dk3sto_it_close(i_j); + } + dk3sto_close(s_j); + } + +#line 375 "dkwt-cp.ctr" +} + + + +void +dkwt_clear_printers_local( + dk3_app_t *app, + dkChar const * const *msg, + dkChar const * const *kwnl, + dkChar const *userName +) +{ + char peb[DKWT_PRINTER_ENUM_BUFFER_SIZE]; + dkChar hn[256]; /* Host name. */ + dk3_sto_t *s_q; /* Storage for print queues. */ + dk3_sto_it_t *i_q; /* Iterator for print queues storage. */ + DKWT_CP_QUEUE *q; /* Current queue to process. */ + PRINTER_INFO_4 *pi4; /* Printer information array. */ + DWORD szpeb; /* Size of peb buffer. */ + DWORD bneed; /* Needed bytes. */ + DWORD np; /* Number of printers found. */ + DWORD i; /* Index of current printer. */ + DWORD szhn; /* Size of host name. */ + BOOL res; /* Result from printer enumeration. */ + s_q = NULL; i_q = NULL; + if(userName) { + hn[0] = dkT('\0'); + szhn = DK3_SIZEOF(hn,dkChar); +#if DK3_CHAR_SIZE > 1 + res = GetComputerNameExW(ComputerNameNetBIOS, hn, &szhn); +#else + res = GetComputerNameExA(ComputerNameNetBIOS, hn, &szhn); +#endif + if(res) { + hn[(szhn < (DK3_SIZEOF(hn,dkChar)-1)) ? szhn : (DK3_SIZEOF(hn,dkChar)-1)] = dkT('\0'); + } else { + szhn = 0; + } + s_q = dk3sto_open_app(app); + if(s_q) { + dk3sto_set_comp(s_q, dkwt_cp_queue_comp, 0); + i_q = dk3sto_it_open(s_q); + } + if((s_q) && (i_q)) { + /* Enumerate printers, fill s_q + */ + szpeb = sizeof(peb); + bneed = 0; + np = 0; +#if DK3_CHAR_SIZE > 1 + res = EnumPrintersW( + PRINTER_ENUM_LOCAL, + NULL, + 4, + (LPBYTE)peb, + szpeb, + &bneed, + &np + ); +#else + res = EnumPrintersA( + PRINTER_ENUM_LOCAL, + NULL, + 4, + (LPBYTE)peb, + szpeb, + &bneed, + &np + ); +#endif + if(res) { + pi4 = (PRINTER_INFO_4 *)peb; + if(np > 0) { + for(i = 0; i < np; i++) { + if(pi4[i].pPrinterName) { + q = dkwt_cp_queue_new(app, pi4[i].pPrinterName); + if(q) { + if(!dk3sto_add(s_q, (void *)q)) { + dkwt_cp_queue_del(q); + } + } + } + } + } + } else { + /* ERROR: Failed to enumerate local printers */ + dk3app_log_1(app, DK3_LL_ERROR, msg, 94); + } + /* Handle all the queues in i_q. + */ + dk3sto_it_reset(i_q); + while(NULL != (q = (DKWT_CP_QUEUE *)dk3sto_it_next(i_q))) { + dkwt_cp_remove_all_jobs(app, msg, kwnl, userName, ((szhn > 0) ? hn : NULL), q); + } + } + /* Release memory. + */ + if(s_q) { + if(i_q) { + dk3sto_it_reset(i_q); + while(NULL != (q = (DKWT_CP_QUEUE *)dk3sto_it_next(i_q))) { + dkwt_cp_queue_del(q); + } + dk3sto_it_close(i_q); + } + dk3sto_close(s_q); + } + } else { + /* ERROR: Missing user name! */ + dk3app_log_1(app, DK3_LL_ERROR, msg, 95); + } +} + + + +/** Send request to host. + @param app Application structure. + @param msg Localized message texts. + @param kwnl Keywords, not localized. + @param rq Request to send. + @param hn Host name to send the request to. +*/ +static +void +dkwt_cp_send_request( + dk3_app_t *app, + dkChar const * const *msg, + dkChar const * const *kwnl, + char const *rq, + dkChar const *hn +) +{ + char buf[512]; + dkChar eb[64]; + struct sockaddr_in in; + struct hostent *he; + unsigned long ip; + unsigned long *ptr; + unsigned long **pptr; + size_t lgt; + SOCKET sock; + int res; + int cc; + int ie; + + ip = 0UL; + dk3enc_ipaddr_to_ul_app(hn, &ip, app); + if(ip) { + ip = dk3enc_htonl(ip); + } else { + ie = dk3app_get_encoding(app); + if(dk3str_to_c8u_app(buf, sizeof(buf), hn, ie, app)) { + he = gethostbyname(buf); + if(he) { + if(he->h_addr_list) { + pptr = (unsigned long **)he->h_addr_list; + ptr = *pptr; + if(ptr) { + ip = *ptr; + } + } + } + } else { + /* ERROR: Failed to convert host name to UTF-8! */ + } + } + if(ip) { + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if(INVALID_SOCKET != sock) { + in.sin_family = AF_INET; + in.sin_addr.s_addr = ip; /* already in network byte order */ + in.sin_port = dk3enc_htons(515); + ip = dk3enc_ntohl(ip); + sprintf( + buf, "%lu.%lu.%lu.%lu", + ((ip >> 24) & 0x000000FFUL), + ((ip >> 16) & 0x000000FFUL), + ((ip >> 8) & 0x000000FFUL), + ( ip & 0x000000FFUL) + ); + if(dk3str_c8_to_str_simple_app(eb, DK3_SIZEOF(eb,dkChar), buf, app)) + { + dk3app_log_3(app, DK3_LL_DEBUG, msg, 115, 116, eb); + } + res = connect( + sock, + (const struct sockaddr *)(&in), + sizeof(struct sockaddr_in) + ); + if(0 == res) { + lgt = strlen(rq); + res = send(sock, rq, (int)lgt, 0); + if(res == lgt) { + shutdown(sock, SD_SEND); + cc = 1; + while(cc) { + cc = 0; + res = recv(sock, buf, sizeof(buf), 0); + if(res > 0) { + cc = 1; + } + } + /* PROGRESS: Print queue cleaned up successfully. */ + dk3app_log_1(app, DK3_LL_PROGRESS, msg, 96); + } else { + /* ERROR: Failed to send request! */ + dk3app_log_1(app, DK3_LL_ERROR, msg, 97); +#if VERSION_BEFORE_20140716 + dk3sf_sprintf3(eb, dkT("%d"), WSAGetLastError()); + dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb); +#else + if (dk3ma_im_to_string(eb, DK3_SIZEOF(eb,dkChar), (dk3_im_t)WSAGetLastError())) { + dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb); + } +#endif + } + } else { + /* ERROR: Failed to connect! */ + dk3app_log_1(app, DK3_LL_ERROR, msg, 98); +#if VERSION_BEFORE_20140716 + dk3sf_sprintf3(eb, dkT("%d"), WSAGetLastError()); + dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb); +#else + if (dk3ma_im_to_string(eb, DK3_SIZEOF(eb,dkChar), (dk3_im_t)WSAGetLastError())) { + dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb); + } +#endif + } + closesocket(sock); + } else { + /* ERROR: Failed to obtain socket! */ + dk3app_log_1(app, DK3_LL_ERROR, msg, 99); + } + } else { + /* ERROR: Failed to find IP address for host! */ + dk3app_log_1(app, DK3_LL_ERROR, msg, 100); + } +} + + + +/** Clean up one remote print queue. + @param app Application structure. + @param msg Localized message texts. + @param kwnl Keywords, not localized. + @param userName User name. + @param queueName Print queue name. +*/ +static +void +dkwt_clear_one_remote_queue( + dk3_app_t *app, + dkChar const * const *msg, + dkChar const * const *kwnl, + dkChar const *userName, + dkChar const *queueName +) +{ + dkChar qnb[256]; /* Copy of queue name. */ + char qnc[256]; /* Queue name as char. */ + char unc[256]; /* User name as char. */ + char rqc[512]; /* Request. */ + dkChar *p1; /* Host name part. */ + size_t sz; + int ie; /* Used encoding. */ + ie = dk3app_get_encoding(app); + if(dk3str_len(queueName) < DK3_SIZEOF(qnb,dkChar)) { + dk3str_cpy_not_overlapped(qnb, queueName); + p1 = dk3str_chr(qnb, dkT('@')); + if(p1) { + *(p1++) = dkT('\0'); + p1 = dk3str_start(p1, NULL); + if(p1) { + dk3str_normalize(qnb, NULL, dkT(' ')); + if(dk3str_len(qnb) > 0) { + if(dk3str_to_c8u_app(qnc, sizeof(qnc), qnb, ie, app)) { + if(dk3str_to_c8u_app(unc, sizeof(unc), userName, ie, app)) { + sz = strlen(qnc) + strlen(unc) + 8; + if(sz < sizeof(rqc)) { + sprintf(rqc, "%c%s %s all\n", 0x05, qnc, unc); + /* PROGRESS: Cleaning up remote print queue ... */ + dk3app_log_3(app, DK3_LL_PROGRESS, msg, 101, 102, queueName); + dkwt_cp_send_request(app, msg, kwnl, rqc, p1); + } else { + /* ERROR: Reqeust becomes too long! */ + dk3app_log_1(app, DK3_LL_ERROR, msg, 103); + } + } else { + /* ERROR: Failed to re-encode user name to UTF-8! */ + } + } else { + /* ERROR: Failed to re-encode the queue name to UTF-8! */ + } + } else { + /* ERROR: Empty queue name! */ + dk3app_log_3(app, DK3_LL_ERROR, msg, 104, 105, queueName); + } + } else { + /* ERROR: Empty host name! */ + dk3app_log_3(app, DK3_LL_ERROR, msg, 106, 107, queueName); + } + } else { + /* ERROR: Not a queue@host name! */ + dk3app_log_3(app, DK3_LL_ERROR, msg, 108, 109, queueName); + } + } else { + /* ERROR: Queue name too long! */ + dk3app_log_3(app, DK3_LL_ERROR, msg, 110, 111, queueName); + } +} + + + +void +dkwt_clear_printers_remote( + dk3_app_t *app, + dkChar const * const *msg, + dkChar const * const *kwnl, + dkChar const *userName, + dk3_sto_it_t *iterator +) +{ + WORD vrq; + WSADATA wsa; + dkChar const *qn; + vrq = MAKEWORD(2,0); + if(0 == WSAStartup(vrq, &wsa)) { + dk3sto_it_reset(iterator); + while(NULL != (qn = (dkChar const *)dk3sto_it_next(iterator))) { + dkwt_clear_one_remote_queue(app, msg, kwnl, userName, qn); + } + (void)WSACleanup(); + } else { + /* ERROR: Failed to initialize Windows socket! */ + dk3app_log_1(app, DK3_LL_ERROR, msg, 112); + } +} + + + +/* vim: set ai sw=2 : */ + |