Contiki 3.x
shell-base64.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * Base64-related shell commands
36  * \author
37  * Adam Dunkels <adam@sics.se>
38  */
39 
40 #include "contiki.h"
41 #include "shell.h"
42 
43 #include <ctype.h>
44 #include <stdio.h>
45 #ifndef HAVE_SNPRINTF
46 int snprintf(char *str, size_t size, const char *format, ...);
47 #endif /* HAVE_SNPRINTF */
48 
49 #include <string.h>
50 
51 /*---------------------------------------------------------------------------*/
52 PROCESS(shell_dec64_process, "dec64");
53 SHELL_COMMAND(dec64_command,
54  "dec64",
55  "dec64: decode base64 input",
56  &shell_dec64_process);
57 /*---------------------------------------------------------------------------*/
58 #define BASE64_MAX_LINELEN 76
59 
60 struct base64_decoder_state {
61  uint8_t data[3 * BASE64_MAX_LINELEN / 4];
62  int dataptr;
63  unsigned long tmpdata;
64  int sextets;
65  int padding;
66 };
67 /*---------------------------------------------------------------------------*/
68 static int
69 base64_decode_char(char c)
70 {
71  if(c >= 'A' && c <= 'Z') {
72  return c - 'A';
73  } else if(c >= 'a' && c <= 'z') {
74  return c - 'a' + 26;
75  } else if(c >= '0' && c <= '9') {
76  return c - '0' + 52;
77  } else if(c == '+') {
78  return 62;
79  } else if(c == '/') {
80  return 63;
81  } else {
82  return 0;
83  }
84 }
85 /*---------------------------------------------------------------------------*/
86 static int
87 base64_add_char(struct base64_decoder_state *s, char c)
88 {
89  if(isspace(c)) {
90  return 0;
91  }
92 
93  if(s->dataptr >= sizeof(s->data)) {
94  return 0;
95  }
96  if(c == '=') {
97  ++s->padding;
98  }
99 
100  s->tmpdata = (s->tmpdata << 6) | base64_decode_char(c);
101  ++s->sextets;
102  if(s->sextets == 4) {
103  s->sextets = 0;
104  s->data[s->dataptr] = (uint8_t)(s->tmpdata >> 16);
105  s->data[s->dataptr + 1] = (uint8_t)(s->tmpdata >> 8);
106  s->data[s->dataptr + 2] = (uint8_t)(s->tmpdata);
107  s->dataptr += 3;
108  if(s->dataptr == sizeof(s->data)) {
109  return 0;
110  } else {
111  return 1;
112  }
113  }
114  return 1;
115 }
116 /*---------------------------------------------------------------------------*/
117 PROCESS_THREAD(shell_dec64_process, ev, data)
118 {
119  struct shell_input *input;
120  struct base64_decoder_state s;
121  int i;
122 
123  PROCESS_BEGIN();
124 
125  while(1) {
127  input = data;
128 
129  if(input->len1 + input->len2 == 0) {
130  PROCESS_EXIT();
131  }
132 
133  s.sextets = s.dataptr = s.padding = 0;
134 
135  for(i = 0; i < input->len1; ++i) {
136  base64_add_char(&s, input->data1[i]);
137  }
138  for(i = 0; i < input->len2; ++i) {
139  base64_add_char(&s, input->data2[i]);
140  }
141  shell_output(&dec64_command, s.data, s.dataptr - s.padding, "", 0);
142  }
143  PROCESS_END();
144 }
145 /*---------------------------------------------------------------------------*/
146 void
147 shell_base64_init(void)
148 {
149  shell_register_command(&dec64_command);
150 }
151 /*---------------------------------------------------------------------------*/
#define PROCESS_EXIT()
Exit the currently running process.
Definition: process.h:200
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
Main header file for the Contiki shell
void shell_output(struct shell_command *c, void *data1, int len1, const void *data2, int len2)
Output data from a shell command.
Definition: shell.c:395
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
Structure for shell input data.
Definition: shell.h:365
void shell_register_command(struct shell_command *c)
Register a command with the shell.
Definition: shell.c:413
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
Definition: process.h:157
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
int shell_event_input
The event number for shell input data.
Definition: shell.c:70
#define SHELL_COMMAND(name, command, description, process)
Define a shell command.
Definition: shell.h:219