"Fossies" - the Fresh Open Source Software Archive

Member "ktx/utils/pdfopen/pdfdde.c" (11 Feb 2018, 20576 Bytes) of package /windows/misc/w32tex-src.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pdfdde.c" see the Fossies "Dox" file reference documentation.

    1 /* pdfdde.c -- control Adobe Acrobat under Windows.  Written by Fabrice
    2    Popineau many years ago, based on Adobe documentation.
    3    Modified by Akira Kakuto 2014-2016.
    4    Public domain.  */
    5 
    6 #include <afx.h>
    7 #include <ddeml.h>
    8 #include <dde.h>
    9 #include <stdio.h>
   10 #include <stdlib.h>
   11 #include <string.h>
   12 #include <malloc.h>
   13 #include <shellapi.h>
   14 
   15 #include <getopt.h>
   16 
   17 #define ACROBAT     "acroview"
   18 #define ACROBATR10  "acroviewR10"
   19 #define ACROBATA10  "acroviewA10"
   20 #define ACROBATR11  "acroviewR11"
   21 #define ACROBATA11  "acroviewA11"
   22 #define ACROBATR15  "acroviewR15"
   23 #define ACROBATA15  "acroviewA15"
   24 
   25 #define SRV_NUM 7
   26 char *SrvNam[SRV_NUM];
   27 
   28 #define EVAL_TOPIC  "control"
   29 #define RESULT_ITEM "Result"
   30 #define ERROR_ITEM  "Error"
   31 
   32 /* Timeouts & delays */
   33 #define CONNECT_DELAY       100     /* ms */
   34 #define TRANSACTION_TIMEOUT 5000        /* ms */
   35 #define MAX_INPUT_IDLE_WAIT     INFINITE    /* ms */
   36 
   37 static DWORD DDEsession;
   38 static HCONV DDEconversation;
   39 
   40 /* The raw base name */
   41 static char *argv0 = NULL;
   42 static int nPage = 0;
   43 static char *sFileName = NULL;
   44 static int bAll = 0;
   45 static int bServer = 0;
   46 static int iDebug = 0;
   47 static char *sGoto = NULL;
   48 static char sLongFileName[256];
   49 static int nPrefer = 0;
   50 static char *sServerName = NULL;
   51 
   52 const char *pdfdde_version_string = "0.6";
   53 
   54 /* Test whether getopt found an option ``A''.
   55    Assumes the option index is in the variable `option_index', and the
   56    option table in a variable `long_options'.  */
   57 #define ARGUMENT_IS(a) (_stricmp(long_options[option_index].name, a) == 0)
   58 #define PROGRAM_IS(a) (_stricmp(a, argv0) == 0)
   59 
   60 static struct option long_options [] = {
   61     { "rx",                  0, &nPrefer, 1},
   62     { "ax",                  0, &nPrefer, 2},
   63     { "rxi",                 0, &nPrefer, 3},
   64     { "axi",                 0, &nPrefer, 4},
   65     { "rxv",                 0, &nPrefer, 5},
   66     { "axv",                 0, &nPrefer, 6},
   67     { "r10",                 0, &nPrefer, 1},
   68     { "a10",                 0, &nPrefer, 2},
   69     { "r11",                 0, &nPrefer, 3},
   70     { "a11",                 0, &nPrefer, 4},
   71     { "r15",                 0, &nPrefer, 5},
   72     { "a15",                 0, &nPrefer, 6},
   73     { "debug",               0, 0, 0},
   74     { "help",                0, 0, 0},
   75     { "version",             0, 0, 0},
   76     { "file",                1, 0, 0},
   77     { "page",                1, 0, 0},
   78     { "goto",                1, 0, 0},
   79     { "all",                 0, 0, 0},
   80     {0, 0, 0, 0}
   81 };
   82 
   83 
   84 char *FindAcrobatModule()
   85 {
   86     char buf[260];
   87     char path[260];
   88     char *program;
   89     HANDLE hFile;
   90     HINSTANCE hInst;
   91  
   92     program = (char *)malloc(MAX_PATH*sizeof(char));
   93     if (program == NULL) goto exit_1;
   94 
   95     buf[0] = path[0] = program[0] = '\0';
   96     
   97     if (GetTempPath(sizeof(path), path) != 0) {
   98     strcpy(buf, path);
   99     }
  100 
  101 
  102     strcat(buf, "dummy.pdf");
  103     
  104     hFile = CreateFile(buf, 
  105                GENERIC_READ|GENERIC_WRITE, 
  106                FILE_SHARE_READ | FILE_SHARE_WRITE, 
  107                NULL,
  108                OPEN_ALWAYS, 
  109                FILE_ATTRIBUTE_NORMAL, 
  110                NULL);
  111     
  112     CloseHandle(hFile);
  113     
  114     hInst = FindExecutable("dummy.pdf", path, program);
  115     
  116     DeleteFile(buf);
  117     
  118 #if 0
  119     switch ((int)hInst) {
  120     case SE_ERR_FNF:
  121     fprintf(stdout, "File not found: %s\n", argv[1]);
  122     break;
  123     case SE_ERR_NOASSOC:
  124     fprintf(stdout, "No association for %s\n", argv[1]);
  125     break;
  126     default:
  127     fprintf(stdout, "File .pdf is opened by %s\n", program);
  128     break;
  129     }
  130 #endif
  131 
  132     if (*program == '\0' || (GetFileAttributes(program) == 0xFFFFFFFF)) {
  133     program = NULL;
  134     }
  135 
  136 exit_1:
  137     return program;
  138 
  139 }
  140 
  141 void CloseConversation (void)
  142 {
  143     if (DDEconversation)
  144     DdeDisconnect(DDEconversation);
  145     if (DDEsession)
  146     DdeUninitialize(DDEsession);
  147 }
  148 
  149 void error(LPCTSTR fmt, ...)
  150 {
  151     va_list ap;
  152     va_start(ap, fmt);
  153     vfprintf(stderr, fmt, ap);
  154     va_end(ap);
  155     fputc('\n', stderr);
  156 
  157     /* Tidy up */
  158     CloseConversation();
  159     exit(1);
  160 }
  161 
  162 void *emalloc(size_t len)
  163 {
  164     void *p = malloc(len);
  165 
  166     if (p == NULL)
  167     error("Out of memory - cannot allocate %d bytes", len);
  168 
  169     return p;
  170 }
  171 
  172 int outstanding_requests;
  173 
  174 HDDEDATA CALLBACK
  175 Callback (UINT uType, UINT uFmt, HCONV hconv, HSZ hsz1, HSZ hsz2,
  176       HDDEDATA hdata, DWORD dwData1, DWORD dwData2)
  177 {
  178     if (uType == XTYP_ADVDATA) {
  179     DWORD len = DdeGetData(hdata, NULL, 0, 0);
  180     char *buf =(char *) _alloca(len + 1);
  181     DdeGetData(hdata, (LPBYTE)buf, len + 1, 0);
  182     
  183     if (--outstanding_requests == 0)
  184         PostQuitMessage(0);
  185     
  186     return (HDDEDATA) DDE_FACK;
  187     }
  188     
  189     return (HDDEDATA) NULL;
  190 }
  191 
  192 int StartServer(LPCTSTR prog)
  193 {
  194     STARTUPINFO si;
  195     PROCESS_INFORMATION pi;
  196     
  197     /* To be sure ... */
  198     if (! prog) 
  199     return 1;
  200 
  201     ZeroMemory (&si, sizeof (si));
  202     si.cb = sizeof (si);
  203     if (!CreateProcess (NULL, (LPTSTR)prog, NULL, NULL, FALSE, 0,
  204             NULL, NULL, &si, &pi))
  205     {
  206     error("Could not start process %s", prog);
  207     return 1;
  208     }
  209 
  210     /* Wait for the process to enter an idle state */
  211     WaitForInputIdle (pi.hProcess, MAX_INPUT_IDLE_WAIT);
  212 
  213     /* Close the handles */
  214     CloseHandle (pi.hThread);
  215     CloseHandle (pi.hProcess);
  216     return 0;
  217 }
  218 
  219 HSZ DDEString(LPCTSTR str)
  220 {
  221     HSZ hsz = DdeCreateStringHandle(DDEsession, str, CP_WINANSI);
  222     if (hsz == 0)
  223     error("Cannot create string for %s", str);
  224     return hsz;
  225 }
  226 
  227 void FreeString(HSZ hsz)
  228 {
  229     DdeFreeStringHandle(DDEsession, hsz);
  230 }
  231 
  232 void OpenConversation(LPCTSTR topic_name)
  233 {
  234     UINT ret;
  235     HSZ service;
  236     HSZ topic;
  237     int i, n;
  238     int nn = 0;
  239     
  240     ret = DdeInitialize(&DDEsession, (PFNCALLBACK)Callback, APPCMD_CLIENTONLY, 0);
  241     if (ret != DMLERR_NO_ERROR)
  242     error("Cannot start DDE");
  243 
  244     topic = DDEString(topic_name);
  245 
  246     if(nPrefer == 0) {
  247         if(sServerName)
  248           strcpy(SrvNam[0], sServerName);
  249         else
  250           strcpy(SrvNam[0], ACROBATA11);
  251         strcpy(SrvNam[1], ACROBATR11);
  252         strcpy(SrvNam[2], ACROBATA15);
  253         strcpy(SrvNam[3], ACROBATR15);
  254         strcpy(SrvNam[4], ACROBATA10);
  255         strcpy(SrvNam[5], ACROBATR10);
  256         strcpy(SrvNam[6], ACROBAT);
  257     } else if(nPrefer == 1) {
  258         if(sServerName)
  259           strcpy(SrvNam[0], sServerName);
  260         else
  261           strcpy(SrvNam[0], ACROBATR10);
  262         strcpy(SrvNam[1], ACROBATA10);
  263         strcpy(SrvNam[2], ACROBATR15);
  264         strcpy(SrvNam[3], ACROBATA15);
  265         strcpy(SrvNam[4], ACROBATR11);
  266         strcpy(SrvNam[5], ACROBATA11);
  267         strcpy(SrvNam[6], ACROBAT);
  268     } else if(nPrefer == 2) {
  269         if(sServerName)
  270           strcpy(SrvNam[0], sServerName);
  271         else
  272           strcpy(SrvNam[0], ACROBATA10);
  273         strcpy(SrvNam[1], ACROBATR10);
  274         strcpy(SrvNam[2], ACROBATA15);
  275         strcpy(SrvNam[3], ACROBATR15);
  276         strcpy(SrvNam[4], ACROBATA11);
  277         strcpy(SrvNam[5], ACROBATR11);
  278         strcpy(SrvNam[6], ACROBAT);
  279     } else if(nPrefer == 3) {
  280         if(sServerName)
  281           strcpy(SrvNam[0], sServerName);
  282         else
  283           strcpy(SrvNam[0], ACROBATR11);
  284         strcpy(SrvNam[1], ACROBATA11);
  285         strcpy(SrvNam[2], ACROBATR15);
  286         strcpy(SrvNam[3], ACROBATA15);
  287         strcpy(SrvNam[4], ACROBATR10);
  288         strcpy(SrvNam[5], ACROBATA10);
  289         strcpy(SrvNam[6], ACROBAT);
  290     } else if(nPrefer == 4) {
  291         if(sServerName)
  292           strcpy(SrvNam[0], sServerName);
  293         else
  294           strcpy(SrvNam[0], ACROBATA11);
  295         strcpy(SrvNam[1], ACROBATR11);
  296         strcpy(SrvNam[2], ACROBATA15);
  297         strcpy(SrvNam[3], ACROBATR15);
  298         strcpy(SrvNam[4], ACROBATA10);
  299         strcpy(SrvNam[5], ACROBATR10);
  300         strcpy(SrvNam[6], ACROBAT);
  301     } else if(nPrefer == 5) {
  302         if(sServerName)
  303           strcpy(SrvNam[0], sServerName);
  304         else
  305           strcpy(SrvNam[0], ACROBATR15);
  306         strcpy(SrvNam[1], ACROBATA15);
  307         strcpy(SrvNam[2], ACROBATR11);
  308         strcpy(SrvNam[3], ACROBATA11);
  309         strcpy(SrvNam[4], ACROBATR10);
  310         strcpy(SrvNam[5], ACROBATA10);
  311         strcpy(SrvNam[6], ACROBAT);
  312     } else if(nPrefer == 6) {
  313         if(sServerName)
  314           strcpy(SrvNam[0], sServerName);
  315         else
  316           strcpy(SrvNam[0], ACROBATA15);
  317         strcpy(SrvNam[1], ACROBATR15);
  318         strcpy(SrvNam[2], ACROBATA11);
  319         strcpy(SrvNam[3], ACROBATR11);
  320         strcpy(SrvNam[4], ACROBATA10);
  321         strcpy(SrvNam[5], ACROBATR10);
  322         strcpy(SrvNam[6], ACROBAT);
  323     }
  324 
  325     if (nn == 0) {
  326         service = DDEString(SrvNam[0]);
  327         DDEconversation = DdeConnect(DDEsession, service, topic, 0);
  328 
  329         if (DDEconversation == 0)
  330         {
  331         if (StartServer(FindAcrobatModule()) == 0)
  332         {
  333             for (n = 0; n < 3; n++)
  334             {
  335             Sleep (CONNECT_DELAY);
  336             DDEconversation = DdeConnect(DDEsession, service, topic, 0);
  337             if (DDEconversation)
  338                 break;
  339             }
  340             if (DDEconversation == 0)
  341             nn = 1;
  342         }
  343         }
  344     }
  345 
  346     if (nn == 1) {
  347         for(i = 1; i < SRV_NUM; i++) {
  348             FreeString(service);
  349             service = DDEString(SrvNam[i]);
  350             DDEconversation = DdeConnect(DDEsession, service, topic, 0);
  351             if(DDEconversation != 0)
  352                 nn = 0;
  353             else if(StartServer(FindAcrobatModule()) == 0) {
  354             for (n = 0; n < 3; n++) {
  355             Sleep (CONNECT_DELAY);
  356             DDEconversation = DdeConnect(DDEsession, service, topic, 0);
  357             if (DDEconversation)
  358                 break;
  359             }
  360             if (DDEconversation == 0)
  361             nn = 2;
  362                 else
  363                     nn = 0;
  364         }
  365             if(nn == 0)
  366                 break;
  367     }
  368     }
  369 
  370     if (nn == 2)
  371         error("Cannot contact a server.");
  372 
  373     FreeString(service);
  374     FreeString(topic);
  375 }
  376 
  377 void __cdecl ExecuteCommand(LPCTSTR command, ...)
  378 {
  379     HDDEDATA ret;
  380     va_list args;
  381     int len;
  382     char *buffer;
  383     char tp[1024];
  384 
  385     va_start( args, command );
  386     len = _vsnprintf(tp, 1023, command, args)+1; // _vsnprintf doesn't count
  387                                                  // terminating '\0'
  388     buffer = (char *)malloc( len * sizeof(char) );
  389     vsprintf( buffer, command, args );
  390     
  391     ret = DdeClientTransaction((LPBYTE)buffer, strlen(buffer) + 1,
  392                    DDEconversation, 0, 0, XTYP_EXECUTE,
  393                    TRANSACTION_TIMEOUT, 0);
  394     if (ret == 0)
  395     error("Cannot execute command \"%s\" (error %ld)", command, DdeGetLastError(DDEsession));
  396 }
  397 
  398 void StartHotLink(LPCTSTR item_name)
  399 {
  400     HSZ item = DDEString(item_name);
  401     DdeClientTransaction(0, 0, DDEconversation, item, CF_TEXT, XTYP_ADVSTART,
  402              TRANSACTION_TIMEOUT, 0);
  403     FreeString(item);
  404 }
  405 
  406 LPTSTR RequestData (LPCTSTR item_name)
  407 {
  408     HSZ item = DDEString(item_name);
  409     DWORD len;
  410     char *buf;
  411     HDDEDATA result;
  412     result = DdeClientTransaction (NULL, 0, DDEconversation, item, CF_TEXT,
  413                    XTYP_REQUEST, TRANSACTION_TIMEOUT, 0);
  414     FreeString(item);
  415     if (result == 0)
  416     error("Cannot request item %s\n", item_name);
  417 
  418     len = DdeGetData(result, NULL, 0, 0);
  419     buf = (char *)emalloc(len + 1);
  420     DdeGetData(result, (LPBYTE)buf, len + 1, 0);
  421     return buf;
  422 }
  423 
  424 void usage()
  425 {
  426   fprintf(stderr, "Usage:\n");
  427   fprintf(stderr, "\tpdfopen  --file <filename> [--page <page>]\n");
  428   fprintf(stderr, "\tpdfopen  [--page <page>] <filename>\n");
  429   fprintf(stderr, "\t\t       Opens <filename> (at page <page> if available)\n");
  430   fprintf(stderr, "\t\t             in Adobe Acrobat or Adobe Reader.\n");
  431   fprintf(stderr, "\tpdfclose --file <filename>\n");
  432   fprintf(stderr, "\tpdfclose <filename>\n");
  433   fprintf(stderr, "\t         Closes <filename> in Adobe Acrobat or Adobe Reader.\n");
  434   fprintf(stderr, "\tpdfclose --all\n");
  435   fprintf(stderr, "\t         Closes all documents in Adobe Acrobat or Adobe Reader.\n");
  436   fprintf(stderr, "Beware: only documents opened by `pdfopen' can be closed\n");
  437   fprintf(stderr, "        by `pdfclose'.\n");
  438   fprintf(stderr, "Option:\n");
  439   fprintf(stderr, "\t         --rx  : Prefer the server Adobe Reader X.\n");
  440   fprintf(stderr, "\t         --ax  : Prefer the server Adobe Acrobat X.\n");
  441   fprintf(stderr, "\t         --rxi : Prefer the server Adobe Reader XI.\n");
  442   fprintf(stderr, "\t         --axi : Prefer the server Adobe Acrobat XI.\n");
  443   fprintf(stderr, "\t         --rxv : Prefer the server Adobe Reader XV.\n");
  444   fprintf(stderr, "\t         --axv : Prefer the server Adobe Acrobat XV.\n");
  445   fprintf(stderr, "\t         --r10 : Same as --rx.\n");
  446   fprintf(stderr, "\t         --a10 : Same as --ax.\n");
  447   fprintf(stderr, "\t         --r11 : Same as --rxi.\n");
  448   fprintf(stderr, "\t         --a11 : Same as --axi.\n");
  449   fprintf(stderr, "\t         --r15 : Same as --rxv.\n");
  450   fprintf(stderr, "\t         --a15 : Same as --axv.\n\n");
  451   fprintf(stderr, "If you see a message 'Cannot contact a server.'\n");
  452   fprintf(stderr, "you have to specify the DDE server name in a file\n");
  453   fprintf(stderr, "`pdfddeservername.txt' which is in a directory\n");
  454   fprintf(stderr, "where pdfdde.exe exists,\n");
  455   exit(0);
  456 }
  457 
  458 char *CheckFileName(char *p)
  459 {
  460   char sTmp[256];
  461   char *fp;
  462 
  463   sLongFileName[0] = '\0';
  464 
  465   if (GetFileAttributes(p) == -1) {
  466     fprintf(stderr, "%s: non existent file %s\n", argv0, p);
  467     return NULL;
  468   }
  469   if (GetFullPathName(p, sizeof(sTmp), sTmp, &fp) == 0) {
  470     fprintf(stderr, "%s: failed to get full path name for %s (Error %d)\n", argv0, p, GetLastError());
  471     return NULL;
  472   }
  473 
  474 /*
  475   if (GetLongPathName(sTmp, sLongFileName, sizeof(sLongFileName)) == 0) {
  476     fprintf(stderr, "%s: failed to get long path name for %s (Error %d)\n", argv0, sTmp, GetLastError());
  477     return NULL;
  478   }
  479 */
  480 
  481   strcpy(sLongFileName, sTmp);
  482   return sLongFileName;
  483 }
  484 
  485 int pdfopen()
  486 {
  487   if (sLongFileName[0] == '\0') {
  488     fprintf(stderr, "%s: mandatory `--file' argument not found.\n", argv0);
  489     fprintf(stderr, "         if `--file' option is not used, file name\n");
  490     fprintf(stderr, "         must be the last argument.\n");
  491     fprintf(stderr, "         try `--help' option for the usage.\n");
  492     return EXIT_FAILURE;
  493   }
  494 
  495   OpenConversation(EVAL_TOPIC);
  496   
  497   ExecuteCommand("[DocOpen(\"%s\")]", sLongFileName); 
  498   ExecuteCommand("[FileOpen(\"%s\")]", sLongFileName); 
  499 
  500   if (nPage > 0) {
  501     ExecuteCommand("[DocGoTo(\"%s\", %d)]", sLongFileName, nPage); 
  502   }
  503 
  504   if (sGoto != NULL) {
  505     ExecuteCommand("[DocGoToNameDest(\"%s\", %s)]", sLongFileName, sGoto); 
  506   }
  507 
  508   CloseConversation();
  509 #if 0
  510   /* Problem : it seems that these calls can put AR into a strange state.
  511      It would have been simpler if Adobe had simply iconified their application. */
  512   if (stricmp(argv0, "pdfclose") == 0) {
  513     sprintf(buf, "[AppHide()]");
  514   }
  515   else if (stricmp(argv0, "pdfopen") == 0) {
  516     sprintf(buf, "[AppShow()]");
  517   }
  518   bRetVal = DdeClientTransaction((unsigned char *)buf, (DWORD)strlen(buf),
  519                  (HCONV)hConversation, NULL,
  520                  (UINT)CF_TEXT, (UINT)XTYP_EXECUTE, (DWORD)1000, &dwResult);
  521 #endif
  522   
  523   return EXIT_SUCCESS;
  524 }
  525 
  526 int pdfclose()
  527 {
  528     OpenConversation(EVAL_TOPIC);
  529 
  530     if (bAll) {
  531     ExecuteCommand("[CloseAllDocs()]");
  532     }
  533     else if (sLongFileName[0] != '\0') {
  534     ExecuteCommand("[DocClose(\"%s\")]", sLongFileName);
  535     }
  536     
  537 #if 0
  538     fprintf(stderr, "cmd : %s\n", buf);
  539 #endif
  540     
  541     CloseConversation();
  542     
  543     return EXIT_SUCCESS;
  544 }
  545 
  546 int pdfserver()
  547 {
  548   char line[1024];
  549 
  550   OpenConversation(EVAL_TOPIC);
  551   
  552   fprintf(stdout, "Type Ctrl-Z to quit.\n");
  553 
  554   while (fgets(line, sizeof(line), stdin)) {
  555 #define WHITE_DELIM " \t\n"
  556     char *p = strtok(line, WHITE_DELIM);
  557     if (stricmp(p, "open") == 0) {
  558       p = strtok(NULL, WHITE_DELIM);
  559       if (CheckFileName(p) == NULL) goto next;
  560   
  561       ExecuteCommand("[DocOpen(\"%s\")]", sLongFileName); 
  562     }
  563     else if (stricmp(p, "close") == 0) {
  564       p = strtok(NULL, WHITE_DELIM);
  565       if (CheckFileName(p) == NULL) goto next;
  566       ExecuteCommand("[DocClose(\"%s\")]", sLongFileName);
  567     }
  568     else if (stricmp(p, "closeall") == 0) {
  569       ExecuteCommand("[CloseAllDocs()]");
  570     }
  571     else if (stricmp(p, "goto") == 0) {
  572       p = strtok(NULL, WHITE_DELIM);
  573       if (p == NULL) goto next;
  574       if (CheckFileName(p) == NULL) goto next;
  575       p = strtok(NULL, WHITE_DELIM);
  576       if (p == NULL) goto next;
  577       nPage = atoi(p) - 1;
  578       ExecuteCommand("[DocGoTo(\"%s\", %d)]", sLongFileName, nPage); 
  579     }
  580     else if (stricmp(p, "gotoname") == 0) {
  581       p = strtok(NULL, WHITE_DELIM);
  582       if (p == NULL) goto next;
  583       if (CheckFileName(p) == NULL) goto next;
  584       p = strtok(NULL, WHITE_DELIM);
  585       if (p == NULL) goto next;
  586       sGoto = p;
  587       ExecuteCommand("[DocGoToNameDest(\"%s\", %s)]", sLongFileName, sGoto); 
  588     }
  589     else if (stricmp(p, "show") == 0) {
  590       ExecuteCommand("[AppShow()]");
  591 
  592     }
  593     else if (stricmp(p, "hide") == 0) {
  594       ExecuteCommand("[AppHide()]");
  595 
  596     }
  597     else if (stricmp(p, "exit") == 0) {
  598       ExecuteCommand("[AppExit()]");
  599       goto exit;
  600     }
  601     else if (stricmp(p, "list") == 0) {
  602       fprintf(stdout, "open <file>      open the file\n");
  603       fprintf(stdout, "close <file>     close the file\n");
  604       fprintf(stdout, "closeall     close all files\n");
  605       fprintf(stdout, "goto <file> <page>   goto the given <page> in <file>\n");
  606       fprintf(stdout, "gotoname <file> <dest>   goto the <dest> named destination in <file>\n");
  607       fprintf(stdout, "show         show acroview\n");
  608       fprintf(stdout, "hide         hide acroview\n");
  609       fprintf(stdout, "exit         exit acroview and %s\n", argv0);
  610     }
  611   next: ;   
  612   }
  613 
  614 #if 0
  615   fprintf(stderr, "cmd : %s\n", buf);
  616 #endif
  617 exit:
  618   CloseConversation();
  619 
  620   return EXIT_SUCCESS;
  621 }
  622 
  623 static char *getservername(void)
  624 {
  625   FILE *f;
  626   const char *fname = "pdfddeservername.txt";
  627   char buf[256];
  628   size_t  len;
  629   char buffer[256];
  630   char *ret = NULL;
  631 
  632   if (GetModuleFileNameA(NULL, (LPCH) buffer, 256)) {
  633     char *p = strrchr(buffer, '\\');
  634     if (p) {
  635       p++;
  636       *p = '\0';
  637     }
  638     strcat (buffer, fname);
  639   } else {
  640     return NULL;
  641   }
  642 
  643   f = fopen(buffer, "r");
  644   if (f == NULL)
  645     return NULL;
  646 
  647   while(fgets(buf, 256, f)) {
  648     if (buf[0] != '#' && buf[0] != '\n')
  649       break;
  650     else
  651       continue;
  652   }
  653 
  654   fclose(f);
  655   if(strncmp(buf, "un", 2) == 0)
  656     return NULL;
  657 
  658   len = strlen (buf);
  659   if (len < 8 || buf[0] == '#')
  660     return NULL;
  661 
  662   if (buf[len - 1] == '\n')
  663     buf[len - 1] = '\0';
  664 
  665   ret = _strdup(buf);
  666   return ret;
  667 }
  668 
  669 int main (int argc, char *argv[])
  670 {
  671   BOOL bRet = FALSE;
  672   char *p;
  673   int argv0len = 0;
  674   int g; /* getopt return code */
  675   int option_index;
  676   int i;
  677 
  678   sServerName = getservername();
  679  
  680   for(i=0; i < SRV_NUM; i++)
  681       SrvNam[i] = (char *)malloc(16);
  682 
  683   /* Make argv0 to point to the raw base name */
  684   argv0 = argv[0];
  685   if ((p = strrchr(argv0, '/'))
  686       || (p = strrchr(argv0, '\\'))) {
  687     argv0 = _strdup(p+1);
  688   }
  689 
  690   if ((argv0len = strlen(argv0)) > 4 
  691       && _strnicmp(argv0 + argv0len - 4, ".exe", 4) == 0)
  692     argv0[argv0len - 4] = '\0';
  693 
  694   sLongFileName[0] = '\0';
  695 
  696   if ((p = strrchr(argv[argc-1], '.')) && !_stricmp(p, ".pdf"))
  697     CheckFileName(argv[argc-1]);
  698 
  699   for(;;) {
  700     g = getopt_long_only (argc, argv, "", long_options, &option_index);
  701     
  702     if (g == EOF)
  703       break;
  704 
  705     if (g == '?') {
  706       usage();          /* Unknown option.  */
  707       for(i=0; i < SRV_NUM; i++)
  708           free(SrvNam[i]);
  709       if(sServerName)
  710           free(sServerName);
  711       exit(EXIT_FAILURE);
  712     }
  713 
  714     if (ARGUMENT_IS ("debug")) {
  715       iDebug = TRUE;
  716     }
  717     else if (ARGUMENT_IS ("help")) {
  718       usage();
  719       for(i=0; i < SRV_NUM; i++)
  720           free(SrvNam[i]);
  721       if(sServerName)
  722           free(sServerName);
  723       exit(EXIT_SUCCESS);
  724     }
  725     else if (ARGUMENT_IS ("version")) {
  726       fprintf(stderr, "%s of %s.\n", argv0, pdfdde_version_string);
  727       for(i=0; i < SRV_NUM; i++)
  728           free(SrvNam[i]);
  729       if(sServerName)
  730           free(sServerName);
  731       exit(EXIT_SUCCESS);
  732     }
  733     else if (PROGRAM_IS("pdfopen")) {
  734       if (ARGUMENT_IS("file")) {
  735     CheckFileName(optarg);
  736       }
  737       else if (ARGUMENT_IS("page")) {
  738     nPage = atoi(optarg) - 1;
  739       }
  740       else if (ARGUMENT_IS("goto")) {
  741     sGoto = optarg;
  742       }
  743     }
  744     else if (PROGRAM_IS("pdfclose")) {
  745       if (ARGUMENT_IS("file")) {
  746     CheckFileName(optarg);
  747       }
  748       else if (ARGUMENT_IS("all") && !sLongFileName[0]) {
  749     bAll = TRUE;
  750       }
  751     }
  752   }
  753 
  754   if (PROGRAM_IS("pdfopen")) {
  755     bRet = pdfopen();
  756   }
  757   else if (PROGRAM_IS("pdfclose")) {
  758     bRet = pdfclose();
  759   }
  760   else if (PROGRAM_IS("pdfdde")) {
  761     bRet = pdfserver();
  762   }
  763   else {
  764     fprintf(stderr, "This program has been incorrectly copied to the name %s.\n", argv[0]);
  765     bRet = EXIT_FAILURE;
  766   }
  767   for(i=0; i < SRV_NUM; i++)
  768       free(SrvNam[i]);
  769   if(sServerName)
  770       free(sServerName);
  771   return bRet;
  772 }