baseline

yet another open-source distributed versioning control system
Log | Files | Refs

common.c (2743B)


      1 /*
      2  * Copyright (c) 2014 Mohamed Aslan <maslan@sce.carleton.ca>
      3  *
      4  * Permission to use, copy, modify, and distribute this software for any
      5  * purpose with or without fee is hereby granted, provided that the above
      6  * copyright notice and this permission notice appear in all copies.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #include <stdio.h>
     18 #include <stdlib.h>
     19 
     20 #include <string.h>
     21 #include <limits.h>
     22 #include <unistd.h>
     23 
     24 #include <sys/stat.h>
     25 
     26 #include "defaults.h"
     27 #include "common.h"
     28 
     29 
     30 /* cache the repository root dir for future calls of baseline_repo_get_rootdir() */
     31 static char *repo_rootdir = NULL;
     32 static char *repo_baselinedir = NULL;		/* repo_rootdir/BASELINE_DIR */
     33 
     34 int
     35 exists(const char *f)
     36 {
     37 	struct stat s;
     38 
     39 	if(stat(f, &s) == -1)
     40 		return 0;
     41 	return 1;
     42 }
     43 
     44 int
     45 dir_exists(const char *dir)
     46 {
     47 	struct stat s;
     48 
     49 	if (stat(dir, &s) == -1)
     50 		return 0;
     51 	if (!S_ISDIR(s.st_mode))
     52 		return 0;
     53 	return 1;
     54 }
     55 
     56 static int
     57 baseline_validate_repo(const char *path)
     58 {
     59 	char *ptr = NULL;
     60 	int valid;
     61 
     62 	asprintf(&ptr, "%s/%s", path, BASELINE_DIR);
     63 	if (ptr == NULL)
     64 		return 0;
     65 	valid = dir_exists(ptr);
     66 	/* TODO: use access & check for modes as well */
     67 	/* TODO: ask objdb, and may be dircache too */
     68 	free(ptr);
     69 	return valid;
     70 }
     71 
     72 /*
     73  * may not be so safe
     74  * do not free the returned pointer, it will be cached for later calls
     75  * try not to use chdir() as possible
     76  */
     77 const char *
     78 baseline_repo_get_rootdir()
     79 {
     80 	char cwd[PATH_MAX+1];
     81 	int i;
     82 	size_t len;
     83 
     84 	/* check if the repository root dir already cached */
     85 	if (repo_rootdir != NULL)
     86 		return repo_rootdir;
     87 	if (getcwd(cwd, sizeof(cwd)) == NULL)
     88 		return NULL;
     89 	len = strlen(cwd);
     90 	for (i=len-1 ; i>=0 ; i--) {
     91 		if (cwd[i] == '/') {
     92 			if (baseline_validate_repo(cwd))
     93 				break;
     94 			cwd[i] = '\0';
     95 		}
     96 	}
     97 	if (i == -1) {
     98 		if (baseline_validate_repo(cwd))
     99 			repo_rootdir = strdup("/");
    100 		else
    101 			return NULL;
    102 	}
    103 	else {
    104 		repo_rootdir = strdup(cwd);
    105 	}
    106 #ifdef DEBUG
    107 	printf("repository root dir: %s\n", repo_rootdir);
    108 #endif
    109 	return repo_rootdir;
    110 }
    111 
    112 const char*
    113 baseline_repo_get_baselinedir()
    114 {
    115 	const char *root_dir;
    116 	if (repo_baselinedir != NULL)
    117 		return repo_baselinedir;
    118 	root_dir = baseline_repo_get_rootdir();
    119 	asprintf(&repo_baselinedir, "%s/%s", root_dir, BASELINE_DIR);
    120 	return repo_baselinedir;
    121 }
    122