1// Copyright (c) 2006, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10//     * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14//     * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30// minidump_upload.m: Upload a minidump to a HTTP server.  The upload is sent as
31// a multipart/form-data POST request with the following parameters:
32//  prod: the product name
33//  ver: the product version
34//  symbol_file: the breakpad format symbol file
35
36#import <unistd.h>
37
38#import <Foundation/Foundation.h>
39
40#import "common/mac/HTTPMultipartUpload.h"
41
42typedef struct {
43  NSString *minidumpPath;
44  NSString *uploadURLStr;
45  NSString *product;
46  NSString *version;
47  BOOL success;
48} Options;
49
50//=============================================================================
51static void Start(Options *options) {
52  NSURL *url = [NSURL URLWithString:options->uploadURLStr];
53  HTTPMultipartUpload *ul = [[HTTPMultipartUpload alloc] initWithURL:url];
54  NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
55
56  // Add parameters
57  [parameters setObject:options->product forKey:@"prod"];
58  [parameters setObject:options->version forKey:@"ver"];
59  [ul setParameters:parameters];
60
61  // Add file
62  [ul addFileAtPath:options->minidumpPath name:@"upload_file_minidump"];
63
64  // Send it
65  NSError *error = nil;
66  NSData *data = [ul send:&error];
67  NSString *result = [[NSString alloc] initWithData:data
68                                           encoding:NSUTF8StringEncoding];
69
70  NSLog(@"Send: %@", error ? [error description] : @"No Error");
71  NSLog(@"Response: %d", [[ul response] statusCode]);
72  NSLog(@"Result: %d bytes\n%@", [data length], result);
73
74  [result release];
75  [ul release];
76  options->success = !error;
77}
78
79//=============================================================================
80static void
81Usage(int argc, const char *argv[]) {
82  fprintf(stderr, "Submit minidump information.\n");
83  fprintf(stderr, "Usage: %s -p <product> -v <version> <minidump> "
84          "<upload-URL>\n", argv[0]);
85  fprintf(stderr, "<minidump> should be a minidump.\n");
86  fprintf(stderr, "<upload-URL> is the destination for the upload\n");
87
88  fprintf(stderr, "\t-h: Usage\n");
89  fprintf(stderr, "\t-?: Usage\n");
90}
91
92//=============================================================================
93static void
94SetupOptions(int argc, const char *argv[], Options *options) {
95  extern int optind;
96  char ch;
97
98  while ((ch = getopt(argc, (char * const *)argv, "p:v:h?")) != -1) {
99    switch (ch) {
100      case 'p':
101        options->product = [NSString stringWithUTF8String:optarg];
102        break;
103      case 'v':
104        options->version = [NSString stringWithUTF8String:optarg];
105        break;
106
107      default:
108        Usage(argc, argv);
109        exit(0);
110        break;
111    }
112  }
113
114  if ((argc - optind) != 2) {
115    fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]);
116    Usage(argc, argv);
117    exit(1);
118  }
119
120  options->minidumpPath = [NSString stringWithUTF8String:argv[optind]];
121  options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]];
122}
123
124//=============================================================================
125int main (int argc, const char * argv[]) {
126  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
127  Options options;
128
129  bzero(&options, sizeof(Options));
130  SetupOptions(argc, argv, &options);
131  Start(&options);
132
133  [pool release];
134  return options.success ? 0 : 1;
135}
136