summaryrefslogtreecommitdiff
path: root/cvsfs.h
blob: 43970a7dbf5473875dbb070be52aba30a620d469 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/**********************************************************
 * cvsfs.h
 *
 * Copyright (C) 2004, 2005 by Stefan Siegl <stesie@brokenpipe.de>, Germany
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Publice License,
 * version 2 or any later. The license is contained in the COPYING
 * file that comes with the cvsfs distribution.
 *
 * configuration structures
 */

#ifndef CVSFS_CONFIG_H
#define CVSFS_CONFIG_H

#include <sys/types.h>
#include <maptime.h>
extern volatile struct mapped_time_value *cvsfs_maptime;

#include <stdio.h>


typedef struct {
  enum { PSERVER, EXT, LOCAL } cvs_mode;
  char *cvs_shell_client; /* program to use for :ext: connection */

  char *cvs_hostname;
  int cvs_port; /* port no. in localhost's endianess */

  char *cvs_username;
  char *cvs_password;

  char *cvs_root;
  char *cvs_module;

  char *homedir; /* homedir of user (location of .cvspass file) */

  /* whether or whether not the user wants to have no true stats information,
   * this would save downloading revisions just to have the timestamp and
   * permissions set correctly.
   */
  unsigned nostats :1;

#if HAVE_LIBZ
  /* which gzip level to use for file requests */
  unsigned gzip_level :4;
#endif

  /* file-handle to write debug information out to,
   * NULL, if no debug info is to be written out */
  FILE *debug_port;

} cvsfs_config;
extern cvsfs_config config;



typedef struct {
  __uid_t uid;
  __gid_t gid;
  __uid_t author;
  __fsid_t fsid;
  __mode_t mode;
} cvsfs_stat_template;
extern cvsfs_stat_template stat_template;



struct revision;
struct revision {
  /* revision id, something like 1.14 or 1.2.1.12 */
  char *id;

  /* this revisions access permissions */
  mode_t perm;

  /* revision's mtime stamp */
  time_t time;

  /* length of contents field */
  size_t length;

  /* pointer to this revision's contents */
  char *contents;

  /* pointer to the next revision structure, if there are multiple
   * revisions available locally
   */
  struct revision *next;

  /* locking mechanism for the revision structure, needs to be held,
   * on read/write access to contents field.
   */
  pthread_rwlock_t lock;
};



struct netnode;
struct netnode {
  /* name of this node, aka file or directory */
  char *name; 

  /* link to the next file or directory, within this directory */
  struct netnode *sibling;

  /* link to the first child of this directory, this points to the second
   * child via it's sibling pointer. NULL, if either this directory is empty
   * or this node represents a file
   */
  struct netnode *child;

  /* link to the parent netnode of this file or directory */
  struct netnode *parent;

  /* head revision number of this netnode, NULL to show, that this node
   * represents a directory!
   */ 
  struct revision *revision;

  /* inode number, assigned to this netnode structure */
  unsigned int fileno;

  /* pointer to node structure, assigned to this netnode */
  struct node *node;

  /* locking mechanism for the netnode. this needs to be held whenever touching
   * the revisions tree (the linking), access to revision to check whether it
   * is NULL (and therefore a directory) doesn't need to be locked.
   * for the revision structure itself there
   * is a separate lock inside each struct revision.
   *
   * furthermore access to node pointer must be locked.
   */
  pthread_rwlock_t lock;
};

/* pointer to root netnode */
extern struct netnode *rootdir;



/* helper macros for debugging ****/
#define DEBUG(cat,msg...) \
  if(config.debug_port) \
    fprintf(config.debug_port, PACKAGE ": " cat ": " msg);

#define FUNC_PROLOGUE_(func_name, fmt...) \
  do \
    { \
      const char *debug_func_name = func_name; \
      DEBUG("tracing", "entering %s (" __FILE__ ":%d) ", \
	    debug_func_name, __LINE__); \
      if(config.debug_port) \
        { \
          fmt; \
	  fprintf(config.debug_port, "\n"); \
	}

#define FUNC_PROLOGUE(func_name) \
  FUNC_PROLOGUE_(func_name, (void)0)

#define FUNC_PROLOGUE_FMT(func_name, fmt...) \
  FUNC_PROLOGUE_(func_name, fprintf(config.debug_port, fmt))

#define FUNC_PROLOGUE_NODE(func_name, node) \
  FUNC_PROLOGUE_FMT(func_name, "node=%s", (node)->nn->name)

#define FUNC_EPILOGUE_NORET() \
      DEBUG("tracing", "leaving %s\n", debug_func_name); \
    } while(0);

#define FUNC_RETURN_(ret, fmt) \
      { \
        int retval = (ret); \
        DEBUG("tracing", "leaving %s (" __FILE__ ":%d) ret=%d ", \
	      debug_func_name, __LINE__, retval); \
        if(config.debug_port) \
          { \
	    fmt; \
	    fprintf(config.debug_port, "\n"); \
	  } \
        return retval; \
      }

#define FUNC_EPILOGUE_(ret, fmt) \
      FUNC_RETURN_(ret, fmt) \
    } while(0);

#define FUNC_RETURN_FMT(ret, fmt...) \
  FUNC_RETURN_(ret, fprintf(config.debug_port, fmt))

#define FUNC_EPILOGUE_FMT(ret, fmt...) \
  FUNC_EPILOGUE_(ret, fprintf(config.debug_port, fmt))

#define FUNC_RETURN(ret) \
  FUNC_RETURN_(ret, (void)0)

#define FUNC_EPILOGUE(ret) \
  FUNC_EPILOGUE_(ret, (void)0)

#endif /* CVSFS_CONFIG_H */