Imported Upstream version 0.2.5
[platform/upstream/libtirpc.git] / src / getnetconfig.c
index af4a484..635c03a 100644 (file)
@@ -120,6 +120,7 @@ static struct netconfig *dup_ncp(struct netconfig *);
 
 static FILE *nc_file;          /* for netconfig db */
 static struct netconfig_info   ni = { 0, 0, NULL, NULL};
+extern pthread_mutex_t nc_db_lock;
 
 #define MAXNETCONFIGLINE    1000
 
@@ -136,17 +137,18 @@ __nc_error()
         * (including non-threaded programs), or if an allocation
         * fails.
         */
-       if (nc_key == -1) {
+       if (nc_key == KEY_INITIALIZER) {
                error = 0;
                mutex_lock(&nc_lock);
-               if (nc_key == -1)
+               if (nc_key == KEY_INITIALIZER)
                        error = thr_keycreate(&nc_key, free);
                mutex_unlock(&nc_lock);
                if (error)
                        return (&nc_error);
        }
        if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) {
-               nc_addr = (int *)malloc(sizeof (int));
+               if((nc_addr = (int *)malloc(sizeof (int))) == NULL)
+                       return (&nc_error);
                if (thr_setspecific(nc_key, (void *) nc_addr) != 0) {
                        if (nc_addr)
                                free(nc_addr);
@@ -191,14 +193,17 @@ setnetconfig()
      * For multiple calls, i.e. nc_file is not NULL, we just return the
      * handle without reopening the netconfig db.
      */
+    mutex_lock(&nc_db_lock);
     ni.ref++;
     if ((nc_file != NULL) || (nc_file = fopen(NETCONFIG, "r")) != NULL) {
        nc_vars->valid = NC_VALID;
        nc_vars->flag = 0;
        nc_vars->nc_configs = ni.head;
+       mutex_unlock(&nc_db_lock);
        return ((void *)nc_vars);
     }
     ni.ref--;
+    mutex_unlock(&nc_db_lock);
     nc_error = NC_NONETCONFIG;
     free(nc_vars);
     return (NULL);
@@ -221,12 +226,15 @@ void *handlep;
     char *stringp;             /* tmp string pointer */
     struct netconfig_list      *list;
     struct netconfig *np;
+    struct netconfig *result;
 
     /*
      * Verify that handle is valid
      */
+    mutex_lock(&nc_db_lock);
     if (ncp == NULL || nc_file == NULL) {
        nc_error = NC_NOTINIT;
+       mutex_unlock(&nc_db_lock);
        return (NULL);
     }
 
@@ -243,11 +251,14 @@ void *handlep;
        if (ncp->flag == 0) {   /* first time */
            ncp->flag = 1;
            ncp->nc_configs = ni.head;
-           if (ncp->nc_configs != NULL)        /* entry already exist */
+           if (ncp->nc_configs != NULL)        /* entry already exist */ {
+               mutex_unlock(&nc_db_lock);
                return(ncp->nc_configs->ncp);
+               }
        }
        else if (ncp->nc_configs != NULL && ncp->nc_configs->next != NULL) {
            ncp->nc_configs = ncp->nc_configs->next;
+           mutex_unlock(&nc_db_lock);
            return(ncp->nc_configs->ncp);
        }
 
@@ -255,16 +266,22 @@ void *handlep;
         * If we cannot find the entry in the list and is end of file,
         * we give up.
         */
-       if (ni.eof == 1)        return(NULL);
+       if (ni.eof == 1) {
+           mutex_unlock(&nc_db_lock);
+           return(NULL);
+       }
        break;
     default:
        nc_error = NC_NOTINIT;
+       mutex_unlock(&nc_db_lock);
        return (NULL);
     }
 
     stringp = (char *) malloc(MAXNETCONFIGLINE);
-    if (stringp == NULL)
-       return (NULL);
+    if (stringp == NULL) {
+    mutex_unlock(&nc_db_lock);
+    return (NULL);
+    }
 
 #ifdef MEM_CHK
     if (malloc_verify() == 0) {
@@ -280,6 +297,7 @@ void *handlep;
        if (fgets(stringp, MAXNETCONFIGLINE, nc_file) == NULL) {
            free(stringp);
            ni.eof = 1;
+           mutex_unlock(&nc_db_lock);
            return (NULL);
         }
     } while (*stringp == '#');
@@ -287,12 +305,14 @@ void *handlep;
     list = (struct netconfig_list *) malloc(sizeof (struct netconfig_list));
     if (list == NULL) {
        free(stringp);
+               mutex_unlock(&nc_db_lock);
        return(NULL);
     }
     np = (struct netconfig *) malloc(sizeof (struct netconfig));
     if (np == NULL) {
        free(stringp);
-       free(list);
+               free(list);
+               mutex_unlock(&nc_db_lock);
        return(NULL);
     }
     list->ncp = np;
@@ -303,6 +323,7 @@ void *handlep;
        free(stringp);
        free(np);
        free(list);
+       mutex_unlock(&nc_db_lock);
        return (NULL);
     }
     else {
@@ -320,7 +341,9 @@ void *handlep;
            ni.tail = ni.tail->next;
        }
        ncp->nc_configs = ni.tail;
-       return(ni.tail->ncp);
+       result = ni.tail->ncp;
+       mutex_unlock(&nc_db_lock);
+       return result;
     }
 }
 
@@ -354,8 +377,10 @@ void *handlep;
     nc_handlep->valid = NC_INVALID;
     nc_handlep->flag = 0;
     nc_handlep->nc_configs = NULL;
+    mutex_lock(&nc_db_lock);
     if (--ni.ref > 0) {
-       free(nc_handlep);
+       mutex_unlock(&nc_db_lock);
+       free(nc_handlep);
        return(0);
     }
 
@@ -376,9 +401,11 @@ void *handlep;
        q = p;
     }
     free(nc_handlep);
-
-    fclose(nc_file);
+    if(nc_file != NULL) {
+        fclose(nc_file);
+    }
     nc_file = NULL;
+    mutex_unlock(&nc_db_lock);
     return (0);
 }
 
@@ -426,16 +453,21 @@ getnetconfigent(netid)
      * If all the netconfig db has been read and placed into the list and
      * there is no match for the netid, return NULL.
      */
+    mutex_lock(&nc_db_lock);
     if (ni.head != NULL) {
        for (list = ni.head; list; list = list->next) {
            if (strcmp(list->ncp->nc_netid, netid) == 0) {
-               return(dup_ncp(list->ncp));
+                       ncp = dup_ncp(list->ncp);
+                       mutex_unlock(&nc_db_lock);
+                       return ncp;
            }
        }
-       if (ni.eof == 1)        /* that's all the entries */
-               return(NULL);
+        if (ni.eof == 1) {     /* that's all the entries */
+               mutex_unlock(&nc_db_lock);
+               return(NULL);
+        }
     }
-
+    mutex_unlock(&nc_db_lock);
 
     if ((file = fopen(NETCONFIG, "r")) == NULL) {
        nc_error = NC_NONETCONFIG;