/[svn]/liblscp/trunk/src/common.c
ViewVC logotype

Diff of /liblscp/trunk/src/common.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 189 by capela, Thu Jul 8 16:31:47 2004 UTC revision 253 by capela, Mon Sep 27 14:40:08 2004 UTC
# Line 49  void lscp_client_set_result ( lscp_clien Line 49  void lscp_client_set_result ( lscp_clien
49          pClient->pszResult = strdup(lscp_ltrim(pszResult));          pClient->pszResult = strdup(lscp_ltrim(pszResult));
50  }  }
51    
52  // The main client requester call executive.  
53  lscp_status_t lscp_client_call ( lscp_client_t *pClient, const char *pszQuery )  // The common client receiver executive.
54    lscp_status_t lscp_client_recv ( lscp_client_t *pClient, char *pchBuffer, int *pcchBuffer, int iTimeout )
55  {  {
56      fd_set fds;                         // File descriptor list for select().      fd_set fds;                         // File descriptor list for select().
57      int    fd, fdmax;                   // Maximum file descriptor number.      int    fd, fdmax;                   // Maximum file descriptor number.
58      struct timeval tv;                  // For specifying a timeout value.      struct timeval tv;                  // For specifying a timeout value.
59      int    iSelect;                     // Holds select return status.      int    iSelect;                     // Holds select return status.
60      int    iTimeout;  
61        lscp_status_t ret = LSCP_FAILED;
62    
63        if (pClient == NULL)
64            return ret;
65    
66        // Prepare for waiting on select...
67        fd = (int) pClient->cmd.sock;
68        FD_ZERO(&fds);
69        FD_SET((unsigned int) fd, &fds);
70        fdmax = fd;
71    
72        // Use the timeout select feature...
73        if (iTimeout < 1)
74            iTimeout = pClient->iTimeout;
75        if (iTimeout > 1000) {
76            tv.tv_sec = iTimeout / 1000;
77            iTimeout -= tv.tv_sec * 1000;
78        }
79        else tv.tv_sec = 0;
80        tv.tv_usec = iTimeout * 1000;
81    
82        // Wait for event...
83        iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);
84        if (iSelect > 0 && FD_ISSET(fd, &fds)) {
85            // May recv now...
86            *pcchBuffer = recv(pClient->cmd.sock, pchBuffer, *pcchBuffer, 0);
87            if (*pcchBuffer > 0)
88                ret = LSCP_OK;
89            else if (*pcchBuffer < 0)
90                lscp_socket_perror("lscp_client_recv: recv");
91            else if (*pcchBuffer == 0) {
92                // Damn, server probably disconnected,
93                // we better free everything down here.
94                lscp_socket_agent_free(&(pClient->evt));
95                lscp_socket_agent_free(&(pClient->cmd));
96                // Fake a result message.
97                ret = LSCP_QUIT;
98            }
99        }   // Check if select has timed out.
100        else if (iSelect == 0)
101            ret = LSCP_TIMEOUT;
102        else
103            lscp_socket_perror("lscp_client_recv: select");
104    
105        return ret;
106    }
107    
108    
109    // The main client requester call executive.
110    lscp_status_t lscp_client_call ( lscp_client_t *pClient, const char *pszQuery )
111    {
112      int    cchQuery;      int    cchQuery;
113      char   achResult[LSCP_BUFSIZ];      char   achResult[LSCP_BUFSIZ];
114      int    cchResult;      int    cchResult;
# Line 84  lscp_status_t lscp_client_call ( lscp_cl Line 136  lscp_status_t lscp_client_call ( lscp_cl
136      // Send data, and then, wait for the result...      // Send data, and then, wait for the result...
137      cchQuery = strlen(pszQuery);      cchQuery = strlen(pszQuery);
138      if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {      if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {
139          lscp_socket_perror("_lscp_client_call: send");          lscp_socket_perror("lscp_client_call: send");
140          pszResult = "Failure during send operation";          pszResult = "Failure during send operation";
141          lscp_client_set_result(pClient, pszResult, iErrno);          lscp_client_set_result(pClient, pszResult, iErrno);
142          return ret;          return ret;
143      }      }
144    
145      // Prepare for waiting on select...      // Wait for receive event...
146      fd = (int) pClient->cmd.sock;      cchResult = sizeof(achResult);
147      FD_ZERO(&fds);      ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);
148      FD_SET((unsigned int) fd, &fds);  
149      fdmax = fd;      switch (ret) {
150    
151      // Use the timeout select feature...        case LSCP_OK:
152      iTimeout = pClient->iTimeout;          // Always force the result to be null terminated (and trim trailing CRLFs)!
153      if (iTimeout > 1000) {          while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))
154          tv.tv_sec = iTimeout / 1000;              cchResult--;
155          iTimeout -= tv.tv_sec * 1000;          achResult[cchResult] = (char) 0;
156      }          // Check if the response it's an error or warning message.
157      else tv.tv_sec = 0;          if (strncasecmp(achResult, "WRN:", 4) == 0)
158      tv.tv_usec = iTimeout * 1000;              ret = LSCP_WARNING;
159            else if (strncasecmp(achResult, "ERR:", 4) == 0)
160      // Wait for event...              ret = LSCP_ERROR;
161      iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);          // So we got a result...
162      if (iSelect > 0 && FD_ISSET(fd, &fds)) {          if (ret == LSCP_OK) {
163          // May recv now...              // Reset errno in case of success.
164          cchResult = recv(pClient->cmd.sock, achResult, sizeof(achResult), 0);              iErrno = 0;
165          if (cchResult > 0) {              // Is it a special successful response?
166              // Assume early success.              if (strncasecmp(achResult, "OK[", 3) == 0) {
167              ret = LSCP_OK;                  // Parse the OK message, get the return string under brackets...
             // Always force the result to be null terminated (and trim trailing CRLFs)!  
             while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))  
                 cchResult--;  
             achResult[cchResult] = (char) 0;  
             // Check if the response it's an error or warning message.  
             if (strncasecmp(achResult, "WRN:", 4) == 0)  
                 ret = LSCP_WARNING;  
             else if (strncasecmp(achResult, "ERR:", 4) == 0)  
                 ret = LSCP_ERROR;  
             // So we got a result...  
             if (ret == LSCP_OK) {  
                 // Reset errno in case of success.  
                 iErrno = 0;  
                 // Is it a special successful response?  
                 if (strncasecmp(achResult, "OK[", 3) == 0) {  
                     // Parse the OK message, get the return string under brackets...  
                     pszToken = lscp_strtok(achResult, pszSeps, &(pch));  
                     if (pszToken)  
                         pszResult = lscp_strtok(NULL, pszSeps, &(pch));  
                 }  
                 else pszResult = achResult;  
                 // The result string is now set to the command response, if any.  
             } else {  
                 // Parse the error/warning message, skip first colon...  
168                  pszToken = lscp_strtok(achResult, pszSeps, &(pch));                  pszToken = lscp_strtok(achResult, pszSeps, &(pch));
169                    if (pszToken)
170                        pszResult = lscp_strtok(NULL, pszSeps, &(pch));
171                }
172                else pszResult = achResult;
173                // The result string is now set to the command response, if any.
174            } else {
175                // Parse the error/warning message, skip first colon...
176                pszToken = lscp_strtok(achResult, pszSeps, &(pch));
177                if (pszToken) {
178                    // Get the error number...
179                    pszToken = lscp_strtok(NULL, pszSeps, &(pch));
180                  if (pszToken) {                  if (pszToken) {
181                      // Get the error number...                      iErrno = atoi(pszToken);
182                      pszToken = lscp_strtok(NULL, pszSeps, &(pch));                      // And make the message text our final result.
183                      if (pszToken) {                      pszResult = lscp_strtok(NULL, pszSeps, &(pch));
                         iErrno = atoi(pszToken);  
                         // And make the message text our final result.  
                         pszResult = lscp_strtok(NULL, pszSeps, &(pch));  
                     }  
184                  }                  }
                 // The result string is set to the error/warning message text.  
185              }              }
186                // The result string is set to the error/warning message text.
187          }          }
188          else if (cchResult == 0) {          break;
189              // Damn, server disconnected, we better free everything down here.  
190              lscp_socket_agent_free(&(pClient->evt));        case LSCP_TIMEOUT:
             lscp_socket_agent_free(&(pClient->cmd));  
             // Fake a result message.  
             ret = LSCP_QUIT;  
             pszResult = "Server terminated the connection";  
             iErrno = (int) ret;  
         } else {  
             // What's down?  
             lscp_socket_perror("_lscp_client_call: recv");  
             pszResult = "Failure during receive operation";  
         }  
     }   // Check if select has timed out.  
     else if (iSelect == 0) {  
191          // Fake a result message.          // Fake a result message.
         ret = LSCP_TIMEOUT;  
192          pszResult = "Timeout during receive operation";          pszResult = "Timeout during receive operation";
193          iErrno = (int) ret;          iErrno = (int) ret;
194     }          break;
195      else lscp_socket_perror("_lscp_client_call: select");  
196          case LSCP_QUIT:
197            // Fake a result message.
198            pszResult = "Server terminated the connection";
199            iErrno = (int) ret;
200            break;
201    
202          case LSCP_FAILED:
203          default:
204            // What's down?
205            pszResult = "Failure during receive operation";
206            break;
207        }
208    
209      // Make the result official...      // Make the result official...
210      lscp_client_set_result(pClient, pszResult, iErrno);      lscp_client_set_result(pClient, pszResult, iErrno);

Legend:
Removed from v.189  
changed lines
  Added in v.253

  ViewVC Help
Powered by ViewVC