Back to index

courier  0.68.2
abooksearch.c
Go to the documentation of this file.
00001 /*
00002 **
00003 ** Copyright 2003-2006, Double Precision Inc.
00004 **
00005 ** See COPYING for distribution information.
00006 */
00007 
00008 #include      "config.h"
00009 #include      "ldapaddressbook.h"
00010 
00011 #include      <stdio.h>
00012 #include      <string.h>
00013 #include      <signal.h>
00014 #include      <stdlib.h>
00015 #include      <unistd.h>
00016 #include      <errno.h>
00017 #include      <sys/types.h>
00018 #if HAVE_SYS_WAIT_H
00019 #include      <sys/wait.h>
00020 #endif
00021 #ifndef WEXITSTATUS
00022 #define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
00023 #endif
00024 #ifndef WIFEXITED
00025 #define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
00026 #endif
00027 
00028 #define exit(_a_) _exit(_a_)
00029 
00030 int ldapabook_search(const struct ldapabook *b,  /* Search this address book */
00031                    const char *script,
00032                    const char *search,
00033                    int (*callback_func)(const char *utf8_name,
00034                                      const char *address,
00035                                      void *callback_arg),
00036                    void (*callback_err)(const char *errmsg,
00037                                      void *callback_arg),
00038                    void *callback_arg)
00039 {
00040        int    pipefd[2];
00041        pid_t  p;
00042        const char *argv[40];
00043        char   buf1[BUFSIZ];
00044        char   buf2[BUFSIZ];
00045        FILE   *t, *fp;
00046        int    rc_code=0;
00047        pid_t p2;
00048        int waitstat;
00049 
00050        signal(SIGCHLD, SIG_DFL);
00051 
00052        if (pipe(pipefd) < 0)       return (-1);
00053 
00054        if ((t=tmpfile()) == NULL)
00055        {
00056               close(pipefd[0]);
00057               close(pipefd[1]);
00058               return (-1);
00059        }
00060 
00061        if ((p=fork()) == -1)
00062        {
00063               fclose(t);
00064               close(pipefd[0]);
00065               close(pipefd[1]);
00066               return (-1);
00067        }
00068 
00069        if (p == 0)
00070        {
00071               dup2(pipefd[1], 1);
00072               close(pipefd[0]);
00073               close(pipefd[1]);
00074 
00075               dup2(fileno(t), 2);
00076               fclose(t);
00077 
00078               argv[0]=script;
00079               argv[1]=b->host;
00080               argv[2]=b->port;
00081               argv[3]=b->suffix;
00082               argv[4]=search;
00083               argv[5]=NULL;
00084 
00085               execvp(script, (char **)argv);
00086               perror(script);
00087               exit(1);
00088        }
00089 
00090        fp=fdopen(pipefd[0], "r");
00091        close(pipefd[1]);
00092 
00093        if (!fp)
00094        {
00095               sprintf(buf1, "%1.256s", strerror(errno));
00096 
00097               close(pipefd[0]);
00098 
00099               while ((p2=wait(NULL)) != p)
00100                      ;
00101               fclose(t);
00102 
00103               (*callback_err)(buf1, callback_arg);
00104               return -1;
00105        }
00106 
00107        while (fgets(buf1, sizeof(buf1), fp) != NULL &&
00108               fgets(buf2, sizeof(buf2), fp) != NULL)
00109        {
00110               char *p=strchr(buf1, '\n');
00111 
00112               if (p) *p=0;
00113 
00114               p=strchr(buf2, '\n');
00115               if (p) *p=0;
00116 
00117               if (rc_code == 0)
00118                      rc_code=(*callback_func)(buf1, buf2, callback_arg);
00119        }
00120 
00121        fclose(fp);
00122        close(pipefd[0]);
00123 
00124        while ((p2=wait(&waitstat)) != p)
00125               ;
00126 
00127        if (waitstat && rc_code == 0)
00128        {
00129               rc_code= -1;
00130               fseek(t, 0L, SEEK_SET);
00131 
00132               if (fgets(buf1, sizeof(buf1), t))
00133               {
00134                      char *p=strchr(buf1, '\n');
00135                      if (p) *p=0;
00136 
00137                      (*callback_err)(buf1, callback_arg);
00138               }
00139        }
00140        fclose(t);
00141        return rc_code;
00142 }