Simple Geolocalization and Course Transmission Protocol (SGCTP)
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros Pages
principal.cpp
Go to the documentation of this file.
1 // INDENTING (emacs/vi): -*- mode:c++; tab-width:2; c-basic-offset:2; intent-tabs-mode:nil; -*- ex: set tabstop=2 expandtab:
2 
3 /*
4  * Simple Geolocalization and Course Transmission Protocol (SGCTP)
5  * Copyright (C) 2014 Cedric Dufour <http://cedric.dufour.name>
6  *
7  * The Simple Geolocalization and Course Transmission Protocol (SGCTP) is
8  * free software:
9  * you can redistribute it and/or modify it under the terms of the GNU General
10  * Public License as published by the Free Software Foundation, Version 3.
11  *
12  * The Simple Geolocalization and Course Transmission Protocol (SGCTP) is
13  * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15  * PARTICULAR PURPOSE.
16  *
17  * See the GNU General Public License for more details.
18  */
19 
20 // C
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 // C++
27 #include <set>
28 using namespace std;
29 
30 // SGCTP
31 #include "sgctp/principal.hpp"
32 #include "sgctp/transmit.hpp"
33 using namespace SGCTP;
34 
35 
36 //----------------------------------------------------------------------
37 // METHODS
38 //----------------------------------------------------------------------
39 
40 //
41 // SETTERS
42 //
43 
44 void CPrincipal::reset()
45 {
46  ui64tID = 0;
47  memset( pcPassword, '\0', SGCTP_MAX_PASSWORD_SIZE );
48  ui8tPayloadType_set.clear();
49 }
50 
51 void CPrincipal::erasePassword()
52 {
53  memset( pcPassword, '\0', SGCTP_MAX_PASSWORD_SIZE );
54 }
55 
56 void CPrincipal::setPassword( const char *_pcPassword )
57 {
58  uint8_t __ui8tPasswordLength =
59  ( strlen( _pcPassword ) < SGCTP_MAX_PASSWORD_LENGTH )
60  ? strlen( _pcPassword )
62  memcpy( pcPassword, _pcPassword, __ui8tPasswordLength );
63  pcPassword[__ui8tPasswordLength] = '\0';
64 }
65 
66 void CPrincipal::addPayloadType( uint8_t _ui8tPayloadType )
67 {
68  ui8tPayloadType_set.insert( _ui8tPayloadType );
69 }
70 
71 //
72 // GETTERS
73 //
74 
75 bool CPrincipal::hasPayloadTypes() const
76 {
77  return !ui8tPayloadType_set.empty();
78 }
79 
80 bool CPrincipal::hasPayloadType( uint8_t _ui8tPayloadType ) const
81 {
82  return
83  ui8tPayloadType_set.find( _ui8tPayloadType )
84  != ui8tPayloadType_set.end();
85 }
86 
87 //
88 // OTHER
89 //
90 
91 int CPrincipal::read( const char *_pcPrincipalsPath, uint64_t _ui64tID )
92 {
93  reset();
94 
95  // Open file
96  FILE *__pFILE = fopen( _pcPrincipalsPath, "r" );
97  if( __pFILE == NULL )
98  return -errno;
99 
100  // Parse file
101  char *__pcBuffer = NULL, *__pcDelim1, *__pcDelim2, *__pcDelim3;
102  size_t __sizeBuffer;
103  ssize_t __ssizeLine;
104  for(;;)
105  {
106  // retrieve line
107  __ssizeLine = getline( &__pcBuffer, &__sizeBuffer, __pFILE );
108  if( __ssizeLine < 0 )
109  break;
110 
111  // trim new-line
112  *strchrnul( __pcBuffer, '\r' ) = '\0';
113  *strchrnul( __pcBuffer, '\n' ) = '\0';
114 
115  // trim comments
116  *strchrnul( __pcBuffer, '#' ) = '\0';
117  *strchrnul( __pcBuffer, ' ' ) = '\0';
118 
119  // parse fields
120  char *__pcFieldEnd;
121 
122  // ... first field: ID
123  __pcDelim1 = strchr( __pcBuffer, ':' );
124  if( __pcDelim1 == NULL )
125  continue; // missing delimiter
126  if( __pcDelim1 - __pcBuffer > 20 )
127  continue; // invalid (too long) field
128  *__pcDelim1 = '\0';
129  unsigned long long int __ullID =
130  strtoull( __pcBuffer, &__pcFieldEnd, 10 );
131  if( *__pcFieldEnd != '\0' )
132  continue; // invalid syntax
133  if( __ullID != _ui64tID )
134  continue; // non-matching ID
135  ui64tID = __ullID;
136 
137  // ... second field: password
138  __pcDelim2 = strchr( __pcDelim1+1, ':' );
139  if( __pcDelim2 == NULL )
140  continue; // missing delimiter
141  if( __pcDelim2 - __pcDelim1 > SGCTP_MAX_PASSWORD_LENGTH )
142  continue; // invalid (too long) field
143  *__pcDelim2 = '\0';
144  strcpy( pcPassword, __pcDelim1+1 );
145 
146  // ... third field: payload type(s)
147  __pcDelim3 = __pcDelim2+1;
148  while( *__pcDelim3 != '\0' )
149  {
150  if( *__pcDelim3 == ',' )
151  __pcDelim3++; // skip comma
152  unsigned long int __ulPayloadType =
153  strtoul( __pcDelim3, &__pcDelim3, 10 );
154  if( *__pcDelim3 != ',' && *__pcDelim3 != '\0' )
155  continue; // invalid syntax
156  if( __ulPayloadType > CTransmit::PAYLOAD_UNDEFINED )
157  continue; // invalid value
158  ui8tPayloadType_set.insert( __ulPayloadType );
159  }
160  }
161 
162  // Free resources
163  if( __pcBuffer )
164  {
165  memset( __pcBuffer, '\0', __sizeBuffer );
166  free( __pcBuffer );
167  }
168  fclose( __pFILE );
169 
170  // Done
171  return
172  ( ui64tID == 0 && _ui64tID != 0 )
173  ? -EACCES
174  : 0;
175 }
#define SGCTP_MAX_PASSWORD_LENGTH
Definition: principal.hpp:32
#define SGCTP_MAX_PASSWORD_SIZE
Definition: principal.hpp:31