LCOV - code coverage report
Current view: top level - src - utils.c (source / functions) Hit Total Coverage
Test: deployctl-0.3.15.2.96a2d Code Coverage Lines: 61 137 44.5 %
Date: 2018-06-22 Functions: 7 12 58.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : //  utils.c
       3             : //  deployctl
       4             : //
       5             : //  Created by Danny Goossen on 10/5/17.
       6             : //  Copyright (c) 2017 Danny Goossen. All rights reserved.
       7             : //
       8             : 
       9             : #define _XOPEN_SOURCE 500
      10             : #include <ftw.h>
      11             : typedef unsigned short int u_short;
      12             : #include <fts.h>
      13             : 
      14             : #include "deployd.h"
      15             : 
      16             : 
      17             : 
      18             : 
      19             : #ifndef OPEN_MAX
      20             : #define OPEN_MAX 1023
      21             : #endif
      22             : 
      23             : 
      24             : /*------------------------------------------------------------------------
      25             :  * Convert string to uppercase
      26             :  *------------------------------------------------------------------------*/
      27           8 : void upper_string(char s[]) {
      28          16 :    if (!s) return;
      29             :    int c = 0;
      30             : 
      31          44 :    while (s[c] != '\0') {
      32          37 :       if (s[c] >= 'a' && s[c] <= 'z') {
      33          17 :          s[c] = s[c] - 32;
      34             :       }
      35          37 :       c++;
      36             :    }
      37             : }
      38             : /*------------------------------------------------------------------------
      39             :  * Convert string to lower case
      40             :  *------------------------------------------------------------------------*/
      41           6 : void lower_string(char s[]) {
      42          12 :    if (!s) return;
      43             :    int c = 0;
      44             :    
      45          82 :    while (s[c] != '\0') {
      46          76 :       if (s[c] >= 'A' && s[c] <= 'Z') {
      47           0 :          s[c] = s[c] + 32;
      48             :       }
      49          76 :       c++;
      50             :    }
      51             : }
      52             : 
      53          10 : void upper_string_n(char s[],size_t n) {
      54          20 :    if (!s) return;
      55             :    int c = 0;
      56             : 
      57          41 :    while (s[c] != '\0' && c<n) {
      58          31 :       if (s[c] >= 'a' && s[c] <= 'z') {
      59          15 :          s[c] = s[c] - 32;
      60             :       }
      61          31 :       c++;
      62             :    }
      63             : }
      64             : 
      65           0 : void split_path_file(char** p, char** f,const char *pf) {
      66           0 :   if (!pf || strlen(pf)==0) return;
      67             :    const char *slash = pf;
      68             :    char *next;
      69           0 :    while ((next = strpbrk(slash + 1, "\\/"))) slash = next;
      70           0 :    if (pf != slash) slash++;
      71           0 :    *p = cJSON_strdup_n((const unsigned char *)pf, slash - pf);
      72           0 :    *f = strdup(slash);
      73             : }
      74             : 
      75           4 : void split_path_file_2_path(char** p, const char *pf) {
      76           8 :     if (!pf || strlen(pf)==0) return;
      77             :    const char *slash = pf;
      78             :    char *next;
      79           8 :    while ((next = strpbrk(slash + 1, "\\/"))) slash = next;
      80           4 :    if (pf != slash) slash++;
      81           4 :    *p =cJSON_strdup_n((const unsigned char *)pf, slash - pf);
      82             : }
      83             : 
      84             : int
      85           0 : nftw_x(const char *path, int (*fn)(const char *, const struct stat *, int,
      86             :                                  struct FTW *,void * data), int nfds, int ftwflags,void * data)
      87             : {
      88             :    const char *paths[2];
      89             :    struct FTW ftw;
      90             :    FTSENT *cur;
      91             :    FTS *ftsp;
      92             :    int ftsflags, fnflag, error, postorder, sverrno;
      93             : 
      94             :    /* XXX - nfds is currently unused */
      95           0 :    if (nfds < 1 || nfds > OPEN_MAX) {
      96           0 :       errno = EINVAL;
      97           0 :       return (-1);
      98             :    }
      99             : 
     100           0 :    ftsflags = FTS_COMFOLLOW;
     101           0 :    if (!(ftwflags & FTW_CHDIR))
     102           0 :       ftsflags |= FTS_NOCHDIR;
     103           0 :    if (ftwflags & FTW_MOUNT)
     104           0 :       ftsflags |= FTS_XDEV;
     105           0 :    if (ftwflags & FTW_PHYS)
     106           0 :       ftsflags |= FTS_PHYSICAL;
     107           0 :    postorder = (ftwflags & FTW_DEPTH) != 0;
     108           0 :    paths[0] = path;
     109           0 :    paths[1] = NULL;
     110           0 :    ftsp = fts_open((char * const *)paths, ftsflags, NULL);
     111           0 :    if (ftsp == NULL)
     112             :       return (-1);
     113             :    error = 0;
     114           0 :    while ((cur = fts_read(ftsp)) != NULL) {
     115           0 :       switch (cur->fts_info) {
     116             :          case FTS_D:
     117           0 :             if (postorder)
     118           0 :                continue;
     119             :             fnflag = FTW_D;
     120             :             break;
     121             :          case FTS_DNR:
     122             :             fnflag = FTW_DNR;
     123             :             break;
     124             :          case FTS_DP:
     125           0 :             if (!postorder)
     126           0 :                continue;
     127             :             fnflag = FTW_DP;
     128             :             break;
     129             :          case FTS_F:
     130             :          case FTS_DEFAULT:
     131           0 :             fnflag = FTW_F;
     132           0 :             break;
     133             :          case FTS_NS:
     134             :          case FTS_NSOK:
     135           0 :             fnflag = FTW_NS;
     136           0 :             break;
     137             :          case FTS_SL:
     138           0 :             fnflag = FTW_SL;
     139           0 :             break;
     140             :          case FTS_SLNONE:
     141           0 :             fnflag = FTW_SLN;
     142           0 :             break;
     143             :          case FTS_DC:
     144           0 :             errno = ELOOP;
     145             :             /* FALLTHROUGH */
     146             :          default:
     147             :             error = -1;
     148             :             goto done;
     149             :       }
     150           0 :       ftw.base = cur->fts_pathlen - cur->fts_namelen;
     151           0 :       ftw.level = cur->fts_level;
     152           0 :       error = fn(cur->fts_path, cur->fts_statp, fnflag, &ftw,data);
     153           0 :       if (error != 0)
     154             :          break;
     155             :    }
     156             : done:
     157           0 :    sverrno = errno;
     158           0 :    (void) fts_close(ftsp);
     159           0 :    errno = sverrno;
     160           0 :    return (error);
     161             : }
     162             : 
     163         214 : int remove_it(const char *path, const struct stat *s, int flag, struct FTW *f)
     164             : {
     165         214 :    int status=0;
     166             :    int (*rm_func)( const char * );
     167             : 
     168         214 :    switch( flag ) {
     169             :       default:     rm_func = unlink; break;
     170         152 :       case FTW_DP: rm_func = rmdir;
     171             :    }
     172         214 :   status = (rm_func( path ), status != 0 );
     173             :     //  perror( path );
     174         214 :    return status;
     175             : }
     176             : 
     177             : struct payload{
     178             :    cJSON ** filelist;
     179             : };
     180             : 
     181             : 
     182           0 : int add_to_file_list(const char *path,int mode,cJSON ** filelist)
     183             : {
     184           0 :    int result=0;
     185           0 :    size_t len=strlen(path);
     186           0 :    if ((S_ISDIR(mode) && len>2 && strcmp(path+len-2, ".")!=0 && len >3 && strcmp(path+len-3, "..")!=0 )|| !S_ISDIR(mode))
     187             :    {
     188           0 :       if (!*filelist) *filelist=cJSON_CreateArray();
     189           0 :       if (*filelist)
     190             :       {
     191           0 :          cJSON * tmpo=cJSON_CreateObject();
     192           0 :          cJSON_AddStringToObject(tmpo, "path", path);
     193           0 :          cJSON_AddNumberToObject(tmpo, "mode", mode);
     194           0 :          cJSON_AddItemToArray(*filelist,tmpo);
     195             :       }
     196             :       else
     197             :          result=1;
     198             :    }
     199           0 :    return result;
     200             : }
     201             : 
     202           0 : int list_it(const char *path, const struct stat *s, int flag, struct FTW *f,void* data)
     203             : {
     204           0 :    int status=0;
     205             :    switch( flag ) {
     206             :       default:     ; break;
     207             :          /* we'll handle dir/symlinks/files */
     208             :       case FTW_SL:
     209             :       case FTW_F:
     210             :       case FTW_D:
     211           0 :          status=add_to_file_list( path,s->st_mode ,data) ;break;
     212             :    }
     213           0 :    return status;
     214             : }
     215             : 
     216             : 
     217           0 : int getfilelist(char * projectdir,cJSON * paths,cJSON ** filelist)
     218             : {
     219             :    
     220           0 :    if (!projectdir || !paths || !filelist ) return -1;
     221             :    char tmp[1024];
     222             :    cJSON * path;
     223           0 :    cJSON_ArrayForEach(path,paths)
     224             :    {
     225           0 :       snprintf((char*)tmp,1024,"%s%s",projectdir,path->valuestring);
     226           0 :       debug("get filelist for path %s\n",tmp);
     227             :       
     228             :       
     229             :       struct stat sb;
     230             :       
     231           0 :       if (stat(tmp, &sb) == 0 && S_ISDIR(sb.st_mode))
     232             :       {
     233             :          
     234           0 :          add_to_file_list(path->valuestring, sb.st_mode, filelist);
     235           0 :          if (nftw_x((char*)tmp, list_it, 6 ,FTW_PHYS ,(void*)filelist)) //| FTW_DEPTH
     236             :          {
     237           0 :             perror( tmp );
     238           0 :             error("nftw return non 0\n");
     239           0 :             return 1;
     240             :          }
     241             :       }
     242           0 :       else if (stat(tmp, &sb) == 0 && (S_ISLNK(sb.st_mode)|| S_ISREG(sb.st_mode)))
     243           0 :          add_to_file_list(path->valuestring, sb.st_mode, filelist);
     244             :       
     245             :    }
     246             :    return 0;
     247             : }
     248             : 
     249             : // Recursive remove directory
     250          61 : void _rmdir(const char * dir, const char * base)
     251             : {
     252             :    char tmp[1024];
     253          61 :    if (!dir || strlen(dir)==0)
     254             :    {
     255          14 :       if (!base || strlen(base)==0) return;
     256           7 :       else snprintf((char*)tmp,1024,"%s",base);
     257             :    }
     258          54 :    else if (!base || strlen(base)==0)
     259             :    {
     260          86 :       if (!dir || strlen(dir)==0) return;
     261          43 :       else snprintf((char*)tmp,1024,"%s",dir);
     262             :    }
     263             :    else
     264             :   {
     265          11 :      if (dir[0]=='/')
     266          11 :      snprintf((char*)tmp,1024,"%s%s",base,dir);
     267             :      else
     268           0 :      snprintf((char*)tmp,1024,"%s/%s",base,dir);
     269             :   }
     270             : 
     271             :    struct stat sb;
     272             : 
     273          61 :    if (stat(tmp, &sb) == 0 && S_ISDIR(sb.st_mode))
     274             :    {
     275          47 :       if (nftw((char*)tmp, remove_it, 6 ,FTW_PHYS | FTW_DEPTH))
     276             :       {
     277           0 :           perror( tmp );
     278             :       }
     279             :    }
     280             : }
     281             : 
     282             : // mdir -p
     283          43 : void _mkdir(const char *dir, const char * base) {
     284             :    char tmp[1024];
     285          43 :    char *p = NULL;
     286             :    size_t len;
     287          43 :    if (!dir || strlen(dir)==0)
     288             :    {
     289          26 :       if (!base || strlen(base)==0) return;
     290          13 :       else snprintf((char*)tmp,1024,"%s",base);
     291             :    }
     292          30 :    else if (!base || strlen(base)==0)
     293             :    {
     294           6 :       if (!dir || strlen(dir)==0) return;
     295           3 :       else snprintf((char*)tmp,1024,"%s",dir);
     296             :    }
     297             :    else
     298             :   {
     299          27 :      if (dir[0]=='/')
     300          24 :      snprintf((char*)tmp,1024,"%s%s",base,dir);
     301             :      else
     302           3 :      snprintf((char*)tmp,1024,"%s/%s",base,dir);
     303             :   }
     304             :    struct stat sb;
     305          43 :    if (stat(tmp, &sb) == 0 && S_ISDIR(sb.st_mode))
     306             :    {
     307             :       //debug("directory %s exists\n",tmp);
     308             :    }
     309             :    else
     310             :    {
     311          43 :       len = strlen(tmp);
     312          43 :       if(tmp[len - 1] == '/')
     313           1 :          tmp[len - 1] = 0;
     314             :       //debug("mkdir %s\n",tmp);
     315        3147 :       for(p = tmp + 1; *p; p++)
     316        3147 :          if(*p == '/') {
     317         270 :             *p = 0;
     318         270 :             if (stat(tmp, &sb) == 0 && S_ISDIR(sb.st_mode))
     319             :             {
     320             :                //debug("sub directory %s exists\n",tmp);
     321             :             }
     322             :             else{
     323             :             //debug("mkdir sub %s\n",tmp);
     324         139 :             mkdir(tmp,S_IRWXG | S_IRWXU);
     325             :             }
     326         270 :             *p = '/';
     327             :          }
     328             :       //debug("mkdir sub %s\n",tmp);
     329          43 :       mkdir(tmp, S_IRWXG | S_IRWXU);
     330             :    }
     331             : }
     332             : 
     333             : /*
     334             : 
     335             : */

Generated by: LCOV version 1.10